Regenerate nvim config
This commit is contained in:
@ -0,0 +1,3 @@
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
28
config/neovim/store/lazy-plugins/vim-illuminate/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
28
config/neovim/store/lazy-plugins/vim-illuminate/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal 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.
|
||||
30
config/neovim/store/lazy-plugins/vim-illuminate/.github/workflows/illuminate.yml
vendored
Normal file
30
config/neovim/store/lazy-plugins/vim-illuminate/.github/workflows/illuminate.yml
vendored
Normal 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 }}
|
||||
1
config/neovim/store/lazy-plugins/vim-illuminate/.gitignore
vendored
Normal file
1
config/neovim/store/lazy-plugins/vim-illuminate/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
doc/tags
|
||||
265
config/neovim/store/lazy-plugins/vim-illuminate/README.md
Normal file
265
config/neovim/store/lazy-plugins/vim-illuminate/README.md
Normal 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.
|
||||
|
||||

|
||||
|
||||
# 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
|
||||
```
|
||||
@ -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
|
||||
@ -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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
==============================================================================
|
||||
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 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.
|
||||
|
||||
|
||||
==============================================================================
|
||||
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:
|
||||
31
config/neovim/store/lazy-plugins/vim-illuminate/foo.txt
Normal file
31
config/neovim/store/lazy-plugins/vim-illuminate/foo.txt
Normal 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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
Reference in New Issue
Block a user