Nicholas Marriott wrote:
> This looks fine apart from a couple of things:
> 
> - Why is the count a u_long? I don't see a need for it here, let's just use a
>   u_int. Types that commonly change size depending on arch are stupid. In 
> fact,
>   I might go to far as to say we should put in a hard limit of 1000 repeats or
>   something.
> 
> - Both macros have got to go.

New version.

-- 
Micah J. Cowan
http://micah.cowan.name/
Index: mode-key.c
===================================================================
--- mode-key.c.orig
+++ mode-key.c
@@ -106,6 +106,7 @@
 	{ MODEKEYCOPY_SEARCHDOWN, "search-forward" },
 	{ MODEKEYCOPY_SEARCHREVERSE, "search-reverse" },
 	{ MODEKEYCOPY_SEARCHUP, "search-backward" },
+	{ MODEKEYCOPY_STARTNUMBERPREFIX, "start-number-prefix" },
 	{ MODEKEYCOPY_STARTOFLINE, "start-of-line" },
 	{ MODEKEYCOPY_STARTSELECTION, "begin-selection" },
 	{ MODEKEYCOPY_TOPLINE, "top-line" },
@@ -178,6 +179,15 @@
 	{ '$',			0, MODEKEYCOPY_ENDOFLINE },
 	{ '/',			0, MODEKEYCOPY_SEARCHDOWN },
 	{ '0',			0, MODEKEYCOPY_STARTOFLINE },
+	{ '1',			0, MODEKEYCOPY_STARTNUMBERPREFIX },
+	{ '2',			0, MODEKEYCOPY_STARTNUMBERPREFIX },
+	{ '3',			0, MODEKEYCOPY_STARTNUMBERPREFIX },
+	{ '4',			0, MODEKEYCOPY_STARTNUMBERPREFIX },
+	{ '5',			0, MODEKEYCOPY_STARTNUMBERPREFIX },
+	{ '6',			0, MODEKEYCOPY_STARTNUMBERPREFIX },
+	{ '7',			0, MODEKEYCOPY_STARTNUMBERPREFIX },
+	{ '8',			0, MODEKEYCOPY_STARTNUMBERPREFIX },
+	{ '9',			0, MODEKEYCOPY_STARTNUMBERPREFIX },
 	{ ':',			0, MODEKEYCOPY_GOTOLINE },
 	{ '?',			0, MODEKEYCOPY_SEARCHUP },
 	{ 'B',			0, MODEKEYCOPY_PREVIOUSSPACE },
