Run the most suitable LSP codelens for a given position in buffer.
This plugin provides convenience features for working with executable codelenses provided by some LSP servers (usually as means to run executable parts of programs and tests).
The problem with those codelenses is that they are assigned to a specific, usually short, range of
text (for example function name), and for vim.lsp.codelens.run to work, the cursor needs to be
on the line to which the codelens is attached. This means for example that being inside a test, one
often needs to jump to the function header of the test to execute it and then jump back.
This plugin enables a workflow where a mark is placed in a location of a codelens that runs a
runnable/testable, and then the test can be quickly invoked between changes elsewhere, including
other files. See <Plug>(smart-codelens-run-one-mark) and
<Plug>(smart-codelens-run-one-at).
Some LSP servers (currently, only rust-analyzer is supported) attach extra information to the
codelenses they produce which contains a range of code which spans the runnable/testable. For
rust-analyzer this would be for example the whole main function, the whole test function, or
the whole test module.
For LSP servers that do not attach such information (most likely all except rust-analyzer), a
treesitter-based heuristic is used to expand the range provided by the codelens to the whole
runnable/testable.
smart-codelens-run finds all the codelenses whose expanded range contains the current line /
marked position and presents the user with a choice via vim.ui.select. This allows one to run
the runnable function / test they are currently working on without moving the cursor.
With lazy.nvim:
{
'komar007/smart-codelens-run.nvim',
keys = {
{ "gC", "<Plug>(smart-codelens-run)", desc = "Run related codelens" },
},
}Run the codelens most closely associated with the cursor position or the position of a mark passed
via register prefix (e.g. "r<Plug>(smart-codelens-run)).
Note
Passing a mark via register prefix is a questionable idea but seemed convenient at first. See
<Plug>(smart-codelens-run-mark) and
<Plug>(smart-codelens-run-at) for better alternatives.
For running at the cursor position, this is the recommended way though.
When more than one codelens matches the target position, a vim.ui.select dialog is presented.
Lenses attached directly to the target line are prioritized; among lenses whose expanded range
contains the target, smaller ranges are preferred (e.g. a function body over a whole module).
Like <Plug>(smart-codelens-run), but skips the selection dialog. When
multiple codelenses match, the best match (same prioritization rules) is executed immediately.
Reads a single mark character after the mapping and runs a codelens at that mark's position. This is
an alternative to the questionably vim-like register-prefix interface of
<Plug>(smart-codelens-run) — press the mapping, then the mark letter
(e.g. gCr to run at mark r). When more than one codelens matches, a vim.ui.select dialog is
presented.
Tip
The mapping <Plug>(smart-codelens-run) takes an optional register
prefix ("r) and executes a codelens attached to the line at the position marked by the mark of
the same name as the passed register.
It may be an unconventional approach, but it allows the use of just one mapping for running on the
current line (the default, if the register prefix is not used) and on a selected mark. This cannot
be done with <Plug>(smart-codelens-run-mark) as it consumes a
mandatory keystroke. If it is relevant, consider using
<Plug>(smart-codelens-run) instead.
Like <Plug>(smart-codelens-run-mark), but skips the selection
dialog. The best matching codelens is executed immediately.
Operator-pending mapping. Runs a codelens at the position the motion passed as operator would put
the cursor at. When more than one codelens matches, a vim.ui.select dialog is presented.
This is a generalization of <Plug>(smart-codelens-run-mark) and a
more (neo)vim-idiomatic way of running a codelens at a position indicated by a mark (use 'm as
operator) than using a register prefix in <Plug>(smart-codelens-run).
It is likely of little use with other operators.
With the following mapping:
vim.keymap.set('n', 'gC', '<Plug>(smart-codelens-run-at)')gC'rruns a codelens at the position indicated by registerrin the current buffer,gCggruns a codelens at the beginning of the buffer without moving the cursor,gC10jruns a codelens 10 lines down from the cursor position.
Like <Plug>(smart-codelens-run-at), but skips the selection dialog.
The best matching codelens is executed immediately.
Example:
require('smart-codelens-run').run({ select = true })Run a codelens.
| Parameter | Type | Default | Description |
|---|---|---|---|
opts |
table? |
{} |
Optional configuration table. |
opts.select |
boolean? |
true |
When true and more than one codelens matches, show a vim.ui.select picker. When false, the best match is executed immediately. |
The target position is determined by vim.v.register:
- default (no register prefix): uses the current cursor position,
- with a register prefix (e.g.
"r): uses the position stored in markr.
Run a codelens at a specific position indicated by buffer and row number. Use this to programmatically execute a codelens at an arbitrary location without relying on marks or cursor position.
| Parameter | Type | Default | Description |
|---|---|---|---|
bufnr |
integer |
— | Buffer number. |
row |
integer |
— | 1-based row number. |
col |
integer |
— | 0-based column number. |
opts |
table? |
{} |
see run(opts?) |
Run a codelens at a named mark. This is the programmatic equivalent of
<Plug>(smart-codelens-run-mark) and
<Plug>(smart-codelens-run-one-mark).
| Parameter | Type | Default | Description |
|---|---|---|---|
mark |
string |
— | Single-character mark name (e.g. 'r'). |
opts |
table? |
{} |
see run(opts?) |