new feature: functions to jump to previous or following block of text
And hard-bind the keys Ctrl+Up and Ctrl+Down to these functions. Unlike the paragraph-jumping code, these new functions disregard any indentation, treating only blank lines as separators. They also do an automatic smart home when that option is set. This fulfills https://savannah.gnu.org/bugs/?48291.master
parent
8c7a38596d
commit
c6dbcf91c3
|
@ -510,6 +510,13 @@ Moves the cursor to the beginning of the current paragraph.
|
|||
.B endpara
|
||||
Moves the cursor to the end of the current paragraph.
|
||||
.TP
|
||||
.B prevblock
|
||||
Moves the cursor to the beginning of the current or preceding block of text.
|
||||
(Blocks are separated by one or more blank lines.)
|
||||
.TP
|
||||
.B nextblock
|
||||
Moves the cursor to the beginning of the next block of text.
|
||||
.TP
|
||||
.B prevpage
|
||||
Goes up one screenful.
|
||||
.TP
|
||||
|
|
|
@ -1102,6 +1102,13 @@ Moves the cursor to the beginning of the current paragraph.
|
|||
@item endpara
|
||||
Moves the cursor to the end of the current paragraph.
|
||||
|
||||
@item prevblock
|
||||
Moves the cursor to the beginning of the current or preceding block of text.
|
||||
(Blocks are separated by one or more blank lines.)
|
||||
|
||||
@item nextblock
|
||||
Moves the cursor to the beginning of the next block of text.
|
||||
|
||||
@item prevpage
|
||||
Goes up one screenful.
|
||||
|
||||
|
|
21
src/global.c
21
src/global.c
|
@ -46,6 +46,8 @@ message_type lastmessage = HUSH;
|
|||
#ifndef NANO_TINY
|
||||
int controlleft = CONTROL_LEFT;
|
||||
int controlright = CONTROL_RIGHT;
|
||||
int controlup = CONTROL_UP;
|
||||
int controldown = CONTROL_DOWN;
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_WRAPJUSTIFY
|
||||
|
@ -573,6 +575,10 @@ void shortcut_init(void)
|
|||
const char *nano_nextline_msg = N_("Go to next line");
|
||||
const char *nano_home_msg = N_("Go to beginning of current line");
|
||||
const char *nano_end_msg = N_("Go to end of current line");
|
||||
#ifndef NANO_TINY
|
||||
const char *nano_prevblock_msg = N_("Go to previous block of text");
|
||||
const char *nano_nextblock_msg = N_("Go to next block of text");
|
||||
#endif
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
const char *nano_parabegin_msg =
|
||||
N_("Go to beginning of paragraph; then of previous paragraph");
|
||||
|
@ -872,6 +878,13 @@ void shortcut_init(void)
|
|||
add_to_funcs(do_down_void, MMAIN|MBROWSER,
|
||||
next_line_tag, IFSCHELP(nano_nextline_msg), BLANKAFTER, VIEW);
|
||||
|
||||
#ifndef NANO_TINY
|
||||
add_to_funcs(do_prev_block, MMAIN,
|
||||
N_("Prev Block"), IFSCHELP(nano_prevblock_msg), TOGETHER, VIEW);
|
||||
add_to_funcs(do_next_block, MMAIN,
|
||||
N_("Next Block"), IFSCHELP(nano_nextblock_msg), TOGETHER, VIEW);
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
add_to_funcs(do_para_begin_void, MMAIN|MWHEREIS,
|
||||
N_("Beg of Par"), IFSCHELP(nano_parabegin_msg), TOGETHER, VIEW);
|
||||
|
@ -1133,6 +1146,10 @@ void shortcut_init(void)
|
|||
add_to_sclist(MMAIN|MHELP|MBROWSER, "Up", do_up_void, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "^N", do_down_void, 0);
|
||||
add_to_sclist(MMAIN|MHELP|MBROWSER, "Down", do_down_void, 0);
|
||||
#ifndef NANO_TINY
|
||||
add_to_sclist(MMAIN, "M-7", do_prev_block, 0);
|
||||
add_to_sclist(MMAIN, "M-8", do_next_block, 0);
|
||||
#endif
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
add_to_sclist(MMAIN, "M-(", do_para_begin_void, 0);
|
||||
add_to_sclist(MMAIN, "M-9", do_para_begin_void, 0);
|
||||
|
@ -1453,6 +1470,10 @@ sc *strtosc(const char *input)
|
|||
s->scfunc = do_cut_prev_word;
|
||||
else if (!strcasecmp(input, "cutwordright"))
|
||||
s->scfunc = do_cut_next_word;
|
||||
else if (!strcasecmp(input, "prevblock"))
|
||||
s->scfunc = do_prev_block;
|
||||
else if (!strcasecmp(input, "nextblock"))
|
||||
s->scfunc = do_next_block;
|
||||
else if (!strcasecmp(input, "findbracket"))
|
||||
s->scfunc = do_find_bracket;
|
||||
else if (!strcasecmp(input, "wordcount"))
|
||||
|
|
42
src/move.c
42
src/move.c
|
@ -210,6 +210,48 @@ void do_para_end_void(void)
|
|||
#endif /* !DISABLE_JUSTIFY */
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Move to the preceding block of text in the file. */
|
||||
void do_prev_block(void)
|
||||
{
|
||||
filestruct *was_current = openfile->current;
|
||||
bool is_text = FALSE, seen_text = FALSE;
|
||||
|
||||
/* Skip backward until first blank line after some nonblank line(s). */
|
||||
while (openfile->current->prev != NULL && (!seen_text || is_text)) {
|
||||
openfile->current = openfile->current->prev;
|
||||
is_text = !white_string(openfile->current->data);
|
||||
seen_text = seen_text || is_text;
|
||||
}
|
||||
|
||||
/* Step forward one line again if this one is blank. */
|
||||
if (openfile->current->next != NULL &&
|
||||
white_string(openfile->current->data))
|
||||
openfile->current = openfile->current->next;
|
||||
|
||||
openfile->current_x = 0;
|
||||
edit_redraw(was_current);
|
||||
do_home();
|
||||
}
|
||||
|
||||
/* Move to the next block of text in the file. */
|
||||
void do_next_block(void)
|
||||
{
|
||||
filestruct *was_current = openfile->current;
|
||||
bool is_white = white_string(openfile->current->data);
|
||||
bool seen_white = is_white;
|
||||
|
||||
/* Skip forward until first nonblank line after some blank line(s). */
|
||||
while (openfile->current->next != NULL && (!seen_white || is_white)) {
|
||||
openfile->current = openfile->current->next;
|
||||
is_white = white_string(openfile->current->data);
|
||||
seen_white = seen_white || is_white;
|
||||
}
|
||||
|
||||
openfile->current_x = 0;
|
||||
edit_redraw(was_current);
|
||||
do_home();
|
||||
}
|
||||
|
||||
/* Move to the previous word in the file. If allow_punct is TRUE, treat
|
||||
* punctuation as part of a word. If allow_update is TRUE, update the
|
||||
* screen afterwards. */
|
||||
|
|
|
@ -2527,13 +2527,19 @@ int main(int argc, char **argv)
|
|||
|
||||
#if !defined(NANO_TINY) && defined(HAVE_KEY_DEFINED)
|
||||
const char *keyvalue;
|
||||
/* Ask ncurses for the key codes for Control+Left and Control+Right. */
|
||||
/* Ask ncurses for the key codes for Control+Left/Right/Up/Down. */
|
||||
keyvalue = tigetstr("kLFT5");
|
||||
if (keyvalue != 0 && keyvalue != (char *)-1)
|
||||
controlleft = key_defined(keyvalue);
|
||||
keyvalue = tigetstr("kRIT5");
|
||||
if (keyvalue != 0 && keyvalue != (char *)-1)
|
||||
controlright = key_defined(keyvalue);
|
||||
keyvalue = tigetstr("kUP5");
|
||||
if (keyvalue != 0 && keyvalue != (char *)-1)
|
||||
controlup = key_defined(keyvalue);
|
||||
keyvalue = tigetstr("kDN5");
|
||||
if (keyvalue != 0 && keyvalue != (char *)-1)
|
||||
controldown = key_defined(keyvalue);
|
||||
#endif
|
||||
|
||||
#ifndef USE_SLANG
|
||||
|
|
|
@ -564,6 +564,8 @@ enum
|
|||
/* Codes for "modified" Arrow keys, beyond KEY_MAX of ncurses. */
|
||||
#define CONTROL_LEFT 0x401
|
||||
#define CONTROL_RIGHT 0x402
|
||||
#define CONTROL_UP 0x403
|
||||
#define CONTROL_DOWN 0x404
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* An imaginary key for when we get a SIGWINCH (window resize). */
|
||||
|
|
|
@ -39,6 +39,8 @@ extern message_type lastmessage;
|
|||
#ifndef NANO_TINY
|
||||
extern int controlleft;
|
||||
extern int controlright;
|
||||
extern int controlup;
|
||||
extern int controldown;
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_WRAPJUSTIFY
|
||||
|
@ -397,6 +399,8 @@ void do_para_end(bool allow_update);
|
|||
void do_para_end_void(void);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
void do_prev_block(void);
|
||||
void do_next_block(void);
|
||||
void do_prev_word(bool allow_punct, bool allow_update);
|
||||
void do_prev_word_void(void);
|
||||
bool do_next_word(bool allow_punct, bool allow_update);
|
||||
|
@ -647,6 +651,7 @@ void do_tab(void);
|
|||
void do_indent(ssize_t cols);
|
||||
void do_indent_void(void);
|
||||
void do_unindent(void);
|
||||
bool white_string(const char *s);
|
||||
void do_undo(void);
|
||||
void do_redo(void);
|
||||
#endif
|
||||
|
|
16
src/winio.c
16
src/winio.c
|
@ -635,6 +635,10 @@ int parse_kbinput(WINDOW *win)
|
|||
retval = sc_seq_or(do_prev_word_void, 0);
|
||||
else if (retval == controlright)
|
||||
retval = sc_seq_or(do_next_word_void, 0);
|
||||
else if (retval == controlup)
|
||||
retval = sc_seq_or(do_prev_block, 0);
|
||||
else if (retval == controldown)
|
||||
retval = sc_seq_or(do_next_block, 0);
|
||||
#endif
|
||||
|
||||
/* If our result is an extended keypad value (i.e. a value
|
||||
|
@ -696,8 +700,9 @@ int convert_sequence(const int *seq, size_t seq_len)
|
|||
if (seq_len >= 5) {
|
||||
switch (seq[4]) {
|
||||
case 'A': /* Esc O 1 ; 5 A == Ctrl-Up on Terminal. */
|
||||
return CONTROL_UP;
|
||||
case 'B': /* Esc O 1 ; 5 B == Ctrl-Down on Terminal. */
|
||||
return arrow_from_abcd(seq[4]);
|
||||
return CONTROL_DOWN;
|
||||
case 'C': /* Esc O 1 ; 5 C == Ctrl-Right on Terminal. */
|
||||
return CONTROL_RIGHT;
|
||||
case 'D': /* Esc O 1 ; 5 D == Ctrl-Left on Terminal. */
|
||||
|
@ -766,8 +771,9 @@ int convert_sequence(const int *seq, size_t seq_len)
|
|||
case 'Y': /* Esc O Y == F10 on Mach console. */
|
||||
return KEY_F(10);
|
||||
case 'a': /* Esc O a == Ctrl-Up on rxvt. */
|
||||
return CONTROL_UP;
|
||||
case 'b': /* Esc O b == Ctrl-Down on rxvt. */
|
||||
return arrow_from_abcd(seq[1]);
|
||||
return CONTROL_DOWN;
|
||||
case 'c': /* Esc O c == Ctrl-Right on rxvt. */
|
||||
return CONTROL_RIGHT;
|
||||
case 'd': /* Esc O d == Ctrl-Left on rxvt. */
|
||||
|
@ -841,8 +847,9 @@ int convert_sequence(const int *seq, size_t seq_len)
|
|||
case 'o':
|
||||
switch (seq[1]) {
|
||||
case 'a': /* Esc o a == Ctrl-Up on Eterm. */
|
||||
return CONTROL_UP;
|
||||
case 'b': /* Esc o b == Ctrl-Down on Eterm. */
|
||||
return arrow_from_abcd(seq[1]);
|
||||
return CONTROL_DOWN;
|
||||
case 'c': /* Esc o c == Ctrl-Right on Eterm. */
|
||||
return CONTROL_RIGHT;
|
||||
case 'd': /* Esc o d == Ctrl-Left on Eterm. */
|
||||
|
@ -895,8 +902,9 @@ int convert_sequence(const int *seq, size_t seq_len)
|
|||
if (seq_len >= 5) {
|
||||
switch (seq[4]) {
|
||||
case 'A': /* Esc [ 1 ; 5 A == Ctrl-Up on xterm. */
|
||||
return CONTROL_UP;
|
||||
case 'B': /* Esc [ 1 ; 5 B == Ctrl-Down on xterm. */
|
||||
return arrow_from_abcd(seq[4]);
|
||||
return CONTROL_DOWN;
|
||||
case 'C': /* Esc [ 1 ; 5 C == Ctrl-Right on xterm. */
|
||||
return CONTROL_RIGHT;
|
||||
case 'D': /* Esc [ 1 ; 5 D == Ctrl-Left on xterm. */
|
||||
|
|
Loading…
Reference in New Issue