1

Regenerate nvim config

This commit is contained in:
2024-06-02 03:29:20 +02:00
parent 75eea0c030
commit ef2e28883d
5576 changed files with 604886 additions and 503 deletions

View File

@ -0,0 +1,3 @@
[*]
indent_style = space
indent_size = 4

View File

@ -0,0 +1,28 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior (include minimal `init.vim` or `.vimrc`):
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Note** Omitting a minimal `init.vim`/`init.lua`/`.vimrc` will likely result in the issue being closed without explanation.
**Output from `:IlluminateDebug`**
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,30 @@
name: panvimdoc
on:
push:
branches:
- '*'
jobs:
docs:
runs-on: ubuntu-latest
name: pandoc to vimdoc
steps:
- uses: actions/checkout@v2
- name: illuminate
uses: kdheepak/panvimdoc@main
with:
vimdoc: illuminate
pandoc: "README.md"
toc: true
version: "NVIM v0.8.0"
- name: Check for Changes
id: changes
uses: UnicornGlobal/has-changes-action@v1.0.11
with:
path: 'doc/'
- uses: stefanzweifel/git-auto-commit-action@v4
if: steps.changes.outputs.has_changes == 'true'
with:
commit_message: 'Auto generate docs'
branch: ${{ github.head_ref }}

View File

@ -0,0 +1 @@
doc/tags

View File

