[vim/vim] :help tmux-integration can be improved (Issue #9131)

77 views
Skip to first unread message

lacygoill

unread,
Nov 12, 2021, 8:13:33 PM11/12/21
to vim/vim, Subscribed

Problem: Modified function keys <F1> to <F4> don't work in tmux.
Solution: Add these termcap entries at :help tmux-integration:

execute "set <xF1>=\<Esc>[1;*P"
execute "set <xF2>=\<Esc>[1;*Q"
execute "set <xF3>=\<Esc>[1;*R"
execute "set <xF4>=\<Esc>[1;*S"

Problem: Modified function keys <F5> to <F12> don't work in tmux.
Solution: Add these termcap entries at :help tmux-integration:

execute "set <F5>=\<Esc>[15;*~"
execute "set <F6>=\<Esc>[17;*~"
execute "set <F7>=\<Esc>[18;*~"
execute "set <F8>=\<Esc>[19;*~"
execute "set <F9>=\<Esc>[20;*~"
execute "set <F10>=\<Esc>[21;*~"
execute "set <F11>=\<Esc>[23;*~"
execute "set <F12>=\<Esc>[24;*~"

Problem: Modified <Home> and <End> keys don't work in tmux (except with the shift modifier).
Solution: Add these termcap entries at :help tmux-integration:

execute "set <xHome>=\<Esc>[1;*H"
execute "set <xEnd>=\<Esc>[1;*F"

Problem: Modified <PageUp> and <PageDown> keys don't work in tmux.
Solution: Add these termcap entries at :help tmux-integration:

execute "set <PageUp>=\<Esc>[5;*~"
execute "set <PageDown>=\<Esc>[6;*~"

Problem: modifyOtherKeys doesn't work in tmux.
Solution: add these paragraphs at the end of :help modifyOtherKeys:

NOTE: For this feature to work in tmux, you need these settings in your tmux
config: >
        set -s extended-keys on
        # only necessary if xterm is older than version 354
        set -as terminal-features 'xterm*:extkeys'

This requires a recent tmux version.  Not all key combinations work because
tmux only supports modifyOtherKeys=1 (not modifyOtherKeys=2).

For more info about the status of modifyOtherKeys in tmux, see here, and here.


Problem: :help tmux-integration is not discoverable enough.
Solution: add a link at :help tmux referring to :help tmux-integration:

For other issues related to using Vim inside tmux, see
|tmux-integration|.

For anyone who disagrees with this problem, read this comment:

(I had tried :help tmux but this is about colors.)


As a suggestion, here is a patch which tries to address all of these problems:

diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt
index f50377b4e..ea3ca154b 100644
--- a/runtime/doc/map.txt
+++ b/runtime/doc/map.txt
@@ -938,6 +938,15 @@ modifyOtherKeys is off, if you get <1b>27;5;118~ then it is on.
 When the 'esckeys' option is off, then modifyOtherKeys will be disabled in
 Insert mode to avoid every key with a modifier causing Insert mode to end.
 
+NOTE: For this feature to work in tmux, you need these settings in your tmux
+config: >
+	set -s extended-keys on
+	# only necessary if xterm is older than version 354
+	set -as terminal-features 'xterm*:extkeys'
+
+This requires a recent tmux version.  Not all key combinations work because
+tmux only supports modifyOtherKeys=1 (not modifyOtherKeys=2).
+
 
 1.12 MAPPING AN OPERATOR				*:map-operator*
 
diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt
index 0e8547588..fb4cd0e6b 100644
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -5018,6 +5018,8 @@ ctermul={color-nr}				*highlight-ctermul*
 <	More info at:
 	<https://github.com/tmux/tmux/wiki/FAQ#how-do-i-use-a-256-colour-terminal>
 	<https://github.com/tmux/tmux/wiki/FAQ#how-do-i-use-rgb-colour>
+        For other issues related to using Vim inside tmux, see
+        |tmux-integration|.
 
 	The MS-Windows standard colors are fixed (in a console window), so
 	these have been used for the names.  But the meaning of color names in
diff --git a/runtime/doc/term.txt b/runtime/doc/term.txt
index d6f31d379..2d93b95c4 100644
--- a/runtime/doc/term.txt
+++ b/runtime/doc/term.txt
@@ -152,10 +152,31 @@ terminal that tmux is running in): >
         let &t_fd = "\<Esc>[?1004l"
 
         " Enable modified arrow keys, see  :help xterm-modifier-keys
