aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua
Commit message (Collapse)AuthorAge
...
* feat(input)!: CmdAtom event #41297Justin M. Keyes2026-08-14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: There is no unified notion of a "user action". Vim processes input by one-char-at-a-time, and mostly throws away any hints it might gather about the user's action, with one exception: it stores the last _edit_ action (the "redo buffer", encoded as unstructured `["x][v][count]body` bytes). Plugins can only observe individual keys (vim.on_key) and high-level effects (TextChanged, CursorMoved). Solution: - Users can subscribe to `CmdAtom` events to handle any user action. - Event is deferred; handlers cannot cancel or interfere with user actions. - Capture `CmdSpec` from the normal/insert/visual subsystems. - typeahead/readahead stay unstructured (`buffheader_T`): they are key streams, not commands. - the redo/record buffers become `StringBuilder`: fewer allocations/copies. - Repurpose the input/redo engine to accept `CmdSpec` objects. "atom": one repeatable unit of user input, as a resolved (post-mapping) keysequence plus structured fields. Only user actions, not `:normal`, API calls, or non-"t" `feedkeys`. BREAKING: dot-repeat of an Insert session, replays the entire session including cursor-moves (:help ins-repeat). BREAKING: dot-repeat of a Visual operation, replays the selection instead of operating on a fixed-size region.
* vim-patch:9.2.0957: filetype: ArgoCD config file is not recognized (#41301)zeertzjq2026-08-14
| | | | | | | | | | | | | Problem: filetype: ArgoCD configuration file is not recognized Solution: Detect */argocd/config as yaml filetype (Fionn Fitzmaurice). Reference: https://argo-cd.readthedocs.io/en/latest/user-guide/commands/argocd_configure/#options-inherited-from-parent-commands closes: vim/vim#21031 https://github.com/vim/vim/commit/7807dd22793da0e826618c0ca9c6210bbc1ea3f5 Co-authored-by: Fionn Fitzmaurice <git@fionn.computer>
* fix(diagnostic): don't accumulate BufRead autocmds for unloaded buffers #40869Nathan B.2026-08-13
| | | | | | | | | | | | | | | Problem: vim.diagnostic.set() defers extmark position computation for an unloaded buffer via a once=true BufRead autocmd, registering a new one on every call without replacing the previous one. Each pending autocmd also retains that call's diagnostics. Solution: Instead of registering an autocmd per set() call, register a single static BufRead autocmd that computes positions from the diagnostic cache for any buffer with cached diagnostics when it is read. This removes the per-call registration entirely (nothing left to accumulate) and means diagnostics cleared while the buffer was unloaded no longer produce stale extmarks.
* Merge #41075 from echasnovski/pack-packspec-part1Justin M. Keyes2026-08-13
|\
| * feat(pack): add support for sourcing manifest scriptsEvgeni Chasnovski2026-07-31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: No way for plugins to define hooks that would be executed during plugin lifecycle. Like after install/update or before update/delete. Solution: Automatically source scripts defined in plugin manifest file (if any) after triggering corresponding `PackChanged{,Pre}` events. During sourcing make some termporary adjustments: - Current directory is set to plugin's root to simplify execution of CLI calls like `make build`. - Plugin's path is ensured to be inside 'runtimepath' to allow using `require('plugin-module')` inside manifest scripts. The reason to execute after triggering event is so that there is a possibility for users to execute code both before the script (exactly on event) and after the script (more-or-less via `vim.schedule` called on the event).
| * feat(pack): introduce plugin manifest supportEvgeni Chasnovski2026-07-31
| | | | | | | | | | | | | | | | | | Problem: There is no agreed way for plugins to provide extra information about themselves. Like required Neovim version, install/update/delete hooks, and dependencies. Solution: Introduce basic concept of plugin manifest file `pkg.json` based on https://packspec.org/.
* | vim-patch:02bf089: runtime(doc): clarify diff_filler() function (#41283)zeertzjq2026-08-12
| | | | | | | | | | | | | | fixes: vim/vim#20990 https://github.com/vim/vim/commit/02bf0893d536449548f91b75817748a5e25219c0 Co-authored-by: Christian Brabandt <cb@256bit.org>
* | fix(defaults): emit events on automatic background change #41242Kyle2026-08-10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: After #40270, events are no longer emitted from the automatic background detection. This applies not just during startup, but also if the user manually changes the background of their terminal. Solution: Set the background as normal, assuming that a normal terminal will respond within 100 ms. Change test to match expected behavior: - BG set during startup won't trigger user autocmds since it runs before any user config - If the terminal takes longer than 100 ms to respond to initial OSC 11, it does trigger the OptionSet, but it is triggered through the normal path to ensure values like v:option_new are set #38551 - BG change after startup still triggers autocmds #41146
* | vim-patch:9.2.0926: filetype: Business Central files are not recognized (#41230)Torben Leth2026-08-09
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: filetype: Business Central files are not recognized Solution: Add filetype detection logic for *.al files to detect perl or use either perl or al filetype (Torben Leth). Reference: https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/devenv-dev-overview closes: vim/vim#20975 Supported by AI. https://github.com/vim/vim/commit/9b41cf6386bc0afd1bf5eca396adfdd488e617d0
* | feat(lsp): pass target buffer to `reuse_client` predicate #41163Mike J McGuirk2026-08-07
| | | | | | | | | | | | Problem: The reuse_client predicate does not pass the target buffer, preventing decisions from being truly made per buffer. Solution: Pass the target buffer.
* | fix(terminal): spawn in effective CWD #41211Justin M. Keyes2026-08-07
| | | | | | | | | | | | | | | | | | Problem: `:terminal` does not respect the invocation-time CWD. This wasn't noticeable with `:lcd` because the window-local CWD gets applied to the new terminal buffer. But it is noticeable with `:bcd`. Solution: Specify `cwd` in the job spec.
* | feat(cwd)!: :lcd! (bang), rearrange :bcd/:lcd/… scope precedence #41194Justin M. Keyes2026-08-07
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: - buf-local CWD scope is lower priority than :lcd, which is weird. ``` win > buf > tab > global ``` - No way to clear current CWD at a given scope. Solution: - Rerrange scope precedence to: ``` buf > win > tab > global ``` - Introduce "bang" variants (`:bcd!`/`:lcd!`/`:tcd!`) which clears the local CWD for the given scope.
* | vim-patch:9.2.0920: filetype: json-ld files are not recognizedzeertzjq2026-08-07
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: filetype: json-ld files are not recognized Solution: Detect *.jsonld files as jsonld filetype, include filetype, indent and syntax plugins (Bogdan Barbu). Reference: https://www.w3.org/TR/json-ld11/ closes: vim/vim#20954 https://github.com/vim/vim/commit/a1e2198a2ca8bbddcad69ade8629f371bcb4cf1f Co-authored-by: Bogdan Barbu <l4b.bogdan.barbu@gmail.com>
* | feat(vim._with): `keepcwd`Justin M. Keyes2026-08-06
| |
* | feat(cwd): support explicit chdir (:bcd/:tcd/…) in temp contextJustin M. Keyes2026-08-06
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: - Explicit `:bcd` (etc.) persists from `nvim_buf_call()` but not from an autocmd handler targeting a hidden buf (`LspAttach`, `TermRequest`, …), which needs a `vim.schedule()` workaround. - `vim._with()` is supposed to work as a "sandbox", discarding side-effects, but it leaks CWD changes: `:lcd` from a `win` context, any chdir from a visible-buffer context. Solution: - Explicit :cd/:tcd/:bcd during a temp context persists by default. - "Ambient" directory changes ('autochdir', existing win-local CWD, etc.) are still undone, as before. - Add `kCtxKeepDirs`: snapshot/restore the target's full CWD state (w/b/tp-local, global, cwd). Used by `vim._with()` and `'inccommand'`, which must not leak state.
* | refactor(vim.fs): slug() minor cleanupJustin M. Keyes2026-08-06
| |
* | docs: misc, :bcd, slug()Justin M. Keyes2026-08-06
| |
* | feat(dir): set buffer-local CWD #41174Barrett Ruth2026-08-06
| |
* | feat(fs): vim.fs.normalize{plain:boolean} #41127Olivia Kinnear2026-08-05
| | | | | | | | | | | | `opts.plain=true` does not expand tildes in addition to environment variables, unlike `opts.expand_env=false`. `opts.expand_env=false` is soft-deprecated.
* | fix(ui2): pager handling #41179Justin M. Keyes2026-08-05
| | | | | | | | | | | | | | | | - Avoid shared state. Pass `focus` to set_pos()/expand_msg() instead of a shared `pager_focus` flag: the flag is only cleared when set_pos() actually enters the pager, so ":messages" from inside the pager left it set. - pager_shown(): the pager window is invalid after leaving it with "q". - Reuse pager_shown() in expand_msg().
* | fix(ui2): do not steal focus when consecutive cmds emit messages #41062Erdiansyah2026-08-05
| | | | | | | | | | | | | | | | | | | | Problem: A message emitted while a previous expanded message is still visible opens the pager and enters it, moving focus away from the buffer window without an explicit request (#41061). Solution: Only enter the pager when it was explicitly requested ("g<", :messages, or entered from the expanded cmdline). An unfocused pager is dismissed by the cmdline key handler, which stays armed across the cmdline and no longer dismisses on non-typed keys (#39221).
* | fix(editorconfig): avoid trim_trailing_whitespace in insert-mode #41175Oleh Kostiuk2026-08-05
| | | | | | | | | | | | | | | | | | | | | | Problem: During insert-mode / replace-mode, `autowrite` may trigger. If it does, the cursor position can shift due to the automatic removal of trailing spaces on the current line. When I resume typing, the space between the last word and the new word is suddenly gone. Solution: Disable the "remove trailing spaces" handler during Insert (or a similar) mode. Autosave logic is not affected.
* | fix(zip): preserve alternate file #41178Barrett Ruth2026-08-05
| |
* | fix(dir): preserve alternate file #41177Barrett Ruth2026-08-05
| |
* | feat(lua): vim.fs.slug() #41005Willaaaaaaa2026-08-04
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Several subsystems need to derive a short, filesystem-safe identifier from an arbitrary path, and each reinvents it ad-hoc: - `'undodir'` and `swapfiles` encode the full path into a single filename, which may exceed filesystem length-limits. - `:connect ssh://` needs the SSH ControlPath socket name to stay under the 104-byte `sun_path` limit on macOS; today the path overflows it. - the upcoming :terminal state dir. - arbitrary plugin purposes. Solution: Provide `vim.fs.slug()`, which generates a bounded, one-way filename from an arbitrary string. The input is normalized so equivalent paths produce the same result. An 8-char hash is appended for uniqueness
* | fix(:bcd): do not "inherit" buffer-local dirJustin M. Keyes2026-08-04
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Buffer-local CWD (:bcd) is "sticky", similar to window-local CWD (:lcd). But this contradicts one of its main benefits: per-buffer "project root" for LSP, OSC7. Other problems: - A buffer created with :edit/:enew/:new silently inherits b_localdir (and b_prevdir) from the previous buffer. - curbuf_reusable() refuses to recycle a scratch buffer that has `b_localdir`. - After :new/:vnew/:tabnew the CWD sticks to previous buffer's `b_localdir` even though the new curbuf has none, so :new is not equivalent to ":split | enew", and getcwd() disagrees with haslocaldir(). - Requires "which buffer spawned this buffer" semantics that no other buffer-local state has. Solution: Drop sticky/inherit behavior of buffer-local CWD (:bcd). - do_ecmd: always apply the new curbuf's dir (`fix_current_dir`), like `do_autochdir` already does. :tabnew from a :bcd buffer now reverts to global CWD (and fires DirChanged), same as :tabnew from a :lcd window. - curbuf_reusable(): recycling a scratch buffer frees its b_localdir. To get sticky/inherit behavior of CWD, use `:lcd`.
* | fix(cwd): validate getcwd(…, -1)Justin M. Keyes2026-08-04
| |
* | refactor(editor): cleanup change-directory (:bcd) logicJustin M. Keyes2026-08-04
| |
* | feat(editor): `:bcd` changes buffer-local directorysaher2026-08-04
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: No way to set a buffer-local directory. Use-cases: - "Root dir" for LSP (and the "project" concept). - `:terminal` OSC 7 Solution: Add `:bcd` command. - Extend `getcwd()` to take a third arg; `getcwd(-1, -1, bunfr)` returns the buffer-local working directory. - Buffer-local directories have less priority than window-local ones, and more priority than tab-local ones. Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
* | Merge #41114 from epithet/default-ruler-as-expressionJustin M. Keyes2026-08-04
|\ \
| * | refactor(ruler)!: replace C implementation with 'rulerformat' expressionSébastien Hoffmann2026-08-04
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: The default 'ruler' is implemented in C instead of the 'statusline' DSL. Solution: Replace the C implementation with a default 'rulerformat' expression. This is a continuation of #1248 and #33036. Advantages: - configuration is more discoverable, the default being a useful example - users and plugins can augment the default - code reuse and less C code to maintain - ui2: due to the use of an item group with `minwid`, it can expand instead of truncating when the content gets too long, which is particularly useful for locales with long translations of Top/Bot/All Implementation details: As is the case for 'statusline', when trying to set 'rulerformat' to an empty string, the default expression is restored instead, mimicking how previously the default C implementation would have been activated. Just like before, `:set rulerformat=` and `:set rulerformat&` have the same effect, and the ruler is disabled with `:set noruler`. The default expression uses an item group with `%=`, unlike the fallback in the previous default statusline `%-14.(%l,%c%V%) %P`, because the total width and how it is configured is immediately clear without documentation, it is a more useful pattern in general that works when both sides have flexible width, and it also works for vim, which is useful for configuration sharing/reuse. A truncation marker `%<` is added at the end to mimic how at small screen widths, the scroll percentage would disappear first, so that the cursor position can remain fully visible. BREAKING CHANGES: - `&rulerformat` can no longer be set to an empty string - ui2: the default ruler is no longer of fixed width, but can expand - at very small screen widths (< 36 columns) - ui2: it will no longer try to shrink white-space before truncating - it truncates gradually from the right, whereas previously, the scroll percentage would disappear all at once - l10n can no longer add a space after the comma between line and column (this was only done for one language: Ukrainian)
| * | fix(ruler)!: consistent width in last line and statuslineSébastien Hoffmann2026-08-04
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Traditionally, the ruler in the last line is one cell shorter than in the statusline, leaving the last cell of the screen blank. According to code comments, this is in order to prevent unwanted scrolling on "some" (unspecified, but presumably ancient) terminals. Berkeley vi is more specific in its `vs_modeline` function: dumb terminals with hardware scroll, SunOS 4.1.1 and Ultrix 4.2 curses. (n)curses still has a similar limitation in `(w)addstr`, but apparently only for historical reasons. Maintaining the different widths leads to awkward inconsistencies when the ruler is configured with 'rulerformat', except for the special case where it contains a top-level `%=`. Shifting the ruler in the last line to the left would be a solution, but the empty cell at the end doesn't seem to be relevant anymore. Solution: extend the ruler in the last line all the way to the right edge of the screen, just like in the statusline. The exact same amount of place will be available to the rest of the UI as before. BREAKING CHANGE: - the default ruler width is now 18 cells - the last cell of the screen is no longer empty Closes #41076
* | | docs(api): buffer columns are byte indices #41137Barrett Ruth2026-08-04
| | |
* | | fix(lsp): ignore (and log once) invalid documentSelector globs #41055Rocco Vaccone2026-08-04
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Client:_get_registrations() errors if a documentSelector pattern is not a valid glob (e.g. "**/**.dart" from dartls). The error discards already-matched registrations and propagates to supports_method() and the client/registerCapability handler, disabling capabilities unrelated to the offending pattern. Solution: Skip invalid globs. Treat them as non-matching, and log once per client. (Similar approach was taken for filewatcher globs: 4d9e5acfb5ee081b5b0761205c8a8c36ed7e49e5)
* | | Merge #41112 from erdivartanovich/dir-failed-open-recoveryJustin M. Keyes2026-08-04
|\ \ \
| * | | fix(dir): do not swallow errors raised after the list callbackerdivartanovich2026-08-04
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: An error raised after the list handler ran (e.g. while rendering) unwinds through the pcall around provider.list() and is routed back into the now no-op handler: silently discarded. Solution: Re-raise the error when the handler has already run.
| * | | fix(dir): keep a listing buffer when the initial listing failserdivartanovich2026-08-04
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: A failed initial directory listing discards the listing state: the user is left in an empty modifiable non-listing buffer, and the BufEnter autocmd retries the failing open, repeating the error on every re-entry. Solution: Render the failure as an empty listing with state and handlers intact: the error is reported once and "R" or :edit retries the listing. Keep the error on the listing state so a failed listing is distinguishable from an empty one; the next list clears it.
* | | | fix(zip): only refuse a cwd unzip on WindowsBarrett Ruth2026-08-03
| | | |
* | | | refactor(zip)!: address entries with zip:// pathsBarrett Ruth2026-08-03
| | | | | | | | | | | | | | | | | | | | | | | | |