aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/snippet.lua
Commit message (Collapse)AuthorAge
* fix(snippet): preserve the full TM_DIRECTORY path (#42408)Volodymyr Chernetskyi3 days
| | | | | | | | | | Problem: TM_DIRECTORY expands to the directory's basename, losing its parent path. Solution: Remove the tail modifier when expanding the current file's directory. Extend the existing known-variable test to check the full directory path. AI-assisted
* fix(lua): enable assignment type checking in runtime codeLewis Russell2026-09-25
| | | | | | | | | | | Enable EmmyLua's assign-type-mismatch diagnostic after correcting the runtime annotations and assignments it flags. Correct option, tuple, and return types, and use separate locals when a value changes representation. Add guards and narrow casts where needed so the runtime passes the stricter check. Regenerate the affected docs. AI-assisted
* fix(lua): enable nil-safety diagnostics in runtime codeLewis Russell2026-09-25
| | | | | | | | | | | | Enable EmmyLua's need-check-nil diagnostic and resolve nullable values through more precise types, explicit invariants, and guards for missing runtime state. Keep analyzer-specific workarounds local and update the affected API documentation. Exclude the bundled re.lua from analysis so its nil-check warnings do not fail CI. AI-assisted
* fix(snippet): cancel session on ESC in insert-mode #41555Nathan Zeng2026-08-30
| | | | | | | | Problem: If a snippet does not have a placeholder, we use insert mode instead of select mode. From here <Esc> leaves the session and highlight active. Solution: Cancel the session on <Esc>.
* refactor(api): omit optional paramJustin M. Keyes2026-07-13
|
* refactor: introduce nvim_on internally #39883Justin M. Keyes2026-05-20
| | | | | | | | | Problem: `nvim_create_autocmd` is too verbose and its `callback` requires extra "nesting". Solution: Introduce `nvim_on`. Start using it internally. Then we can get a feel for how it should look before making it public.
* fix(snippet): cancel session on <Esc> in Select mode #39238glepnir2026-05-10
| | | | | | | Problem: <Esc> in a Select-mode tabstop leaves the session and highlight active. CursorMoved isn’t triggered since the cursor doesn’t move. Solution: use ModeChanged (s:n) instead. Defer with vim.schedule() to avoid transient s:n from jump().
* build(lint): allow "bufnr" as positional param #39515Justin M. Keyes2026-04-30
| | | | | Allow `bufnr` as a positional param name because it is very common. However as a field name, or part of a function name, it is usually a mistake.
* refactor: update usages of deprecated "buffer" param #39089Justin M. Keyes2026-04-15
|
* feat(snippet): support multiple sessions #29340Maria Solano2026-04-10
|
* feat(api): rename buffer to buf #35330Jordan2026-04-08
| | | | | | | | | | | | Problem: `:help dev-name-common` states that "buf" should be used instead of "buffer" but there are cases where buffer is mentioned in the lua API. Solution: - Rename occurrences of "buffer" to "buf" for consistency with the documentation. - Support (but deprecate) "buffer" for backwards compatibility. Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
* docs: small fixes (#35791)zeertzjq2025-09-16
| | | | | | | | | | | | | | | | | | | | | Close #34938 Close #35030 Close #35233 Close #35259 Close #35290 Close #35433 Close #35541 Close #35766 Close #35792 Co-authored-by: huylg <45591413+huylg@users.noreply.github.com> Co-authored-by: Jason Del Ponte <961963+jasdel@users.noreply.github.com> Co-authored-by: sooriya <74165167+thuvasooriya@users.noreply.github.com> Co-authored-by: Andrew Braxton <andrewcbraxton@gmail.com> Co-authored-by: Enric Calabuig <enric.calabuig@gmail.com> Co-authored-by: Augusto César Dias <augusto.c.dias@gmail.com> Co-authored-by: David Sierra DiazGranados <davidsierradz@gmail.com> Co-authored-by: Stepan Nikitin <90522882+vectravox@users.noreply.github.com> Co-authored-by: Emilien Breton <bricktech2000@gmail.com>
* feat(snippet): highlight active tabstop (#35378)TheBlob422025-08-19
|
* fix(snippet): adjacent tabstops without placeholders (#35167)TheBlob422025-08-13
| | | | | * fix(snippet): adjacent tabstops without placeholders * test(snippet): add tests for directly adjacent tabstops
* fix(snippet): sync tabstop text also if pmenu is visible (#35250)Mathias Fußenegger2025-08-08
| | | | | | | | | | | | | | | | | Using a snippet like: ${1:name} :: ${2}\n${1:name} ${3}= ${4:undefined}${0} The text for `${1:name}` stopped syncing if the completion popup menu showed up. E.g. typing `par` where the `a` triggered completion resulted in: pat :: pa = undefined Instead of: pat :: pat = undefined
* fix(snippet): early return for final tabstop #35115TheBlob422025-08-03
| | | | | The cursor movement autocommand can not detect when the final tabstop $0 is directly adjacent to another tabstop, which prevents ending the snippet session. The fix is an early return when jumping.
* fix(snippet): jumping backwards to choice node (#35062)TheBlob422025-07-27
| | | | Avoid duplicate text when jumping back to a choice node. Set cursor to end of tabstop range and prioritize current choice in completion items.
* fix(snippet): setting end_right_gravity (#35061)TheBlob422025-07-27
| | | | | | When right_gravity is set to true for deactivating tabstop expansion we have to set end_right_gravity to false to avoid expanding the tabstop region on the right side. Vice versa for activating tabstop expansion again.
* fix(snippet): use <cmd>call cursor() for visual rangeLuuk van Baal2025-04-23
| | | | | | | | Problem: Change applied in d3e495ce uses a byte-offset where a virtual column is expected. Solution: Set the cursor directly through a <Cmd> mapping, while making sure the commands are ordered correctly by adding them to the type-ahead buffer.
* perf(snippet): use "[count]|" to move cursor #33571luukvbaal2025-04-22
| | | | | | | Problem: Flicker when using vim.snippet.jump(). Solution: Pass count instead of multiple <right> keys.
* fix(snippet): wrong indentation when snippet contains "^" #32970Avinash Thakur2025-03-19
| | | | | | | | | | | | | | | | | | | | | | | ## Problem The pattern used to match indentation is wrong as can be seen in ```lua -- current pattern doesn't match starting space print(vim.inspect((" xyz"):match("(^%s+)%S"))) -- nil -- instead, it matches characters `^ ` in text print(vim.inspect(("x^ yz"):match("(^%s+)%S"))) -- "^ " -- indentation could've been matched by, however not required print(vim.inspect((" xyz"):match("^(%s+)%S"))) -- " " ``` ## Solution We don't even need to modify `base_indent` at every line. If every line's indentation is calculated by the previous line's indentation (which already has starting indentation) added to the starting indentation, we see that indentation is multiplied on every line. Hence, we only add the starting line indentation to every line.
* feat(snippet): set snippet keymaps permanent instead of dynamic (#31887)Mathias Fußenegger2025-03-14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Given that `vim.snippet.expand()` sets temporary `<tab>`/`<s-tab>` keymaps there is no way to build "smart-tab" functionality where `<tab>` chooses the next completion candidate if the popup menu is visible. Solution: Set the keymap permanent in `_defaults`. The downside of this approach is that users of multiple snippet engine's need to adapt their keymaps to handle all their engines that are in use. For example: vim.keymap.set({ 'i', 's' }, "<Tab>", function() if foreign_snippet.active() then return "<Cmd>lua require('foreign_snippet').jump()<CR>" elseif vim.snippet.active({ direction = 1 }) then return "<Cmd>lua vim.snippet.jump(1)<CR>" else return key end end, { expr = true }) Upside is that using `vim.keymap.set` to override keymaps is a well established pattern and `vim.snippet.expand` calls made by nvim itself or plugins have working keymaps out of the box. Co-authored-by: Maria José Solano <majosolano99@gmail.com>
* refactor: use nvim.foo.bar format for autocommand groupsMaria José Solano2025-01-14
|
* refactor: use nvim.foo.bar format for namespacesMaria José Solano2025-01-14
|
* fix(snippet): modify base indentation when there's actually whitespace (#29670)Maria José Solano2024-07-16
|
* refactor: use `vim._with` where possibledundargoc2024-06-28
| | | | | This mostly means replacing `nvim_buf_call` and `nvim_win_call` with `vim._with`.
* docs(news): fix inconsistencies (#29381)zeertzjq2024-06-18
|
* Merge pull request #27339 from MariaSolOs/completionGregory Anders2024-05-28
|\ | | | | feat(lsp): completion side effects
| * feat(snippet): add default keymaps during snippet sessionMaria José Solano2024-05-28
| |
* | fix(snippet): cancel snippet session when leaving the buffer (#29031)Maria José Solano2024-05-27
| |
* | fix(snippet): don't override unnamed register on tabstop select (#28998)Mathias Fußenegger2024-05-25
|/
* docs: newsJustin M. Keyes2024-05-15
| | | | Set dev_xx.txt help files to use "flow" layout.
* docs: misc (#28609)dundargoc2024-05-15
| | | | | | | | | | | | Closes https://github.com/neovim/neovim/issues/28484. Closes https://github.com/neovim/neovim/issues/28719. Co-authored-by: Chris <crwebb85@gmail.com> Co-authored-by: Gregory Anders <greg@gpanders.com> Co-authored-by: Jake B <16889000+jakethedev@users.noreply.github.com> Co-authored-by: Jonathan Raines <jonathan.s.raines@gmail.com> Co-authored-by: Yi Ming <ofseed@foxmail.com> Co-authored-by: Zane Dufour <zane@znd4.me> Co-authored-by: zeertzjq <zeertzjq@outlook.com>
* refactor(snippet): rename exit() => stop() #28628Justin M. Keyes2024-05-06
|
* docs: add `hl-SnippetTabstop` tagEvgeni Chasnovski2024-05-02
|
* fix(lsp): redundant vim.snippet.jumpable #28560Maria José Solano2024-04-29
|
* fix(snippet): do not add extra indent on newlines (#28538)Mathias Fußenegger2024-04-28
| | | | | | | | | | | | | | | | | | | | | | | Reverts parts of https://github.com/neovim/neovim/pull/27674 LSP snippets typically do include tabs or spaces to add extra indentation and don't rely on the client using `autoindent` functionality. For example: public static void main(String[] args) {\n\t${0}\n} Notice the `\t` after `{\n` Adding spaces or tabs independent of that breaks snippets for languages like Haskell where you can have snippets like: ${1:name} :: ${2}\n${1:name} ${3}= ${0:undefined} To generate: name :: name = undefined
* refactor(lua): type annotationsLewis Russell2024-03-16
|
* Merge pull request #27674 from glepnir/snippet_indentbfredl2024-03-15
|\ | | | | fix(snippet): correct indent with newline
| * fix(snippet): correct indent with newlineglepnir2024-03-01
| | | | | | | | | | | | Problem: snippet newline use before line indent after expand. Solution: it should level + 1.
* | docs: improve/add documentation of Lua typesLewis Russell2024-03-01
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - Added `@inlinedoc` so single use Lua types can be inlined into the functions docs. E.g. ```lua --- @class myopts --- @inlinedoc --- --- Documentation for some field --- @field somefield integer --- @param opts myOpts function foo(opts) end ``` Will be rendered as ``` foo(opts) Parameters: - {opts} (table) Object with the fields: - somefield (integer) Documentation for some field ``` - Marked many classes with with `@nodoc` or `(private)`. We can eventually introduce these when we want to.
* feat(docs): replace lua2dox.luaLewis Russell2024-02-27
| | | | | | | | | | | | | | | | | | | | | | | | | | Problem: The documentation flow (`gen_vimdoc.py`) has several issues: - it's not very versatile - depends on doxygen - doesn't work well with Lua code as it requires an awkward filter script to convert it into pseudo-C. - The intermediate XML files and filters makes it too much like a rube goldberg machine. Solution: Re-implement the flow using Lua, LPEG and treesitter. - `gen_vimdoc.py` is now replaced with `gen_vimdoc.lua` and replicates a portion of the logic. - `lua2dox.lua` is gone! - No more XML files. - Doxygen is now longer used and instead we now use: - LPEG for comment parsing (see `scripts/luacats_grammar.lua` and `scripts/cdoc_grammar.lua`). - LPEG for C parsing (see `scripts/cdoc_parser.lua`) - Lua patterns for Lua parsing (see `scripts/luacats_parser.lua`). - Treesitter for Markdown parsing (see `scripts/text_utils.lua`). - The generated `runtime/doc/*.mpack` files have been removed. - `scripts/gen_eval_files.lua` now instead uses `scripts/cdoc_parser.lua` directly. - Text wrapping is implemented in `scripts/text_utils.lua` and appears to produce more consistent results (the main contributer to the diff of this change).
* fix(lsp): handle adjacent snippet tabstopsMaria José Solano2024-02-05
|
* refactor: create function for deferred loadingdundargoc2024-02-03
| | | | | | | | | | | | | | | | The benefit of this is that users only pay for what they use. If e.g. only `vim.lsp.buf_get_clients()` is called then they don't need to load all modules under `vim.lsp` which could lead to significant startuptime saving. Also `vim.lsp.module` is a bit nicer to user compared to `require("vim.lsp.module")`. This isn't used for some nested modules such as `filetype` as it breaks tests with error messages such as "attempt to index field 'detect'". It's not entirely certain the reason for this, but it is likely it is due to filetype being precompiled which would imply deferred loading isn't needed for performance reasons.
* fix(snippet): remove misleading comment about TM_FILENAME_BASE (#26465)Maria José Solano2023-12-08
|
* feat(lsp): support for choice snippet nodesMaria José Solano2023-11-17
|
* fix(lsp): do not cancel snippet when selecting placeholder (#25835)Maria José Solano2023-10-30
|
* fix(lsp): cancel session when leaving snippet region (#25762)Maria José Solano2023-10-26
|
* fix(lsp): do not add extra indentationMaria José Solano2023-10-23
|
* fix(lsp): track snippet deletionMaria José Solano2023-10-23
|