From 23fdbc9ea6a6f5c93f042043f0407ed5d9bd0e5b Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 27 Apr 2016 09:36:25 +0000 Subject: [PATCH 1/2] Loads of platforms appear to have old or broken Unicode character type information and are missing widths for relatively common Unicode characters (so mbtowc() works, but wcwidth() fails). So if wcwidth() returns -1, assume a width of 1 instead of ignoring the character. --- utf8.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/utf8.c b/utf8.c index 56281aa2..22ab62c1 100644 --- a/utf8.c +++ b/utf8.c @@ -119,6 +119,14 @@ utf8_width(wchar_t wc) width = wcwidth(wc); if (width < 0 || width > 0xff) { log_debug("Unicode %04x, wcwidth() %d", wc, width); + + /* + * Many platforms have no width for relatively common + * characters (wcwidth() returns -1); assume width 1 in this + * case and hope for the best. + */ + if (width < 0) + return (1); return (-1); } return (width); From 1cedf78284a563b01e9394fa5b38c50470558868 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 27 Apr 2016 09:39:09 +0000 Subject: [PATCH 2/2] Add next/previous paragraph, from J Raynor. --- mode-key.c | 6 ++++++ tmux.1 | 2 ++ tmux.h | 2 ++ window-copy.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/mode-key.c b/mode-key.c index aed161bb..aaa5e0d0 100644 --- a/mode-key.c +++ b/mode-key.c @@ -140,12 +140,14 @@ const struct mode_key_cmdstr mode_key_cmdstr_copy[] = { { MODEKEYCOPY_RECTANGLETOGGLE, "rectangle-toggle" }, { MODEKEYCOPY_MIDDLELINE, "middle-line" }, { MODEKEYCOPY_NEXTPAGE, "page-down" }, + { MODEKEYCOPY_NEXTPARAGRAPH, "next-paragraph" }, { MODEKEYCOPY_NEXTSPACE, "next-space" }, { MODEKEYCOPY_NEXTSPACEEND, "next-space-end" }, { MODEKEYCOPY_NEXTWORD, "next-word" }, { MODEKEYCOPY_NEXTWORDEND, "next-word-end" }, { MODEKEYCOPY_OTHEREND, "other-end" }, { MODEKEYCOPY_PREVIOUSPAGE, "page-up" }, + { MODEKEYCOPY_PREVIOUSPARAGRAPH, "previous-paragraph" }, { MODEKEYCOPY_PREVIOUSSPACE, "previous-space" }, { MODEKEYCOPY_PREVIOUSWORD, "previous-word" }, { MODEKEYCOPY_RIGHT, "cursor-right" }, @@ -335,6 +337,8 @@ const struct mode_key_entry mode_key_vi_copy[] = { { 'q', 0, MODEKEYCOPY_CANCEL }, { 'v', 0, MODEKEYCOPY_RECTANGLETOGGLE }, { 'w', 0, MODEKEYCOPY_NEXTWORD }, + { '{', 0, MODEKEYCOPY_PREVIOUSPARAGRAPH }, + { '}', 0, MODEKEYCOPY_NEXTPARAGRAPH }, { KEYC_BSPACE, 0, MODEKEYCOPY_LEFT }, { KEYC_DOWN | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLDOWN }, { KEYC_DOWN, 0, MODEKEYCOPY_DOWN }, @@ -483,6 +487,8 @@ const struct mode_key_entry mode_key_emacs_copy[] = { { 't', 0, MODEKEYCOPY_JUMPTO }, { 'v' | KEYC_ESCAPE, 0, MODEKEYCOPY_PREVIOUSPAGE }, { 'w' | KEYC_ESCAPE, 0, MODEKEYCOPY_COPYSELECTION }, + { '{' | KEYC_ESCAPE, 0, MODEKEYCOPY_PREVIOUSPARAGRAPH }, + { '}' | KEYC_ESCAPE, 0, MODEKEYCOPY_NEXTPARAGRAPH }, { KEYC_DOWN | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLDOWN }, { KEYC_DOWN | KEYC_ESCAPE, 0, MODEKEYCOPY_HALFPAGEDOWN }, { KEYC_DOWN, 0, MODEKEYCOPY_DOWN }, diff --git a/tmux.1 b/tmux.1 index a304e76b..d2bfe32b 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1025,6 +1025,7 @@ The following keys are supported as appropriate for the mode: .It Li "Jump to backward" Ta "T" Ta "" .It Li "Jump to forward" Ta "t" Ta "" .It Li "Next page" Ta "C-f" Ta "Page down" +.It Li "Next paragraph" Ta "}" Ta "M-}" .It Li "Next space" Ta "W" Ta "" .It Li "Next space, end of word" Ta "E" Ta "" .It Li "Next word" Ta "w" Ta "" @@ -1032,6 +1033,7 @@ The following keys are supported as appropriate for the mode: .It Li "Other end of selection" Ta "o" Ta "" .It Li "Paste buffer" Ta "p" Ta "C-y" .It Li "Previous page" Ta "C-b" Ta "Page up" +.It Li "Previous paragraph" Ta "{" Ta "M-{" .It Li "Previous space" Ta "B" Ta "" .It Li "Previous word" Ta "b" Ta "M-b" .It Li "Quit mode" Ta "q" Ta "Escape" diff --git a/tmux.h b/tmux.h index b2445fce..0b868537 100644 --- a/tmux.h +++ b/tmux.h @@ -536,12 +536,14 @@ enum mode_key_cmd { MODEKEYCOPY_LEFT, MODEKEYCOPY_MIDDLELINE, MODEKEYCOPY_NEXTPAGE, + MODEKEYCOPY_NEXTPARAGRAPH, MODEKEYCOPY_NEXTSPACE, MODEKEYCOPY_NEXTSPACEEND, MODEKEYCOPY_NEXTWORD, MODEKEYCOPY_NEXTWORDEND, MODEKEYCOPY_OTHEREND, MODEKEYCOPY_PREVIOUSPAGE, + MODEKEYCOPY_PREVIOUSPARAGRAPH, MODEKEYCOPY_PREVIOUSSPACE, MODEKEYCOPY_PREVIOUSWORD, MODEKEYCOPY_RECTANGLETOGGLE, diff --git a/window-copy.c b/window-copy.c index 5c907c3d..a97d6dbe 100644 --- a/window-copy.c +++ b/window-copy.c @@ -27,6 +27,8 @@ struct screen *window_copy_init(struct window_pane *); void window_copy_free(struct window_pane *); void window_copy_pagedown(struct window_pane *); +void window_copy_next_paragraph(struct window_pane *); +void window_copy_previous_paragraph(struct window_pane *); void window_copy_resize(struct window_pane *, u_int, u_int); void window_copy_key(struct window_pane *, struct client *, struct session *, key_code, struct mouse_event *); @@ -403,6 +405,44 @@ window_copy_pagedown(struct window_pane *wp) window_copy_redraw_screen(wp); } +void +window_copy_previous_paragraph(struct window_pane *wp) +{ + struct window_copy_mode_data *data = wp->modedata; + u_int ox, oy; + + oy = screen_hsize(data->backing) + data->cy - data->oy; + ox = window_copy_find_length(wp, oy); + + while (oy > 0 && window_copy_find_length(wp, oy) == 0) + oy--; + + while (oy > 0 && window_copy_find_length(wp, oy) > 0) + oy--; + + window_copy_scroll_to(wp, 0, oy); +} + +void +window_copy_next_paragraph(struct window_pane *wp) +{ + struct window_copy_mode_data *data = wp->modedata; + struct screen *s = &data->screen; + u_int maxy, ox, oy; + + oy = screen_hsize(data->backing) + data->cy - data->oy; + maxy = screen_hsize(data->backing) + screen_size_y(s) - 1; + + while (oy < maxy && window_copy_find_length(wp, oy) == 0) + oy++; + + while (oy < maxy && window_copy_find_length(wp, oy) > 0) + oy++; + + ox = window_copy_find_length(wp, oy); + window_copy_scroll_to(wp, ox, oy); +} + void window_copy_resize(struct window_pane *wp, u_int sx, u_int sy) { @@ -548,6 +588,14 @@ window_copy_key(struct window_pane *wp, struct client *c, struct session *sess, for (; np != 0; np--) window_copy_pagedown(wp); break; + case MODEKEYCOPY_PREVIOUSPARAGRAPH: + for (; np != 0; np--) + window_copy_previous_paragraph(wp); + break; + case MODEKEYCOPY_NEXTPARAGRAPH: + for (; np != 0; np--) + window_copy_next_paragraph(wp); + break; case MODEKEYCOPY_HALFPAGEUP: n = screen_size_y(s) / 2; for (; np != 0; np--) {