diff options
author | pgen <p.gen.progs@gmail.com> | 2019-03-24 18:23:18 +0100 |
---|---|---|
committer | pgen <p.gen.progs@gmail.com> | 2019-03-25 00:14:28 +0100 |
commit | 01ea40a6cffccd89f97fa59c0a056df496a1ed3a (patch) | |
tree | 4ee8b458cc29cfe3f2e5dd6320e7f45beb41cc69 | |
parent | c464effa80ed83d4e146dabd6b8bd6bb9dacb3f9 (diff) |
Improve the PgUp/PgDn scrolling
When on the first/last line containing a selectable word, PgUp/PgDn will
move the window to show the maximum number of non selectable lines while
keeping the cursor in the window.
-rw-r--r-- | smenu.c | 240 | ||||
-rw-r--r-- | tests/scrolling/data7 | 20 | ||||
-rw-r--r-- | tests/scrolling/t0005.good | 10 | ||||
-rw-r--r-- | tests/scrolling/t0006.good | 10 | ||||
-rw-r--r-- | tests/scrolling/t0011.good | 19 | ||||
l--------- | tests/scrolling/t0011.in | 1 | ||||
-rw-r--r-- | tests/scrolling/t0011.tst | 4 |
7 files changed, 216 insertions, 88 deletions
@@ -4525,6 +4525,7 @@ move_up(win_t * win, term_t * term, toggle_t * toggle, long line; /* The line being processed (the target line) */ long start_line; /* The first line of the window */ long cur_line; /* The line of the cursor */ + long nlines; /* Number of line in the window */ long first_selectable_line; /* the line containing the first * * selectable word */ long lines_skipped; /* The number of line between the target line and the * @@ -4548,52 +4549,92 @@ move_up(win_t * win, term_t * term, toggle_t * toggle, first_selectable_line = line_nb_of_word_a[first_selectable]; lines_skipped = 0; found = 0; + nlines = win->max_lines < last_line + 1 ? win->max_lines : last_line + 1; /* initialise the target line */ /* """""""""""""""""""""""""" */ line = cur_line; - if (line - page < 0) - { - /* Trivial case, we are already on the first page */ - /* just jump to the first selectable line */ - /* """""""""""""""""""""""""""""""""""""""""""""" */ - line = first_selectable_line; - last_word = get_line_last_word(line, last_line); - find_best_word_upward(win, term, line, last_word, s, e); + /* Special case if the cursor is already in the line containing the */ + /* first selectable word. */ + /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ + if (line == first_selectable_line) + { + /* we can't move the cursor up but we still can try to show the */ + /* more non selectable words as we can. */ + /* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' */ + if (line <= start_line + nlines - 1 - page) + { + /* We are scrolling one line at a time and the cursor is not in */ + /* the last line of the window. */ + /* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' */ + if (start_line - page > 0) + /* There is enough remaining line to fill a window. */ + /* '''''''''''''''''''''''''''''''''''''''''''''''' */ + start_line -= page; + else + /* We cannot scroll further */ + /* '''''''''''''''''''''''' */ + start_line = 0; + } + else + { + /* The cursor is already in the last line of the windows. */ + /* '''''''''''''''''''''''''''''''''''''''''''''''''''''' */ + if (line >= nlines) + /* There is enough remaining line to fill a window. */ + /* '''''''''''''''''''''''''''''''''''''''''''''''' */ + start_line = line - nlines + 1; + else + /* We cannot scroll further */ + /* '''''''''''''''''''''''' */ + start_line = 0; + } } else { - /* Temporarily move up one page */ - /* """""""""""""""""""""""""""" */ - line -= page; - - /* The target line cannot be before the line containing the first */ - /* selectable word. */ - /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ - if (line < first_selectable_line) + if (line - page < 0) { + /* Trivial case, we are already on the first page */ + /* just jump to the first selectable line */ + /* """""""""""""""""""""""""""""""""""""""""""""" */ line = first_selectable_line; last_word = get_line_last_word(line, last_line); find_best_word_upward(win, term, line, last_word, s, e); } else { - /* If this is not the case, search upward for the line with a */ - /* selectable word. This line is guaranteed to exist. */ - /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ - while (line >= first_selectable_line) + /* Temporarily move up one page */ + /* """""""""""""""""""""""""""" */ + line -= page; + + /* The target line cannot be before the line containing the first */ + /* selectable word. */ + /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ + if (line < first_selectable_line) { + line = first_selectable_line; last_word = get_line_last_word(line, last_line); - - if (find_best_word_upward(win, term, line, last_word, s, e)) + find_best_word_upward(win, term, line, last_word, s, e); + } + else + { + /* If this is not the case, search upward for the line with a */ + /* selectable word. This line is guaranteed to exist. */ + /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ + while (line >= first_selectable_line) { - found = 1; - break; - } + last_word = get_line_last_word(line, last_line); - line--; - lines_skipped++; + if (find_best_word_upward(win, term, line, last_word, s, e)) + { + found = 1; + break; + } + + line--; + lines_skipped++; + } } } } @@ -4606,7 +4647,7 @@ move_up(win_t * win, term_t * term, toggle_t * toggle, /* There is enough place to scroll up a page but only scrolls */ /* up if the cursor remains in the window */ /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ - if (start_line + win->max_lines - line > page) + if (start_line + nlines - line > page) start_line -= page; } else if (line < start_line) @@ -4647,6 +4688,7 @@ move_down(win_t * win, term_t * term, toggle_t * toggle, long line; /* The line being processed (the target line) */ long start_line; /* The first line of the window */ long cur_line; /* The line of the cursor */ + long nlines; /* Number of line in the window */ long last_selectable_line; /* the line containing the last * * selectable word */ long lines_skipped; /* The number of line between the target line and the * @@ -4670,78 +4712,120 @@ move_down(win_t * win, term_t * term, toggle_t * toggle, last_selectable_line = line_nb_of_word_a[last_selectable]; lines_skipped = 0; found = 0; + nlines = win->max_lines < last_line + 1 ? win->max_lines : last_line + 1; /* initialise the target line */ /* """""""""""""""""""""""""" */ line = cur_line; - if (last_line - line - page < 0) - { - /* Trivial case, we are already on the last page */ - /* just jump to the last selectable line */ - /* """""""""""""""""""""""""""""""""""""""""""""" */ - line = last_selectable_line; - last_word = get_line_last_word(line, last_line); - find_best_word_downward(win, term, line, last_word, s, e); + /* Special case if the cursor is already in the line containing the */ + /* last selectable word. */ + /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ + if (line == last_selectable_line) + { + /* we can't move the cursor down but we still can try to show the */ + /* more non selectable words as we can. */ + /* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' */ + if (line >= start_line + page) + { + /* We are scrolling one line at a time and the cursor is not in */ + /* the first line of the window. */ + /* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' */ + if (start_line + page + nlines - 1 <= last_line) + /* There is enough remaining line to fill a window. */ + /* '''''''''''''''''''''''''''''''''''''''''''''''' */ + start_line += page; + else + /* We cannot scroll further */ + /* '''''''''''''''''''''''' */ + start_line = last_line - nlines + 1; + } + else + { + /* The cursor is already in the first line of the windows. */ + /* ''''''''''''''''''''''''''''''''''''''''''''''''''''''' */ + if (last_line - line + 1 > nlines) + /* There is enough remaining line to fill a window. */ + /* '''''''''''''''''''''''''''''''''''''''''''''''' */ + start_line = line; + else + /* We cannot scroll further */ + /* '''''''''''''''''''''''' */ + start_line = last_line - nlines + 1; + } } else { - /* Temporarily move down one page */ - /* """""""""""""""""""""""""""""" */ - line += page; - - /* The target line cannot be before the line containing the first */ - /* selectable word. */ - /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ - if (line > last_selectable_line) + /* The cursor is above the line containing the last selectable word. */ + /* """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ + if (last_line - line - page < 0) { + /* Trivial case, we are already on the last page */ + /* just jump to the last selectable line */ + /* """""""""""""""""""""""""""""""""""""""""""""" */ line = last_selectable_line; last_word = get_line_last_word(line, last_line); find_best_word_downward(win, term, line, last_word, s, e); } else { - /* If this is not the case, search upward for the line with a */ - /* selectable word. This line is guaranteed to exist. */ - /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ - while (line <= last_selectable_line) + /* Temporarily move down one page */ + /* """""""""""""""""""""""""""""" */ + line += page; + + /* The target line cannot be before the line containing the first */ + /* selectable word. */ + /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ + if (line > last_selectable_line) { + line = last_selectable_line; last_word = get_line_last_word(line, last_line); - - if (find_best_word_downward(win, term, line, last_word, s, e)) + find_best_word_downward(win, term, line, last_word, s, e); + } + else + { + /* If this is not the case, search upward for the line with a */ + /* selectable word. This line is guaranteed to exist. */ + /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ + while (line <= last_selectable_line) { - found = 1; - break; - } + last_word = get_line_last_word(line, last_line); - line++; - lines_skipped++; + if (find_best_word_downward(win, term, line, last_word, s, e)) + { + found = 1; + break; + } + + line++; + lines_skipped++; + } } } - } - /* Look if we need to adjust the window to follow the cursor */ - /* """"""""""""""""""""""""""""""""""""""""""""""""""""""""" */ - if (!found && start_line + win->max_lines - 1 + page <= last_line) - { - /* We are on the last line containing a selectable word and */ - /* There is enough place to scroll down a page but only scrolls */ - /* down if the cursor remains in the window */ - /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ - if (line - start_line >= page) - start_line += page; - } - else if (line > start_line + win->max_lines - 1) - { - /* The target line is below the windows */ - /* """""""""""""""""""""""""""""""""""" */ - if (start_line + win->max_lines + page + lines_skipped - 1 > last_line) - /* There isn't enough remaining lines to scroll down */ - /* a page size. */ - /* """"""""""""""""""""""""""""""""""""""""""""""""" */ - start_line = last_line - win->max_lines + 1; - else - start_line += page + lines_skipped; + /* Look if we need to adjust the window to follow the cursor */ + /* """"""""""""""""""""""""""""""""""""""""""""""""""""""""" */ + if (!found && start_line + nlines - 1 + page <= last_line) + { + /* We are on the last line containing a selectable word and */ + /* There is enough place to scroll down a page but only scrolls */ + /* down if the cursor remains in the window */ + /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */ + if (line - start_line >= page) + start_line += page; + } + else if (line > start_line + nlines - 1) + { + /* The target line is below the windows */ + /* """""""""""""""""""""""""""""""""""" */ + if (start_line + nlines + page + lines_skipped - 1 > last_line) + /* There isn't enough remaining lines to scroll down */ + /* a page size. */ + /* """"""""""""""""""""""""""""""""""""""""""""""""" */ + start_line = last_line - nlines + 1; + else + start_line += page + lines_skipped; + } } /* And set the new value of the starting word of the window */ diff --git a/tests/scrolling/data7 b/tests/scrolling/data7 new file mode 100644 index 0000000..dd80bc8 --- /dev/null +++ b/tests/scrolling/data7 @@ -0,0 +1,20 @@ + 0 a a a a a + 1 a a a a a + 2 a a a a a + 3 a a a a a + 4 a a a a a + 5 a a a a a + 6 b b b a a + 7 a a a a a + 8 b b b b b + 9 b b b b b + 10 b b b b b + 11 b b b b b + 12 a a a a a + 13 b b b b b + 14 a a a a a + 15 a a a a a + 16 a a a a a + 17 a a a a a + 18 a a a a a + 19 a a a a a diff --git a/tests/scrolling/t0005.good b/tests/scrolling/t0005.good index bd94555..fe06086 100644 --- a/tests/scrolling/t0005.good +++ b/tests/scrolling/t0005.good @@ -1,14 +1,14 @@ $ OUT=$(LC_ALL=en_US smenu -R 7,13 -c t0005.in) -10 b b b b b ^ -0:24 1:24 3:24 5:24 7:24 9:24 11:24 14:20 -11 a a a a a | +11 a a a a a ^ 0:24 1:24 3:24 5:24 7:24 9:24 11:24 14:20 12 a a a a a | 5:07 14:20 -13 a a a a a + +13 a a a a a | +0:24 1:24 3:24 5:24 7:24 9:24 11:24 14:20 +14 a a a a a + 0:24 1:24 3:24 5:24 7:24 9:24 11:24 14:20 -14 a a a a a v +15 a a a a a / 0:24 1:24 3:24 5:24 7:24 9:24 11:24 14:20 $ diff --git a/tests/scrolling/t0006.good b/tests/scrolling/t0006.good index bb2c605..704583c 100644 --- a/tests/scrolling/t0006.good +++ b/tests/scrolling/t0006.good @@ -1,14 +1,14 @@ $ OUT=$(LC_ALL=en_US smenu -R 6,18,20 -c t0006.in) -4 a a a a a a a a ^ +3 a a a a a a a a ^ 0:24 1:24 3:24 5:24 7:24 9:24 11:24 13:24 15:24 17:24 20:20 -5 a a a a a a a a + +4 a a a a a a a a + +0:24 1:24 3:24 5:24 7:24 9:24 11:24 13:24 15:24 17:24 20:20 +5 a a a a a a a a | 5:07 20:20 6 a a a a a a a a | 0:24 1:24 3:24 5:24 7:24 9:24 11:24 13:24 15:24 17:24 20:20 -7 a a a a a a a a | -0:24 1:24 3:24 5:24 7:24 9:24 11:24 13:24 15:24 17:24 20:20 -8 a a a a a a a a v +7 a a a a a a a a v 0:24 1:24 3:24 5:24 7:24 9:24 11:24 13:24 15:24 17:24 20:20 $ diff --git a/tests/scrolling/t0011.good b/tests/scrolling/t0011.good new file mode 100644 index 0000000..5716b76 --- /dev/null +++ b/tests/scrolling/t0011.good @@ -0,0 +1,19 @@ +$ OUT=$(LC_ALL=en_US smenu -c -e a -e '[0-9]' t0011.in) + +2 a a a a a ^ +0:24 1:24 3:24 5:24 7:24 9:24 11:24 14:20 +3 a a a a a + +0:24 1:24 3:24 5:24 7:24 9:24 11:24 14:20 +4 a a a a a | +0:24 1:24 3:24 5:24 7:24 9:24 11:24 14:20 +5 a a a a a | +0:24 1:24 3:24 5:24 7:24 9:24 11:24 14:20 +6 b b b a a v +0:24 1:24 3:07 9:24 11:24 14:20 +$ + +$ echo ":$OUT:" + +:b: + +$ exit 0 diff --git a/tests/scrolling/t0011.in b/tests/scrolling/t0011.in new file mode 120000 index 0000000..592b7e2 --- /dev/null +++ b/tests/scrolling/t0011.in @@ -0,0 +1 @@ +data7
\ No newline at end of file diff --git a/tests/scrolling/t0011.tst b/tests/scrolling/t0011.tst new file mode 100644 index 0000000..2bb67c5 --- /dev/null +++ b/tests/scrolling/t0011.tst @@ -0,0 +1,4 @@ +\S[150]\s[10]OUT=$(LC_ALL=en_US smenu -c -e a -e '[0-9]' t0011.in) +\S[150]\s[150]JJJJKKKKK\r +\S[150]\s[10]echo ":$\s[10]OUT:" +exit 0 |