@@ -280,6 +290,15 @@
 /* emacs copy mode keys. */
 const struct mode_key_entry mode_key_emacs_copy[] = {
 	{ ' ',			0, MODEKEYCOPY_NEXTPAGE },
+	{ '1' | KEYC_ESCAPE,	0, MODEKEYCOPY_STARTNUMBERPREFIX },
+	{ '2' | KEYC_ESCAPE,	0, MODEKEYCOPY_STARTNUMBERPREFIX },
+	{ '3' | KEYC_ESCAPE,	0, MODEKEYCOPY_STARTNUMBERPREFIX },
+	{ '4' | KEYC_ESCAPE,	0, MODEKEYCOPY_STARTNUMBERPREFIX },
+	{ '5' | KEYC_ESCAPE,	0, MODEKEYCOPY_STARTNUMBERPREFIX },
+	{ '6' | KEYC_ESCAPE,	0, MODEKEYCOPY_STARTNUMBERPREFIX },
+	{ '7' | KEYC_ESCAPE,	0, MODEKEYCOPY_STARTNUMBERPREFIX },
+	{ '8' | KEYC_ESCAPE,	0, MODEKEYCOPY_STARTNUMBERPREFIX },
+	{ '9' | KEYC_ESCAPE,	0, MODEKEYCOPY_STARTNUMBERPREFIX },
 	{ '<' | KEYC_ESCAPE,    0, MODEKEYCOPY_HISTORYTOP },
 	{ '>' | KEYC_ESCAPE,    0, MODEKEYCOPY_HISTORYBOTTOM },
 	{ 'R' | KEYC_ESCAPE,	0, MODEKEYCOPY_TOPLINE },
Index: tmux.h
===================================================================
--- tmux.h.orig
+++ tmux.h
@@ -476,6 +476,7 @@
 	MODEKEYCOPY_SEARCHDOWN,
 	MODEKEYCOPY_SEARCHREVERSE,
 	MODEKEYCOPY_SEARCHUP,
+	MODEKEYCOPY_STARTNUMBERPREFIX,
 	MODEKEYCOPY_STARTOFLINE,
 	MODEKEYCOPY_STARTSELECTION,
 	MODEKEYCOPY_TOPLINE,
Index: window-copy.c
===================================================================
--- window-copy.c.orig
+++ window-copy.c
@@ -28,6 +28,7 @@
 void	window_copy_resize(struct window_pane *, u_int, u_int);
 void	window_copy_key(struct window_pane *, struct client *, int);
 int	window_copy_key_input(struct window_pane *, int);
+int	window_copy_key_numeric_prefix(struct window_pane *, int);
 void	window_copy_mouse(
 	    struct window_pane *, struct client *, struct mouse_event *);
 
@@ -81,6 +82,7 @@
 
 enum window_copy_input_type {
 	WINDOW_COPY_OFF,
+	WINDOW_COPY_NUMERICPREFIX,
 	WINDOW_COPY_SEARCHUP,
 	WINDOW_COPY_SEARCHDOWN,
 	WINDOW_COPY_GOTOLINE,
@@ -112,6 +114,8 @@
 	const char     *inputprompt;
 	char   	       *inputstr;
 
+	u_int		numprefix;
+
 	enum window_copy_input_type searchtype;
 	char	       *searchstr;
 };
@@ -138,6 +142,7 @@
 	data->inputtype = WINDOW_COPY_OFF;
 	data->inputprompt = NULL;
 	data->inputstr = xstrdup("");
+	data->numprefix = 0;
 
 	data->searchtype = WINDOW_COPY_OFF;
 	data->searchstr = NULL;
@@ -321,11 +326,20 @@
 	const char			*word_separators;
 	struct window_copy_mode_data	*data = wp->modedata;
 	struct screen			*s = &data->screen;
-	u_int				 n;
+	u_int				 n, np;
 	int				 keys;
 	enum mode_key_cmd		 cmd;
 
-	if (data->inputtype != WINDOW_COPY_OFF) {
+	np = data->numprefix;
+	if (np == 0)
+		np = 1;
+
+	if (data->inputtype == WINDOW_COPY_NUMERICPREFIX) {
+		if (window_copy_key_numeric_prefix(wp, key) == 0)
+			return;
+		data->inputtype = WINDOW_COPY_OFF;
+		window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1);
+	} else if (data->inputtype != WINDOW_COPY_OFF) {
 		if (window_copy_key_input(wp, key) != 0)
 			goto input_off;
 		return;
@@ -334,55 +348,69 @@
 	cmd = mode_key_lookup(&data->mdata, key);
 	switch (cmd) {
 	case MODEKEYCOPY_CANCEL:
-		window_pane_reset_mode(wp);
+		for ( ; np != 0; np--)
+			window_pane_reset_mode(wp);
 		break;
 	case MODEKEYCOPY_LEFT:
-		window_copy_cursor_left(wp);
-		return;
+		for ( ; np != 0; np--)
+			window_copy_cursor_left(wp);
+		break;
 	case MODEKEYCOPY_RIGHT:
-		window_copy_cursor_right(wp);
-		return;
+		for ( ; np != 0; np--)
+			window_copy_cursor_right(wp);
+		break;
 	case MODEKEYCOPY_UP:
-		window_copy_cursor_up(wp, 0);
-		return;
+		for ( ; np != 0; np--)
+			window_copy_cursor_up(wp, 0);
+		break;
 	case MODEKEYCOPY_DOWN:
-		window_copy_cursor_down(wp, 0);
-		return;
+		for ( ; np != 0; np--)
+			window_copy_cursor_down(wp, 0);
+		break;
 	case MODEKEYCOPY_SCROLLUP:
-		window_copy_cursor_up(wp, 1);
+		for ( ; np != 0; np--)
+			window_copy_cursor_up(wp, 1);
 		break;
 	case MODEKEYCOPY_SCROLLDOWN:
-		window_copy_cursor_down(wp, 1);
+		for ( ; np != 0; np--)
+			window_copy_cursor_down(wp, 1);
 		break;
 	case MODEKEYCOPY_PREVIOUSPAGE:
-		window_copy_pageup(wp);
+		for ( ; np != 0; np--)
+			window_copy_pageup(wp);
 		break;
 	case MODEKEYCOPY_NEXTPAGE:
 		n = 1;
 		if (screen_size_y(s) > 2)
 			n = screen_size_y(s) - 2;
-		if (data->oy < n)
-			data->oy = 0;
-		else
-			data->oy -= n;
+		for ( ; np != 0; np--) {
+			if (data->oy < n)
+				data->oy = 0;
+			else
+				data->oy -= n;
+		}
 		window_copy_update_selection(wp);
 		window_copy_redraw_screen(wp);
 		break;
 	case MODEKEYCOPY_HALFPAGEUP:
 		n = screen_size_y(s) / 2;
-		if (data->oy + n > screen_hsize(data->backing))
-			data->oy = screen_hsize(data->backing);
-		else
-			data->oy += n;
+		for ( ; np != 0; np--) {
+			if (data->oy + n > screen_hsize(data->backing))
+				data->oy = screen_hsize(data->backing);
+			else
+				data->oy += n;
+		}
 		window_copy_update_selection(wp);
 		window_copy_redraw_screen(wp);
 		break;
 	case MODEKEYCOPY_HALFPAGEDOWN:
 		n = screen_size_y(s) / 2;
-		if (data->oy < n)
-			data->oy = 0;
-		else
-			data->oy -= n;
+		for ( ; np != 0; np--) {
+			if (data->oy < n)
+				data->oy = 0;
+			else
+				data->oy -= n;
+		}
 		window_copy_update_selection(wp);
 		window_copy_redraw_screen(wp);
 		break;
@@ -442,28 +470,34 @@
 		window_copy_cursor_end_of_line(wp);
 		break;
 	case MODEKEYCOPY_NEXTSPACE:
-		window_copy_cursor_next_word(wp, " ");
+		for ( ; np != 0; np--)
+			window_copy_cursor_next_word(wp, " ");
 		break;
 	case MODEKEYCOPY_NEXTSPACEEND:
-		window_copy_cursor_next_word_end(wp, " ");
+		for ( ; np != 0; np--)
+			window_copy_cursor_next_word_end(wp, " ");
 		break;
 	case MODEKEYCOPY_NEXTWORD:
 		word_separators =
 		    options_get_string(&wp->window->options, "word-separators");
-		window_copy_cursor_next_word(wp, word_separators);
+		for ( ; np != 0; np--)
+			window_copy_cursor_next_word(wp, word_separators);
 		break;
 	case MODEKEYCOPY_NEXTWORDEND:
 		word_separators =
 		    options_get_string(&wp->window->options, "word-separators");
-		window_copy_cursor_next_word_end(wp, word_separators);
+		for ( ; np != 0; np--)
+			window_copy_cursor_next_word_end(wp, word_separators);
 		break;
 	case MODEKEYCOPY_PREVIOUSSPACE:
-		window_copy_cursor_previous_word(wp, " ");
+		for ( ; np != 0; np--)
+			window_copy_cursor_previous_word(wp, " ");
 		break;
 	case MODEKEYCOPY_PREVIOUSWORD:
 		word_separators =
 		    options_get_string(&wp->window->options, "word-separators");
-		window_copy_cursor_previous_word(wp, word_separators);
+		for ( ; np != 0; np--)
+			window_copy_cursor_previous_word(wp, word_separators);
 		break;
 	case MODEKEYCOPY_SEARCHUP:
 		data->inputtype = WINDOW_COPY_SEARCHUP;
@@ -478,18 +512,29 @@
 		switch (data->searchtype) {
 		case WINDOW_COPY_OFF:
 		case WINDOW_COPY_GOTOLINE:
+		case WINDOW_COPY_NUMERICPREFIX:
 			break;
 		case WINDOW_COPY_SEARCHUP:
-			if (cmd == MODEKEYCOPY_SEARCHAGAIN)
-				window_copy_search_up(wp, data->searchstr);
-			else
-				window_copy_search_down(wp, data->searchstr);
+			if (cmd == MODEKEYCOPY_SEARCHAGAIN) {
+				for ( ; np != 0; np--)
+					window_copy_search_up(
+					    wp, data->searchstr);
+			} else {
+				for ( ; np != 0; np--)
+					window_copy_search_down(
+					    wp, data->searchstr);
+			}
 			break;
 		case WINDOW_COPY_SEARCHDOWN:
-			if (cmd == MODEKEYCOPY_SEARCHAGAIN)
-				window_copy_search_down(wp, data->searchstr);
-			else
-				window_copy_search_up(wp, data->searchstr);
+			if (cmd == MODEKEYCOPY_SEARCHAGAIN) {
+				for ( ; np != 0; np--)
+					window_copy_search_down(
+					    wp, data->searchstr);
+			} else {
+				for ( ; np != 0; np--)
+					window_copy_search_up(
+					    wp, data->searchstr);
+			}
 			break;
 		}
 		break;
@@ -498,13 +543,26 @@
 		data->inputprompt = "Goto Line";
 		*data->inputstr = '\0';
 		goto input_on;
+	case MODEKEYCOPY_STARTNUMBERPREFIX:
+		if ((key & 0xff) >= '0' && (key & 0xff) <= '9') {
+			data->inputtype = WINDOW_COPY_NUMERICPREFIX;
+			data->numprefix = 0;
+			window_copy_key_numeric_prefix(wp, key & 0xff);
+			return;
+		} else {
+			/* Ignore this command for non-digit keys. */
+		}
+		break;
 	case MODEKEYCOPY_RECTANGLETOGGLE:
 		window_copy_rectangle_toggle(wp);
-		return;
+		break;
 	default:
 		break;
 	}
 
+	/* Remove numeric prefix after processing the command. */
+	data->numprefix = 0;
+
 	return;
 
 input_on:
@@ -551,6 +609,7 @@
 	case MODEKEYEDIT_ENTER:
 		switch (data->inputtype) {
 		case WINDOW_COPY_OFF:
+		case WINDOW_COPY_NUMERICPREFIX:
 			break;
 		case WINDOW_COPY_SEARCHUP:
 			window_copy_search_up(wp, data->inputstr);
@@ -585,6 +644,20 @@
 	return (0);
 }
 
+int
+window_copy_key_numeric_prefix(struct window_pane *wp, int key)
+{
+	struct window_copy_mode_data	*data = wp->modedata;
+	struct screen			*s = &data->screen;
+
+	if (!(key >= '0' && key <= '9'))
+		return 1;
+	data->numprefix = data->numprefix * 10 + (key - '0');
+
+	window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1);
+	return 0;
+}
+
 /* ARGSUSED */
 void
 window_copy_mouse(
@@ -853,8 +926,13 @@
 		screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
 		screen_write_puts(ctx, &gc, "%s", hdr);
 	} else if (py == last && data->inputtype != WINDOW_COPY_OFF) {
-		xoff = size = xsnprintf(hdr, sizeof hdr,
-		    "%s: %s", data->inputprompt, data->inputstr);
+		if (data->inputtype == WINDOW_COPY_NUMERICPREFIX) {
+			xoff = size = xsnprintf(hdr, sizeof hdr,
+			    "(Prefix) %u", data->numprefix);
+		} else {
+			xoff = size = xsnprintf(hdr, sizeof hdr,
+			    "%s: %s", data->inputprompt, data->inputstr);
+		}
 		screen_write_cursormove(ctx, 0, last);
 		screen_write_puts(ctx, &gc, "%s", hdr);
 	} else
Index: tmux.1
===================================================================
--- tmux.1.orig
+++ tmux.1
@@ -591,6 +591,16 @@
 The three next and previous space keys work similarly but use a space alone as
 the word separator.
 .Pp
+Most key commands in copy mode may be prefaced by an optional
+repeat count. In the vi bindings, you may just type the number before
+the command you desire; in the emacs bindings, you must hold the Alt
+(meta) key while you press the first digit. For example, to move the
+cursor forward by ten words, you would type
+.Ql M-1 0 M-f
+in emacs mode, and
+.Ql 10w
+in vi.
+.Pp
 These key bindings are defined in a set of named tables:
 .Em vi-edit
 and
------------------------------------------------------------------------------
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace,
Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to