mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 11:28:22 +00:00
Merge pull request #19584 from bfredl/terminal_c_BSL_c_O
implement <c-\><c-o> key for terminal mode
This commit is contained in:
@@ -5311,6 +5311,7 @@ mode([expr]) Return a string that indicates the current mode.
|
|||||||
niV Normal using |i_CTRL-O| in |Virtual-Replace-mode|
|
niV Normal using |i_CTRL-O| in |Virtual-Replace-mode|
|
||||||
nt Normal in |terminal-emulator| (insert goes to
|
nt Normal in |terminal-emulator| (insert goes to
|
||||||
Terminal mode)
|
Terminal mode)
|
||||||
|
ntT Normal using |t_CTRL-\_CTRL-O| in |terminal-mode|
|
||||||
v Visual by character
|
v Visual by character
|
||||||
vs Visual by character using |v_CTRL-O| in Select mode
|
vs Visual by character using |v_CTRL-O| in Select mode
|
||||||
V Visual by line
|
V Visual by line
|
||||||
|
@@ -1101,8 +1101,11 @@ tag command action in Command-line editing mode ~
|
|||||||
5. Terminal mode *terminal-mode-index*
|
5. Terminal mode *terminal-mode-index*
|
||||||
|
|
||||||
In a |terminal| buffer all keys except CTRL-\ are forwarded to the terminal
|
In a |terminal| buffer all keys except CTRL-\ are forwarded to the terminal
|
||||||
job. If CTRL-\ is pressed, the next key is forwarded unless it is CTRL-N.
|
job. If CTRL-\ is pressed, the next key is forwarded unless it is CTRL-N
|
||||||
|
or CTRL-O.
|
||||||
Use |CTRL-\_CTRL-N| to go to Normal mode.
|
Use |CTRL-\_CTRL-N| to go to Normal mode.
|
||||||
|
Use |t_CTRL-\_CTRL-O| to execute one normal mode command and then return
|
||||||
|
to terminal mode.
|
||||||
|
|
||||||
|
|
||||||
You found it, Arthur! *holy-grail*
|
You found it, Arthur! *holy-grail*
|
||||||
|
@@ -458,7 +458,7 @@ Ex mode Like Command-line mode, but after entering a command
|
|||||||
Terminal mode In Terminal mode all input (except CTRL-\) is sent to
|
Terminal mode In Terminal mode all input (except CTRL-\) is sent to
|
||||||
the process running in the current |terminal| buffer.
|
the process running in the current |terminal| buffer.
|
||||||
If CTRL-\ is pressed, the next key is sent unless it
|
If CTRL-\ is pressed, the next key is sent unless it
|
||||||
is CTRL-N (|CTRL-\_CTRL-N|).
|
is CTRL-N (|CTRL-\_CTRL-N|) or CTRL-O (|t_CTRL-\_CTRL-O|).
|
||||||
If the 'showmode' option is on "-- TERMINAL --" is shown
|
If the 'showmode' option is on "-- TERMINAL --" is shown
|
||||||
at the bottom of the window.
|
at the bottom of the window.
|
||||||
|
|
||||||
@@ -550,7 +550,8 @@ Ex :vi -- -- -- -- --
|
|||||||
*6 Go from Select mode to Insert mode by typing a printable character. The
|
*6 Go from Select mode to Insert mode by typing a printable character. The
|
||||||
selection is deleted and the character is inserted.
|
selection is deleted and the character is inserted.
|
||||||
|
|
||||||
*CTRL-\_CTRL-N* *i_CTRL-\_CTRL-N* *c_CTRL-\_CTRL-N* *v_CTRL-\_CTRL-N*
|
*CTRL-\_CTRL-N* *i_CTRL-\_CTRL-N* *c_CTRL-\_CTRL-N*
|
||||||
|
*v_CTRL-\_CTRL-N* *t_CTRL-\_CTRL-N*
|
||||||
Additionally the command CTRL-\ CTRL-N or <C-\><C-N> can be used to go to
|
Additionally the command CTRL-\ CTRL-N or <C-\><C-N> can be used to go to
|
||||||
Normal mode from any other mode. This can be used to make sure Vim is in
|
Normal mode from any other mode. This can be used to make sure Vim is in
|
||||||
Normal mode, without causing a beep like <Esc> would. However, this does not
|
Normal mode, without causing a beep like <Esc> would. However, this does not
|
||||||
|
@@ -47,8 +47,10 @@ Input *terminal-input*
|
|||||||
|
|
||||||
To send input, enter |Terminal-mode| with |i|, |I|, |a|, |A| or
|
To send input, enter |Terminal-mode| with |i|, |I|, |a|, |A| or
|
||||||
|:startinsert|. In this mode all keys except <C-\> are sent to the underlying
|
|:startinsert|. In this mode all keys except <C-\> are sent to the underlying
|
||||||
program. If <C-\> is pressed, the next key is sent unless it is <C-N>. Use
|
program. If <C-\> is pressed, the next key is sent unless it is <C-N> or <C-O>.
|
||||||
<C-\><C-N> to return to normal-mode. |CTRL-\_CTRL-N|
|
Use <C-\><C-N> to return to normal mode. |CTRL-\_CTRL-N|
|
||||||
|
Use <C-\><C-O> to execute one normal mode command and then return to terminal
|
||||||
|
mode. *t_CTRL-\_CTRL-O*
|
||||||
|
|
||||||
Terminal-mode forces these local options:
|
Terminal-mode forces these local options:
|
||||||
|
|
||||||
|
@@ -239,7 +239,8 @@ g8 Print the hex values of the bytes used in the
|
|||||||
|
|
||||||
Type |i| to enter |Terminal-mode|, then keys are sent to
|
Type |i| to enter |Terminal-mode|, then keys are sent to
|
||||||
the job running in the terminal. Type <C-\><C-N> to
|
the job running in the terminal. Type <C-\><C-N> to
|
||||||
leave Terminal-mode. |CTRL-\_CTRL-N|
|
leave Terminal-mode. |CTRL-\_CTRL-N|. Type <C-\><C-O>
|
||||||
|
to execute a single normal mode command |t_CTRL-\_CTRL-O|
|
||||||
|
|
||||||
Fails if changes have been made to the current buffer,
|
Fails if changes have been made to the current buffer,
|
||||||
unless 'hidden' is set.
|
unless 'hidden' is set.
|
||||||
|
@@ -1223,10 +1223,10 @@ bool edit(int cmdchar, bool startln, long count)
|
|||||||
// the value of `restart_edit` before `ex_normal` returns.
|
// the value of `restart_edit` before `ex_normal` returns.
|
||||||
restart_edit = 'i';
|
restart_edit = 'i';
|
||||||
force_restart_edit = true;
|
force_restart_edit = true;
|
||||||
|
return false;
|
||||||
} else {
|
} else {
|
||||||
terminal_enter();
|
return terminal_enter();
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't allow inserting in the sandbox.
|
// Don't allow inserting in the sandbox.
|
||||||
|
@@ -6026,7 +6026,11 @@ int showmode(void)
|
|||||||
msg_puts_attr(_(" INSERT"), attr);
|
msg_puts_attr(_(" INSERT"), attr);
|
||||||
} else if (restart_edit == 'I' || restart_edit == 'i'
|
} else if (restart_edit == 'I' || restart_edit == 'i'
|
||||||
|| restart_edit == 'a' || restart_edit == 'A') {
|
|| restart_edit == 'a' || restart_edit == 'A') {
|
||||||
msg_puts_attr(_(" (insert)"), attr);
|
if (curbuf->terminal) {
|
||||||
|
msg_puts_attr(_(" (terminal)"), attr);
|
||||||
|
} else {
|
||||||
|
msg_puts_attr(_(" (insert)"), attr);
|
||||||
|
}
|
||||||
} else if (restart_edit == 'R') {
|
} else if (restart_edit == 'R') {
|
||||||
msg_puts_attr(_(" (replace)"), attr);
|
msg_puts_attr(_(" (replace)"), attr);
|
||||||
} else if (restart_edit == 'V') {
|
} else if (restart_edit == 'V') {
|
||||||
|
@@ -211,12 +211,15 @@ void get_mode(char *buf)
|
|||||||
buf[i++] = 'o';
|
buf[i++] = 'o';
|
||||||
// to be able to detect force-linewise/blockwise/charwise operations
|
// to be able to detect force-linewise/blockwise/charwise operations
|
||||||
buf[i++] = (char)motion_force;
|
buf[i++] = (char)motion_force;
|
||||||
|
} else if (curbuf->terminal) {
|
||||||
|
buf[i++] = 't';
|
||||||
|
if (restart_edit == 'I') {
|
||||||
|
buf[i++] = 'T';
|
||||||
|
}
|
||||||
} else if (restart_edit == 'I' || restart_edit == 'R'
|
} else if (restart_edit == 'I' || restart_edit == 'R'
|
||||||
|| restart_edit == 'V') {
|
|| restart_edit == 'V') {
|
||||||
buf[i++] = 'i';
|
buf[i++] = 'i';
|
||||||
buf[i++] = (char)restart_edit;
|
buf[i++] = (char)restart_edit;
|
||||||
} else if (curbuf->terminal) {
|
|
||||||
buf[i++] = 't';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -82,6 +82,7 @@ typedef struct terminal_state {
|
|||||||
int save_rd; // saved value of RedrawingDisabled
|
int save_rd; // saved value of RedrawingDisabled
|
||||||
bool close;
|
bool close;
|
||||||
bool got_bsl; // if the last input was <C-\>
|
bool got_bsl; // if the last input was <C-\>
|
||||||
|
bool got_bsl_o; // if left terminal mode with <c-\><c-o>
|
||||||
} TerminalState;
|
} TerminalState;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
@@ -388,12 +389,11 @@ void terminal_check_size(Terminal *term)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Implements MODE_TERMINAL state. :help Terminal-mode
|
/// Implements MODE_TERMINAL state. :help Terminal-mode
|
||||||
void terminal_enter(void)
|
bool terminal_enter(void)
|
||||||
{
|
{
|
||||||
buf_T *buf = curbuf;
|
buf_T *buf = curbuf;
|
||||||
assert(buf->terminal); // Should only be called when curbuf has a terminal.
|
assert(buf->terminal); // Should only be called when curbuf has a terminal.
|
||||||
TerminalState state, *s = &state;
|
TerminalState s[1] = { 0 };
|
||||||
memset(s, 0, sizeof(TerminalState));
|
|
||||||
s->term = buf->terminal;
|
s->term = buf->terminal;
|
||||||
stop_insert_mode = false;
|
stop_insert_mode = false;
|
||||||
|
|
||||||
@@ -443,7 +443,9 @@ void terminal_enter(void)
|
|||||||
s->state.check = terminal_check;
|
s->state.check = terminal_check;
|
||||||
state_enter(&s->state);
|
state_enter(&s->state);
|
||||||
|
|
||||||
restart_edit = 0;
|
if (!s->got_bsl_o) {
|
||||||
|
restart_edit = 0;
|
||||||
|
}
|
||||||
State = save_state;
|
State = save_state;
|
||||||
RedrawingDisabled = s->save_rd;
|
RedrawingDisabled = s->save_rd;
|
||||||
apply_autocmds(EVENT_TERMLEAVE, NULL, NULL, false, curbuf);
|
apply_autocmds(EVENT_TERMLEAVE, NULL, NULL, false, curbuf);
|
||||||
@@ -467,7 +469,11 @@ void terminal_enter(void)
|
|||||||
if (curbuf->terminal == s->term && !s->close) {
|
if (curbuf->terminal == s->term && !s->close) {
|
||||||
terminal_check_cursor();
|
terminal_check_cursor();
|
||||||
}
|
}
|
||||||
unshowmode(true);
|
if (restart_edit) {
|
||||||
|
showmode();
|
||||||
|
} else {
|
||||||
|
unshowmode(true);
|
||||||
|
}
|
||||||
ui_busy_stop();
|
ui_busy_stop();
|
||||||
if (s->close) {
|
if (s->close) {
|
||||||
bool wipe = s->term->buf_handle != 0;
|
bool wipe = s->term->buf_handle != 0;
|
||||||
@@ -477,6 +483,8 @@ void terminal_enter(void)
|
|||||||
do_cmdline_cmd("bwipeout!");
|
do_cmdline_cmd("bwipeout!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return s->got_bsl_o;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void terminal_check_cursor(void)
|
static void terminal_check_cursor(void)
|
||||||
@@ -564,6 +572,14 @@ static int terminal_execute(VimState *state, int key)
|
|||||||
}
|
}
|
||||||
FALLTHROUGH;
|
FALLTHROUGH;
|
||||||
|
|
||||||
|
case Ctrl_O:
|
||||||
|
if (s->got_bsl) {
|
||||||
|
s->got_bsl_o = true;
|
||||||
|
restart_edit = 'I';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
FALLTHROUGH;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (key == Ctrl_BSL && !s->got_bsl) {
|
if (key == Ctrl_BSL && !s->got_bsl) {
|
||||||
s->got_bsl = true;
|
s->got_bsl = true;
|
||||||
|
@@ -13,6 +13,7 @@ local exc_exec = helpers.exc_exec
|
|||||||
local matches = helpers.matches
|
local matches = helpers.matches
|
||||||
local exec_lua = helpers.exec_lua
|
local exec_lua = helpers.exec_lua
|
||||||
local sleep = helpers.sleep
|
local sleep = helpers.sleep
|
||||||
|
local funcs = helpers.funcs
|
||||||
|
|
||||||
describe(':terminal buffer', function()
|
describe(':terminal buffer', function()
|
||||||
local screen
|
local screen
|
||||||
@@ -300,6 +301,44 @@ describe(':terminal buffer', function()
|
|||||||
feed_command('put a') -- register a is empty
|
feed_command('put a') -- register a is empty
|
||||||
helpers.assert_alive()
|
helpers.assert_alive()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it([[can use temporary normal mode <c-\><c-o>]], function()
|
||||||
|
eq('t', funcs.mode(1))
|
||||||
|
feed [[<c-\><c-o>]]
|
||||||
|
screen:expect{grid=[[
|
||||||
|
tty ready |
|
||||||
|
{2:^ } |
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
{3:-- (terminal) --} |
|
||||||
|
]]}
|
||||||
|
eq('ntT', funcs.mode(1))
|
||||||
|
|
||||||
|
feed [[:let g:x = 17]]
|
||||||
|
screen:expect{grid=[[
|
||||||
|
tty ready |
|
||||||
|
{2: } |
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
:let g:x = 17^ |
|
||||||
|
]]}
|
||||||
|
|
||||||
|
feed [[<cr>]]
|
||||||
|
screen:expect{grid=[[
|
||||||
|
tty ready |
|
||||||
|
{1: } |
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
{3:-- TERMINAL --} |
|
||||||
|
]]}
|
||||||
|
eq('t', funcs.mode(1))
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('No heap-buffer-overflow when using', function()
|
describe('No heap-buffer-overflow when using', function()
|
||||||
|
Reference in New Issue
Block a user