aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@openbsd.org>2010-02-22 20:41:16 +0000
committerNicholas Marriott <nicm@openbsd.org>2010-02-22 20:41:16 +0000
commit6767072c9d4774e8e44d7222c01ecee08a35dad8 (patch)
tree49a03195220386ce2b182213804ea76a83bae4ce
parentefbcf8747da18d62ed83d34d5eda1ba56d658f82 (diff)
downloadrtmux-6767072c9d4774e8e44d7222c01ecee08a35dad8.tar.gz
rtmux-6767072c9d4774e8e44d7222c01ecee08a35dad8.tar.bz2
rtmux-6767072c9d4774e8e44d7222c01ecee08a35dad8.zip
Option to set the characters considered word separators in copy mode, from
Micah Cowan.
-rw-r--r--cmd-set-option.c1
-rw-r--r--tmux.115
-rw-r--r--tmux.c1
-rw-r--r--window-copy.c92
4 files changed, 69 insertions, 40 deletions
diff --git a/cmd-set-option.c b/cmd-set-option.c
index 6658b90b..90b6d611 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -165,6 +165,7 @@ const struct set_option_entry set_window_option_table[] = {
{ "window-status-current-format", SET_OPTION_STRING, 0, 0, NULL },
{ "window-status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-format", SET_OPTION_STRING, 0, 0, NULL },
+ { "word-separators", SET_OPTION_STRING, 0, 0, NULL },
{ "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
diff --git a/tmux.1 b/tmux.1
index bbb66dc7..348c2b3a 100644
--- a/tmux.1
+++ b/tmux.1
@@ -649,11 +649,13 @@ The following keys are supported as appropriate for the mode:
.Pp
The next and previous word keys use space and the
.Ql - ,
-.Ql _ ,
-.Ql \&"
+.Ql _
and
.Ql @
-characters as word delimiters.
+characters as word delimiters by default, but this can be adjusted by
+setting the
+.Em word-separators
+window option.
Next word moves to the start of the next word, next word end to the end of the
next word and previous word to the start of the previous word.
The three next and previous space keys work similarly but use a space alone as
@@ -2031,6 +2033,13 @@ Like
.Ar window-status-format ,
but is the format used when the window is the current window.
.Pp
+.It Ic word-separators Ar string
+Sets the window's conception of what characters are considered word
+separators, for the purposes of the next and previous word commands in
+copy mode.
+The default is
+.Ql \ -_@ .
+.Pp
.It Xo Ic xterm-keys
.Op Ic on | off
.Xc
diff --git a/tmux.c b/tmux.c
index 8671e323..4f0a9090 100644
--- a/tmux.c
+++ b/tmux.c
@@ -418,6 +418,7 @@ main(int argc, char **argv)
options_set_number(wo, "window-status-fg", 8);
options_set_string(wo, "window-status-format", "#I:#W#F");
options_set_string(wo, "window-status-current-format", "#I:#W#F");
+ options_set_string(wo, "word-separators", " -_@");
options_set_number(wo, "xterm-keys", 0);
options_set_number(wo, "remain-on-exit", 0);
options_set_number(wo, "synchronize-panes", 0);
diff --git a/window-copy.c b/window-copy.c
index 0f956bd0..82ae9a2b 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -226,7 +226,7 @@ window_copy_resize(struct window_pane *wp, u_int sx, u_int sy)
void
window_copy_key(struct window_pane *wp, struct client *c, int key)
{
- const char *word_separators = " -_@";
+ const char *word_separators;
struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
u_int n;
@@ -356,15 +356,21 @@ window_copy_key(struct window_pane *wp, struct client *c, int key)
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);
break;
case MODEKEYCOPY_NEXTWORDEND:
+ word_separators =
+ options_get_string(&wp->window->options, "word-separators");
window_copy_cursor_next_word_end(wp, word_separators);
break;
case MODEKEYCOPY_PREVIOUSSPACE:
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);
break;
case MODEKEYCOPY_SEARCHUP:
@@ -1271,30 +1277,36 @@ window_copy_cursor_next_word(struct window_pane *wp, const char *separators)
struct window_copy_mode_data *data = wp->modedata;
struct screen *base_s = &wp->base;
u_int px, py, xx, yy;
+ int expected = 0;
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 in a word? Skip it! */
- while (!window_copy_in_set(wp, px, py, separators))
- px++;
-
- /* Find the start of a word. */
- while (px > xx || window_copy_in_set(wp, px, py, separators)) {
- /* 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);
- } else
- px++;
- }
+ /*
+ * First skip past any nonword characters and then any word characters.
+ *
+ * expected is initially set to 0 for the former and then 1 for the
+ * latter.
+ */
+ do {
+ while (px > xx ||
+ window_copy_in_set(wp, px, py, separators) == expected) {
+ /* Move down if we're past the end of the line. */
+ 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);
+ } else
+ px++;
+ }
+ expected = !expected;
+ } while (expected == 1);
window_copy_update_cursor(wp, px, data->cy);
if (window_copy_update_selection(wp))
@@ -1307,30 +1319,36 @@ window_copy_cursor_next_word_end(struct window_pane *wp, const char *separators)
struct window_copy_mode_data *data = wp->modedata;
struct screen *base_s = &wp->base;
u_int px, py, xx, yy;
+ int expected = 1;
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_in_set(wp, px, py, separators)) {
- /* Nothing but spaces past the end of the line, so move down. */
- 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);
- } else
- px++;
- }
-
- /* Find the end of this word. */
- while (!window_copy_in_set(wp, px, py, separators))
- px++;
+ /*
+ * First skip past any word characters, then any nonword characters.
+ *
+ * expected is initially set to 1 for the former and then 0 for the
+ * latter.
+ */
+ do {
+ while (px > xx ||
+ window_copy_in_set(wp, px, py, separators) == expected) {
+ /* Move down if we're past the end of the line. */
+ 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);
+ } else
+ px++;
+ }
+ expected = !expected;
+ } while (expected == 0);
window_copy_update_cursor(wp, px, data->cy);
if (window_copy_update_selection(wp))