aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/channel.c
Commit message (Collapse)AuthorAge
* fix(windows): server dies with terminal after :restartJustin M. Keyes11 days
| | | | | | | | | | | | | Problem: On Windows, a server started by :restart attaches to the TUI's console. Closing the host-terminal kills the server, even after :detach or :detach!: the swap to a hidden console only happens when a stdio UI disconnects, but after :restart the TUI is on a socket. Solution: Track whether the console is inherited from the parent. When the last UI disconnects and the server keeps running, swap an inherited console for a hidden one.
* feat(api): nvim_chan_set()Justin M. Keyes12 days
| | | | | | | | | | | | | | | | | | | Problem: Only the stdio channel can "own" a server (self-exit on close). After :restart the TUI reconnects over a socket, so the restarted server does not have "self-exit" behavior when the channel closes (e.g. by UI disconnect, host-terminal close, etc.), which leaves a dangling server. Solution: - Introduce `nvim_chan_set`. (`nvim_set_client_info` doesn't fit: exposing it to Lua would require a `channel` param, which is not backwards-compatible, plus it's awkward because it doesn't merge info.) - Broadcast per-channel properties in the "restart" UI event as an opaque dict (a potentially useful pattern for other UI-events in the future). - UIs are expected to restore the channel properties on restart. - `nvim_get_chan_info()` reports "detach". - Remove `nvim__chan_set_detach()`.
* fix(channel): handle socket accept failure #41240HX L2026-08-10
|
* refactor(:restart): unnecessary console allocation on Windows #40919Sanzhar Kuandyk2026-07-23
| | | | | | | | | | | | | | | | | | | | | | | | | Problem: `:restart` on Windows always forces `AllocConsole`, even though we could reuse old server's existing console + unnecessary env. Analysis: After d5516daf121aa718e79bcd423ee24c24492893c0 changed the restart lifecycle and 789741bb83d1f31b7162cd8944bc2d846fa2fa51 separated the Windows console paths, we no longer need to force `AllocConsole()` for `:restart`. The `:detach` path now allocates its own console when it actually runs. Solution: Try to attach the replacement server to its parent’s console and fall back to `AllocConsole()` if attachment fails. Drop the restart-specific env that forced allocation. As documented by Microsoft, [“A console is closed when the last process attached to it terminates or calls `FreeConsole`.”](https://learn.microsoft.com/en-us/windows/console/attachconsole) Btw, this way we can preserve `io.stdout:write()`, though if for some reason `AttachConsole` would fail then it won't work; but now at least it's not always not rendering on `:restart`.
* feat(channel): add ChanClose event #40568Barrett Ruth2026-07-04
| | | | | | | | | Problem: Plugins using RPC sockets cannot detect when the peer closes a `sockconnect()` channel, so reconnect logic has no reliable trigger. Solution: Add a `ChanClose` event with channel info before the channel is removed, matching the existing `ChanOpen`/`ChanInfo` event model.
* refactor(os): deduplicate console/fd boilerplate #40509Justin M. Keyes2026-06-30
| | | | | | | | | Problem: Scattered, redundant boilerplate for Windows console/fd plumbing. Solution: - Add os_dup_cloexec() - Add os_reattach_console_stdio(). - Use os_open_conin_fd().
* refactor(os): libuv_proc_stdio #40506Justin M. Keyes2026-06-30
|
* fix(process): avoid inherited stdio for Windows jobs #40074Sanzhar Kuandyk2026-06-29
| | | | | | | | | | | Problem: On Windows, channel jobs inherit Nvim's stdio, so a background job writing to CON (e.g. gutentags) draws onto the TUI and stays until redraw. Solution: Give Windows job stdin/stderr libuv-created pipes (UV_CREATE_PIPE) instead of inherited fds, so libuv spawns the child with CREATE_NO_WINDOW and CON writes no longer leak onto the TUI.
* fix(:restart): set job env instead of mutating parent env #40308Justin M. Keyes2026-06-18
| | | | | | | | | | | Problem: - Transient mutation of the parent env is visible to any concurrent code. Or at least just kinda sloppy. - Latent bug:`channel_job_start` queues the spawn and returns before `uv_spawn` runs, so the prior `os_unsetenv` immediately after the call could in principle race with the deferred spawn. Solution: Pass `env` to the channel.
* feat(ui_client): "press ENTER" free nvim crash debuggingbfredl2026-05-11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This feature might be a little silly and niche, but it is very useful for _my_ workflow (and open source is about mee) An issue which is never present on high quality RELEASE builds, but might occur on Debug builds is that the Nvim server crashes on some error in your unfinished PR code. If you compile your debug builds with sanitizers enabled, as you should, the ASAN/UBSAN runtime will print some useful info about your mistake to stderr or a log file, such as a stack trace. This can be used to jump to the error in the code. This allows the nvim server to install a signal hander in the ui client, which can load this log file in a good safe version of nvim and parse it using 'errorformat' This is inspired by the "press ENTER" free workflow of ui2 and applies it beyond the lifetime cycle of the nvim instance. example config: ```lua local asan = vim.env.ASAN_OPTIONS if asan ~= nil and string.match(asan, "log_path=/tmp/nvim_asan") then local myname = "/tmp/nvim_asan."..vim.uv.getpid() local args = {"--embed", "-n", "+set efm=%+A%*[^/]%f:%l:%c", "+silent cfile "..myname, "+silent cfirst", "+silent copen"} vim.api.nvim__set_restart_on_crash("nvim", args) end ``` and run your debug nvim like so ASAN_OPTIONS=handle_abort=1,handle_sigill=1,log_path=/tmp/nvim_asan ./build/bin/nvim
* feat(api): rename buffer to buf in retval #38900Justin M. Keyes2026-04-13
| | | | | | In 3a4a66017b74192caaf9af9af172bdc08e0c1608, 4d3a67cd620152d11ab9b5f5bdd973f84cc2d44b we renamed "buffer" to "buf" in dict parameters. This commit also renames such keys in dict return-values.
* Merge pull request #38669 from SanzharKuandyk/fix-38667zeertzjq2026-04-07
|\ | | | | fix(channel): fix Windows console regressions from #37977
| * fix(channel): fix Ctrl-C handling regression in terminalSanzhar Kuandyk2026-04-06
| | | | | | | | | | | | Problem: Normal Windows builtin-TUI startup spawns the embedded server as DETACHED_PROCESS, which breaks Ctrl-C delivery to :terminal jobs. Solution: Restores the default behavior once the embedded server has a console so terminal jobs inherit it.
| * refactor(channel): defer hidden console allocation to :detachSanzhar Kuandyk2026-04-01
| | | | | | | | Refactor #37977: instead of allocating a hidden console at startup, borrow the parent's console via AttachConsole() and only create an isolated hidden console when :detach is called, with fd 0/1/2 re-bound to the new CONIN$/CONOUT$.
* | fix(channel): crash on exit after closing v:stderr channel (#38754)zeertzjq2026-04-04
|/ | | | | | | Problem: Crash on exit after closing v:stderr channel when piping to stdin. Solution: Reopen stderr as /dev/null or NUL instead of closing it. This also avoids writing to an related file if one is opened after closing v:stderr.
* fix(:restart): formalize restart event #35223Sathya Pramodh2026-03-28
| | | | | | | | | | | | | | | | | | | Problem: The "restart" event has some problems: - all UI clients must implement a somewhat complex set of setups - UI must be on the same machine as the server - only works for the "current" UI - race/edge case: If the user config has errors / waiting for input, are all UIs able to attach while Nvim is waiting for input? Solution: - Perform the restart on the server, not the client. - Pass listen address (instead of CLI args) in the UI event. - Simplifies UI logic: they only need to attach to new address. - Opens the door for more enhancements in the future, such as allowing all UIs to reattach instead of only the "current" UI. Co-authored-by: zeertzjq <zeertzjq@outlook.com> Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
* fix(terminal): don't poll for output during scrollback refresh (#38365)zeertzjq2026-03-19
| | | | | | | | Problem: If buffer update callbacks poll for uv events during terminal scrollback refresh, new output from PTY process may lead to incorrect scrollback. Solution: Don't poll for output to the same terminal as the one being refreshed.
* feat(terminal): surface exit code via virttext + nvim_get_chan_info #37987Ayaan2026-03-10
| | | | | | | | | | Problem: When a terminal process exits, "[Process Exited]" text is added to the buffer contents. Solution: - Return `exitcode` field from `nvim_get_chan_info`. - Show it in the default 'statusline'. - Show exitcode as virtual text in the terminal buffer.
* revert: "fix(tui): server --listen error sometimes not visible (#38027)" ↵zeertzjq2026-03-06
| | | | | | | | (#38175) This reverts commit ab8371a26cf47a40d26af637455ea71da0d5a59d. Need to think of a different solution, which may require adding new flags to nvim_ui_attach() (e.g. passing stdout or stderr fd).
* fix(tui): server --listen error sometimes not visible (#38027)zeertzjq2026-03-02
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: If Nvim server fails to --listen and prints error before the TUI enters alternate screen, the error isn't visible. Solution: Forward server stderr using client side stderr handler instead of having the server inherit client stderr file descriptor. This does mean that `stderr_isatty` will be `false` in the server, but that value doesn't matter in embedded mode. Always pass `stdin_fd` to embedded server to avoid a hang when reading from stdin when it's a TTY (not sure why one wants to do that, perhaps by mistake), because if `stdin_fd` isn't passed, the server will try to use stderr as stdin. Example test failure on CI: FAILED test/functional/terminal/tui_spec.lua @ 41: TUI exit status 1 and error message with server --listen error #34365 test/functional/terminal\tui_spec.lua:55: Failed to match any screen lines. Expected (anywhere): "nvim%.exe: Failed to %-%-listen: address already in use:" Actual: |{114:nvim.exe -h"} | | | |[Process exited 1]^ | | | | | | | | | | | | | | | | | | | | | | | | | | | |{5:-- TERMINAL --} | Snapshot: screen:expect([[ {114:nvim.exe -h"} | | [Process exited 1]^ | |*13 {5:-- TERMINAL --} | ]]) stack traceback: test\functional\ui\screen.lua:909: in function '_wait' test\functional\ui\screen.lua:537: in function 'expect' test/functional/terminal\tui_spec.lua:55: in function <test/functional/terminal\tui_spec.lua:41> In this case, it appears that the client entered alternate screen in the middle of the server's print_mainerr().
* fix(channel): support :detach, :restart on Windows #37977Sanzhar Kuandyk2026-02-28
| | | | | | | | | | | | | | fix: allocate hidden console for detached server Starting the server with UV_PROCESS_DETACHED results in DETACHED_PROCESS, leaving the child without a console. Without a console: CONIN$ / CONOUT$ cannot resolve, causing channel_from_stdio to fail. ConPTY cannot attach, breaking :terminal. This patch allocates a hidden console via AllocConsole() when the server has none, restoring working stdio and enabling ConPTY. Also updates os_set_cloexec to clear HANDLE_FLAG_INHERIT on the RPC pipe handles, matching the Unix F_DUPFD_CLOEXEC behavior.
* fix(process): handle poll() interrupted by a signal (#38024)zeertzjq2026-02-23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | It is indeed possible that a signal may arrive during flush_stream() (e.g. SIGCHLD from another child process), so poll() again on EINTR. Fixes the following Coverity warning: _____________________________________________________________________________________________ *** CID 644345: Error handling issues (CHECKED_RETURN) /src/nvim/event/proc.c: 405 in flush_stream() 399 400 #ifdef __linux__ 401 // On Linux, libuv's polling (which uses epoll) doesn't flush PTY master's pending 402 // work on kernel workqueue, so use an explcit poll() before that. #37982 403 if (proc->type == kProcTypePty && !stream->did_eof) { 404 struct pollfd pollfd = { .fd = ((PtyProc *)proc)->tty_fd, .events = POLLIN }; >>> CID 644345: Error handling issues (CHECKED_RETURN) >>> Calling "poll(&pollfd, 1UL, 0)" without checking return value. This library function may fail and return an error code. 405 poll(&pollfd, 1, 0); 406 } 407 #endif 408 // Poll for data and process the generated events. 409 loop_poll_events(proc->loop, 0); 410 if (stream->s.events) { Another possible error is ENOMEM, which is probably not worth handling. For reference, #23308 previously removed a case of ENOMEM handling, and this PR also removes an outdated mention of that. Also reduce the number of #ifdefs in non-OS-specific files.
* fix(rpc): include write failure reason in log (#37959)zeertzjq2026-02-19
| | | Also don't use LOGLVL_ERR on UV_EPIPE.
* feat(prompt): plugins can update prompt during user input #37743Shadman2026-02-14
| | | | | | | | | | | Problem: Currently, if prompt gets changed during user-input with prompt_setprompt() it only gets reflected in next prompt. And that behavior is not also consistent. If user re-enters insert mode then the user input gets discarded and a new prompt gets created with the new prompt. Solution: Handle prompt_setprompt eagerly. Update the prompt display, preserve user input.
* feat(terminal): detect suspended PTY process (#37845)zeertzjq2026-02-13
| | | | | | | Problem: Terminal doesn't detect if the PTY process is suspended or offer a convenient way for the user to resume the process. Solution: Detect suspended PTY process on SIGCHLD and show virtual text "[Process suspended]" at the bottom-left. Resume the process when the user presses a key.
* fix(channel): crash on failed sockconnect() (#37811)zeertzjq2026-02-11
| | | | | | | Problem: Crash on failed sockconnect() if a new connection is accepted while polling for uv events. Solution: Don't use channel_destroy_early(). Also test "tcp" mode failure properly.
* fix(vterm): handle split UTF-8 after ASCII properly (#37721)zeertzjq2026-02-06
| | | | Problem: libvterm doesn't handle split UTF-8 sequence after ASCII. Solution: Only use one UTF-8 encoding state per vterm state.
* fix(terminal): losing output if BufFile* poll for events (#37580)zeertzjq2026-01-28
| | | | | | Problem: Terminal loses output if a BufFilePre or BufFilePost autocmd polls for events. Solution: Rename the buffer after allocating the terminal instance. Also fix buffer getting wrong name if BufFilePre uses NameBuff.
* fix(channel): unreference list after callback finishes (#37358)zeertzjq2026-01-12
|
* fix(:ls): check for finished terminal properly (#37303)zeertzjq2026-01-09
| | | Use terminal_running() instead of channel_job_running().
* Merge pull request #36393 from zeertzjq/rstream-close-cbzeertzjq2025-10-31
| | | fix(channel): closing socket with pending writes leaks memory
* fix(rpc): handle more cases when identifying loopback #36100Vlad2025-10-09
| | | | | | | | | | | | | | Problem: On MacOS it is a relatively common pattern to set XDG_RUNTIME_DIR under `/tmp` or `/var`. Both of these are symlinks to `/private/tmp` and `/private/var`. When checking for loopback the input address is normalized using `fix_fname`, however this is not applied to the addresses of the sockets. As a result of one address being normalized and the other not the comparison would fail. Solution: Normalize both sides of the comparison using `fix_fname`.
* refactor(build): remove INCLUDE_GENERATED_DECLARATIONS guardsbfredl2025-08-14
| | | | | | | | | These are not needed after #35129 but making uncrustify still play nice with them was a bit tricky. Unfortunately `uncrustify --update-config-with-doc` breaks strings with backslashes. This issue has been reported upstream, and in the meanwhile auto-update on every single run has been disabled.
* vim-patch:8.1.1584: the evalfunc.c file is getting too bigJan Edmund Lazo2025-07-20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: The evalfunc.c file is getting too big. Solution: Move channel and job related functions to channel.c. https://github.com/vim/vim/commit/0a1f56fcfe31be929e9cd8c3d81a984c960e4180 --- N/A patches below: vim-patch:8.1.0770: inconsistent use of ELAPSED_FUNC Problem: Inconsistent use of ELAPSED_FUNC. Solution: Consistently use ELAPSED_FUNC. Also turn ELAPSED_TYPE into a typedef. (Ozaki Kiichi, closes vim/vim#3815) https://github.com/vim/vim/commit/1ac56c2d11da5ffa44db23e1fd0c533d02ab2f66 vim-patch:8.1.0914: code related to findfile() is spread out Problem: Code related to findfile() is spread out. Solution: Put findfile() related code into a new source file. (Yegappan Lakshmanan, closes vim/vim#3934) https://github.com/vim/vim/commit/5fd0f5052f9a312bb4cfe7b4176b1211d45127ee vim-patch:8.1.1004: function "luaV_setref()" not covered with tests Problem: Function "luaV_setref()" not covered with tests. Solution: Add a test. (Dominique Pelle, closes vim/vim#4089) https://github.com/vim/vim/commit/e165f63598b58bfdac0168583aa1ef75fbf7be6d vim-patch:8.1.1551: warning for shadowing popup_dragwin Problem: Warning for shadowing popup_dragwin. (Dominique Pelle) Solution: Add missing change. https://github.com/vim/vim/commit/6c17543b5634ccccedfbffa4993e9fbd4a990067 vim-patch:8.1.1629: terminal function help is in the wrong file Problem: Terminal function help is in the wrong file. Solution: Move the function details to terminal.txt. https://github.com/vim/vim/commit/6bf2c6264b5ebbe4981751840c5a8b69da08e744 vim-patch:8.1.1641: garbage collection may run at a wrong moment Problem: Garbage collection may run at a wrong moment. (Trygve Aaberge) Solution: Postpone garbage collection while parsing messages. (closes vim/vim#4620) https://github.com/vim/vim/commit/6cc7e21412487ff8bd531c73ac9325f5ba2409a9 vim-patch:8.1.1703: breaking out of loop by checking window pointer insufficient Problem: Breaking out of loop by checking window pointer is insufficient. Solution: Check the window ID and the buffer number. (closes vim/vim#4683) https://github.com/vim/vim/commit/61386408063a2300d7d7f42c5156f66f6252fb54 vim-patch:8.1.1802: missing change to call_callback() Problem: Missing change to call_callback(). Solution: Add missing change. https://github.com/vim/vim/commit/b2129068a55261bea1e293a6a1ce8491a03e7de6 vim-patch:8.1.1853: timers test is still flaky Problem: Timers test is still flaky. Solution: Compute the time to sleep more accurately. https://github.com/vim/vim/commit/52953194afccbcb6c2fd013b7a9e2cfbf202b9d0 --- Seems N/A now because of commit 09370eae7756b07bb8f1f116b690b22aec7ec563 --- vim-patch:8.1.2200: crash when memory allocation fails Problem: Crash when memory allocation fails. Solution: Check for NULL curwin and curbuf. (Christian Brabandt, closes vim/vim#4839) https://github.com/vim/vim/commit/1cac70953d3c012453ea85b1308a8b1f94359c26 vim-patch:8.2.3922: cannot build with dynamic Ruby 3.1 Problem: Cannot build with dynamic Ruby 3.1. Solution: Add "_EXTRA" variables for CI. Add missing functions. (Ozaki Kiichi, closes vim/vim#9420) https://github.com/vim/vim/commit/8bb3fe4d4dcd27c02e903f6772fdc8fe2e9eba70 vim-patch:9.0.0546: supporting Ruby 1.8 makes code complicated Problem: Supporting Ruby 1.8 makes code complicated. Solution: Drop Ruby 1.8 support, it is ancient. (Ken Takata, closes vim/vim#11195) https://github.com/vim/vim/commit/236ccbf6f8a671a45b773de4b34558ecfdf9ac02 vim-patch:9.0.0928: using Ruby LDFLAGS may cause build problems Problem: Using Ruby LDFLAGS may cause build problems. Solution: Do not add Ruby LDFLAGS to Vim's LDFLAGS. (Zdenek Dohnal, closes vim/vim#11592) https://github.com/vim/vim/commit/1d822afaf66a84fab71c84521fd92db11d2c8925 vim-patch:9.1.1382: if_ruby: unused compiler warnings from ruby internals Problem: if_ruby: unused compiler warnings from ruby internals Solution: disable -Wunused-parameter for if_ruby internal code (Philip H.) closes: vim/vim#17297 https://github.com/vim/vim/commit/411730e277c408f89c82ae7dbb1ebfa71ec0f4e5 Co-authored-by: Bram Moolenaar <Bram@vim.org>
* docs: misc #32959Justin M. Keyes2025-03-18
|
* fix(events): always allow some events to be nested (#32706)zeertzjq2025-03-08
| | | | | | | | | | | | | | | Always allow the following four events to be nested, as they may contain important information, and are triggered on the event loop, which may be processed by a blocking call inside another autocommand. - ChanInfo - ChanOpen - TermRequest - TermResponse There are some other events that are triggered on the event loop, but they are mostly triggered by user actions in a UI client, and therefore not very likely to happen during another autocommand, so leave them unchanged for now.
* feat(ui): UI :detach commandJustin M. Keyes2025-02-10
| | | | | | | | | | | Problem: Cannot detach the current UI. Solution: - Introduce `:detach`. - Introduce `Channel.detach`. Co-authored-by: bfredl <bjorn.linse@gmail.com>
* refactor: iwyu #31637Justin M. Keyes2024-12-23
| | | Result of `make iwyu` (after some "fixups").
* refactor(api)!: rename Dictionary => DictJustin M. Keyes2024-09-23
| | | | | | | | | | | | | | In the api_info() output: :new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val') ... {'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1} The `ArrayOf(Integer, 2)` return type didn't break clients when we added it, which is evidence that clients don't use the `return_type` field, thus renaming Dictionary => Dict in api_info() is not (in practice) a breaking change.
* refactor: rename "process" => "proc" #30387Justin M. Keyes2024-09-15
| | | | | | | | | | | | Problem: - "process" is often used as a verb (`multiqueue_process_events`), which is ambiguous for cases where it's used as a topic. - The documented naming convention for processes is "proc". - `:help dev-name-common` - Shorter is better, when it doesn't harm readability or discoverability. Solution: Rename "process" => "proc" in all C symbols and module names.
* revert: "refactor: use S_LEN macro" (#29319)Lewis Russell2024-06-14
| | | | | revert: "refactor: use S_LEN(s) instead of s, n (#29219)" This reverts commit c37695a5d5f2e8914fff86f3581bed70b4c85d3c.
* refactor: use S_LEN(s) instead of s, n (#29219)James2024-06-11
|
* refactor(io): make rstream use a linear bufferbfredl2024-06-08
| | | | | | | | | If you like it you shouldn't put a ring on it. This is what _every_ consumer of RStream used anyway, either by calling rbuffer_reset, or rbuffer_consumed_compact (same as rbuffer_reset without needing a scratch buffer), or by consuming everything in each stream_read_cb call directly.
* refactor: move shared messages to errors.h #26214Justin M. Keyes2024-06-01
|
* refactor(io): separate types for read and write streamsbfredl2024-05-31
| | | | | | | | | | | | This is a structural refactor with no logical changes, yet. Done in preparation for simplifying rstream/rbuffer which will require more state inline in RStream. The initial idea was to have RStream and WStream as sub-types symetrically but that doesn't work, as sockets are both reading and writing. Also there is very little write-specific state to start with, so the benefit of a separate WStream struct is a lot smaller. Just document what fields in `Stream` are write specific.
* docs: misc #24163Justin M. Keyes2024-04-30
| | | | | | | | | | - Also delete old perl scripts which are not used since 8+ years ago. fix #23251 fix #27367 ref https://github.com/neovim/neovim/issues/2252#issuecomment-1902662577 Helped-by: Daniel Kongsgaard <dakongsgaard@gmail.com> Co-authored-by: Kevin Pham <keevan.pham@gmail.com>
* fix: prevent child processes from inheriting ui channel file descriptorsFred Sundvik2024-04-02
|
* fix(terminal): don't pass incomplete UTF-8 sequence to libvterm (#27922)zeertzjq2024-03-19