-        execute "silent! set <xUp>=\<Esc>[@;*A"
-        execute "silent! set <xDown>=\<Esc>[@;*B"
-        execute "silent! set <xRight>=\<Esc>[@;*C"
-        execute "silent! set <xLeft>=\<Esc>[@;*D"
+        execute "set <xUp>=\<Esc>[@;*A"
+        execute "set <xDown>=\<Esc>[@;*B"
+        execute "set <xRight>=\<Esc>[@;*C"
+        execute "set <xLeft>=\<Esc>[@;*D"
+
+        " Enable modified Home, End, and F1 to F4 function keys,
+        " see  :help xterm-function-keys
+        execute "set <xHome>=\<Esc>[1;*H"
+        execute "set <xEnd>=\<Esc>[1;*F"
+        execute "set <xF1>=\<Esc>[1;*P"
+        execute "set <xF2>=\<Esc>[1;*Q"
+        execute "set <xF3>=\<Esc>[1;*R"
+        execute "set <xF4>=\<Esc>[1;*S"
+
+        " Enable modified PageUp, PageDown, and F5 to F12 function keys:
+        execute "set <PageUp>=\<Esc>[5;*~"
+        execute "set <PageDown>=\<Esc>[6;*~"
+        execute "set <F5>=\<Esc>[15;*~"
+        execute "set <F6>=\<Esc>[17;*~"
+        execute "set <F7>=\<Esc>[18;*~"
+        execute "set <F8>=\<Esc>[19;*~"
+        execute "set <F9>=\<Esc>[20;*~"
+        execute "set <F10>=\<Esc>[21;*~"
+        execute "set <F11>=\<Esc>[23;*~"
+        execute "set <F12>=\<Esc>[24;*~"
     endif
 <
 							*cs7-problem*


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

lacygoill

unread,
Nov 12, 2021, 10:49:54 PM11/12/21
to vim/vim, Subscribed

For future reference, I used this script during the tests:

vim9script
const KEYS: list<string> =<< trim END
    BS
    Del
    Up
    Down
    Right
    Left
    Home
    End
    PageUp
    PageDown
END
for key: string in KEYS + range(1, 12)->mapnew((_, v) => 'F' .. v)
    execute printf('nnoremap       <%s> <Cmd>echomsg "''      %s'' was hit"<CR>', key, key)
    execute printf('nnoremap     <S-%s> <Cmd>echomsg "''S    -%s'' was hit"<CR>', key, key)
    execute printf('nnoremap     <A-%s> <Cmd>echomsg "''  A  -%s'' was hit"<CR>', key, key)
    execute printf('nnoremap     <C-%s> <Cmd>echomsg "''    C-%s'' was hit"<CR>', key, key)
    execute printf('nnoremap   <S-A-%s> <Cmd>echomsg "''S-A  -%s'' was hit"<CR>', key, key)
    execute printf('nnoremap   <S-C-%s> <Cmd>echomsg "''S  -C-%s'' was hit"<CR>', key, key)
    execute printf('nnoremap   <A-C-%s> <Cmd>echomsg "''  A-C-%s'' was hit"<CR>', key, key)
    execute printf('nnoremap <S-A-C-%s> <Cmd>echomsg "''S-A-C-%s'' was hit"<CR>', key, key)
endfor

