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
[RDY] Builtin terminal emulation #2076
Conversation
Wondering how it deals with https://bugs.launchpad.net/libvterm/+bug/1412093. Also what is the $TERM value (see https://bugs.launchpad.net/libvterm/+bug/1412091 for why this is relevant)? |
@ZyX-I I've directed the URL to a fork that fixes these messages: https://github.com/neovim/libvterm/commits/cflags-override( @leonerd will probably merge them once he gets back from holidays) As for https://bugs.launchpad.net/libvterm/+bug/1412091 , libvterm aims have xterm compliance but its not there yet. |
Very nice! Is it possible to somehow paste/send stdin data to the vte ? (perhaps |
Shouldn't the "real" terminal cursor follow the vte cursor when in "insert" mode ? Otherwise it looks weird when e.g. using input methods |
@bfredl I plan to fully integrate this with vimscript job control API(it will be possible to control debuggers, paste data, etc) Im still not sure about the cursor behavior(perhaps it should simply become invisible when in normal mode?) |
Invisible cursor looks like neovim doing something. Always invisible cursor looks like neovim hang forever. |
@ZyX-I I meant that the vterm cursor should be invisible when in normal mode and also the other way around, so there will only be one visible cursor at a time |
@tarruda yes, and when in vterm mode the vterm cursor should be forwarded as ui cursor events. This is required to make the preview buffer of input methods to show up at the right place (that is, at the cursor) |
@tarruda Is this in reference to #1802? I'm not attached to that PR, but the purpose of that PR is to give plugins (and core) the option to emit non-blocking messages, not to eliminate them entirely. The next (future) step I was envisioning was for We could offer an option to eliminate all "Press ENTER" messages, but I'm not sure this would actually be a good thing for users to do. The "pager" that Vim emulates for messages is quite handy for messages that the user wants to briefly check, and the fact that it can be dismissed by pressing any normal-mode key (which is then executed) is a feature that would be missed. So, #1802 has a small imperfection that I still need to fix, but perhaps we should discuss whether it is worth continuing. I would really like to wrap it up this weekend one way or other. |
Btw, the obligatory nvim-within-nvim test already works (probably not practically useful, but reckon it is a good "stress test" ) 👍 |
@bfredl Really cool :) Going to try this PR now |
I agree @justinmk. I don't think it's wise to remove them all, they do serve a purpose and sometimes you really do want to call attention to the user. |
This is awesome :) |
Awesome! I really don't know how I would use this feature but it's impressive how well it works. Some things I noticed:
|
This is SUPER AWESOME :) |
👍 awesome feature from Neovim. |
Just one thing, when I type Fucking awesome feature. |
@rainerborene on my system I don't see either of the bugs you describe with |
Whats the value of your |
if (linenr <= term->buf->b_ml.ml_line_count) { | ||
ml_replace(linenr, (uint8_t *)line, false); | ||
} else { | ||
ml_append(linenr - 1, (uint8_t *)line, 0, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need a free(line);
here. ml_append
seems to copy line
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@justinmk / @jszakmeister The states where user feedback is required can be easily emulated with the new terminal module. For example, here's how I plan to enhance bang commands with this new feature while still maintaining vimscript compatibility:
Note that the keypress sequence is still the same, the differences are:
A similar concept can be applied to message output:
The advantage of using this approach may not be obvious but here are some:
|
👍 |
With time, the numerous use cases for this feature will be clear, but here's one idea: This allows another level of integration between text mode programs and Neovim. For example, we'll be able to make gdb respond to nvim mappings and change file/line numbers when a breakpoint is hit(Technically this might be possible with tmux but not without numerous hacks)
👍 needs to be fixed
Not sure what you mean, but when you leave terminal focus(Ctrl+w, esc) you can move around the scrollback just like any other buffer)
Thats expected, the terminal buffer cannot receive direct modifications from the user: The key presses are forwarded to the underlying program which outputs redraw instructions. This is how any terminal behaves(you cannot delete lines from tmux panes for example)
👍 Its just a redraw glitch, should be easy to fix. |
I know, this was one of the first things I tried with 5 levels of nesting 😄 |
@tarruda do you plan on documenting this soonish? I assume you have a lot to do already, but I can't think of a better person to document this than the person who wrote it. If I can help in any way just ask. |
Definitely. I didnt do it yet because I will create another PR after this one that will contain changes to the job API, so I'd rather document everything in one step. |
👍 Thanks for clarifying. |
This is required to avoid event loop recursion due to indirect calls to os_breakcheck by screenalloc
This ifndef causes problems when including fileio headers.
Most internal functions to modify buffers operate on the current buffer and require temporary switchs. This macro is a temporary workaround until a cleaner refactoring of the internal API is performed.
This commit integrates libvterm with Neovim and implements a terminal emulator with nvim buffers as the display mechanism. Terminal buffers can be created using any of the following methods: - Opening a file with name following the "term://[${cwd}//[${pid}:]]${cmd}" URI pattern where: - cwd is the working directory of the process - pid is the process id. This is just for use in session files where a pid would have been assigned to the saved buffer title. - cmd is the command to run - Invoking the `:terminal` ex command - Invoking the `termopen` function which returns a job id for automating the terminal window. Some extra changes were also implemented to adapt with terminal buffers. Here's an overview: - The `main` function now sets a BufReadCmd autocmd to intercept the term:// URI and spawn the terminal buffer instead of reading the file. - terminal buffers behave as if the following local buffer options were set: - `nomodifiable` - `swapfile` - `undolevels=-1` - `bufhidden=hide` - All commands that delete buffers(`:bun`, `:bd` and `:bw`) behave the same for terminal buffers, but only work when bang is passed(eg: `:bwipeout!`) - A new "terminal" mode was added. A consequence is that a new set of mapping commands were implemented with the "t" prefix(tmap, tunmap, tnoremap...) - The `edit` function(which enters insert mode) will actually enter terminal mode if the current buffer is a terminal - The `put` operator was adapted to send data to the terminal instead of modifying the buffer directly. - A window being resized will also trigger a terminal resize if the window displays the terminal.
- Free memory allocated for job data when the job table is full.
Since all reads are queued by the event loop, we must also queue the exit event, or else the process_close function can close the job streams before received data is processed.
- Modify tty-test to allow easier control over the terminal - Add a new directory with various terminal tests/specifications - Remove a pending job/pty test. - Flush stdout in Screen:snapshot_util() (avoid waiting for the test to finish) - Replace libuv sigwinch watcher by a sigaction handler. libuv randomly fails to deliver signals on OSX. Might be related to the problem fixed by @bbcddc55ee1e5605657592644be0102ed3a5f104 (under the hoods, libuv uses a pipe to deliver signals to the main thread, which might be blocking in some situations)
f4e9af1
to
2aa2513
Compare
I wouldn't want to use all those other means because those means are already part of Neovim, and we can use them on the terminal buffer. It's so convenient. |
Current busted output type does not allow determining failing test.
This PR uses libvterm(big thanks to @leonerd for that project) to implement a full VT220 terminal emulator using Neovim buffers and windows. ~~It will also refactor the calling of shell commands to use this facility, fixing #1044 #1386 #1496 #1716 (all caused by an issue introduced in #1365)~~~(I've decided to not touch the generic
os_call_shell
for now)Still a WIP but the
:terminal
ex command can already be used, here's a quick rundown::term [prog/args]
will open a new special buffer "connected" to a pseudo terminal running prog/args<c-\><c-n>
combination will return to normal mode.tnoremap <c-a> <c-\><c-n>
exit terminal focus using ctrl+a)@justinmk An observation about the new
Terminal
class: It is not coupled to job control so we can use it for implementing #901 and eventually remove all blocking messages(press enter to continue) from nvim(We could have a Terminal instance created at startup and feed all messages to it, for example)