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

Reply via email to