@ -0,0 +1,265 @@
# Overview
Neovim plugin for automatically highlighting other uses of the word under the cursor using either LSP, Tree-sitter, or regex matching.
![gif](https://media.giphy.com/media/mSG0nwAHDt3Fl7WyoL/giphy.gif)
# Quickstart
Just install the plugin and things will work *just work*, no configuration needed.
You'll also get `<a-n>` and `<a-p>` as keymaps to move between references and `<a-i>` as a textobject for the reference illuminated under the cursor.
*Note: Vim users should refer to the [docs](https://github.com/RRethy/vim-illuminate?tab=readme-ov-file#vim-users) for the Vimscript implementation of this plugin.*
# Configuration
```lua
-- default configuration
require('illuminate').configure({
-- providers: provider used to get references in the buffer, ordered by priority
providers = {
'lsp',
'treesitter',
'regex',
},
-- delay: delay in milliseconds
delay = 100,
-- filetype_overrides: filetype specific overrides.
-- The keys are strings to represent the filetype while the values are tables that
-- supports the same keys passed to .configure except for filetypes_denylist and filetypes_allowlist
filetype_overrides = {},
-- filetypes_denylist: filetypes to not illuminate, this overrides filetypes_allowlist
filetypes_denylist = {
'dirbuf',
'dirvish',
'fugitive',
},
-- filetypes_allowlist: filetypes to illuminate, this is overridden by filetypes_denylist
-- You must set filetypes_denylist = {} to override the defaults to allow filetypes_allowlist to take effect
filetypes_allowlist = {},
-- modes_denylist: modes to not illuminate, this overrides modes_allowlist
-- See `:help mode()` for possible values
modes_denylist = {},
-- modes_allowlist: modes to illuminate, this is overridden by modes_denylist
-- See `:help mode()` for possible values
modes_allowlist = {},
-- providers_regex_syntax_denylist: syntax to not illuminate, this overrides providers_regex_syntax_allowlist
-- Only applies to the 'regex' provider
-- Use :echom synIDattr(synIDtrans(synID(line('.'), col('.'), 1)), 'name')
providers_regex_syntax_denylist = {},
-- providers_regex_syntax_allowlist: syntax to illuminate, this is overridden by providers_regex_syntax_denylist
-- Only applies to the 'regex' provider
-- Use :echom synIDattr(synIDtrans(synID(line('.'), col('.'), 1)), 'name')
providers_regex_syntax_allowlist = {},
-- under_cursor: whether or not to illuminate under the cursor
under_cursor = true,
-- large_file_cutoff: number of lines at which to use large_file_config
-- The `under_cursor` option is disabled when this cutoff is hit
large_file_cutoff = nil,
-- large_file_config: config to use for large files (based on large_file_cutoff).
-- Supports the same keys passed to .configure
-- If nil, vim-illuminate will be disabled for large files.
large_file_overrides = nil,
-- min_count_to_highlight: minimum number of matches required to perform highlighting
min_count_to_highlight = 1,
-- should_enable: a callback that overrides all other settings to
-- enable/disable illumination. This will be called a lot so don't do
-- anything expensive in it.
should_enable = function(bufnr) return true end,
-- case_insensitive_regex: sets regex case sensitivity
case_insensitive_regex = false,
})
```
# Highlight Groups
#### IlluminatedWordText
Default highlight group used for references if no kind information is available.
```vim
hi def IlluminatedWordText gui=underline
```
#### IlluminatedWordRead
Highlight group used for references of kind read.
```vim
hi def IlluminatedWordRead gui=underline
```
#### IlluminatedWordWrite
Highlight group used for references of kind write.
```vim
hi def IlluminatedWordWrite gui=underline
```
# Commands
#### :IlluminatePause
Globally pause vim-illuminate.
#### :IlluminateResume
Globally resume vim-illuminate.
#### :IlluminateToggle
Globally toggle the pause/resume for vim-illuminate.
#### :IlluminatePauseBuf
Buffer-local pause of vim-illuminate.
#### :IlluminateResumeBuf
Buffer-local resume of vim-illuminate.
#### :IlluminateToggleBuf
Buffer-local toggle of the pause/resume for vim-illuminate.
# Functions
#### require('illuminate').configure(config)
Override the default configuration with `config`
#### require('illuminate').pause()
Globally pause vim-illuminate.
#### require('illuminate').resume()
Globally resume vim-illuminate.
#### require('illuminate').toggle()
Globally toggle the pause/resume for vim-illuminate.
#### require('illuminate').toggle_buf()
Buffer-local toggle of the pause/resume for vim-illuminate.
#### require('illuminate').pause_buf()
Buffer-local pause of vim-illuminate.
#### require('illuminate').resume_buf()
Buffer-local resume of vim-illuminate.
#### require('illuminate').freeze_buf()
Freeze the illumination on the buffer, this won't clear the highlights.
#### require('illuminate').unfreeze_buf()
Unfreeze the illumination on the buffer.
#### require('illuminate').toggle_freeze_buf()
Toggle the frozen state of the buffer.
#### require('illuminate').invisible_buf()
Turn off the highlighting for the buffer, this won't stop the engine from running so you can still use `<c-n>` and `<c-p>`.
#### require('illuminate').visible_buf()
Turn on the highlighting for the buffer, this is only needed if you've previous called `require('illuminate').invisible_buf()`.
#### require('illuminate').toggle_visibility_buf()
Toggle the visibility of highlights in the buffer.
#### require('illuminate').goto_next_reference(wrap)
Move the cursor to the closest references after the cursor which it is not currently on. Wraps the buffer if on the last reference.
Wraps the references unless `wrap` is false (defaults to **'wrapscan'**).
#### require('illuminate').goto_prev_reference(wrap)
Move the cursor to the closest references before the cursor which it is not currently on. Wraps the buffer if on the first reference.
Wraps the references unless `wrap` is false (defaults to **'wrapscan'**).
#### require('illuminate').textobj_select()
Selects the reference the cursor is currently on for use as a text-object.
# Vim Users
**Note:** This section is deprecated for Neovim users, Neovim users can use the newer version of the plugin. Neovim users can force this old version of the plugin by adding `let g:Illuminate_useDeprecated = 1` to their `init.vim`.
Illuminate will delay before highlighting, this is not lag, it is to avoid the jarring experience of things illuminating too fast. This can be controlled with `g:Illuminate_delay` (which is default to 0 milliseconds):
**Note**: Delay only works for Vim8 and Neovim.
```vim
" Time in milliseconds (default 0)
let g:Illuminate_delay = 0
```
Illuminate will by default highlight the word under the cursor to match the behaviour seen in Intellij and VSCode. However, to make it not highlight the word under the cursor, use the following:
```vim
" Don't highlight word under cursor (default: 1)
let g:Illuminate_highlightUnderCursor = 0
```
By default illuminate will highlight all words the cursor passes over, but for many languages, you will only want to highlight certain highlight-groups.
You can determine the highlight-group of a symbol under your cursor with `:echo synIDattr(synID(line("."), col("."), 1), "name")`.
You can define which highlight groups you want the illuminating to apply to. This can be done with a dict mapping a filetype to a list of highlight-groups in your vimrc such as:
```vim
let g:Illuminate_ftHighlightGroups = {
\ 'vim': ['vimVar', 'vimString', 'vimLineComment',
\ 'vimFuncName', 'vimFunction', 'vimUserFunc', 'vimFunc']
\ }
```
A blacklist of highlight groups can also be setup by adding the suffix `:blacklist` to the filetype. However, if the whitelist for that filetype already exists, it will override the blacklist.
```vim
let g:Illuminate_ftHighlightGroups = {
\ 'vim:blacklist': ['vimVar', 'vimString', 'vimLineComment',
\ 'vimFuncName', 'vimFunction', 'vimUserFunc', 'vimFunc']
\ }
```
illuminate can also be disabled for various filetypes using the following:
```vim
let g:Illuminate_ftblacklist = ['nerdtree']
```
Or you can enable it only for certain filetypes with:
```vim
let g:Illuminate_ftwhitelist = ['vim', 'sh', 'python']
```
By default the highlighting will be done with the highlight-group `CursorLine` since that is in my opinion the nicest. It can however be overridden using the following (use standard Vim highlighting syntax):
Note: It must be in an autocmd to get around a weird Neovim behaviour.
```vim
augroup illuminate_augroup
autocmd!
autocmd VimEnter * hi link illuminatedWord CursorLine
augroup END
augroup illuminate_augroup
autocmd!
autocmd VimEnter * hi illuminatedWord cterm=underline gui=underline
augroup END
```
Lastly, you can also specify a specific highlight for the word under the cursor so it differs from all other matches using the following higlight group:
```vim
augroup illuminate_augroup
autocmd!
autocmd VimEnter * hi illuminatedCurWord cterm=italic gui=italic
augroup END
```

View File

@ -0,0 +1,202 @@
" illuminate.vim - Vim plugin for selectively illuminating other uses of current word
" Maintainer: Adam P. Regasz-Rethy (RRethy) <rethy.spud@gmail.com>
" Version: 0.4
let s:previous_match = ''
let s:enabled = 1
let g:Illuminate_delay = get(g:, 'Illuminate_delay', 0)
let g:Illuminate_highlightUnderCursor = get(g:, 'Illuminate_highlightUnderCursor', 1)
let g:Illuminate_highlightPriority = get(g:, 'Illuminate_highlightPriority', -1)
fun! illuminate#on_cursor_moved() abort
if !s:should_illuminate_file()
return
endif
if s:previous_match !=# s:get_cur_word()
call s:remove_illumination()
elseif get(g:, 'Illuminate_highlightUnderCursor', 1) == 0 || hlexists('illuminatedCurWord')
call s:remove_illumination()
call s:illuminate()
return
else
return
endif
" Any delay at or below 17 milliseconds gets counted as no delay
if !has('timers') || g:Illuminate_delay <= 17
call s:illuminate()
return
endif
if exists('s:timer_id') && s:timer_id > -1
call timer_stop(s:timer_id)
endif
let s:timer_id = timer_start(g:Illuminate_delay, function('s:illuminate'))
endf
fun! illuminate#on_leaving_autocmds() abort
if s:should_illuminate_file()
call s:remove_illumination()
endif
endf
fun! illuminate#on_cursor_moved_i() abort
if get(g:, 'Illuminate_insert_mode_highlight', 0)
call illuminate#on_cursor_moved()
endif
endf
fun! illuminate#on_insert_entered() abort
if !get(g:, 'Illuminate_insert_mode_highlight', 0) && s:should_illuminate_file()
call s:remove_illumination()
endif
endf
fun! illuminate#toggle_illumination(bufonly) abort
if a:bufonly
let b:illuminate_enabled = get(b:, 'illuminate_enabled', s:enabled)
if !b:illuminate_enabled
call illuminate#enable_illumination(1)
else
call illuminate#disable_illumination(1)
endif
else
if !s:enabled
call illuminate#enable_illumination(0)
else
call illuminate#disable_illumination(0)
endif
endif
endf
fun! illuminate#disable_illumination(bufonly) abort
if a:bufonly
let b:illuminate_enabled = 0
else
let s:enabled = 0
endif
call s:remove_illumination()
endf
fun! illuminate#enable_illumination(bufonly) abort
if a:bufonly
let b:illuminate_enabled = 1
else
let s:enabled = 1
endif
if s:should_illuminate_file()
call s:illuminate()
endif
endf
fun! s:illuminate(...) abort
if !get(b:, 'illuminate_enabled', s:enabled)
return
endif
call s:remove_illumination()
if s:should_illuminate_word()
call s:match_word(s:get_cur_word())
endif
let s:previous_match = s:get_cur_word()
endf
fun! s:match_word(word) abort
if (a:word ==# '\<\>')
return
endif
if g:Illuminate_highlightUnderCursor
if hlexists('illuminatedCurWord')
let w:match_id = matchadd('illuminatedWord', '\V\(\k\*\%#\k\*\)\@\!\&' . a:word, g:Illuminate_highlightPriority)
let w:match_curword_id = matchadd('illuminatedCurWord', '\V\(\k\*\%#\k\*\)\&' . a:word, g:Illuminate_highlightPriority)
else
let w:match_id = matchadd('illuminatedWord', '\V' . a:word, g:Illuminate_highlightPriority)
endif
else
let w:match_id = matchadd('illuminatedWord', '\V\(\k\*\%#\k\*\)\@\!\&' . a:word, g:Illuminate_highlightPriority)
endif
endf
fun! s:get_cur_word() abort
let line = getline('.')
let col = col('.') - 1
let left_part = strpart(line, 0, col + 1)
let right_part = strpart(line, col, col('$'))
let word = matchstr(left_part, '\k*$') . matchstr(right_part, '^\k*')[1:]
return '\<' . escape(word, '/\') . '\>'
endf
fun! s:remove_illumination() abort
if has('timers') && exists('s:timer_id') && s:timer_id > -1
call timer_stop(s:timer_id)
let s:timer_id = -1
endif
if exists('w:match_id')
try
call matchdelete(w:match_id)
catch /\v(E803|E802)/
endtry
endif
if exists('w:match_curword_id')
try
call matchdelete(w:match_curword_id)
catch /\v(E803|E802)/
endtry
endif
let s:previous_match = ''
endf
fun! s:should_illuminate_file() abort
let g:Illuminate_ftblacklist = get(g:, 'Illuminate_ftblacklist', [])
let g:Illuminate_ftwhitelist = get(g:, 'Illuminate_ftwhitelist', [])
return !s:list_contains_pat(g:Illuminate_ftblacklist, &filetype)
\ && (empty(g:Illuminate_ftwhitelist) || s:list_contains_pat(g:Illuminate_ftwhitelist, &filetype))
endf
fun! s:should_illuminate_word() abort
let ft_hl_groups = get(g:, 'Illuminate_ftHighlightGroups', {})
let hl_groups_whitelist = get(ft_hl_groups, &filetype, [])
call extend(hl_groups_whitelist, get(ft_hl_groups, '*', []))
if empty(hl_groups_whitelist)
let hl_groups_blacklist = get(ft_hl_groups, &filetype.':blacklist', [])
call extend(hl_groups_blacklist, get(ft_hl_groups, '*:blacklist', []))
if empty(hl_groups_blacklist)
return 1
else
return index(hl_groups_blacklist, synIDattr(synIDtrans(synID(line('.'), col('.'), 1)), 'name')) < 0
\ && index(hl_groups_blacklist, synIDattr(synID(line('.'), col('.'), 1), 'name')) < 0
endif
endif
return index(ft_hl_groups[&filetype], synIDattr(synIDtrans(synID(line('.'), col('.'), 1)), 'name')) >= 0
\ || index(ft_hl_groups[&filetype], synIDattr(synID(line('.'), col('.'), 1), 'name')) >= 0
endf
fun! s:dict_has_key_pat(d, key) abort
for [k, v] in items(a:d)
if key =~# '^'.k.'$'
return 1
endif
endfor
return 0
endfun
fun! s:list_contains_pat(list, val) abort
for pat in a:list
if a:val =~# '^'.pat.'$'
return 1
endif
endfor
return 0
endfun
" vim: foldlevel=1 foldmethod=expr tabstop=2 softtabstop=2 shiftwidth=2

View File

@ -0,0 +1,343 @@
*illuminate.txt* For NVIM v0.8.0 Last change: 2023 March 19
==============================================================================
Table of Contents *illuminate-table-of-contents*
1. Overview |illuminate-overview|
2. Quickstart |illuminate-quickstart|
3. Configuration |illuminate-configuration|
4. Highlight Groups |illuminate-highlight-groups|
5. Commands |illuminate-commands|
6. Functions |illuminate-functions|
7. Vim Users |illuminate-vim-users|
==============================================================================
1. Overview *illuminate-overview*
Vim plugin for automatically highlighting other uses of the word under the
cursor using either LSP, Tree-sitter, or regex matching.
==============================================================================
2. Quickstart *illuminate-quickstart*
Just install the plugin and things will work _just work_, no configuration
needed.
Youll also get `<a-n>` and `<a-p>` as keymaps to move between references and
`<a-i>` as a textobject for the reference illuminated under the cursor.
==============================================================================
3. Configuration *illuminate-configuration*
>lua
-- default configuration
require('illuminate').configure({
-- providers: provider used to get references in the buffer, ordered by priority
providers = {
'lsp',
'treesitter',
'regex',
},
-- delay: delay in milliseconds
delay = 100,
-- filetype_overrides: filetype specific overrides.
-- The keys are strings to represent the filetype while the values are tables that
-- supports the same keys passed to .configure except for filetypes_denylist and filetypes_allowlist
filetype_overrides = {},
-- filetypes_denylist: filetypes to not illuminate, this overrides filetypes_allowlist
filetypes_denylist = {
'dirvish',
'fugitive',
},
-- filetypes_allowlist: filetypes to illuminate, this is overriden by filetypes_denylist
filetypes_allowlist = {},
-- modes_denylist: modes to not illuminate, this overrides modes_allowlist
-- See `:help mode()` for possible values
modes_denylist = {},
-- modes_allowlist: modes to illuminate, this is overriden by modes_denylist
-- See `:help mode()` for possible values
modes_allowlist = {},
-- providers_regex_syntax_denylist: syntax to not illuminate, this overrides providers_regex_syntax_allowlist
-- Only applies to the 'regex' provider
-- Use :echom synIDattr(synIDtrans(synID(line('.'), col('.'), 1)), 'name')
providers_regex_syntax_denylist = {},
-- providers_regex_syntax_allowlist: syntax to illuminate, this is overriden by providers_regex_syntax_denylist
-- Only applies to the 'regex' provider
-- Use :echom synIDattr(synIDtrans(synID(line('.'), col('.'), 1)), 'name')
providers_regex_syntax_allowlist = {},
-- under_cursor: whether or not to illuminate under the cursor
under_cursor = true,
-- large_file_cutoff: number of lines at which to use large_file_config
-- The `under_cursor` option is disabled when this cutoff is hit
large_file_cutoff = nil,
-- large_file_config: config to use for large files (based on large_file_cutoff).
-- Supports the same keys passed to .configure
-- If nil, vim-illuminate will be disabled for large files.
large_file_overrides = nil,
-- min_count_to_highlight: minimum number of matches required to perform highlighting
min_count_to_highlight = 1,
})
<
==============================================================================
4. Highlight Groups *illuminate-highlight-groups*
ILLUMINATEDWORDTEXT
Default highlight group used for references if no kind information is
available.
>vim
hi def IlluminatedWordText gui=underline
<
ILLUMINATEDWORDREAD
Highlight group used for references of kind read.
>vim
hi def IlluminatedWordRead gui=underline
<
ILLUMINATEDWORDWRITE
Highlight group used for references of kind write.
>vim
hi def IlluminatedWordWrite gui=underline
<
==============================================================================
5. Commands *illuminate-commands*
:ILLUMINATEPAUSE
Globally pause vim-illuminate.
:ILLUMINATERESUME
Globally resume vim-illuminate.
:ILLUMINATETOGGLE
Globally toggle the pause/resume for vim-illuminate.
:ILLUMINATEPAUSEBUF
Buffer-local pause of vim-illuminate.
:ILLUMINATERESUMEBUF
Buffer-local resume of vim-illuminate.
:ILLUMINATETOGGLEBUF
Buffer-local toggle of the pause/resume for vim-illuminate.
==============================================================================
6. Functions *illuminate-functions*
REQUIRE(ILLUMINATE).CONFIGURE(CONFIG)
Override the default configuration with `config`
REQUIRE(ILLUMINATE).PAUSE()
Globally pause vim-illuminate.
REQUIRE(ILLUMINATE).RESUME()
Globally resume vim-illuminate.
REQUIRE(ILLUMINATE).TOGGLE()
Globally toggle the pause/resume for vim-illuminate.
REQUIRE(ILLUMINATE).TOGGLE_BUF()
Buffer-local toggle of the pause/resume for vim-illuminate.
REQUIRE(ILLUMINATE).PAUSE_BUF()
Buffer-local pause of vim-illuminate.
REQUIRE(ILLUMINATE).RESUME_BUF()
Buffer-local resume of vim-illuminate.
REQUIRE(ILLUMINATE).FREEZE_BUF()
Freeze the illumination on the buffer, this wont clear the highlights.
REQUIRE(ILLUMINATE).UNFREEZE_BUF()
Unfreeze the illumination on the buffer.
REQUIRE(ILLUMINATE).TOGGLE_FREEZE_BUF()
Toggle the frozen state of the buffer.
REQUIRE(ILLUMINATE).INVISIBLE_BUF()
Turn off the highlighting for the buffer, this wont stop the engine from
running so you can still use `<c-n>` and `<c-p>`.
REQUIRE(ILLUMINATE).VISIBLE_BUF()
Turn on the highlighting for the buffer, this is only needed if youve
previous called `require('illuminate').invisible_buf()`.
REQUIRE(ILLUMINATE).TOGGLE_VISIBILITY_BUF()
Toggle the visibility of highlights in the buffer.
REQUIRE(ILLUMINATE).GOTO_NEXT_REFERENCE(WRAP)
Move the cursor to the closest references after the cursor which it is not
currently on. Wraps the buffer if on the last reference.
Wraps the references unless `wrap` is false (defaults to **wrapscan**).
REQUIRE(ILLUMINATE).GOTO_PREV_REFERENCE(WRAP)
Move the cursor to the closest references before the cursor which it is not
currently on. Wraps the buffer if on the first reference.
Wraps the references unless `wrap` is false (defaults to **wrapscan**).
REQUIRE(ILLUMINATE).TEXTOBJ_SELECT()
Selects the reference the cursor is currently on for use as a text-object.
==============================================================================
7. Vim Users *illuminate-vim-users*
**Note:** This section is deprecated for Neovim users, Neovim users can use the
newer version of the plugin. Neovim users can force this old version of the
plugin by adding `let g:Illuminate_useDeprecated = 1` to their `init.vim`.
Illuminate will delay before highlighting, this is not lag, it is to avoid the
jarring experience of things illuminating too fast. This can be controlled with
`g:Illuminate_delay` (which is default to 0 milliseconds):
**Note**: Delay only works for Vim8 and Neovim.
>vim
" Time in milliseconds (default 0)
let g:Illuminate_delay = 0
<
Illuminate will by default highlight the word under the cursor to match the
behaviour seen in Intellij and VSCode. However, to make it not highlight the
word under the cursor, use the following:
>vim
" Don't highlight word under cursor (default: 1)
let g:Illuminate_highlightUnderCursor = 0
<
By default illuminate will highlight all words the cursor passes over, but for
many languages, you will only want to highlight certain highlight-groups. You
can determine the highlight-group of a symbol under your cursor with `:echo
synIDattr(synID(line("."), col("."), 1), "name")`.
You can define which highlight groups you want the illuminating to apply to.
This can be done with a dict mapping a filetype to a list of highlight-groups
in your vimrc such as:
>vim
let g:Illuminate_ftHighlightGroups = {
\ 'vim': ['vimVar', 'vimString', 'vimLineComment',
\ 'vimFuncName', 'vimFunction', 'vimUserFunc', 'vimFunc']
\ }
<
A blacklist of highlight groups can also be setup by adding the suffix
`:blacklist` to the filetype. However, if the whitelist for that filetype
already exists, it will override the blacklist.
>vim
let g:Illuminate_ftHighlightGroups = {
\ 'vim:blacklist': ['vimVar', 'vimString', 'vimLineComment',
\ 'vimFuncName', 'vimFunction', 'vimUserFunc', 'vimFunc']
\ }
<
illuminate can also be disabled for various filetypes using the following:
>vim
let g:Illuminate_ftblacklist = ['nerdtree']
<
Or you can enable it only for certain filetypes with:
>vim
let g:Illuminate_ftwhitelist = ['vim', 'sh', 'python']
<
By default the highlighting will be done with the highlight-group `CursorLine`
since that is in my opinion the nicest. It can however be overridden using the
following (use standard Vim highlighting syntax): Note: It must be in an
autocmd to get around a weird Neovim behaviour.
>vim
augroup illuminate_augroup
autocmd!
autocmd VimEnter * hi link illuminatedWord CursorLine
augroup END
augroup illuminate_augroup
autocmd!
autocmd VimEnter * hi illuminatedWord cterm=underline gui=underline
augroup END
<
Lastly, you can also specify a specific highlight for the word under the cursor
so it differs from all other matches using the following higlight group:
>vim
augroup illuminate_augroup
autocmd!
autocmd VimEnter * hi illuminatedCurWord cterm=italic gui=italic
augroup END
<
==============================================================================
8. Links *illuminate-links*
1. *gif*: https://media.giphy.com/media/mSG0nwAHDt3Fl7WyoL/giphy.gif
Generated by panvimdoc <https://github.com/kdheepak/panvimdoc>
vim:tw=78:ts=8:noet:ft=help:norl:

View File

@ -0,0 +1,31 @@
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello world
hello hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello

View File

@ -0,0 +1,321 @@
local M = {}
local timers = {}
local references = {}
local paused_bufs = {}
-- returns r1 < r2 based on start of range
local function before_by_start(r1, r2)
if r1['start'].line < r2['start'].line then return true end
if r2['start'].line < r1['start'].line then return false end
if r1['start'].character < r2['start'].character then return true end
return false
end
-- returns r1 < r2 base on start and if they are disjoint
local function before_disjoint(r1, r2)
if r1['end'].line < r2['start'].line then return true end
if r2['start'].line < r1['end'].line then return false end
if r1['end'].character < r2['start'].character then return true end
return false
end
-- check for cursor row in [start,end]
-- check for cursor col in [start,end]
-- While the end is technically exclusive based on the highlighting, we treat it as inclusive to match the server.
local function point_in_range(point, range)
if point.row == range['start']['line'] and point.col < range['start']['character'] then
return false
end
if point.row == range['end']['line'] and point.col > range['end']['character'] then
return false
end
return point.row >= range['start']['line'] and point.row <= range['end']['line']
end
local function cursor_in_references(bufnr)
if not references[bufnr] then
return false
end
if vim.api.nvim_win_get_buf(0) ~= bufnr then
return false
end
local crow, ccol = unpack(vim.api.nvim_win_get_cursor(0))
crow = crow - 1 -- reference ranges are (0,0)-indexed for (row,col)
for _, reference in pairs(references[bufnr]) do
local range = reference.range
if point_in_range({ row = crow, col = ccol }, range) then
return true
end
end
return false
end
local function handle_document_highlight(result, bufnr, client_id)
if not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then return end
local btimer = timers[bufnr]
if btimer then
vim.loop.timer_stop(btimer)
-- vim.loop.close(btimer)
end
if type(result) ~= 'table' then
vim.lsp.util.buf_clear_references(bufnr)
return
end
timers[bufnr] = vim.defer_fn(function()
if not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then return end
vim.lsp.util.buf_clear_references(bufnr)
if cursor_in_references(bufnr) then
local client = vim.lsp.get_client_by_id(client_id)
if client then
vim.lsp.util.buf_highlight_references(bufnr, result, client.offset_encoding)
end
end
end, vim.g.Illuminate_delay or 17)
table.sort(result, function(a, b)
return before_by_start(a.range, b.range)
end)
references[bufnr] = result
end
local function valid(bufnr, range)
return range
and range.start.line < vim.api.nvim_buf_line_count(bufnr)
and range.start.character < #vim.fn.getline(range.start.line + 1)
end
local function augroup(bufnr, autocmds)
vim.cmd('augroup vim_illuminate_lsp' .. bufnr)
vim.cmd('autocmd!')
if autocmds then
vim.b.illuminate_lsp_enabled = true
autocmds()
else
vim.b.illuminate_lsp_enabled = false
end
vim.cmd('augroup END')
end
local function autocmd(bufnr)
vim.cmd(string.format('autocmd CursorMoved,CursorMovedI <buffer=%d> lua require"illuminate".on_cursor_moved(%d)',
bufnr, bufnr))
end
local function move_cursor(row, col)
if not paused_bufs[vim.api.nvim_get_current_buf()] then
augroup(vim.api.nvim_get_current_buf(), function()
vim.api.nvim_win_set_cursor(0, { row, col })
autocmd(vim.api.nvim_get_current_buf())
end)
else
vim.api.nvim_win_set_cursor(0, { row, col })
end
end
function M.on_attach(client)
M.stop_buf()
if client and not client.supports_method('textDocument/documentHighlight') then
return
end
pcall(vim.api.nvim_command, 'IlluminationDisable!')
augroup(vim.api.nvim_get_current_buf(), function()
autocmd(vim.api.nvim_get_current_buf())
end)
vim.lsp.handlers['textDocument/documentHighlight'] = function(...)
if vim.fn.has('nvim-0.5.1') == 1 then
handle_document_highlight(select(2, ...), select(3, ...).bufnr, select(3, ...).client_id)
else
handle_document_highlight(select(3, ...), select(5, ...), nil)
end
end
vim.lsp.buf.document_highlight()
end
function M.on_cursor_moved(bufnr)
if not cursor_in_references(bufnr) then
vim.lsp.util.buf_clear_references(bufnr)
end
-- Best-effort check if any client support textDocument/documentHighlight
local supported = nil
-- For nvim 0.10+
if vim.lsp.get_clients then
supported = false
for _, client in ipairs(vim.lsp.get_clients({bufnr = bufnr})) do
if client and client.supports_method('textDocument/documentHighlight') then
supported = true
end
end
-- For older versions
elseif vim.lsp.for_each_buffer_client then
supported = false
vim.lsp.for_each_buffer_client(bufnr, function(client)
if client.supports_method('textDocument/documentHighlight') then
supported = true
end
end)
end
if supported == nil or supported then
vim.lsp.buf.document_highlight()
else
augroup(vim.api.nvim_get_current_buf(), function()
end)
end
end
function M.get_document_highlights(bufnr)
return references[bufnr]
end
function M.next_reference(opt)
opt = vim.tbl_extend('force', { reverse = false, wrap = false, range_ordering = 'start', silent = false }, opt or {})
local before
if opt.range_ordering == 'start' then
before = before_by_start
else
before = before_disjoint
end
local bufnr = vim.api.nvim_get_current_buf()
local refs = M.get_document_highlights(bufnr)
if not refs or #refs == 0 then return nil end
local next = nil
local nexti = nil
local crow, ccol = unpack(vim.api.nvim_win_get_cursor(0))
local crange = { start = { line = crow - 1, character = ccol } }
for i, ref in ipairs(refs) do
local range = ref.range
if valid(bufnr, range) then
if opt.reverse then
if before(range, crange) and (not next or before(next, range)) then
next = range
nexti = i
end
else
if before(crange, range) and (not next or before(range, next)) then
next = range
nexti = i
end
end
end
end
if not next and opt.wrap then
nexti = opt.reverse and #refs or 1
next = refs[nexti].range
end
if next then
move_cursor(next.start.line + 1, next.start.character)
if not opt.silent then
print('[' .. nexti .. '/' .. #refs .. ']')
end
end
return next
end
function M.toggle_pause()
if paused_bufs[vim.api.nvim_get_current_buf()] then
paused_bufs[vim.api.nvim_get_current_buf()] = false
augroup(vim.api.nvim_get_current_buf(), function()
autocmd(vim.api.nvim_get_current_buf())
end)
M.on_cursor_moved(vim.api.nvim_get_current_buf())
else
paused_bufs[vim.api.nvim_get_current_buf()] = true
augroup(vim.api.nvim_get_current_buf(), nil)
end
end
function M.configure(config)
require('illuminate.config').set(config)
end
function M.pause()
require('illuminate.engine').pause()
end
function M.resume()
require('illuminate.engine').resume()
end
function M.toggle()
require('illuminate.engine').toggle()
end
function M.toggle_buf()
require('illuminate.engine').toggle_buf()
end
function M.pause_buf()
require('illuminate.engine').pause_buf()
end
function M.stop_buf()
require('illuminate.engine').stop_buf()
end
function M.resume_buf()
require('illuminate.engine').resume_buf()
end
function M.freeze_buf()
require('illuminate.engine').freeze_buf()
end
function M.unfreeze_buf()
require('illuminate.engine').unfreeze_buf()
end
function M.toggle_freeze_buf()
require('illuminate.engine').toggle_freeze_buf()
end
function M.invisible_buf()
require('illuminate.engine').invisible_buf()
end
function M.visible_buf()
require('illuminate.engine').visible_buf()
end
function M.toggle_visibility_buf()
require('illuminate.engine').toggle_visibility_buf()
end
function M.goto_next_reference(wrap)
if wrap == nil then
wrap = vim.o.wrapscan
end
require('illuminate.goto').goto_next_reference(wrap)
end
function M.goto_prev_reference(wrap)
if wrap == nil then
wrap = vim.o.wrapscan
end
require('illuminate.goto').goto_prev_reference(wrap)
end
function M.textobj_select()
require('illuminate.textobj').select()
end
function M.debug()
require('illuminate.engine').debug()
end
function M.is_paused()
return require('illuminate.engine').is_paused()
end
function M.set_highlight_defaults()
vim.cmd [[
hi def IlluminatedWordText guifg=none guibg=none gui=underline
hi def IlluminatedWordRead guifg=none guibg=none gui=underline
hi def IlluminatedWordWrite guifg=none guibg=none gui=underline
]]
end
return M

View File

@ -0,0 +1,137 @@
local M = {}
local config = {
providers = {
'lsp',
'treesitter',
'regex',
},
delay = 100,
filetype_overrides = {},
filetypes_denylist = {
'dirbuf',
'dirvish',
'fugitive',
},
filetypes_allowlist = {},
modes_denylist = {},
modes_allowlist = {},
providers_regex_syntax_denylist = {},
providers_regex_syntax_allowlist = {},
under_cursor = true,
max_file_lines = nil,
large_file_cutoff = nil,
large_file_config = nil,
min_count_to_highlight = 1,
should_enable = nil,
case_insensitive_regex = false,
}
function M.set(config_overrides)
config = vim.tbl_extend('force', config, config_overrides or {})
end
function M.get_raw()
return config
end
function M.get()
return (
M.large_file_cutoff() == nil
or vim.fn.line('$') <= M.large_file_cutoff()
or M.large_file_overrides() == nil
)
and config
or M.large_file_overrides()
end
function M.filetype_override(bufnr)
local ft = vim.api.nvim_buf_get_option(bufnr, 'filetype')
return M.get()['filetype_overrides'] and M.get()['filetype_overrides'][ft] or {}
end
function M.providers(bufnr)
return M.filetype_override(bufnr)['providers'] or M.get()['providers']
end
function M.filetypes_denylist()
return M.get()['filetypes_denylist'] or {}
end
function M.filetypes_allowlist()
return M.get()['filetypes_allowlist'] or {}
end
function M.modes_denylist(bufnr)
return M.filetype_override(bufnr)['modes_denylist'] or M.get()['modes_denylist'] or {}
end
function M.modes_allowlist(bufnr)
return M.filetype_override(bufnr)['modes_allowlist'] or M.get()['modes_allowlist'] or {}
end
function M.provider_regex_syntax_denylist(bufnr)
return M.filetype_override(bufnr)['providers_regex_syntax_denylist']
or M.get()['providers_regex_syntax_denylist']
or {}
end
function M.provider_regex_syntax_allowlist(bufnr)
return M.filetype_override(bufnr)['providers_regex_syntax_allowlist']
or M.get()['providers_regex_syntax_allowlist']
or {}
end
function M.under_cursor(bufnr)
if M.filetype_override(bufnr)['under_cursor'] ~= nil then
return M.filetype_override(bufnr)['under_cursor'] ~= nil
end
return M.get()['under_cursor']
end
function M.delay(bufnr)
local delay = M.filetype_override(bufnr)['delay'] or M.get()['delay'] or 17
if string.sub(vim.api.nvim_get_mode().mode, 1, 1) == 'i' then
delay = delay + 100
end
if delay < 17 then
return 17
end
return delay
end
function M.max_file_lines()
return M.get()['max_file_lines']
end
function M.large_file_cutoff()
return config['large_file_cutoff']
end
function M.large_file_overrides()
if config['large_file_overrides'] ~= nil then
if config['large_file_overrides']['under_cursor'] == nil then
config['large_file_overrides']['under_cursor'] = true
end
return config['large_file_overrides']
end
return {
filetypes_allowlist = { '_none' }
}
end
function M.min_count_to_highlight()
return M.get()['min_count_to_highlight'] or 1
end
function M.should_enable()
return M.get()['should_enable'] or function(_)
return true
end
end
function M.case_insensitive_regex()
return M.get()['case_insensitive_regex']
end
return M

View File

@ -0,0 +1,267 @@
local hl = require('illuminate.highlight')
local ref = require('illuminate.reference')
local config = require('illuminate.config')
local util = require('illuminate.util')
local M = {}
local AUGROUP = 'vim_illuminate_v2_augroup'
local timers = {}
local paused_bufs = {}
local stopped_bufs = {}
local is_paused = false
local written = {}
local error_timestamps = {}
local frozen_bufs = {}
local invisible_bufs = {}
local started = false
local function buf_should_illuminate(bufnr)
if is_paused or paused_bufs[bufnr] or stopped_bufs[bufnr] then
return false
end
return config.should_enable()(bufnr)
and (config.max_file_lines() == nil or vim.fn.line('$') <= config.max_file_lines())
and util.is_allowed(
config.modes_allowlist(bufnr),
config.modes_denylist(bufnr),
vim.api.nvim_get_mode().mode
) and util.is_allowed(
config.filetypes_allowlist(),
config.filetypes_denylist(),
vim.api.nvim_buf_get_option(bufnr, 'filetype')
)
end
local function stop_timer(timer)
if vim.loop.is_active(timer) then
vim.loop.timer_stop(timer)
vim.loop.close(timer)
end
end
function M.start()
started = true
vim.api.nvim_create_augroup(AUGROUP, { clear = true })
vim.api.nvim_create_autocmd({ 'VimEnter', 'CursorMoved', 'CursorMovedI', 'ModeChanged', 'TextChanged' }, {
group = AUGROUP,
callback = function()
M.refresh_references()
end,
})
-- If vim.lsp.buf.format is called, this will call vim.api.nvim_buf_set_text which messes up extmarks.
-- By using this `written` variable, we can ensure refresh_references doesn't terminate early based on
-- ref.buf_cursor_in_references being incorrect (we have references but they're not actually showing
-- as illuminated). vim.lsp.buf.format will trigger CursorMoved so we don't need to do it here.
vim.api.nvim_create_autocmd({ 'BufWritePost' }, {
group = AUGROUP,
callback = function()
written[vim.api.nvim_get_current_buf()] = true
end,
})
vim.api.nvim_create_autocmd({ 'VimLeave' }, {
group = AUGROUP,
callback = function()
for _, timer in pairs(timers) do
stop_timer(timer)
end
end,
})
end
function M.stop()
started = false
vim.api.nvim_create_augroup(AUGROUP, { clear = true })
end
--- Get the highlighted references for the item under the cursor for
--- @bufnr and clears any old reference highlights
---
--- @bufnr (number)
function M.refresh_references(bufnr, winid)
bufnr = bufnr or vim.api.nvim_get_current_buf()
winid = winid or vim.api.nvim_get_current_win()
if frozen_bufs[bufnr] then
return
end
if not buf_should_illuminate(bufnr) then
hl.buf_clear_references(bufnr)
ref.buf_set_references(bufnr, {})
return
end
-- We might want to optimize here by returning early if cursor is in references.
-- The downside is that LSP servers can sometimes return a different list of references
-- as you move around an existing reference (like return statements).
if written[bufnr] or not ref.buf_cursor_in_references(bufnr, util.get_cursor_pos(winid)) then
hl.buf_clear_references(bufnr)
ref.buf_set_references(bufnr, {})
elseif config.large_file_cutoff() ~= nil and vim.fn.line('$') > config.large_file_cutoff() then
return
end
written[bufnr] = nil
if timers[bufnr] then
stop_timer(timers[bufnr])
end
local provider = M.get_provider(bufnr)
if not provider then return end
pcall(provider['initiate_request'], bufnr, winid)
local changedtick = vim.api.nvim_buf_get_changedtick(bufnr)
local timer = vim.loop.new_timer()
timers[bufnr] = timer
timer:start(config.delay(bufnr), 17, vim.schedule_wrap(function()
local ok, err = pcall(function()
if not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then
stop_timer(timer)
return
end
hl.buf_clear_references(bufnr)
ref.buf_set_references(bufnr, {})
if vim.api.nvim_buf_get_changedtick(bufnr) ~= changedtick
or vim.api.nvim_get_current_win() ~= winid
or bufnr ~= vim.api.nvim_win_get_buf(0) then
stop_timer(timer)
return
end
provider = M.get_provider(bufnr)
if not provider then
stop_timer(timer)
return
end
local references = provider.get_references(bufnr, util.get_cursor_pos(winid))
if references ~= nil then
ref.buf_set_references(bufnr, references)
if ref.buf_cursor_in_references(bufnr, util.get_cursor_pos(winid)) then
if not invisible_bufs[bufnr] == true then
hl.buf_highlight_references(bufnr, ref.buf_get_references(bufnr))
end
else
ref.buf_set_references(bufnr, {})
end
stop_timer(timer)
end
end)
if not ok then
local time = vim.loop.hrtime()
if #error_timestamps == 5 then
vim.notify(
'vim-illuminate: An internal error has occured: ' .. vim.inspect(ok) .. vim.inspect(err),
vim.log.levels.ERROR,
{}
)
M.stop()
stop_timer(timer)
elseif #error_timestamps == 0 or time - error_timestamps[#error_timestamps] < 500000000 then
table.insert(error_timestamps, time)
else
error_timestamps = { time }
end
end
end))
end
function M.get_provider(bufnr)
for _, provider in ipairs(config.providers(bufnr) or {}) do
local ok, providerModule = pcall(require, string.format('illuminate.providers.%s', provider))
if ok and providerModule.is_ready(bufnr) then
return providerModule, provider
end
end
return nil
end
function M.pause()
is_paused = true
M.refresh_references()
end
function M.resume()
is_paused = false
M.refresh_references()
end
function M.toggle()
is_paused = not is_paused
M.refresh_references()
end
function M.toggle_buf(bufnr)
bufnr = bufnr or vim.api.nvim_get_current_buf()
if paused_bufs[bufnr] then
paused_bufs[bufnr] = nil
else
paused_bufs[bufnr] = true
end
M.refresh_references()
end
function M.pause_buf(bufnr)
paused_bufs[bufnr or vim.api.nvim_get_current_buf()] = true
M.refresh_references()
end
function M.resume_buf(bufnr)
paused_bufs[bufnr or vim.api.nvim_get_current_buf()] = nil
M.refresh_references()
end
function M.stop_buf(bufnr)
stopped_bufs[bufnr or vim.api.nvim_get_current_buf()] = true
M.refresh_references()
end
function M.freeze_buf(bufnr)
frozen_bufs[bufnr or vim.api.nvim_get_current_buf()] = true
end
function M.unfreeze_buf(bufnr)
frozen_bufs[bufnr or vim.api.nvim_get_current_buf()] = nil
end
function M.toggle_freeze_buf(bufnr)
bufnr = bufnr or vim.api.nvim_get_current_buf()
frozen_bufs[bufnr] = not frozen_bufs[bufnr]
end
function M.invisible_buf(bufnr)
invisible_bufs[bufnr or vim.api.nvim_get_current_buf()] = true
M.refresh_references()
end
function M.visible_buf(bufnr)
invisible_bufs[bufnr or vim.api.nvim_get_current_buf()] = nil
M.refresh_references()
end
function M.toggle_visibility_buf(bufnr)
bufnr = bufnr or vim.api.nvim_get_current_buf()
invisible_bufs[bufnr] = not invisible_bufs[bufnr]
M.refresh_references()
end
function M.debug()
local bufnr = vim.api.nvim_get_current_buf()
print('buf_should_illuminate', bufnr, buf_should_illuminate(bufnr))
print('config', vim.inspect(config.get_raw()))
print('started', started)
print('provider', M.get_provider(bufnr))
print('`termguicolors`', vim.opt.termguicolors:get())
end
function M.is_paused()
return is_paused
end
return M

View File

@ -0,0 +1,63 @@
local util = require('illuminate.util')
local ref = require('illuminate.reference')
local engine = require('illuminate.engine')
local M = {}
function M.goto_next_reference(wrap)
local bufnr = vim.api.nvim_get_current_buf()
local winid = vim.api.nvim_get_current_win()
local cursor_pos = util.get_cursor_pos(winid)
if #ref.buf_get_references(bufnr) == 0 then
return
end
local i = ref.bisect_left(ref.buf_get_references(bufnr), cursor_pos)
i = i + 1
if i > #ref.buf_get_references(bufnr) then
if wrap then
i = 1
else
vim.api.nvim_err_writeln("E384: vim-illuminate: goto_next_reference hit BOTTOM of the references")
return
end
end
local pos, _ = unpack(ref.buf_get_references(bufnr)[i])
local new_cursor_pos = { pos[1] + 1, pos[2] }
vim.cmd('normal! m`')
engine.freeze_buf(bufnr)
vim.api.nvim_win_set_cursor(winid, new_cursor_pos)
engine.unfreeze_buf(bufnr)
end
function M.goto_prev_reference(wrap)
local bufnr = vim.api.nvim_get_current_buf()
local winid = vim.api.nvim_get_current_win()
local cursor_pos = util.get_cursor_pos(winid)
if #ref.buf_get_references(bufnr) == 0 then
return
end
local i = ref.bisect_left(ref.buf_get_references(bufnr), cursor_pos)
i = i - 1
if i == 0 then
if wrap then
i = #ref.buf_get_references(bufnr)
else
vim.api.nvim_err_writeln("E384: vim-illuminate: goto_prev_reference hit TOP of the references")
return
end
end
local pos, _ = unpack(ref.buf_get_references(bufnr)[i])
local new_cursor_pos = { pos[1] + 1, pos[2] }
vim.cmd('normal! m`')
engine.freeze_buf(bufnr)
vim.api.nvim_win_set_cursor(winid, new_cursor_pos)
engine.unfreeze_buf(bufnr)
end
return M

View File

@ -0,0 +1,59 @@
local util = require('illuminate.util')
local config = require('illuminate.config')
local ref = require('illuminate.reference')
local M = {}
local HL_NAMESPACE = vim.api.nvim_create_namespace('illuminate.highlight')
local function kind_to_hl_group(kind)
return kind == vim.lsp.protocol.DocumentHighlightKind.Text and 'IlluminatedWordText'
or kind == vim.lsp.protocol.DocumentHighlightKind.Read and 'IlluminatedWordRead'
or kind == vim.lsp.protocol.DocumentHighlightKind.Write and 'IlluminatedWordWrite'
or 'IlluminatedWordText'
end
function M.buf_highlight_references(bufnr, references)
if config.min_count_to_highlight() > #references then
return
end
local cursor_pos = util.get_cursor_pos()
for _, reference in ipairs(references) do
if config.under_cursor(bufnr) or not ref.is_pos_in_ref(cursor_pos, reference) then
M.range(
bufnr,
reference[1],
reference[2],
reference[3]
)
end
end
end
function M.range(bufnr, start, finish, kind)
local region = vim.region(bufnr, start, finish, 'v', false)
for linenr, cols in pairs(region) do
if linenr == -1 then
linenr = 0
end
local end_row
if cols[2] == -1 then
end_row = linenr + 1
cols[2] = 0
end
vim.api.nvim_buf_set_extmark(bufnr, HL_NAMESPACE, linenr, cols[1], {
hl_group = kind_to_hl_group(kind),
end_row = end_row,
end_col = cols[2],
priority = 199,
strict = false,
})
end
end
function M.buf_clear_references(bufnr)
vim.api.nvim_buf_clear_namespace(bufnr, HL_NAMESPACE, 0, -1)
end
return M

View File

@ -0,0 +1,130 @@
local M = {}
local bufs = {}
local function _str_byteindex_enc(line, col, encoding)
if not encoding then
encoding = 'utf-16'
end
if encoding == 'utf-8' then
if col then
return col
else
return #line
end
elseif encoding == 'utf-16' then
return vim.str_byteindex(line, col, true)
elseif encoding == 'utf-32' then
return vim.str_byteindex(line, col)
else
return col
end
end
local function get_line_byte_from_position(bufnr, line, col, offset_encoding)
if col == 0 then
return col
end
local lines = vim.api.nvim_buf_get_lines(bufnr, line, line + 1, false)
if not lines or #lines == 0 then
return col
end
local ok, result = pcall(_str_byteindex_enc, lines[1], col, offset_encoding)
if ok then
return result
end
return math.min(#(lines[1]), col)
end
function M.get_references(bufnr)
if not bufs[bufnr] or not bufs[bufnr][3] then
return nil
end
return bufs[bufnr][3]
end
function M.is_ready(bufnr)
local supported = false
-- For nvim 0.10+
if vim.lsp.get_clients then
supported = false
for _, client in ipairs(vim.lsp.get_clients({bufnr = bufnr})) do
if client and client.supports_method('textDocument/documentHighlight') then
supported = true
end
end
-- For older versions
elseif vim.lsp.for_each_buffer_client then
supported = false
vim.lsp.for_each_buffer_client(bufnr, function(client)
if client and client.supports_method('textDocument/documentHighlight') then
supported = true
end
end)
end
return supported
end
function M.initiate_request(bufnr, winid)
local id = 1
if bufs[bufnr] then
local prev_id, cancel_fn, references = unpack(bufs[bufnr])
if references == nil then
pcall(cancel_fn)
end
id = prev_id + 1
end
local cancel_fn = vim.lsp.buf_request_all(
bufnr,
'textDocument/documentHighlight',
vim.lsp.util.make_position_params(winid),
function(client_results)
if bufs[bufnr][1] ~= id then
return
end
if not vim.api.nvim_buf_is_valid(bufnr) then
bufs[bufnr][3] = {}
return
end
local references = {}
for client_id, results in pairs(client_results) do
local client = vim.lsp.get_client_by_id(client_id)
if client and results['result'] then
for _, res in ipairs(results['result']) do
local start_col = get_line_byte_from_position(
bufnr,
res['range']['start']['line'],
res['range']['start']['character'],
res['offset_encoding']
)
local end_col = get_line_byte_from_position(
bufnr,
res['range']['end']['line'],
res['range']['end']['character'],
res['offset_encoding']
)
table.insert(references, {
{ res['range']['start']['line'], start_col },
{ res['range']['end']['line'], end_col },
res['kind'],
})
end
end
end
bufs[bufnr][3] = references
end
)
bufs[bufnr] = {
id,
cancel_fn,
}
end
return M

View File

@ -0,0 +1,74 @@
local config = require('illuminate.config')
local util = require('illuminate.util')
local M = {}
local START_WORD_REGEX = vim.regex([[^\k*]])
local END_WORD_REGEX = vim.regex([[\k*$]])
-- foo
-- foo
-- Foo
-- fOo
local function get_cur_word(bufnr, cursor)
local line = vim.api.nvim_buf_get_lines(bufnr, cursor[1], cursor[1] + 1, false)[1]
local left_part = string.sub(line, 0, cursor[2] + 1)
local right_part = string.sub(line, cursor[2] + 1)
local start_idx, _ = END_WORD_REGEX:match_str(left_part)
local _, end_idx = START_WORD_REGEX:match_str(right_part)
local word = string.format('%s%s', string.sub(left_part, start_idx + 1), string.sub(right_part, 2, end_idx))
local modifiers = [[\V]]
if config.case_insensitive_regex() then
modifiers = modifiers .. [[\c]]
end
local ok, escaped = pcall(vim.fn.escape, word, [[/\]])
if ok then
return modifiers .. [[\<]] .. escaped .. [[\>]]
end
end
function M.get_references(bufnr, cursor)
local refs = {}
local ok, re = pcall(vim.regex, get_cur_word(bufnr, cursor))
if not ok then
return refs
end
local line_count = vim.api.nvim_buf_line_count(bufnr)
for i = 0, line_count - 1 do
local start_byte, end_byte = 0, 0
while true do
local start_offset, end_offset = re:match_line(bufnr, i, end_byte)
if not start_offset then break end
start_byte = end_byte + start_offset
end_byte = end_byte + end_offset
table.insert(refs, {
{ i, start_byte },
{ i, end_byte },
vim.lsp.protocol.DocumentHighlightKind.Text,
})
end
end
return refs
end
function M.is_ready(bufnr)
local name = vim.fn.synIDattr(
vim.fn.synIDtrans(
vim.fn.synID(vim.fn.line('.'), vim.fn.col('.'), 1)
),
'name'
)
if util.is_allowed(
config.provider_regex_syntax_allowlist(bufnr),
config.provider_regex_syntax_denylist(bufnr),
name
) then
return true
end
return false
end
return M

View File

@ -0,0 +1,51 @@
local ts_utils = require('nvim-treesitter.ts_utils')
local locals = require('nvim-treesitter.locals')
local M = {}
local buf_attached = {}
function M.get_references(bufnr)
local node_at_point = ts_utils.get_node_at_cursor()
if not node_at_point then
return
end
local refs = {}
local def_node, scope = locals.find_definition(node_at_point, bufnr)
if def_node ~= node_at_point then
local range = { def_node:range() }
table.insert(refs, {
{ range[1], range[2] },
{ range[3], range[4] },
vim.lsp.protocol.DocumentHighlightKind.Write,
})
end
local usages = locals.find_usages(def_node, scope, bufnr)
for _, node in ipairs(usages) do
local range = { node:range() }
table.insert(refs, {
{ range[1], range[2] },
{ range[3], range[4] },
vim.lsp.protocol.DocumentHighlightKind.Read,
})
end
return refs
end
function M.is_ready(bufnr)
return buf_attached[bufnr] and vim.api.nvim_buf_get_option(bufnr, 'filetype') ~= 'yaml'
end
function M.attach(bufnr)
buf_attached[bufnr] = true
end
function M.detach(bufnr)
buf_attached[bufnr] = nil
end
return M

View File

@ -0,0 +1,91 @@
local M = {}
-- @table pos
-- @field 1 (number) line (0-indexed)
-- @field 2 (number) col (0-indexed)
--
-- @table ref
-- @field 1 (table) start pos
-- @field 2 (table) end pos
local buf_references = {}
local function get_references(bufnr)
return buf_references[bufnr] or {}
end
local function pos_before(pos1, pos2)
if pos1[1] < pos2[1] then return true end
if pos1[1] > pos2[1] then return false end
if pos1[2] < pos2[2] then return true end
return false
end
local function pos_equal(pos1, pos2)
return pos1[1] == pos2[1] and pos1[2] == pos2[2]
end
local function ref_before(ref1, ref2)
return pos_before(ref1[1], ref2[1]) or pos_equal(ref1[1], ref2[1]) and pos_before(ref1[2], ref2[2])
end
local function buf_sort_references(bufnr)
local should_sort = false
for i, ref in ipairs(get_references(bufnr)) do
if i > 1 then
if not ref_before(get_references(bufnr)[i - 1], ref) then
should_sort = true
break
end
end
end
if should_sort then
table.sort(get_references(bufnr), ref_before)
end
end
function M.is_pos_in_ref(pos, ref)
return (pos_before(ref[1], pos) or pos_equal(ref[1], pos)) and (pos_before(pos, ref[2]) or pos_equal(pos, ref[2]))
end
function M.bisect_left(references, pos)
local l, r = 1, #references + 1
while l < r do
local m = l + math.floor((r - l) / 2)
if pos_before(references[m][2], pos) then
l = m + 1
else
r = m
end
end
return l
end
function M.buf_get_references(bufnr)
return get_references(bufnr)
end
function M.buf_set_references(bufnr, references)
buf_references[bufnr] = references
buf_sort_references(bufnr)
end
function M.buf_cursor_in_references(bufnr, cursor_pos)
if not get_references(bufnr) then
return false
end
local i = M.bisect_left(get_references(bufnr), cursor_pos)
if i > #get_references(bufnr) then
return false
end
if not M.is_pos_in_ref(cursor_pos, get_references(bufnr)[i]) then
return false
end
return true
end
return M

View File

@ -0,0 +1,42 @@
local util = require('illuminate.util')
local ref = require('illuminate.reference')
local M = {}
local visual_modes = {
['v'] = true,
['vs'] = true,
['V'] = true,
['Vs'] = true,
['CTRL-V'] = true,
['CTRL-Vs'] = true,
['s'] = true,
['S'] = true,
['CTRL-S'] = true,
}
function M.select()
local bufnr = vim.api.nvim_get_current_buf()
local winid = vim.api.nvim_get_current_win()
local cursor_pos = util.get_cursor_pos(winid)
if #ref.buf_get_references(bufnr) == 0 then
return
end
local i = ref.bisect_left(ref.buf_get_references(bufnr), cursor_pos)
if i > #ref.buf_get_references(bufnr) then
return
end
local reference = ref.buf_get_references(bufnr)[i]
vim.api.nvim_win_set_cursor(winid, { reference[1][1] + 1, reference[1][2] })
if not visual_modes[vim.api.nvim_get_mode().mode] then
vim.cmd('normal! v')
else
vim.cmd('normal! o')
end
vim.api.nvim_win_set_cursor(winid, { reference[2][1] + 1, reference[2][2] - 1 })
end
return M

View File

@ -0,0 +1,51 @@
local M = {}
function M.get_cursor_pos(winid)
winid = winid or vim.api.nvim_get_current_win()
local cursor = vim.api.nvim_win_get_cursor(winid)
cursor[1] = cursor[1] - 1 -- we always want line to be 0-indexed
return cursor
end
function M.list_to_set(list)
if list == nil then
return nil
end
local set = {}
for _, v in pairs(list) do
set[v] = true
end
return set
end
function M.is_allowed(allow_list, deny_list, thing)
if #allow_list == 0 and #deny_list == 0 then
return true
end
if #deny_list > 0 then
return not vim.tbl_contains(deny_list, thing)
end
return vim.tbl_contains(allow_list, thing)
end
function M.tbl_get(tbl, expected_type, ...)
local cur = tbl
for _, key in ipairs({ ... }) do
if type(cur) ~= 'table' or cur[key] == nil then
return nil
end
cur = cur[key]
end
return type(cur) == expected_type and cur or nil
end
function M.has_keymap(mode, lhs)
return vim.fn.mapcheck(lhs, mode) ~= ''
end
return M

View File

@ -0,0 +1,88 @@
" illuminate.vim - Vim plugin for selectively illuminating other uses of current word
" Maintainer: Adam P. Regasz-Rethy (RRethy) <rethy.spud@gmail.com>
" Version: 2.0
if exists('g:loaded_illuminate')
finish
endif
let g:loaded_illuminate = 1
if has('nvim-0.7.2') && get(g:, 'Illuminate_useDeprecated', 0) != 1
lua << EOF
local ok, ts = pcall(require, 'nvim-treesitter')
if ok then
ts.define_modules({
illuminate = {
module_path = 'illuminate.providers.treesitter',
enable = true,
disable = {},
is_supported = require('nvim-treesitter.query').has_locals,
}
})
end
require('illuminate.engine').start()
vim.api.nvim_create_user_command('IlluminatePause', require('illuminate').pause, { bang = true })
vim.api.nvim_create_user_command('IlluminateResume', require('illuminate').resume, { bang = true })
vim.api.nvim_create_user_command('IlluminateToggle', require('illuminate').toggle, { bang = true })
vim.api.nvim_create_user_command('IlluminatePauseBuf', require('illuminate').pause_buf, { bang = true })
vim.api.nvim_create_user_command('IlluminateResumeBuf', require('illuminate').resume_buf, { bang = true })
vim.api.nvim_create_user_command('IlluminateToggleBuf', require('illuminate').toggle_buf, { bang = true })
vim.api.nvim_create_user_command('IlluminateDebug', require('illuminate').debug, { bang = true })
if not require('illuminate.util').has_keymap('n', '<a-n>') then
vim.keymap.set('n', '<a-n>', require('illuminate').goto_next_reference, { desc = "Move to next reference" })
end
if not require('illuminate.util').has_keymap('n', '<a-p>') then
vim.keymap.set('n', '<a-p>', require('illuminate').goto_prev_reference, { desc = "Move to previous reference" })
end
if not require('illuminate.util').has_keymap('o', '<a-i>') then
vim.keymap.set('o', '<a-i>', require('illuminate').textobj_select)
end
if not require('illuminate.util').has_keymap('x', '<a-i>') then
vim.keymap.set('x', '<a-i>', require('illuminate').textobj_select)
end
EOF
lua require('illuminate').set_highlight_defaults()
augroup vim_illuminate_autocmds
autocmd!
autocmd ColorScheme * lua require('illuminate').set_highlight_defaults()
augroup END
finish
end
" Highlight group(s) {{{
if !hlexists('illuminatedWord')
" this is for backwards compatibility
if !empty(get(g:, 'Illuminate_hl_link', ''))
exe get(g:, 'Illuminate_hl_link', '')
else
hi def link illuminatedWord cursorline
endif
endif
" }}}
" Autocommands {{{
if has('autocmd')
augroup illuminated_autocmd
autocmd!
autocmd CursorMoved,InsertLeave * call illuminate#on_cursor_moved()
autocmd WinLeave,BufLeave * call illuminate#on_leaving_autocmds()
autocmd CursorMovedI * call illuminate#on_cursor_moved_i()
autocmd InsertEnter * call illuminate#on_insert_entered()
augroup END
else
echoerr 'Illuminate requires Vim compiled with +autocmd'
finish
endif
" }}}
" Commands {{{
command! -nargs=0 -bang IlluminationDisable call illuminate#disable_illumination(<bang>0)
command! -nargs=0 -bang IlluminationEnable call illuminate#enable_illumination(<bang>0)
command! -nargs=0 -bang IlluminationToggle call illuminate#toggle_illumination(<bang>0)
" }}} Commands:
" vim: foldlevel=1 foldmethod=marker