mirror of
https://github.com/tmux/tmux.git
synced 2026-10-11 21:14:21 +00:00
Extend word commands to use any Unicode whitespace character, GitHub
issue 5562 from Hongyi Zhao.
This commit is contained in:
34
grid.c
34
grid.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: grid.c,v 1.157 2026/08/28 08:11:08 nicm Exp $ */
|
/* $OpenBSD: grid.c,v 1.158 2026/09/01 12:49:49 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -1660,21 +1660,29 @@ grid_in_set(struct grid *gd, u_int px, u_int py, const char *set)
|
|||||||
{
|
{
|
||||||
struct grid_cell gc, tmp_gc;
|
struct grid_cell gc, tmp_gc;
|
||||||
u_int pxx;
|
u_int pxx;
|
||||||
|
int has_tab, has_space;
|
||||||
|
|
||||||
|
has_tab = (strchr(set, '\t') != NULL);
|
||||||
|
has_space = (strchr(set, ' ') != NULL);
|
||||||
|
|
||||||
grid_get_cell(gd, px, py, &gc);
|
grid_get_cell(gd, px, py, &gc);
|
||||||
if (strchr(set, '\t')) {
|
if (gc.flags & GRID_FLAG_PADDING) {
|
||||||
if (gc.flags & GRID_FLAG_PADDING) {
|
if (!has_tab && !has_space)
|
||||||
pxx = px;
|
return (0);
|
||||||
do
|
pxx = px;
|
||||||
grid_get_cell(gd, --pxx, py, &tmp_gc);
|
do
|
||||||
while (pxx > 0 && tmp_gc.flags & GRID_FLAG_PADDING);
|
grid_get_cell(gd, --pxx, py, &tmp_gc);
|
||||||
if (tmp_gc.flags & GRID_FLAG_TAB)
|
while (pxx > 0 && tmp_gc.flags & GRID_FLAG_PADDING);
|
||||||
return (tmp_gc.data.width - (px - pxx));
|
if (((has_tab || has_space) &&
|
||||||
} else if (gc.flags & GRID_FLAG_TAB)
|
(tmp_gc.flags & GRID_FLAG_TAB)) ||
|
||||||
return (gc.data.width);
|
(has_space && utf8_has_whitespace(&tmp_gc.data)))
|
||||||
}
|
return (tmp_gc.data.width - (px - pxx));
|
||||||
if (gc.flags & GRID_FLAG_PADDING)
|
|
||||||
return (0);
|
return (0);
|
||||||
|
}
|
||||||
|
if ((has_tab || has_space) && (gc.flags & GRID_FLAG_TAB))
|
||||||
|
return (gc.data.width);
|
||||||
|
if (has_space && utf8_has_whitespace(&gc.data))
|
||||||
|
return (gc.data.width == 0 ? 1 : gc.data.width);
|
||||||
return (utf8_cstrhas(set, &gc.data));
|
return (utf8_cstrhas(set, &gc.data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: options-table.c,v 1.243 2026/08/25 08:37:08 nicm Exp $ */
|
/* $OpenBSD: options-table.c,v 1.244 2026/09/01 12:49:49 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -1251,7 +1251,8 @@ const struct options_table_entry options_table[] = {
|
|||||||
* underscore.
|
* underscore.
|
||||||
*/
|
*/
|
||||||
.default_str = "!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~",
|
.default_str = "!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~",
|
||||||
.text = "Characters considered to separate words."
|
.text = "Characters considered to separate words; a space matches "
|
||||||
|
"any character with the Unicode White_Space property."
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Window options. */
|
/* Window options. */
|
||||||
|
|||||||
19
tmux.1
19
tmux.1
@@ -1,4 +1,4 @@
|
|||||||
.\" $OpenBSD: tmux.1,v 1.1162 2026/08/31 19:34:09 nicm Exp $
|
.\" $OpenBSD: tmux.1,v 1.1163 2026/09/01 12:49:49 nicm Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
.\"
|
.\"
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: August 31 2026 $
|
.Dd $Mdocdate: September 1 2026 $
|
||||||
.Dt TMUX 1
|
.Dt TMUX 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -2206,14 +2206,14 @@ Move to the end of the next word.
|
|||||||
.Xc
|
.Xc
|
||||||
Same as
|
Same as
|
||||||
.Ic next\-word
|
.Ic next\-word
|
||||||
but use a space alone as the word separator.
|
but treat all non-whitespace characters as part of a word.
|
||||||
.It Xo
|
.It Xo
|
||||||
.Ic next\-space\-end
|
.Ic next\-space\-end
|
||||||
(vi: E)
|
(vi: E)
|
||||||
.Xc
|
.Xc
|
||||||
Same as
|
Same as
|
||||||
.Ic next\-word\-end
|
.Ic next\-word\-end
|
||||||
but use a space alone as the word separator.
|
but treat all non-whitespace characters as part of a word.
|
||||||
.It Xo
|
.It Xo
|
||||||
.Ic other\-end
|
.Ic other\-end
|
||||||
(vi: o)
|
(vi: o)
|
||||||
@@ -2287,7 +2287,7 @@ Move to the previous word.
|
|||||||
.Xc
|
.Xc
|
||||||
Same as
|
Same as
|
||||||
.Ic previous\-word
|
.Ic previous\-word
|
||||||
but use a space alone as the word separator.
|
but treat all non-whitespace characters as part of a word.
|
||||||
.It Xo
|
.It Xo
|
||||||
.Ic rectangle\-on
|
.Ic rectangle\-on
|
||||||
.Xc
|
.Xc
|
||||||
@@ -2572,8 +2572,8 @@ Word separators can be customized with the
|
|||||||
session option.
|
session option.
|
||||||
Next word moves to the start of the next word, next word end to the end of the
|
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.
|
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 three next and previous space keys work similarly but treat all
|
||||||
the word separator.
|
non-whitespace characters as part of a word.
|
||||||
Setting
|
Setting
|
||||||
.Em word\-separators
|
.Em word\-separators
|
||||||
to the empty string makes next/previous word equivalent to next/previous space.
|
to the empty string makes next/previous word equivalent to next/previous space.
|
||||||
@@ -5647,6 +5647,11 @@ If set to both, a bell and a message are produced.
|
|||||||
Sets the session's conception of what characters are considered word
|
Sets the session's conception of what characters are considered word
|
||||||
separators, for the purposes of the next and previous word commands in
|
separators, for the purposes of the next and previous word commands in
|
||||||
copy mode.
|
copy mode.
|
||||||
|
A space in
|
||||||
|
.Ar string
|
||||||
|
matches any character with the Unicode
|
||||||
|
.Em White_Space
|
||||||
|
property.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
Available window options are:
|
Available window options are:
|
||||||
|
|||||||
3
tmux.h
3
tmux.h
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: tmux.h,v 1.1432 2026/08/31 19:34:09 nicm Exp $ */
|
/* $OpenBSD: tmux.h,v 1.1433 2026/09/01 12:49:49 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -4057,6 +4057,7 @@ void session_update_history(struct session *);
|
|||||||
/* utf8.c */
|
/* utf8.c */
|
||||||
enum utf8_state utf8_towc (const struct utf8_data *, wchar_t *);
|
enum utf8_state utf8_towc (const struct utf8_data *, wchar_t *);
|
||||||
enum utf8_state utf8_fromwc(wchar_t wc, struct utf8_data *);
|
enum utf8_state utf8_fromwc(wchar_t wc, struct utf8_data *);
|
||||||
|
int utf8_has_whitespace(const struct utf8_data *);
|
||||||
void utf8_update_width_cache(void);
|
void utf8_update_width_cache(void);
|
||||||
utf8_char utf8_build_one(u_char);
|
utf8_char utf8_build_one(u_char);
|
||||||
enum utf8_state utf8_from_data(const struct utf8_data *, utf8_char *);
|
enum utf8_state utf8_from_data(const struct utf8_data *, utf8_char *);
|
||||||
|
|||||||
68
utf8.c
68
utf8.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: utf8.c,v 1.71 2026/05/12 09:37:25 nicm Exp $ */
|
/* $OpenBSD: utf8.c,v 1.72 2026/09/01 12:49:49 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -594,6 +594,72 @@ utf8_towc(const struct utf8_data *ud, wchar_t *wc)
|
|||||||
return (UTF8_DONE);
|
return (UTF8_DONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check for a Unicode whitespace character. */
|
||||||
|
int
|
||||||
|
utf8_has_whitespace(const struct utf8_data *ud)
|
||||||
|
{
|
||||||
|
struct utf8_data tmp;
|
||||||
|
wchar_t wc;
|
||||||
|
u_int offset = 0, size;
|
||||||
|
u_char ch;
|
||||||
|
|
||||||
|
while (offset < ud->size) {
|
||||||
|
ch = ud->data[offset];
|
||||||
|
if (ch < 0x80) {
|
||||||
|
wc = ch;
|
||||||
|
size = 1;
|
||||||
|
} else {
|
||||||
|
if (ch >= 0xc2 && ch <= 0xdf)
|
||||||
|
size = 2;
|
||||||
|
else if (ch >= 0xe0 && ch <= 0xef)
|
||||||
|
size = 3;
|
||||||
|
else if (ch >= 0xf0 && ch <= 0xf4)
|
||||||
|
size = 4;
|
||||||
|
else
|
||||||
|
return (0);
|
||||||
|
if (size > ud->size - offset)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
memset(&tmp, 0, sizeof tmp);
|
||||||
|
memcpy(tmp.data, ud->data + offset, size);
|
||||||
|
tmp.size = tmp.have = size;
|
||||||
|
if (utf8_towc(&tmp, &wc) != UTF8_DONE)
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
offset += size;
|
||||||
|
|
||||||
|
switch (wc) {
|
||||||
|
case 0x0009:
|
||||||
|
case 0x000A:
|
||||||
|
case 0x000B:
|
||||||
|
case 0x000C:
|
||||||
|
case 0x000D:
|
||||||
|
case 0x0020:
|
||||||
|
case 0x0085:
|
||||||
|
case 0x00A0:
|
||||||
|
case 0x1680:
|
||||||
|
case 0x2000:
|
||||||
|
case 0x2001:
|
||||||
|
case 0x2002:
|
||||||
|
case 0x2003:
|
||||||
|
case 0x2004:
|
||||||
|
case 0x2005:
|
||||||
|
case 0x2006:
|
||||||
|
case 0x2007:
|
||||||
|
case 0x2008:
|
||||||
|
case 0x2009:
|
||||||
|
case 0x200A:
|
||||||
|
case 0x2028:
|
||||||
|
case 0x2029:
|
||||||
|
case 0x202F:
|
||||||
|
case 0x205F:
|
||||||
|
case 0x3000:
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert wide character to UTF-8 character. */
|
/* Convert wide character to UTF-8 character. */
|
||||||
enum utf8_state
|
enum utf8_state
|
||||||
utf8_fromwc(wchar_t wc, struct utf8_data *ud)
|
utf8_fromwc(wchar_t wc, struct utf8_data *ud)
|
||||||
|
|||||||
Reference in New Issue
Block a user