New version of the patch. It's now split into two separate diffs, and
meant to apply after your reworking of window_copy_cursor_next_word
(which isn't in Sourceforge CVS yet). As you requested, I used a copy of
that function, rather than introducing a flag (so the enum definition's
gone, too).
Apologies if I missed anything from our earlier IRC conversation; the
logs are on my work laptop, and I didn't have access to them when I
reworked the patches.
"vi-e-cmd.diff" applies first, followed by "vi-B-W-E-cmds.diff". Not
sure which order my mailer will put them in.
--
Micah J. Cowan
http://micah.cowan.name/
Index: mode-key.c
===================================================================
--- mode-key.c.orig
+++ mode-key.c
@@ -87,9 +87,12 @@
{ MODEKEYCOPY_LEFT, "cursor-left" },
{ MODEKEYCOPY_MIDDLELINE, "middle-line" },
{ MODEKEYCOPY_NEXTPAGE, "page-down" },
+ { MODEKEYCOPY_NEXTNONSPACEWORD, "next-nonspace-word" },
+ { MODEKEYCOPY_NEXTNONSPACEWORDEND, "next-nonspace-word-end" },
{ MODEKEYCOPY_NEXTWORD, "next-word" },
{ MODEKEYCOPY_NEXTWORDEND, "next-word-end" },
{ MODEKEYCOPY_PREVIOUSPAGE, "page-up" },
+ { MODEKEYCOPY_PREVIOUSNONSPACEWORD, "previous-nonspace-word" },
{ MODEKEYCOPY_PREVIOUSWORD, "previous-word" },
{ MODEKEYCOPY_RIGHT, "cursor-right" },
{ MODEKEYCOPY_SCROLLDOWN, "scroll-down" },
@@ -165,11 +168,14 @@
{ '0', 0, MODEKEYCOPY_STARTOFLINE },
{ ':', 0, MODEKEYCOPY_GOTOLINE },
{ '?', 0, MODEKEYCOPY_SEARCHUP },
+ { 'B', 0, MODEKEYCOPY_PREVIOUSNONSPACEWORD },
+ { 'E', 0, MODEKEYCOPY_NEXTNONSPACEWORDEND },
{ 'H', 0, MODEKEYCOPY_TOPLINE },
{ 'J', 0, MODEKEYCOPY_SCROLLDOWN },
{ 'K', 0, MODEKEYCOPY_SCROLLUP },
{ 'L', 0, MODEKEYCOPY_BOTTOMLINE },
{ 'M', 0, MODEKEYCOPY_MIDDLELINE },
+ { 'W', 0, MODEKEYCOPY_NEXTNONSPACEWORD },
{ '\002' /* C-b */, 0, MODEKEYCOPY_PREVIOUSPAGE },
{ '\003' /* C-c */, 0, MODEKEYCOPY_CANCEL },
{ '\004' /* C-d */, 0, MODEKEYCOPY_HALFPAGEDOWN },
Index: tmux.1
===================================================================
--- tmux.1.orig
+++ tmux.1
@@ -535,7 +535,7 @@
.Ic mode-keys
option).
The following keys are supported as appropriate for the mode:
-.Bl -column "FunctionXXXXXXXXXXXX" "viXXXXXXXXXX" "emacs" -offset indent
+.Bl -column "FunctionXXXXXXXXXXXXXX" "viXXXXXXXXXX" "emacs" -offset indent
.It Sy "Function" Ta Sy "vi" Ta Sy "emacs"
.It Li "Back to indentation" Ta "^" Ta "M-m"
.It Li "Clear selection" Ta "Escape" Ta "C-g"
@@ -554,11 +554,14 @@
.It Li "Half page down" Ta "C-d" Ta "M-Down"
.It Li "Half page up" Ta "C-u" Ta "M-Up"
.It Li "Next page" Ta "C-f" Ta "Page down"
+.It Li "Next non-space word" Ta "W" Ta ""
+.It Li "Next non-space word end" Ta "E" Ta ""
.It Li "Next word" Ta "w" Ta ""
.It Li "Next word end" Ta "e" Ta "M-f"
.It Li "Paste buffer" Ta "p" Ta "C-y"
.It Li "Previous page" Ta "C-b" Ta "Page up"
.It Li "Previous word" Ta "b" Ta "M-b"
+.It Li "Previous non-space word" Ta "B" Ta ""
.It Li "Quit mode" Ta "q" Ta "Escape"
.It Li "Scroll down" Ta "C-Down or C-e" Ta "C-Down"
.It Li "Scroll up" Ta "C-Up or C-y" Ta "C-Up"
Index: tmux.h
===================================================================
--- tmux.h.orig
+++ tmux.h
@@ -457,9 +457,12 @@
MODEKEYCOPY_LEFT,
MODEKEYCOPY_MIDDLELINE,
MODEKEYCOPY_NEXTPAGE,
+ MODEKEYCOPY_NEXTNONSPACEWORD,
+ MODEKEYCOPY_NEXTNONSPACEWORDEND,
MODEKEYCOPY_NEXTWORD,
MODEKEYCOPY_NEXTWORDEND,
MODEKEYCOPY_PREVIOUSPAGE,
+ MODEKEYCOPY_PREVIOUSNONSPACEWORD,
MODEKEYCOPY_PREVIOUSWORD,
MODEKEYCOPY_RIGHT,
MODEKEYCOPY_SCROLLDOWN,
Index: window-copy.c
===================================================================
--- window-copy.c.orig
+++ window-copy.c
@@ -54,7 +54,8 @@
void window_copy_copy_selection(struct window_pane *, struct client *);
void window_copy_copy_line(
struct window_pane *, char **, size_t *, u_int, u_int, u_int);
-int window_copy_is_space(struct window_pane *, u_int, u_int);
+int window_copy_char_in_set(
+ struct window_pane *, u_int, u_int, const char *);
u_int window_copy_find_length(struct window_pane *, u_int);
void window_copy_cursor_start_of_line(struct window_pane *);
void window_copy_cursor_back_to_indentation(struct window_pane *);
@@ -63,9 +64,9 @@
void window_copy_cursor_right(struct window_pane *);
void window_copy_cursor_up(struct window_pane *, int);
void window_copy_cursor_down(struct window_pane *, int);
-void window_copy_cursor_next_word(struct window_pane *);
-void window_copy_cursor_next_word_end(struct window_pane *);
-void window_copy_cursor_previous_word(struct window_pane *);
+void window_copy_cursor_next_word(struct window_pane *, const char *);
+void window_copy_cursor_next_word_end(struct window_pane *, const char *);
+void window_copy_cursor_previous_word(struct window_pane *, const char *);
void window_copy_scroll_up(struct window_pane *, u_int);
void window_copy_scroll_down(struct window_pane *, u_int);
@@ -219,6 +220,8 @@
u_int n;
int keys;
+ const char *nonword_chars = " -...@.";
+
if (data->inputtype != WINDOW_COPY_OFF) {
if (window_copy_key_input(wp, key) != 0)
goto input_off;
@@ -320,14 +323,23 @@
case MODEKEYCOPY_ENDOFLINE:
window_copy_cursor_end_of_line(wp);
break;
+ case MODEKEYCOPY_NEXTNONSPACEWORD:
+ window_copy_cursor_next_word(wp, " ");
+ break;
+ case MODEKEYCOPY_NEXTNONSPACEWORDEND:
+ window_copy_cursor_next_word_end(wp, " ");
+ break;
case MODEKEYCOPY_NEXTWORD:
- window_copy_cursor_next_word(wp);
+ window_copy_cursor_next_word(wp, nonword_chars);
break;
case MODEKEYCOPY_NEXTWORDEND:
- window_copy_cursor_next_word_end(wp);
+ window_copy_cursor_next_word_end(wp, nonword_chars);
+ break;
+ case MODEKEYCOPY_PREVIOUSNONSPACEWORD:
+ window_copy_cursor_previous_word(wp, " ");
break;
case MODEKEYCOPY_PREVIOUSWORD:
- window_copy_cursor_previous_word(wp);
+ window_copy_cursor_previous_word(wp, nonword_chars);
break;
case MODEKEYCOPY_SEARCHUP:
data->inputtype = WINDOW_COPY_SEARCHUP;
@@ -949,17 +961,17 @@
}
int
-window_copy_is_space(struct window_pane *wp, u_int px, u_int py)
+window_copy_char_in_set(
+ struct window_pane *wp, u_int px, u_int py, const char *chars)
{
const struct grid_cell *gc;
- const char *spaces = " -...@.";
gc = grid_peek_cell(wp->base.grid, px, py);
if (gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8))
return (0);
if (gc->data == 0x00 || gc->data == 0x7f)
return (0);
- return (strchr(spaces, gc->data) != NULL);
+ return (strchr(chars, gc->data) != NULL);
}
u_int
@@ -1009,10 +1021,6 @@
py = screen_hsize(&wp->base) + data->cy - data->oy;
xx = window_copy_find_length(wp, py);
- /*
- * Don't use window_copy_is_space because that treats some word
- * delimiters as spaces.
- */
while (px < xx) {
gc = grid_peek_cell(wp->base.grid, px, py);
if (gc->flags & GRID_FLAG_UTF8)
@@ -1146,7 +1154,7 @@
}
void
-window_copy_cursor_next_word(struct window_pane *wp)
+window_copy_cursor_next_word(struct window_pane *wp, const char *nonword)
{
struct window_copy_mode_data *data = wp->modedata;
struct screen *base_s = &wp->base;
@@ -1158,11 +1166,11 @@
yy = screen_hsize(base_s) + screen_size_y(base_s) - 1;
/* Are we in a word? Skip it! */
- while (!window_copy_is_space(wp, px, py))
+ while (!window_copy_char_in_set(wp, px, py, nonword))
px++;
/* Find the start of a word. */
- while (px > xx || window_copy_is_space(wp, px, py)) {
+ while (px > xx || window_copy_char_in_set(wp, px, py, nonword)) {
/* Past the end of the line? Nothing but spaces. */
if (px > xx) {
if (py == yy)
@@ -1182,7 +1190,7 @@
}
void
-window_copy_cursor_next_word_end(struct window_pane *wp)
+window_copy_cursor_next_word_end(struct window_pane *wp, const char *nonword)
{
struct window_copy_mode_data *data = wp->modedata;
struct screen *base_s = &wp->base;
@@ -1194,7 +1202,7 @@
yy = screen_hsize(base_s) + screen_size_y(base_s) - 1;
/* Are we on spaces? Skip 'em! */
- while (px > xx || window_copy_is_space(wp, px, py)) {
+ while (px > xx || window_copy_char_in_set(wp, px, py, nonword)) {
/* Past the end of the line? Nothing but spaces. */
if (px > xx) {
if (py == yy)
@@ -1209,7 +1217,7 @@
}
/* Find the end of this word. */
- while (!window_copy_is_space(wp, px, py))
+ while (!window_copy_char_in_set(wp, px, py, nonword))
px++;
window_copy_update_cursor(wp, px, data->cy);
@@ -1219,7 +1227,7 @@
/* Move to the previous place where a word begins. */
void
-window_copy_cursor_previous_word(struct window_pane *wp)
+window_copy_cursor_previous_word(struct window_pane *wp, const char *nonword)
{
struct window_copy_mode_data *data = wp->modedata;
u_int px, py;
@@ -1231,7 +1239,7 @@
for (;;) {
if (px > 0) {
px--;
- if (!window_copy_is_space(wp, px, py))
+ if (!window_copy_char_in_set(wp, px, py, nonword))
break;
} else {
if (data->cy == 0 &&
@@ -1246,7 +1254,7 @@
}
/* Move back to the beginning of this word. */
- while (px > 0 && !window_copy_is_space(wp, px - 1, py))
+ while (px > 0 && !window_copy_char_in_set(wp, px - 1, py, nonword))
px--;
out:
Index: mode-key.c
===================================================================
--- mode-key.c.orig
+++ mode-key.c
@@ -88,6 +88,7 @@
{ MODEKEYCOPY_MIDDLELINE, "middle-line" },
{ MODEKEYCOPY_NEXTPAGE, "page-down" },
{ MODEKEYCOPY_NEXTWORD, "next-word" },
+ { MODEKEYCOPY_NEXTWORDEND, "next-word-end" },
{ MODEKEYCOPY_PREVIOUSPAGE, "page-up" },
{ MODEKEYCOPY_PREVIOUSWORD, "previous-word" },
{ MODEKEYCOPY_RIGHT, "cursor-right" },
@@ -181,6 +182,7 @@
{ '\r', 0, MODEKEYCOPY_COPYSELECTION },
{ '^', 0, MODEKEYCOPY_BACKTOINDENTATION },
{ 'b', 0, MODEKEYCOPY_PREVIOUSWORD },
+ { 'e', 0, MODEKEYCOPY_NEXTWORDEND },
{ 'h', 0, MODEKEYCOPY_LEFT },
{ 'j', 0, MODEKEYCOPY_DOWN },
{ 'k', 0, MODEKEYCOPY_UP },
@@ -269,7 +271,7 @@
{ '\027' /* C-w */, 0, MODEKEYCOPY_COPYSELECTION },
{ '\033' /* Escape */, 0, MODEKEYCOPY_CANCEL },
{ 'b' | KEYC_ESCAPE, 0, MODEKEYCOPY_PREVIOUSWORD },
- { 'f' | KEYC_ESCAPE, 0, MODEKEYCOPY_NEXTWORD },
+ { 'f' | KEYC_ESCAPE, 0, MODEKEYCOPY_NEXTWORDEND },
{ 'g', 0, MODEKEYCOPY_GOTOLINE },
{ 'm' | KEYC_ESCAPE, 0, MODEKEYCOPY_BACKTOINDENTATION },
{ 'n', 0, MODEKEYCOPY_SEARCHAGAIN },
Index: tmux.1
===================================================================
--- tmux.1.orig
+++ tmux.1
@@ -554,7 +554,8 @@
.It Li "Half page down" Ta "C-d" Ta "M-Down"
.It Li "Half page up" Ta "C-u" Ta "M-Up"
.It Li "Next page" Ta "C-f" Ta "Page down"
-.It Li "Next word" Ta "w" Ta "M-f"
+.It Li "Next word" Ta "w" Ta ""
+.It Li "Next word end" Ta "e" Ta "M-f"
.It Li "Paste buffer" Ta "p" Ta "C-y"
.It Li "Previous page" Ta "C-b" Ta "Page up"
.It Li "Previous word" Ta "b" Ta "M-b"
Index: tmux.h
===================================================================
--- tmux.h.orig
+++ tmux.h
@@ -458,6 +458,7 @@
MODEKEYCOPY_MIDDLELINE,
MODEKEYCOPY_NEXTPAGE,
MODEKEYCOPY_NEXTWORD,
+ MODEKEYCOPY_NEXTWORDEND,
MODEKEYCOPY_PREVIOUSPAGE,
MODEKEYCOPY_PREVIOUSWORD,
MODEKEYCOPY_RIGHT,
Index: window-copy.c
===================================================================
--- window-copy.c.orig
+++ window-copy.c
@@ -64,6 +64,7 @@
void window_copy_cursor_up(struct window_pane *, int);
void window_copy_cursor_down(struct window_pane *, int);
void window_copy_cursor_next_word(struct window_pane *);
+void window_copy_cursor_next_word_end(struct window_pane *);
void window_copy_cursor_previous_word(struct window_pane *);
void window_copy_scroll_up(struct window_pane *, u_int);
void window_copy_scroll_down(struct window_pane *, u_int);
@@ -322,6 +323,9 @@
case MODEKEYCOPY_NEXTWORD:
window_copy_cursor_next_word(wp);
break;
+ case MODEKEYCOPY_NEXTWORDEND:
+ window_copy_cursor_next_word_end(wp);
+ break;
case MODEKEYCOPY_PREVIOUSWORD:
window_copy_cursor_previous_word(wp);
break;
@@ -948,7 +952,7 @@
window_copy_is_space(struct window_pane *wp, u_int px, u_int py)
{
const struct grid_cell *gc;
- const char *spaces = " -_@";
+ const char *spaces = " -...@.";
gc = grid_peek_cell(wp->base.grid, px, py);
if (gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8))
@@ -1153,6 +1157,42 @@
xx = window_copy_find_length(wp, py);
yy = screen_hsize(base_s) + screen_size_y(base_s) - 1;
+ /* Are we in a word? Skip it! */
+ while (!window_copy_is_space(wp, px, py))
+ px++;
+
+ /* Find the start of a word. */
+ while (px > xx || window_copy_is_space(wp, px, py)) {
+ /* Past the end of the line? Nothing but spaces. */
+ if (px > xx) {
+ if (py == yy)
+ return;
+ window_copy_cursor_down(wp, 0);
+ px = 0;
+
+ py = screen_hsize(base_s) + data->cy - data->oy;
+ xx = window_copy_find_length(wp, py);
+ }
+ px++;
+ }
+
+ window_copy_update_cursor(wp, px, data->cy);
+ if (window_copy_update_selection(wp))
+ window_copy_redraw_lines(wp, data->cy, 1);
+}
+
+void
+window_copy_cursor_next_word_end(struct window_pane *wp)
+{
+ struct window_copy_mode_data *data = wp->modedata;
+ struct screen *base_s = &wp->base;
+ u_int px, py, xx, yy;
+
+ px = data->cx;
+ py = screen_hsize(base_s) + data->cy - data->oy;
+ xx = window_copy_find_length(wp, py);
+ yy = screen_hsize(base_s) + screen_size_y(base_s) - 1;
+
/* Are we on spaces? Skip 'em! */
while (px > xx || window_copy_is_space(wp, px, py)) {
/* Past the end of the line? Nothing but spaces. */
------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users