Environment: xterm patch 353, tmux 3.3, Vim 8.2.3588

lacygoill

unread,
Nov 12, 2021, 10:59:39 PM11/12/21
to vim/vim, Subscribed

Not sure whether it's a bug, but I've noticed that <F1> to <F4> don't work with modifiers in xterm, even outside tmux. That's because, when <F1> is modified, xterm generates a sequence such as:

^[[1;XP

Where X encodes the modifier. The problem is that none of the current default entries relevant to <F1> can match this kind of sequence:

<F1>        ^[[11;*~

<xF1>       ^[O*P

Without modifier, xterm generates ^[OP when <F1> is pressed, which is matched by the <xF1> termcap entry. So, only the other termcap entry is currently useless and could be reset to match <S-F1>, <A-F1>, <C-F1>, <S-A-F1>, ...

Anyway, these settings fix the issue:

vim9script

execute "set <F1>=\<Esc>[1;*P"

execute "set <F2>=\<Esc>[1;*Q"

execute "set <F3>=\<Esc>[1;*R"

execute "set <F4>=\<Esc>[1;*S"

Alternatively, maybe this patch could fix the issue without the user having to set anything:

diff --git a/src/term.c b/src/term.c

index cb38b9338..9dc573c1a 100644

--- a/src/term.c

+++ b/src/term.c

@@ -932,10 +932,10 @@ static struct builtin_term builtin_termcaps[] =

     {K_XF2,		IF_EB("\033O*Q", ESC_STR "O*Q")},

     {K_XF3,		IF_EB("\033O*R", ESC_STR "O*R")},

     {K_XF4,		IF_EB("\033O*S", ESC_STR "O*S")},

-    {K_F1,		IF_EB("\033[11;*~", ESC_STR "[11;*~")},

-    {K_F2,		IF_EB("\033[12;*~", ESC_STR "[12;*~")},

-    {K_F3,		IF_EB("\033[13;*~", ESC_STR "[13;*~")},

-    {K_F4,		IF_EB("\033[14;*~", ESC_STR "[14;*~")},

+    {K_F1,		IF_EB("\033[1;*P", ESC_STR "[1;*P")},

+    {K_F2,		IF_EB("\033[1;*Q", ESC_STR "[1;*Q")},

+    {K_F3,		IF_EB("\033[1;*R", ESC_STR "[1;*R")},

+    {K_F4,		IF_EB("\033[1;*S", ESC_STR "[1;*S")},

     {K_F5,		IF_EB("\033[15;*~", ESC_STR "[15;*~")},

     {K_F6,		IF_EB("\033[17;*~", ESC_STR "[17;*~")},

     {K_F7,		IF_EB("\033[18;*~", ESC_STR "[18;*~")},

Unless we need to keep the old values because changing them would break Vim on older xterms.


Same issue with <Del>. It doesn't work with modifiers. That's because, in the default termcap database, the entry for <Del> is missing a wildcard to match a possible modifier digit:

# before

<Del>       ^[[3~

               ^

               ✘



# after

<Del>       ^[[3;*~

                ^^

                ✔

This setting fixes the issue:

execute "set <Del>=\<Esc>[3;*~"

I don't think it would break anything if the current default entry was changed to include the wildcard. That is, the old sequences would still be matched. As a suggestion, here is a patch:

diff --git a/src/term.c b/src/term.c

index cb38b9338..38ad96683 100644

--- a/src/term.c

+++ b/src/term.c

@@ -761,7 +761,7 @@ static struct builtin_term builtin_termcaps[] =

     {K_F19,		IF_EB("\033[33~", ESC_STR "[33~")},

     {K_F20,		IF_EB("\033[34~", ESC_STR "[34~")},

     {K_INS,		IF_EB("\033[2~", ESC_STR "[2~")},

-    {K_DEL,		IF_EB("\033[3~", ESC_STR "[3~")},

+    {K_DEL,		IF_EB("\033[3;*~", ESC_STR "[3;*~")},

     {K_HOME,		IF_EB("\033[1~", ESC_STR "[1~")},

     {K_END,		IF_EB("\033[4~", ESC_STR "[4~")},

     {K_PAGEUP,		IF_EB("\033[5~", ESC_STR "[5~")},

lacygoill

unread,
Nov 12, 2021, 11:01:33 PM11/12/21
to vim/vim, Subscribed

Also, not sure whether it's another bug, but it's weird that setting 'ttymouse' is required for <F1> to <F4> to work when combined with a modifier, in a gnome terminal where TERM is gnome:

# start a gnome terminal
TERM=gnome vim -Nu NONE -i NONE -S <(cat <<'EOF'
    execute "set <xF1>=\<Esc>[1;*P"
    nnoremap <S-F1> <Cmd>echomsg "'S-F1'"<CR>
EOF
)

Press <S-F1>.
Expected: 'S-F1' is printed on the command-line.
Actual: After 1s, E353: Nothing in register " is given.

Setting 'ttymouse' to sgr, xterm, xterm2 or urxvt, fixes the issue.
But why is that necessary?
'ttymouse' is for mouse codes; it has nothing to do with <F1>. Setting the right entry in the termcap database (like <S-F1> or <xF1>) should be enough. Why do we also need to set 'ttymouse'? If that's not a bug, we might want to document this requirement:

diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index cf953c115..993ec462b 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -8351,6 +8351,8 @@ A jump table for the options with a short description can be found at |Q_op|.
 	If you do not want 'ttymouse' to be set to "xterm2" or "sgr"
 	automatically, set t_RV to an empty string: >
 		:set t_RV=
+<	On non-xterm terminals, if you want to use <F1> to <F4> with modifiers,
+	you may need to set this option to "sgr", "xterm", "xterm2", or "urxvt".
 <
 						*'ttyscroll'* *'tsl'*
 'ttyscroll' 'tsl'	number	(default 999)

lacygoill

unread,
Nov 13, 2021, 1:24:55 PM11/13/21
to vim/vim, Subscribed

Actually, since Vim doesn't handle modifyOtherKeys=1, and that's all tmux can support for now, we might want to remove the paragraphs about enabling modifyOtherKeys in tmux.

lacygoill

unread,
Nov 14, 2021, 7:31:37 PM11/14/21
to vim/vim, Subscribed

Also, about :help modifyOtherKeys, the tip to temporarily disable the feature by executing a :! command is a bit hacky. Using echoraw() seems more reliable and easier to understand:

diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt
index f50377b4e..b5daedee2 100644
--- a/runtime/doc/map.txt
+++ b/runtime/doc/map.txt
@@ -913,10 +913,9 @@ not used you can enable modifyOtherKeys with these lines in your vimrc: >
       let &t_TE = "\<Esc>[>4;m"
 
 In case the modifyOtherKeys mode causes problems you can disable it: >
-      let &t_TI = ""
-      let &t_TE = ""
-It does not take effect immediately.  To have this work without restarting Vim
-execute a shell command, e.g.: `!ls`  Or put the lines in your |vimrc|.
+      call echoraw(&t_TE)
+Or put this line in your |vimrc|: >
+      set t_TI= t_TE=
 
 When modifyOtherKeys is enabled you can map <C-[> and <C-S-{>: >
 	imap <C-[> [[[

lacygoill

unread,
Nov 14, 2021, 10:58:37 PM11/14/21
to vim/vim, Subscribed

Also, about :help modifyOtherKeys, the tip to temporarily disable the feature by executing a :! command is a bit hacky. Using echoraw() seems more reliable and easier to understand:

Never mind, I'll open a separate issue later to try to improve :help modifyOtherKeys. There is another inconsistency which might be worth documenting.

Reply all
Reply to author
Forward
0 new messages