-/* $OpenBSD: grid-reader.c,v 1.5 2021/06/10 07:22:37 nicm Exp $ */
+/* $OpenBSD: grid-reader.c,v 1.6 2021/06/10 07:56:47 nicm Exp $ */
/*
* Copyright (c) 2020 Anindya Mukherjee <anindya49@hotmail.com>
gr->cx = grid_reader_line_length(gr);
}
+/* Handle line wrapping while moving the cursor. */
+static int
+grid_reader_handle_wrap(struct grid_reader *gr, u_int *xx, u_int *yy)
+{
+ /*
+ * Make sure the cursor lies within the grid reader's bounding area,
+ * wrapping to the next line as necessary. Return zero if the cursor
+ * would wrap past the bottom of the grid.
+ */
+ while (gr->cx > *xx) {
+ if (gr->cy == *yy)
+ return (0);
+ grid_reader_cursor_start_of_line(gr, 0);
+ grid_reader_cursor_down(gr);
+
+ if (grid_get_line(gr->gd, gr->cy)->flags & GRID_LINE_WRAPPED)
+ *xx = gr->gd->sx - 1;
+ else
+ *xx = grid_reader_line_length(gr);
+ }
+ return (1);
+}
+
/* Check if character under cursor is in set. */
int
grid_reader_in_set(struct grid_reader *gr, const char *set)
grid_reader_cursor_next_word(struct grid_reader *gr, const char *separators)
{
u_int xx, yy;
- int expected = 0;
/* Do not break up wrapped words. */
if (grid_get_line(gr->gd, gr->cy)->flags & GRID_LINE_WRAPPED)
yy = gr->gd->hsize + gr->gd->sy - 1;
/*
- * If we started inside a word, skip over word characters. Then skip
- * over separators till the next word.
+ * When navigating via spaces (for example with next-space) separators
+ * should be empty.
*
- * expected is initially set to 0 for the former and then 1 for the
- * latter. It is finally set to 0 when the beginning of the next word is
- * found.
+ * If we started on a separator that is not whitespace, skip over
+ * subsequent separators that are not whitespace. Otherwise, if we
+ * started on a non-whitespace character, skip over subsequent
+ * characters that are neither whitespace nor separators. Then, skip
+ * over whitespace (if any) until the next non-whitespace character.
*/
- do {
- while (gr->cx > xx ||
- grid_reader_in_set(gr, separators) == expected) {
- /* Move down if we are past the end of the line. */
- if (gr->cx > xx) {
- if (gr->cy == yy)
- return;
- grid_reader_cursor_start_of_line(gr, 0);
- grid_reader_cursor_down(gr);
-
- if (grid_get_line(gr->gd, gr->cy)->flags &
- GRID_LINE_WRAPPED)
- xx = gr->gd->sx - 1;
- else
- xx = grid_reader_line_length(gr);
- } else
+ if (!grid_reader_handle_wrap(gr, &xx, &yy))
+ return;
+ if (!grid_reader_in_set(gr, WHITESPACE)) {
+ if (grid_reader_in_set(gr, separators)) {
+ do
gr->cx++;
+ while (grid_reader_handle_wrap(gr, &xx, &yy) &&
+ grid_reader_in_set(gr, separators) &&
+ !grid_reader_in_set(gr, WHITESPACE));
+ } else {
+ do
+ gr->cx++;
+ while (grid_reader_handle_wrap(gr, &xx, &yy) &&
+ !(grid_reader_in_set(gr, separators) ||
+ grid_reader_in_set(gr, WHITESPACE)));
}
- expected = !expected;
- } while (expected == 1);
+ }
+ while (grid_reader_handle_wrap(gr, &xx, &yy) &&
+ grid_reader_in_set(gr, WHITESPACE))
+ gr->cx++;
}
/* Move cursor to the end of the next word. */
grid_reader_cursor_next_word_end(struct grid_reader *gr, const char *separators)
{
u_int xx, yy;
- int expected = 1;
/* Do not break up wrapped words. */
if (grid_get_line(gr->gd, gr->cy)->flags & GRID_LINE_WRAPPED)
yy = gr->gd->hsize + gr->gd->sy - 1;
/*
- * If we started on a separator, skip over separators. Then skip over
- * word characters till the next separator.
+ * When navigating via spaces (for example with next-space), separators
+ * should be empty in both modes.
*
- * expected is initially set to 1 for the former and then 1 for the
- * latter. It is finally set to 1 when the end of the next word is
- * found.
+ * If we started on a whitespace, move until reaching the first
+ * non-whitespace character. If that character is a separator, treat
+ * subsequent separators as a word, and continue moving until the first
+ * non-separator. Otherwise, continue moving until the first separator
+ * or whitespace.
*/
- do {
- while (gr->cx > xx ||
- grid_reader_in_set(gr, separators) == expected) {
- /* Move down if we are past the end of the line. */
- if (gr->cx > xx) {
- if (gr->cy == yy)
- return;
- grid_reader_cursor_start_of_line(gr, 0);
- grid_reader_cursor_down(gr);
-
- if (grid_get_line(gr->gd, gr->cy)->flags &
- GRID_LINE_WRAPPED)
- xx = gr->gd->sx - 1;
- else
- xx = grid_reader_line_length(gr);
- } else
+
+ while (grid_reader_handle_wrap(gr, &xx, &yy)) {
+ if (grid_reader_in_set(gr, WHITESPACE))
+ gr->cx++;
+ else if (grid_reader_in_set(gr, separators)) {
+ do
+ gr->cx++;
+ while (grid_reader_handle_wrap(gr, &xx, &yy) &&
+ grid_reader_in_set(gr, separators) &&
+ !grid_reader_in_set(gr, WHITESPACE));
+ return;
+ } else {
+ do
gr->cx++;
+ while (grid_reader_handle_wrap(gr, &xx, &yy) &&
+ !(grid_reader_in_set(gr, WHITESPACE) ||
+ grid_reader_in_set(gr, separators)));
+ return;
}
- expected = !expected;
- } while (expected == 0);
+ }
}
/* Move to the previous place where a word begins. */
void
grid_reader_cursor_previous_word(struct grid_reader *gr, const char *separators,
- int already)
+ int already, int stop_at_eol)
{
- int oldx, oldy, r;
+ int oldx, oldy, at_eol, word_is_letters;
/* Move back to the previous word character. */
- if (already || grid_reader_in_set(gr, separators)) {
+ if (already || grid_reader_in_set(gr, WHITESPACE)) {
for (;;) {
if (gr->cx > 0) {
gr->cx--;
- if (!grid_reader_in_set(gr, separators))
+ if (!grid_reader_in_set(gr, WHITESPACE)) {
+ word_is_letters =
+ !grid_reader_in_set(gr, separators);
break;
+ }
} else {
if (gr->cy == 0)
return;
grid_reader_cursor_end_of_line(gr, 0, 0);
/* Stop if separator at EOL. */
- if (gr->cx > 0) {
+ if (stop_at_eol && gr->cx > 0) {
oldx = gr->cx;
gr->cx--;
- r = grid_reader_in_set(gr, separators);
+ at_eol = grid_reader_in_set(gr,
+ WHITESPACE);
gr->cx = oldx;
- if (r)
+ if (at_eol) {
+ word_is_letters = 0;
break;
+ }
}
}
}
- }
+ } else
+ word_is_letters = !grid_reader_in_set(gr, separators);
/* Move back to the beginning of this word. */
do {
oldy = gr->cy;
if (gr->cx == 0) {
if (gr->cy == 0 ||
- ~grid_get_line(gr->gd, gr->cy - 1)->flags &
- GRID_LINE_WRAPPED)
+ (~grid_get_line(gr->gd, gr->cy - 1)->flags &
+ GRID_LINE_WRAPPED))
break;
grid_reader_cursor_up(gr);
grid_reader_cursor_end_of_line(gr, 0, 1);
}
if (gr->cx > 0)
gr->cx--;
- } while (!grid_reader_in_set(gr, separators));
+ } while (!grid_reader_in_set(gr, WHITESPACE) &&
+ word_is_letters != grid_reader_in_set(gr, separators));
gr->cx = oldx;
gr->cy = oldy;
}
memcmp(gc.data.data, jc->data, gc.data.size) == 0) {
gr->cx = px;
gr->cy = py;
- return 1;
+ return (1);
}
px++;
}
if (py == yy ||
!(grid_get_line(gr->gd, py)->flags & GRID_LINE_WRAPPED))
- return 0;
+ return (0);
px = 0;
}
- return 0;
+ return (0);
}
/* Jump back to character. */
memcmp(gc.data.data, jc->data, gc.data.size) == 0) {
gr->cx = px - 1;
gr->cy = py - 1;
- return 1;
+ return (1);
}
}
if (py == 1 ||
!(grid_get_line(gr->gd, py - 2)->flags & GRID_LINE_WRAPPED))
- return 0;
+ return (0);
xx = grid_line_length(gr->gd, py - 2);
}
- return 0;
+ return (0);
}
/* Jump back to the first non-blank character of the line. */
-/* $OpenBSD: options-table.c,v 1.142 2021/06/10 07:50:03 nicm Exp $ */
+/* $OpenBSD: options-table.c,v 1.143 2021/06/10 07:56:47 nicm Exp $ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
{ .name = "word-separators",
.type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_SESSION,
- .default_str = " ",
+ /*
+ * The set of non-alphanumeric printable ASCII characters minus the
+ * underscore.
+ */
+ .default_str = "!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~",
.text = "Characters considered to separate words."
},
-/* $OpenBSD: status.c,v 1.224 2021/06/10 07:50:04 nicm Exp $ */
+/* $OpenBSD: status.c,v 1.225 2021/06/10 07:56:47 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*new_key = KEYC_BSPACE;
return (1);
case 'b':
- case 'B':
*new_key = 'b'|KEYC_META;
return (1);
+ case 'B':
+ *new_key = 'B'|KEYC_VI;
+ return (1);
case 'd':
*new_key = '\025';
return (1);
case 'e':
+ *new_key = 'e'|KEYC_VI;
+ return (1);
case 'E':
+ *new_key = 'E'|KEYC_VI;
+ return (1);
case 'w':
+ *new_key = 'w'|KEYC_VI;
+ return (1);
case 'W':
- *new_key = 'f'|KEYC_META;
+ *new_key = 'W'|KEYC_VI;
return (1);
case 'p':
*new_key = '\031'; /* C-y */
return (1);
}
+/* Prompt forward to the next beginning of a word. */
+static void
+status_prompt_forward_word(struct client *c, size_t size, int vi,
+ const char *separators)
+{
+ size_t idx = c->prompt_index;
+ int word_is_separators;
+
+ /* In emacs mode, skip until the first non-whitespace character. */
+ if (!vi)
+ while (idx != size &&
+ status_prompt_space(&c->prompt_buffer[idx]))
+ idx++;
+
+ /* Can't move forward if we're already at the end. */
+ if (idx == size) {
+ c->prompt_index = idx;
+ return;
+ }
+
+ /* Determine the current character class (separators or not). */
+ word_is_separators = status_prompt_in_list(separators,
+ &c->prompt_buffer[idx]) &&
+ !status_prompt_space(&c->prompt_buffer[idx]);
+
+ /* Skip ahead until the first space or opposite character class. */
+ do {
+ idx++;
+ if (status_prompt_space(&c->prompt_buffer[idx])) {
+ /* In vi mode, go to the start of the next word. */
+ if (vi)
+ while (idx != size &&
+ status_prompt_space(&c->prompt_buffer[idx]))
+ idx++;
+ break;
+ }
+ } while (idx != size && word_is_separators == status_prompt_in_list(
+ separators, &c->prompt_buffer[idx]));
+
+ c->prompt_index = idx;
+}
+
+/* Prompt forward to the next end of a word. */
+static void
+status_prompt_end_word(struct client *c, size_t size, const char *separators)
+{
+ size_t idx = c->prompt_index;
+ int word_is_separators;
+
+ /* Can't move forward if we're already at the end. */
+ if (idx == size)
+ return;
+
+ /* Find the next word. */
+ do {
+ idx++;
+ if (idx == size) {
+ c->prompt_index = idx;
+ return;
+ }
+ } while (status_prompt_space(&c->prompt_buffer[idx]));
+
+ /* Determine the character class (separators or not). */
+ word_is_separators = status_prompt_in_list(separators,
+ &c->prompt_buffer[idx]);
+
+ /* Skip ahead until the next space or opposite character class. */
+ do {
+ idx++;
+ if (idx == size)
+ break;
+ } while (!status_prompt_space(&c->prompt_buffer[idx]) &&
+ word_is_separators == status_prompt_in_list(separators,
+ &c->prompt_buffer[idx]));
+
+ /* Back up to the previous character to stop at the end of the word. */
+ c->prompt_index = idx - 1;
+}
+
+/* Prompt backward to the previous beginning of a word. */
+static void
+status_prompt_backward_word(struct client *c, const char *separators)
+{
+ size_t idx = c->prompt_index;
+ int word_is_separators;
+
+ /* Find non-whitespace. */
+ while (idx != 0) {
+ --idx;
+ if (!status_prompt_space(&c->prompt_buffer[idx]))
+ break;
+ }
+ word_is_separators = status_prompt_in_list(separators,
+ &c->prompt_buffer[idx]);
+
+ /* Find the character before the beginning of the word. */
+ while (idx != 0) {
+ --idx;
+ if (status_prompt_space(&c->prompt_buffer[idx]) ||
+ word_is_separators != status_prompt_in_list(separators,
+ &c->prompt_buffer[idx])) {
+ /* Go back to the word. */
+ idx++;
+ break;
+ }
+ }
+ c->prompt_index = idx;
+}
+
/* Handle keys in prompt. */
int
status_prompt_key(struct client *c, key_code key)
{
struct options *oo = c->session->options;
char *s, *cp, prefix = '=';
- const char *histstr, *ws = NULL, *keystring;
+ const char *histstr, *separators = NULL, *keystring;
size_t size, idx;
struct utf8_data tmp;
- int keys;
+ int keys, word_is_separators;
if (c->prompt_flags & PROMPT_KEY) {
keystring = key_string_lookup_key(key, 0);
}
break;
case '\027': /* C-w */
- ws = options_get_string(oo, "word-separators");
+ separators = options_get_string(oo, "word-separators");
idx = c->prompt_index;
- /* Find a non-separator. */
+ /* Find non-whitespace. */
while (idx != 0) {
idx--;
- if (!status_prompt_in_list(ws, &c->prompt_buffer[idx]))
+ if (!status_prompt_space(&c->prompt_buffer[idx]))
break;
}
+ word_is_separators = status_prompt_in_list(separators,
+ &c->prompt_buffer[idx]);
- /* Find the separator at the beginning of the word. */
+ /* Find the character before the beginning of the word. */
while (idx != 0) {
idx--;
- if (status_prompt_in_list(ws, &c->prompt_buffer[idx])) {
+ if (status_prompt_space(&c->prompt_buffer[idx]) ||
+ word_is_separators != status_prompt_in_list(
+ separators, &c->prompt_buffer[idx])) {
/* Go back to the word. */
idx++;
break;
c->prompt_index = idx;
goto changed;
- case 'f'|KEYC_META:
case KEYC_RIGHT|KEYC_CTRL:
- ws = options_get_string(oo, "word-separators");
-
- /* Find a word. */
- while (c->prompt_index != size) {
- idx = ++c->prompt_index;
- if (!status_prompt_in_list(ws, &c->prompt_buffer[idx]))
- break;
- }
-
- /* Find the separator at the end of the word. */
- while (c->prompt_index != size) {
- idx = ++c->prompt_index;
- if (status_prompt_in_list(ws, &c->prompt_buffer[idx]))
- break;
- }
-
- /* Back up to the end-of-word like vi. */
- if (options_get_number(oo, "status-keys") == MODEKEY_VI &&
- c->prompt_index != 0)
- c->prompt_index--;
-
+ case 'f'|KEYC_META:
+ separators = options_get_string(oo, "word-separators");
+ status_prompt_forward_word(c, size, 0, separators);
+ goto changed;
+ case 'E'|KEYC_VI:
+ status_prompt_end_word(c, size, "");
+ goto changed;
+ case 'e'|KEYC_VI:
+ separators = options_get_string(oo, "word-separators");
+ status_prompt_end_word(c, size, separators);
+ goto changed;
+ case 'W'|KEYC_VI:
+ status_prompt_forward_word(c, size, 1, "");
+ goto changed;
+ case 'w'|KEYC_VI:
+ separators = options_get_string(oo, "word-separators");
+ status_prompt_forward_word(c, size, 1, separators);
+ goto changed;
+ case 'B'|KEYC_VI:
+ status_prompt_backward_word(c, "");
goto changed;
- case 'b'|KEYC_META:
case KEYC_LEFT|KEYC_CTRL:
- ws = options_get_string(oo, "word-separators");
-
- /* Find a non-separator. */
- while (c->prompt_index != 0) {
- idx = --c->prompt_index;
- if (!status_prompt_in_list(ws, &c->prompt_buffer[idx]))
- break;
- }
-
- /* Find the separator at the beginning of the word. */
- while (c->prompt_index != 0) {
- idx = --c->prompt_index;
- if (status_prompt_in_list(ws, &c->prompt_buffer[idx])) {
- /* Go back to the word. */
- c->prompt_index++;
- break;
- }
- }
+ case 'b'|KEYC_META:
+ separators = options_get_string(oo, "word-separators");
+ status_prompt_backward_word(c, separators);
goto changed;
case KEYC_UP:
case '\020': /* C-p */
return (0);
if (key <= 0x7f)
utf8_set(&tmp, key);
- else
+ else if (KEYC_IS_UNICODE(key))
utf8_to_data(key, &tmp);
+ else
+ return (0);
c->prompt_buffer = xreallocarray(c->prompt_buffer, size + 2,
sizeof *c->prompt_buffer);
-.\" $OpenBSD: tmux.1,v 1.840 2021/06/10 07:52:56 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.841 2021/06/10 07:56:47 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\"
.Ql -no-clear
variants do not clear the selection.
.Pp
-The next and previous word keys use space and the
-.Ql - ,
-.Ql _
-and
-.Ql @
-characters as word delimiters by default, but this can be adjusted by
-setting the
+The next and previous word keys skip over whitespace and treat consecutive
+runs of either word separators or other letters as words.
+Word separators can be customized with the
.Em word-separators
session 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
the word separator.
+Setting
+.Em word-separators
+to the empty string makes next/previous word equivalent to next/previous space.
.Pp
The jump commands enable quick movement within a line.
For instance, typing
Sets the session'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 \ -_@ .
-.El
.Pp
Available window options are:
.Pp
-/* $OpenBSD: tmux.h,v 1.1109 2021/06/10 07:50:04 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.1110 2021/06/10 07:56:47 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
#define KEYC_CURSOR 0x04000000000000ULL
#define KEYC_IMPLIED_META 0x08000000000000ULL
#define KEYC_BUILD_MODIFIERS 0x10000000000000ULL
+#define KEYC_VI 0x20000000000000ULL
/* Masks for key bits. */
#define KEYC_MASK_MODIFIERS 0x00f00000000000ULL
int stream;
};
+/* Character classes. */
+#define WHITESPACE " "
+
/* Mode keys. */
#define MODEKEY_EMACS 0
#define MODEKEY_VI 1
void grid_reader_cursor_next_word(struct grid_reader *, const char *);
void grid_reader_cursor_next_word_end(struct grid_reader *, const char *);
void grid_reader_cursor_previous_word(struct grid_reader *, const char *,
- int);
+ int, int);
int grid_reader_cursor_jump(struct grid_reader *,
const struct utf8_data *);
int grid_reader_cursor_jump_back(struct grid_reader *,
-/* $OpenBSD: utf8.c,v 1.57 2020/09/16 18:37:55 nicm Exp $ */
+/* $OpenBSD: utf8.c,v 1.58 2021/06/10 07:56:47 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
static u_int utf8_next_index;
#define UTF8_GET_SIZE(uc) (((uc) >> 24) & 0x1f)
-#define UTF8_GET_WIDTH(flags) (((uc) >> 29) - 1)
+#define UTF8_GET_WIDTH(uc) (((uc) >> 29) - 1)
#define UTF8_SET_SIZE(size) (((utf8_char)(size)) << 24)
#define UTF8_SET_WIDTH(width) ((((utf8_char)(width)) + 1) << 29)
-/* $OpenBSD: window-copy.c,v 1.322 2021/04/05 08:43:48 nicm Exp $ */
+/* $OpenBSD: window-copy.c,v 1.323 2021/06/10 07:56:47 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
static void window_copy_cursor_next_word_end(struct window_mode_entry *,
const char *, int);
static void window_copy_cursor_previous_word_pos(struct window_mode_entry *,
- const char *, int, u_int *, u_int *);
+ const char *, u_int *, u_int *);
static void window_copy_cursor_previous_word(struct window_mode_entry *,
const char *, int);
static void window_copy_scroll_up(struct window_mode_entry *, u_int);
SEL_LINE, /* select one line at a time */
} selflag;
- const char *ws; /* word separators */
+ const char *separators; /* word separators */
u_int dx; /* drag start position */
u_int dy;
tried = 1;
goto retry;
}
- window_copy_cursor_previous_word(wme, "}]) ", 1);
+ window_copy_cursor_previous_word(wme, close, 1);
}
continue;
}
tried = 1;
goto retry;
}
- window_copy_cursor_next_word_end(wme, "{[( ",
- 0);
+ window_copy_cursor_next_word_end(wme, open, 0);
continue;
}
/* For vi, continue searching for bracket until EOL. */
u_int np = wme->prefix;
for (; np != 0; np--)
- window_copy_cursor_next_word(wme, " ");
+ window_copy_cursor_next_word(wme, "");
return (WINDOW_COPY_CMD_NOTHING);
}
u_int np = wme->prefix;
for (; np != 0; np--)
- window_copy_cursor_next_word_end(wme, " ", 0);
+ window_copy_cursor_next_word_end(wme, "", 0);
return (WINDOW_COPY_CMD_NOTHING);
}
window_copy_cmd_next_word(struct window_copy_cmd_state *cs)
{
struct window_mode_entry *wme = cs->wme;
- struct session *s = cs->s;
u_int np = wme->prefix;
- const char *ws;
+ const char *separators;
+
+ separators = options_get_string(cs->s->options, "word-separators");
- ws = options_get_string(s->options, "word-separators");
for (; np != 0; np--)
- window_copy_cursor_next_word(wme, ws);
+ window_copy_cursor_next_word(wme, separators);
return (WINDOW_COPY_CMD_NOTHING);
}
window_copy_cmd_next_word_end(struct window_copy_cmd_state *cs)
{
struct window_mode_entry *wme = cs->wme;
- struct session *s = cs->s;
u_int np = wme->prefix;
- const char *ws;
+ const char *separators;
+
+ separators = options_get_string(cs->s->options, "word-separators");
- ws = options_get_string(s->options, "word-separators");
for (; np != 0; np--)
- window_copy_cursor_next_word_end(wme, ws, 0);
+ window_copy_cursor_next_word_end(wme, separators, 0);
return (WINDOW_COPY_CMD_NOTHING);
}
u_int np = wme->prefix;
for (; np != 0; np--)
- window_copy_cursor_previous_word(wme, " ", 1);
+ window_copy_cursor_previous_word(wme, "", 1);
return (WINDOW_COPY_CMD_NOTHING);
}
window_copy_cmd_previous_word(struct window_copy_cmd_state *cs)
{
struct window_mode_entry *wme = cs->wme;
- struct session *s = cs->s;
u_int np = wme->prefix;
- const char *ws;
+ const char *separators;
+
+ separators = options_get_string(cs->s->options, "word-separators");
- ws = options_get_string(s->options, "word-separators");
for (; np != 0; np--)
- window_copy_cursor_previous_word(wme, ws, 1);
+ window_copy_cursor_previous_word(wme, separators, 1);
return (WINDOW_COPY_CMD_NOTHING);
}
window_copy_cmd_select_word(struct window_copy_cmd_state *cs)
{
struct window_mode_entry *wme = cs->wme;
- struct session *s = cs->s;
+ struct options *session_options = cs->s->options;
struct window_copy_mode_data *data = wme->data;
u_int px, py, nextx, nexty;
+
data->lineflag = LINE_SEL_LEFT_RIGHT;
data->rectflag = 0;
data->selflag = SEL_WORD;
data->dx = data->cx;
data->dy = screen_hsize(data->backing) + data->cy - data->oy;
- data->ws = options_get_string(s->options, "word-separators");
- window_copy_cursor_previous_word(wme, data->ws, 0);
+ data->separators = options_get_string(session_options,
+ "word-separators");
+ window_copy_cursor_previous_word(wme, data->separators, 0);
px = data->cx;
py = screen_hsize(data->backing) + data->cy - data->oy;
data->selrx = px;
nexty++;
}
if (px >= window_copy_find_length(wme, py) ||
- !window_copy_in_set(wme, nextx, nexty, data->ws))
- window_copy_cursor_next_word_end(wme, data->ws, 1);
+ !window_copy_in_set(wme, nextx, nexty, WHITESPACE))
+ window_copy_cursor_next_word_end(wme, data->separators, 1);
else {
window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1, 1))
begin = 0;
if (data->dy > yy || (data->dy == yy && data->dx > xx)) {
/* Right to left selection. */
- window_copy_cursor_previous_word_pos(wme, data->ws, 0,
- &xx, &yy);
+ window_copy_cursor_previous_word_pos(wme,
+ data->separators, &xx, &yy);
begin = 1;
/* Reset the end. */
} else {
/* Left to right selection. */
if (xx >= window_copy_find_length(wme, yy) ||
- !window_copy_in_set(wme, xx + 1, yy, data->ws))
+ !window_copy_in_set(wme, xx + 1, yy, WHITESPACE)) {
window_copy_cursor_next_word_end_pos(wme,
- data->ws, &xx, &yy);
+ data->separators, &xx, &yy);
+ }
/* Reset the start. */
data->selx = data->selrx;
struct screen *back_s = data->backing;
struct grid_reader gr;
u_int px, py, hsize;
- int keys;
px = data->cx;
hsize = screen_hsize(back_s);
py = hsize + data->cy - data->oy;
grid_reader_start(&gr, back_s->grid, px, py);
- keys = options_get_number(oo, "mode-keys");
- if (keys == MODEKEY_VI && !grid_reader_in_set(&gr, separators))
- grid_reader_cursor_right(&gr, 0, 0);
- grid_reader_cursor_next_word_end(&gr, separators);
- if (keys == MODEKEY_VI)
+ if (options_get_number(oo, "mode-keys") == MODEKEY_VI) {
+ if (!grid_reader_in_set(&gr, WHITESPACE))
+ grid_reader_cursor_right(&gr, 0, 0);
+ grid_reader_cursor_next_word_end(&gr, separators);
grid_reader_cursor_left(&gr, 1);
+ } else
+ grid_reader_cursor_next_word_end(&gr, separators);
grid_reader_get_cursor(&gr, &px, &py);
*ppx = px;
*ppy = py;
struct screen *back_s = data->backing;
struct grid_reader gr;
u_int px, py, oldy, hsize;
- int keys;
px = data->cx;
hsize = screen_hsize(back_s);
oldy = data->cy;
grid_reader_start(&gr, back_s->grid, px, py);
- keys = options_get_number(oo, "mode-keys");
- if (keys == MODEKEY_VI && !grid_reader_in_set(&gr, separators))
- grid_reader_cursor_right(&gr, 0, 0);
- grid_reader_cursor_next_word_end(&gr, separators);
- if (keys == MODEKEY_VI)
+ if (options_get_number(oo, "mode-keys") == MODEKEY_VI) {
+ if (!grid_reader_in_set(&gr, WHITESPACE))
+ grid_reader_cursor_right(&gr, 0, 0);
+ grid_reader_cursor_next_word_end(&gr, separators);
grid_reader_cursor_left(&gr, 1);
+ } else
+ grid_reader_cursor_next_word_end(&gr, separators);
grid_reader_get_cursor(&gr, &px, &py);
window_copy_acquire_cursor_down(wme, hsize, screen_size_y(back_s),
data->oy, oldy, px, py, no_reset);
/* Compute the previous place where a word begins. */
static void
window_copy_cursor_previous_word_pos(struct window_mode_entry *wme,
- const char *separators, int already, u_int *ppx, u_int *ppy)
+ const char *separators, u_int *ppx, u_int *ppy)
{
struct window_copy_mode_data *data = wme->data;
struct screen *back_s = data->backing;
py = hsize + data->cy - data->oy;
grid_reader_start(&gr, back_s->grid, px, py);
- grid_reader_cursor_previous_word(&gr, separators, already);
+ grid_reader_cursor_previous_word(&gr, separators, /* already= */ 0,
+ /* stop_at_eol= */ 1);
grid_reader_get_cursor(&gr, &px, &py);
*ppx = px;
*ppy = py;
struct screen *back_s = data->backing;
struct grid_reader gr;
u_int px, py, oldy, hsize;
+ int stop_at_eol;
+
+ stop_at_eol =
+ options_get_number(wme->wp->window->options, "mode-keys")
+ == MODEKEY_EMACS;
px = data->cx;
hsize = screen_hsize(back_s);
oldy = data->cy;
grid_reader_start(&gr, back_s->grid, px, py);
- grid_reader_cursor_previous_word(&gr, separators, already);
+ grid_reader_cursor_previous_word(&gr, separators, already, stop_at_eol);
grid_reader_get_cursor(&gr, &px, &py);
window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, px, py);
}
data->selflag = SEL_CHAR;
switch (data->selflag) {
case SEL_WORD:
- if (data->ws != NULL) {
+ if (data->separators != NULL) {
window_copy_update_cursor(wme, x, y);
- window_copy_cursor_previous_word_pos(wme, data->ws, 0,
- &x, &y);
+ window_copy_cursor_previous_word_pos(wme,
+ data->separators, &x, &y);
y -= screen_hsize(data->backing) - data->oy;
}
window_copy_update_cursor(wme, x, y);