Repository navigation
Expand file tree
/
Copy pathmini-statuscolumn.txt
More file actions
298 lines (241 loc) · 13.1 KB
/
Copy pathmini-statuscolumn.txt
File metadata and controls
298 lines (241 loc) · 13.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
*mini.statuscolumn* Statuscolumn
MIT License Copyright (c) 2026 Evgeni Chasnovski
------------------------------------------------------------------------------
*MiniStatuscolumn*
Features:
- Fast |'statuscolumn'| with improved defaults.
- Fully customizable content via functions that take precomputed useful data.
- |MiniStatuscolumn.gen_content.main()| for simplified customization.
- Automatic dimming inside inactive windows content.
Notes:
- Works best on Neovim>=0.11.
- Default content follows the behavior defined by options for the built-in
statuscolumn sections. Like |'number'|, |'signcolumn'|, |'foldcolumn'|, etc.
# Setup ~
This module needs a setup with `require('mini.statuscolumn').setup({})`
(replace `{}` with your `config` table). It will create global Lua table
`MiniStatuscolumn` which you can use for scripting or manually (with
`:lua MiniStatuscolumn.*`).
See |MiniStatuscolumn.config| for `config` structure and default values.
# Suggested option values ~
- Default content works best with enabled |'number'| and |'signcolumn'|.
- Depending on how distinctive |hl-FoldColumn| is from |hl-LineNr|, it might
be a good idea to use minimal fold column characters in |'fillchars'|.
Like `foldopen:` and `foldclose:🮥`, while `foldsep` and `foldinner` (on
Neovim>=0.12) set to a single space.
# Comparisons ~
- [luukvball/statuscol.nvim](https://github.com/luukvbaal/statuscol.nvim):
- A framework with building blocks and configuration: custom sections,
sign filters, fold functions.
While this module aims to provide a performant |'statuscolumn'| with
a sensible default with a limited (yet enough) customization and an
entry point to building own |'statuscolumn'|.
- [folke/snacks.nvim#statuscolumn](https://github.com/folke/snacks.nvim):
- An opinionated |'statuscolumn'| implementation with a limited
customization.
While this module provides more opportunities for building custom
implementation and more customization.
# Highlight groups ~
*MiniStatuscolumn-hl-groups*
- `MiniStatuscolumnDim` - dimmed column. By default is a dimmed |hl-LineNr|.
- `MiniStatuscolumnDimCursor` - dimmed column at cursor line.
- `MiniStatuscolumnSep` - separator of column and text.
- `MiniStatuscolumnSepCursor` - separator of column and text at cursor line.
------------------------------------------------------------------------------
*MiniStatuscolumn.setup()*
`MiniStatuscolumn.setup`({config})
Module setup
Parameters ~
{config} `(table|nil)` Module config table. See |MiniStatuscolumn.config|.
Usage ~
>lua
require('mini.statuscolumn').setup() -- use default config
-- OR
require('mini.statuscolumn').setup({}) -- replace {} with your config table
<
------------------------------------------------------------------------------
*MiniStatuscolumn.config*
`MiniStatuscolumn.config`
Defaults ~
>lua
MiniStatuscolumn.config = {
-- Statuscolumn content as functions that return statusline-like string
content = {
-- Content of an active window
active = nil,
-- Content of an inactive window
inactive = nil,
},
-- Whether to dim column content in inactive windows
dim_inactive = true,
}
<
# Content ~
`config.content` is a table that defines |'statuscolumn'| content for active
(`content.active`) and inactive (`content.inactive`) windows. Each content is
a function that takes a single `data` argument with useful info about the
current Neovim state (precomputed only when needed to improve performance) and
should return a |'statusline'| like string.
An input `data` argument is a table with the following fields:
- <buf_id> `(number)` - identifier of a drawn buffer.
- <is_curs
1010C
orlinenr> `(boolean)` - whether |hl-CursorLineNr| conditions are met.
- <is_foldcolumn_fixed> `(boolean)` - whether |'foldcolumn'| has fixed width.
- <is_signcolumn_fixed> `(boolean)` - whether |'signcolumn'| has fixed width.
- <is_statuscolumn_empty> `(boolean)` - whether |'statuscolumn'| default content
is empty. Useful to determine if anything should be drawn.
- <opt_cursorline> `(boolean)` - current value of |'cursorline'|.
- <opt_cursorlineopt> `(string)` - current value of |'cursorlineopt'|.
- <opt_foldcolumn> `(string)` - current value of |'foldcolumn'|.
- <opt_number> `(boolean)` - current value of |'number'|.
- <opt_relativenumber> `(boolean)` - current value of |'relativenumber'|.
- <opt_signcolumn> `(string)` - current value of |'signcolumn'|.
- <win_id> `(number)` - identifier of a drawn window.
The data about target line (for which content is evaluated) can be accessed
as described in |'statuscolumn'| via the dedicated |v:| variables.
Like |v:lnum|, |v:relnum|, and |v:virtnum|.
Example custom content: >lua
-- Show sign and separator if statuscolumn is not empty
local active = function(data)
return data.is_statuscolumn_empty and '' or '%s│'
end
-- Show nothing in inactive windows
local inactive = function(_) return '' end
local content = { active = active, inactive = inactive }
require('mini.statuscolumn').setup({ content = content })
<
If one content function is missing, the other is used in its place.
If both content functions are missing, the default content is used: the output
of |MiniStatuscolumn.gen_content.main()| with the following specification: >lua
{ fold = '%C', lnum = '%l', sign = '%s' }, -- Default sections
{ format = '=lfs', sep = '▏' }, -- Line-fold-sign-separator format
{ ltype = 'virt', lnum = '•' }, -- Dot in virtual lines
{ ltype = 'wrap', lnum = '↳' }, -- Arrow in wrapped lines
{ win = 'inactive', sep = ' ' }, -- No separator in inactive windows
<
Default content works best with enabled |'number'|, otherwise statuscolumn width
might fluctuate if there are wrapped or virtual lines due to special symbols.
Notes:
- Make sure that custom content functions are as fast as possible since they
will be called VERY frequently: at least every non-pure-cursor-move redraw
(during typing, window scroll, etc.) for every visible line in every visible
window. A rough estimate: about 100 times per redraw and about 1 million
times per hour of text editing.
- For performance reasons there are several |'statuscolumn'| optimizations
that affect any implementation. Like pre-computed width and when it changes.
Make sure to read |'statuscolumn'| to be aware of them.
# Dim inactive windows ~
`config.dim` is a boolean that defines whether to dim statuscolumn content
in inactive windows. It means that all |'statuscolumn'| relevant highlight
groups are overridden to be `MiniStatuscolumnDimCursor` at cursor line and
`MiniStatuscolumnDim` everywhere else. Default: `true`.
Default values of dimming highlight groups are computed as a dimmed variant
of |hl-LineNr| group, meaning its foreground is computed to be closer to its
background. The used approach is good enough, if not - define groups manually.
------------------------------------------------------------------------------
*MiniStatuscolumn.gen_content*
`MiniStatuscolumn.gen_content`
Content generators
This is a table with function elements. Call to actually get a content table.
------------------------------------------------------------------------------
*MiniStatuscolumn.gen_content.main()*
`MiniStatuscolumn.gen_content.main`({spec}, {opts})
Main content generator
Generates a content that can be customized via selected "info" fields applied
at selected drawn line "coordinates".
"Info" string fields (as |'statusline'| like text):
- <fold> - fold section. Default: `'%C'`.
- <sign> - sign section. Default: `'%s'`.
- <lnum> - line number section. Default: `'%l'`.
- <sep> - separator between column and in-buffer text. Default: `' '`.
Highlighted with groups `MiniStatuscolumnSep` and `MiniStatuscolumnSepCursor`
The latter is used under the conditions described in |hl-CursorLineNr|.
- <format> - order of sections (excluding <sep>) as a string containing only
`f` (fold), `s` (sign), `l` (lnum), and `=` (as `%=` in |'statusline'| syntax).
Default: `'fs=l'`.
NOTE: using dedicated |'statusline'| syntax, as in default values, makes
section content follow their respective options. Like using `%l` will show
nothing if |'number'| is disabled.
"Coordinate" fields:
- <win> - type of drawn window. One of `'active'`, `'inactive'`.
- <pos> - position of drawn line relative to the cursor. One of `'cursor'`,
`'above'`, `'below'`. Note: value does not depend on the |'relativenumber'|,
unlike |hl-LineNrAbove| and |hl-LineNrBelow|.
- <ltype> - type of drawn line. One of `'text'` (next to the regular buffer
text), `'virt'` (next to the virtual line), `'wrap'` (next to the wrapped part
of buffer text).
Customization is done via an array specification that acts as a sequence of
rules applied on top of the previous ones. Each rule/item should define at
least one "info" field and may filter by one or more "coordinate" field.
It is recommended to start with wider rules and go towards narrower ones.
If an "info" field is not defined after all rules are processed, its
default value is used.
Each section is clickable with mouse. Clicks will be processed with an
`opts.click` function and can be customized per section-coordinate.
Examples of content specification:
- Specification for default `content` in |MiniStatuscolumn.config|.
Use as a template to adjust/remove added behavior: >lua
local statuscolumn = require('mini.statuscolumn')
local spec = {
-- Prefer visible separator with a more efficient order to use
-- usually present whitespace to the right of signs
{ format = '=lfs', sep = '▏' },
-- Use custom symbol for virtual lines
{ ltype = 'virt', lnum = '•' },
-- Use custom symbol for wrapped lines
{ ltype = 'wrap', lnum = '↳' },
-- Hide separator to better indicate inactive windows
{ win = 'inactive', sep = ' ' },
}
statuscolumn.setup({ content = statuscolumn.gen_content.main(spec) })
<
- Ways to configure separator:
- Thicker separator at cursor: `{ pos = 'cursor', sep = '▍' }`.
- More cell-centered separator: `{ format='=fsl', sep='│' }`
- Ways to indicate inactive windows:
- Hide regular non-cursor line: define `MiniStatuscolumnDim` highlight group
to have the same foreground and background. It will still show cursor line
and lines which have signs or line number with special highlighting (like
diagnostics, diff status, etc.).
- Show nothing: `{ win='inactive', fold='', lnum='', sign='' }`
- Hide separator: `{ win='inactive', sep='' }`
- Force highlighting: `{ pos='cursor', ltype='virt', lnum='%#CursorLineNr#•' }`.
Has problems that it overrides highlighting from extmarks.
Notes:
- Implementation of |'statuscolumn'| has some performance trade-offs when it
comes to computing which areas are clickable. Suggested usage:
- Use one <format> per window type, as section order is better to persist
across lines of the same window.
- Clicking the cell that contains text should work. Clicking an empty cell
of known section might not always work.
- On Neovim<0.13 the `ltype` is always the one that is used in the top
window line.
Parameters ~
{spec} `(table[]|nil)` Specification array. Default: `{}`, which imitates
default |'statuscolumn'|.
{opts} `(table|nil)` Options. Possible fields:
- <click> `(function)` - action to perform on mouse click in statuscolumn.
Default: |MiniStatuscolumn.default_click()|.
Called with a single table `data` argument with the following fields:
- <button> `(string)` - mouse button, as described in `@` |'statusline'| flag.
- <modifiers> `(string)` - modifiers, as described in `@` |'statusline'| flag.
- <n_clicks> `(number)` - number of clicks.
- <ltype> `(string)` - line type "coordinate" field.
- <section> `(string)` - section name. One of `'fold'`, `'sign'`, `'lnum'`, `'sep'`.
- <mousepos> `(table)` - output of |getmousepos()|. Can be used to determine
line number, window identifier/type, etc.
Notes:
- On Neovim<0.13 it is only possible to split statuscolumn line into
"clicking ranges" once per window. This is why `data.ltype` might have
not correct values. Should work as expected on Neovim>=0.13.
- A best available (but somewhat limiting) pattern to identify what was
clicked is to use |screenstring()| with <screenrow> and <screencol>
fields of <mousepos>. For example, fixed distinctive symbols for wrapped
and virtual lines can help identifying that click was done on them.
------------------------------------------------------------------------------
*MiniStatuscolumn.default_click()*
`MiniStatuscolumn.default_click`({data})
Default mouse click handler
Makes clicked window and line current. Centers the line on double click.
Parameters ~
{data} `(table)` As described in |MiniStatuscolumn.gen_content.main()|.
vim:tw=78:ts=8:noet:ft=help:norl: