mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06: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:
commit
0806c882cd
@ -5311,6 +5311,7 @@ mode([expr]) Return a string that indicates the current mode.
|
||||
niV Normal using |i_CTRL-O| in |Virtual-Replace-mode|
|
||||
nt Normal in |terminal-emulator| (insert goes to
|
||||
Terminal mode)
|
||||
ntT Normal using |t_CTRL-\_CTRL-O| in |terminal-mode|
|
||||
v Visual by character
|
||||
vs Visual by character using |v_CTRL-O| in Select mode
|
||||
V Visual by line
|
||||
|
@ -1101,8 +1101,11 @@ tag command action in Command-line editing mode ~
|
||||
5. Terminal mode *terminal-mode-index*
|
||||
|
||||
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 |t_CTRL-\_CTRL-O| to execute one normal mode command and then return
|
||||
to terminal mode.
|
||||
|
||||
|
||||
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
|
||||
the process running in the current |terminal| buffer.
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
@ -47,8 +47,10 @@ Input *terminal-input*
|
||||
|
||||
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
|
||||
program. If <C-\> is pressed, the next key is sent unless it is <C-N>. Use
|
||||
<C-\><C-N> to return to normal-mode. |CTRL-\_CTRL-N|
|
||||
program. If <C-\> is pressed, the next key is sent unless it is <C-N> or <C-O>.
|
||||
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:
|
||||
|
||||
|
@ -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
|
||||
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,
|
||||
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.
|
||||
restart_edit = 'i';
|
||||
force_restart_edit = true;
|
||||
return false;
|
||||
} else {
|
||||
terminal_enter();
|
||||
return terminal_enter();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't allow inserting in the sandbox.
|
||||
|
@ -6026,7 +6026,11 @@ int showmode(void)
|
||||
msg_puts_attr(_(" INSERT"), attr);
|
||||
} else if (restart_edit == 'I' || restart_edit == 'i'
|
||||
|| 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') {
|
||||
msg_puts_attr(_(" (replace)"), attr);
|
||||
} else if (restart_edit == 'V') {
|
||||
|
@ -211,12 +211,15 @@ void get_mode(char *buf)
|
||||
buf[i++] = 'o';
|
||||
// to be able to detect force-linewise/blockwise/charwise operations
|
||||
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'
|
||||
|| restart_edit == 'V') {
|
||||
buf[i++] = 'i';
|
||||
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
|
||||
bool close;
|
||||
bool got_bsl; // if the last input was <C-\>
|
||||
bool got_bsl_o; // if left terminal mode with <c-\><c-o>
|
||||
} TerminalState;
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
@ -388,12 +389,11 @@ void terminal_check_size(Terminal *term)
|
||||
}
|
||||
|
||||
/// Implements MODE_TERMINAL state. :help Terminal-mode
|
||||
void terminal_enter(void)
|
||||
bool terminal_enter(void)
|
||||
{
|
||||
buf_T *buf = curbuf;
|
||||
assert(buf->terminal); // Should only be called when curbuf has a terminal.
|
||||
TerminalState state, *s = &state;
|
||||
memset(s, 0, sizeof(TerminalState));
|
||||
TerminalState s[1] = { 0 };
|
||||
s->term = buf->terminal;
|
||||
stop_insert_mode = false;
|
||||
|
||||
@ -443,7 +443,9 @@ void terminal_enter(void)
|
||||
s->state.check = terminal_check;
|
||||
state_enter(&s->state);
|
||||
|
||||
restart_edit = 0;
|
||||
if (!s->got_bsl_o) {
|
||||
restart_edit = 0;
|
||||
}
|
||||
State = save_state;
|
||||
RedrawingDisabled = s->save_rd;
|
||||
apply_autocmds(EVENT_TERMLEAVE, NULL, NULL, false, curbuf);
|
||||
@ -467,7 +469,11 @@ void terminal_enter(void)
|
||||
if (curbuf->terminal == s->term && !s->close) {
|
||||
terminal_check_cursor();
|
||||
}
|
||||
unshowmode(true);
|
||||
if (restart_edit) {
|
||||
showmode();
|
||||
} else {
|
||||
unshowmode(true);
|
||||
}
|
||||
ui_busy_stop();
|
||||
if (s->close) {
|
||||
bool wipe = s->term->buf_handle != 0;
|
||||
@ -477,6 +483,8 @@ void terminal_enter(void)
|
||||
do_cmdline_cmd("bwipeout!");
|
||||
}
|
||||
}
|
||||
|
||||
return s->got_bsl_o;
|
||||
}
|
||||
|
||||
static void terminal_check_cursor(void)
|
||||
@ -564,6 +572,14 @@ static int terminal_execute(VimState *state, int key)
|
||||
}
|
||||
FALLTHROUGH;
|
||||
|
||||
case Ctrl_O:
|
||||
if (s->got_bsl) {
|
||||
s->got_bsl_o = true;
|
||||
restart_edit = 'I';
|
||||
return 0;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
|
||||
default:
|
||||
if (key == Ctrl_BSL && !s->got_bsl) {
|
||||
s->got_bsl = true;
|
||||
|
@ -13,6 +13,7 @@ local exc_exec = helpers.exc_exec
|
||||
local matches = helpers.matches
|
||||
local exec_lua = helpers.exec_lua
|
||||
local sleep = helpers.sleep
|
||||
local funcs = helpers.funcs
|
||||
|
||||
describe(':terminal buffer', function()
|
||||
local screen
|
||||
@ -300,6 +301,44 @@ describe(':terminal buffer', function()
|
||||
feed_command('put a') -- register a is empty
|
||||
helpers.assert_alive()
|
||||
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)
|
||||
|
||||
describe('No heap-buffer-overflow when using', function()
|
||||
|
Loading…
Reference in New Issue
Block a user