forked from nvim-mini/mini.nvim
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtrailspace.lua
More file actions
198 lines (169 loc) · 6.22 KB
/
Copy pathtrailspace.lua
File metadata and controls
198 lines (169 loc) · 6.22 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
-- MIT License Copyright (c) 2021 Evgeni Chasnovski
-- Documentation ==============================================================
---@brief [[
--- Custom minimal and fast module for working with trailing whitespace.
---
--- Features:
--- - Highlighting is done only in modifiable buffer by default; only in Normal
--- mode; stops in Insert mode and when leaving window.
--- - Trim all trailing whitespace with |MiniTrailspace.trim()| function.
---
--- # Setup
---
--- This module needs a setup with `require('mini.trailspace').setup({})`
--- (replace `{}` with your `config` table). It will create global Lua table
--- `MiniTrailspace` which you can use for scripting or manually (with
--- `:lua MiniTrailspace.*`).
---
--- Default `config`:
--- <code>
--- {
--- -- Highlight only in normal buffers (ones with empty 'buftype'). This is
--- -- useful to not show trailing whitespace where it usually doesn't matter.
--- only_in_normal_buffers = true,
--- }
--- </code>
--- # Highlight groups
---
--- 1. `MiniTrailspace` - highlight group for trailing space.
---
--- To change any highlight group, modify it directly with |:highlight|.
---
--- # Disabling
---
--- To disable, set `g:minitrailspace_disable` (globally) or
--- `b:minitrailspace_disable` (for a buffer) to `v:true`. Note: after
--- disabling there might be highlighting left; it will be removed after next
--- highlighting update (see |events| and `MiniTrailspace` |augroup|).
---@brief ]]
---@tag MiniTrailspace mini.trailspace
-- Module definition ==========================================================
local MiniTrailspace = {}
local H = {}
--- Module setup
---
---@param config table: Module config table.
---@usage `require('mini.trailspace').setup({})` (replace `{}` with your `config` table)
function MiniTrailspace.setup(config)
-- Export module
_G.MiniTrailspace = MiniTrailspace
-- Setup config
config = H.setup_config(config)
-- Apply config
H.apply_config(config)
-- Module behavior
-- Use `defer_fn` for `MiniTrailspace.highlight` to ensure that
-- 'modifiable' option is set to its final value.
vim.api.nvim_exec(
[[augroup MiniTrailspace
au!
au WinEnter,BufEnter,InsertLeave * lua MiniTrailspace.highlight()
au WinLeave,BufLeave,InsertEnter * lua MiniTrailspace.unhighlight()
au FileType TelescopePrompt let b:minitrailspace_disable=v:true
augroup END]],
false
)
if config.only_in_normal_buffers then
-- Add tracking of 'buftype' changing because it can be set after events on
-- which highlighting is done. If not done, highlighting appears but
-- disappears if buffer is reentered.
vim.api.nvim_exec(
[[augroup MiniTrailspace
au OptionSet buftype lua MiniTrailspace.track_normal_buffer()
augroup END]],
false
)
end
-- Create highlighting
vim.api.nvim_exec([[hi default link MiniTrailspace Error]], false)
end
MiniTrailspace.config = {
-- Highlight only in normal buffers (ones with empty 'buftype'). This is
-- useful to not show trailing whitespace where it usually doesn't matter.
only_in_normal_buffers = true,
}
-- Module functionality =======================================================
--- Highlight trailing whitespace
function MiniTrailspace.highlight()
-- Highlight only in normal mode
if H.is_disabled() or vim.fn.mode() ~= 'n' then
MiniTrailspace.unhighlight()
return
end
if MiniTrailspace.config.only_in_normal_buffers and not H.is_buffer_normal() then
return
end
local win_id = vim.api.nvim_get_current_win()
if not vim.api.nvim_win_is_valid(win_id) then
return
end
-- Don't add match id on top of existing one
if H.window_matches[win_id] ~= nil then
return
end
local match_id = vim.fn.matchadd('MiniTrailspace', [[\s\+$]])
H.window_matches[win_id] = { id = match_id }
end
--- Unhighlight trailing whitespace
function MiniTrailspace.unhighlight()
-- Don't do anything if there is no valid information to act upon
local win_id = vim.api.nvim_get_current_win()
local win_match = H.window_matches[win_id]
if not vim.api.nvim_win_is_valid(win_id) or win_match == nil then
return
end
-- Use `pcall` because there is an error if match id is not present. It can
-- happen if something else called `clearmatches`.
pcall(vim.fn.matchdelete, win_match.id)
H.window_matches[win_id] = nil
end
--- Trim trailing whitespace
function MiniTrailspace.trim()
-- Save cursor position to later restore
local curpos = vim.api.nvim_win_get_cursor(0)
-- Search and replace trailing whitespace
vim.cmd([[keeppatterns %s/\s\+$//e]])
vim.api.nvim_win_set_cursor(0, curpos)
end
--- Track normal buffer
---
--- Designed to be used with |autocmd|. No need to use it directly.
function MiniTrailspace.track_normal_buffer()
if not MiniTrailspace.config.only_in_normal_buffers then
return
end
-- This should be used with 'OptionSet' event for 'buftype' option
-- Empty 'buftype' means "normal buffer"
if vim.v.option_new == '' then
MiniTrailspace.highlight()
else
MiniTrailspace.unhighlight()
end
end
-- Helper data ================================================================
-- Module default config
H.default_config = MiniTrailspace.config
-- Information about last match highlighting (stored *per window*):
-- - Key: windows' unique buffer identifiers.
-- - Value: table with `id` field for match id (from `vim.fn.matchadd()`).
H.window_matches = {}
-- Helper functionality =======================================================
-- Settings -------------------------------------------------------------------
function H.setup_config(config)
-- General idea: if some table elements are not present in user-supplied
-- `config`, take them from default config
vim.validate({ config = { config, 'table', true } })
config = vim.tbl_deep_extend('force', H.default_config, config or {})
vim.validate({ only_in_normal_buffers = { config.only_in_normal_buffers, 'boolean' } })
return config
end
function H.apply_config(config)
MiniTrailspace.config = config
end
function H.is_disabled()
return vim.g.minitrailspace_disable == true or vim.b.minitrailspace_disable == true
end
function H.is_buffer_normal(buf_id)
return vim.api.nvim_buf_get_option(buf_id or 0, 'buftype') == ''
end
return MiniTrailspace