New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Terminal not reset correctly when executing a shell command from autocmd #3692
Comments
I'm trying to use [ranger](https://github.com/ranger/ranger) as a replacement for builtin netrw explorer. Here's a code to do so:
```
function! Ranger()
exec '!ranger'
endfunction
command! -bar Ranger call Ranger()
augroup ranger
au!
au VimEnter * sil! au! FileExplorer *
au BufEnter * if isdirectory(expand('%')) | bd | exe 'Ranger' | endif
augroup END
```
My terminal emulator of choice is [urxvt](http://software.schmorp.de/pkg/rxvt-unicode.html).
Contrary to some other terminal emulators, urxvt uses different keycodes for arrow-keys in `Application Cursor Keys` (DECCKM) mode (`ESC [ ?1h`). When the DECCKM mode is, arrow keys stop working in applications like `ranger`.
When executing `:!ranger` command directly from the normal mode, the terminal is properly reset to `normal` cursor mode and the arrow keys work as expected. However, when `:!ranger` command is triggered using the above snippet, the terminal is not longer reset correctly to `Normal` mode (`\ESC ?1l`), but stays in `Application Cursor Mode` (I guess, the default mode for vim), and that causes the arrow keys to stop working.
Have you tried simplifying this? E.g., instead of calling the function,
execute ":!ranger" directly from the user command?
Not as a solution, but to narrow down the problem.
When executing a function some things are saved and restored.
When using the function, instead of:
exec '!ranger'
You can do:
!ranger
(although I doubt that makes a difference).
…--
hundred-and-one symptoms of being an internet addict:
14. You start introducing yourself as "Jim at I-I-Net dot net dot au"
/// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
|
I've tried simplifying it to barebones, but it still happens. The only line in my vimrc:
Still no luck. However, I'm able to get the arrow keys working by resetting cursor mode before running the command:
I've also tried a few different autocmd types, but it happens with all of them. My guess is that autocmd use a different code path than regular |
Looking at the code, I think that the culprit is this:
so when auto commands are active stoptermcap(), a function that sends |
Looking at the code, I think that the culprit is this:
ex_cmds.c:1568
```
/*
* For autocommands we want to get the output on the current screen, to
* avoid having to type return below.
*/
if (!autocmd_busy)
{
...
stoptermcap();
}
```
so when auto commands are active stoptermcap(), a function that sends
`KS_KE` code, is never called.
Ah, yes, didn't think of that. So when an autocommand is executed it
assumes the shell command is not interactive, just a short-lived filter
or something like that.
I don't think we can change the current behavior without causing
problems.
We could add a way to execute a shell command and indicating the command
is used interactively. Then "autocommand_busy" would be overruled.
Perhaps
:interactive !cmd
Since we already have:
:silent !cmd
…--
Shift happens.
-- Doppler
/// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
|
Yes, that's one way to fix the problem. Alternatively, we could send the Something like:
Note: this is just a sample patch, we probably want to reset bracketed mode and maybe some other things as well. Point being, apart from changing the termcap mode any other control characters shouldn't really affect non-interactive commands. |
Yes, that's one way to fix the problem.
Alternatively, we could send the `T_KS` and `T_KE` unconditionally.
That wouldn't require any new 'interactive' flag and would keep the
backwards compatibility.
Something like:
```
diff --git i/src/ex_cmds.c w/src/ex_cmds.c
index cd243a5ef..10adb288d 100644
--- i/src/ex_cmds.c
+++ w/src/ex_cmds.c
@@ -1572,6 +1572,12 @@ do_shell(
#endif
stoptermcap();
}
+ else
+ {
+ /* reset keypad mode in case we run interactive commands */
+ out_str(T_KE);
+ out_flush();
+ }
#ifdef MSWIN
if (!winstart)
#endif
@@ -1617,6 +1623,9 @@ do_shell(
{
if (msg_silent == 0)
redraw_later_clear();
+ /* restore keypad mode in case we run interactive commands */
+ out_str(T_KS);
+ out_flush();
}
else
{
diff --git i/src/globals.h w/src/globals.h
index 131c13be9..561bc87dd 100644
```
Note: this is just a sample patch, we probably want to reset
bracketed mode and maybe some other things as well. Point being, apart
from changing the termcap mode any other control characters shouldn't
really affect non-interactive commands.
This won't always work, because T_KE can also contain an escape sequence
to switch screens, or anything else. One can't assume the termcap
entries are used as they were originally intended.
…--
Far out in the uncharted backwaters of the unfashionable end of the
Western Spiral arm of the Galaxy lies a small unregarded yellow sun.
Orbiting this at a distance of roughly ninety-eight million miles is an
utterly insignificant little blue-green planet whose ape-descended life
forms are so amazingly primitive that they still think digital watches
are a pretty neat idea ...
-- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"
/// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
|
Do you mean terminals that do not follow the spec or people redefining T_KE entry? I guess to solve my problem, I can just echo the T_KE myself before running the application. |
I'm trying to use ranger as a replacement for builtin netrw explorer. Here's a code to do so:
My terminal emulator of choice is urxvt.
Contrary to some other terminal emulators, urxvt uses different keycodes for arrow-keys in
Application Cursor Keys
(DECCKM) mode (ESC [ ?1h
). When the DECCKM mode is, arrow keys stop working in applications likeranger
.When executing
:!ranger
command directly from the normal mode, the terminal is properly reset tonormal
cursor mode and the arrow keys work as expected. However, when:!ranger
command is triggered using the above snippet, the terminal is not longer reset correctly toNormal
mode (\ESC ?1l
), but stays inApplication Cursor Mode
(I guess, the default mode for vim), and that causes the arrow keys to stop working.The text was updated successfully, but these errors were encountered: