1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-23 12:50:04 +08:00

refactor(bundle): update bundle indent-blankline.nvim

0f8df7e43f
close https://github.com/SpaceVim/SpaceVim/issues/4551
This commit is contained in:
wsdjeg 2022-01-05 08:47:47 +08:00
parent da2f51ecb9
commit 76d9a53aa8
10 changed files with 1203 additions and 396 deletions

View File

@ -0,0 +1,22 @@
name: Pull request check
on:
pull_request:
jobs:
format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: JohnnyMorganz/stylua-action@1.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --check .
block-fixup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Block Fixup Commit Merge
uses: 13rac1/block-fixup-merge-action@v2.0.0

View File

@ -9,13 +9,6 @@ features so it will not work in Vim.
There is a legacy version of the plugin that supports Neovim 0.4 under the
branch `version-1`
## Settings
A lot of [Yggdroot/indentLine](https://github.com/Yggdroot/indentLine) options
should work out of the box.
Please see `:help indent_blankline.txt`for more details.
## Install
Use your favourite plugin manager to install.
@ -44,27 +37,123 @@ Plug 'lukas-reineke/indent-blankline.nvim'
call plug#end()
```
## Setup
To configure indent-blankline, either run the setup function, or set variables manually.
The setup function has a single table as argument, keys of the table match the `:help indent-blankline-variables` without the `indent_blankline_` part.
```lua
require("indent_blankline").setup {
-- for example, context is off by default, use this to turn it on
show_current_context = true,
show_current_context_start = true,
}
```
Please see `:help indent_blankline.txt`for more details and all possible values.
A lot of [Yggdroot/indentLine](https://github.com/Yggdroot/indentLine) options should work out of the box.
## Screenshots
#### Default settings
All screenshots use [my custom onedark color scheme](https://github.com/lukas-reineke/onedark.nvim).
### Simple
```lua
vim.opt.list = true
vim.opt.listchars:append("eol:↴")
require("indent_blankline").setup {
show_end_of_line = true,
}
```
<img width="900" src="https://i.imgur.com/3gRG5qI.png" alt="Screenshot" />
#### With custom `listchars` and `g:indent_blankline_space_char`
#### With custom `listchars` and `g:indent_blankline_space_char_blankline`
```lua
vim.opt.list = true
vim.opt.listchars:append("space:⋅")
vim.opt.listchars:append("eol:↴")
require("indent_blankline").setup {
show_end_of_line = true,
space_char_blankline = " ",
}
```
<img width="900" src="https://i.imgur.com/VxCThMu.png" alt="Screenshot" />
#### With custom `g:indent_blankline_char_highlight_list`
```lua
vim.opt.termguicolors = true
vim.cmd [[highlight IndentBlanklineIndent1 guifg=#E06C75 gui=nocombine]]
vim.cmd [[highlight IndentBlanklineIndent2 guifg=#E5C07B gui=nocombine]]
vim.cmd [[highlight IndentBlanklineIndent3 guifg=#98C379 gui=nocombine]]
vim.cmd [[highlight IndentBlanklineIndent4 guifg=#56B6C2 gui=nocombine]]
vim.cmd [[highlight IndentBlanklineIndent5 guifg=#61AFEF gui=nocombine]]
vim.cmd [[highlight IndentBlanklineIndent6 guifg=#C678DD gui=nocombine]]
vim.opt.list = true
vim.opt.listchars:append("space:⋅")
vim.opt.listchars:append("eol:↴")
require("indent_blankline").setup {
space_char_blankline = " ",
char_highlight_list = {
"IndentBlanklineIndent1",
"IndentBlanklineIndent2",
"IndentBlanklineIndent3",
"IndentBlanklineIndent4",
"IndentBlanklineIndent5",
"IndentBlanklineIndent6",
},
}
```
<img width="900" src="https://i.imgur.com/E3B0PUb.png" alt="Screenshot" />
#### With custom background highlight
```lua
vim.opt.termguicolors = true
vim.cmd [[highlight IndentBlanklineIndent1 guibg=#1f1f1f gui=nocombine]]
vim.cmd [[highlight IndentBlanklineIndent2 guibg=#1a1a1a gui=nocombine]]
require("indent_blankline").setup {
char = "",
char_highlight_list = {
"IndentBlanklineIndent1",
"IndentBlanklineIndent2",
},
space_char_highlight_list = {
"IndentBlanklineIndent1",
"IndentBlanklineIndent2",
},
show_trailing_blankline_indent = false,
}
```
<img width="900" src="https://i.imgur.com/DukMZGk.png" alt="Screenshot" />
#### With context indent highlighted by treesitter
<img width="900" src="https://i.imgur.com/mkyGPZZ.png" alt="Screenshot" />
```lua
vim.opt.list = true
vim.opt.listchars:append("space:⋅")
vim.opt.listchars:append("eol:↴")
require("indent_blankline").setup {
space_char_blankline = " ",
show_current_context = true,
show_current_context_start = true,
}
```
<img width="900" src="https://user-images.githubusercontent.com/12900252/140518531-522aa67a-b377-498c-ad39-85113b2b56df.png" alt="Screenshot" />
## Thanks

View File

@ -1,7 +1,11 @@
function! indent_blankline#Refresh()
function! indent_blankline#Refresh(...)
try
lua require("indent_blankline").refresh()
if a:0 > 0
call luaeval("require('indent_blankline').refresh(_A)", a:1)
else
lua require("indent_blankline").refresh()
end
catch /E12/
return
catch

View File

@ -1,11 +0,0 @@
function! indent_blankline#helper#GetListChar(key, fallback)
let l:list_chars = {}
for l:char in split(&listchars, ',')
let l:split = split(l:char, ':')
let l:list_chars[l:split[0]] = l:split[1]
endfor
return get(l:list_chars, a:key, a:fallback)
endfunction

View File

@ -2,17 +2,18 @@
Author: Lukas Reineke <lukas.reineke@protonmail.com>
Version: 2.0.0
Version: 2.11.0
==============================================================================
CONTENTS *indent-blankline*
1. Introduction |indent-blankline-introduction|
2. Highlights |indent-blankline-highlights|
3. Variables |indent-blankline-variables|
4. Commands |indent-blankline-commands|
5. Changelog |indent-blankline-changelog|
6. License |indent-blankline-license|
3. Setup |indent-blankline-setup|
4. Variables |indent-blankline-variables|
5. Commands |indent-blankline-commands|
6. Changelog |indent-blankline-changelog|
7. License |indent-blankline-license|
==============================================================================
1. INTRODUCTION *indent-blankline-introduction*
@ -27,11 +28,12 @@ There is a legacy version of the plugin that supports Neovim 0.4 under the
branch `version-1`
==============================================================================
3. HIGHLIGHTS *indent-blankline-highlights*
2. HIGHLIGHTS *indent-blankline-highlights*
To change the highlighting of either the indent character, or the whitespace
between indent characters, define or update these highlight groups.
------------------------------------------------------------------------------
IndentBlanklineChar *hl-IndentBlanklineChar*
Highlight of indent character.
@ -42,6 +44,7 @@ IndentBlanklineChar *hl-IndentBlanklineChar*
highlight IndentBlanklineChar guifg=#00FF00 gui=nocombine
------------------------------------------------------------------------------
IndentBlanklineSpaceChar *hl-IndentBlanklineSpaceChar*
Highlight of space character.
@ -52,6 +55,7 @@ IndentBlanklineSpaceChar *hl-IndentBlanklineSpaceChar*
highlight IndentBlanklineSpaceChar guifg=#00FF00 gui=nocombine
------------------------------------------------------------------------------
IndentBlanklineSpaceCharBlankline *hl-IndentBlanklineSpaceCharBlankline*
Highlight of space character on blank lines.
@ -62,6 +66,7 @@ IndentBlanklineSpaceCharBlankline *hl-IndentBlanklineSpaceCharBlankline*
highlight IndentBlanklineSpaceCharBlankline guifg=#00FF00 gui=nocombine
------------------------------------------------------------------------------
IndentBlanklineContextChar *hl-IndentBlanklineContextChar*
Highlight of indent character when base of current context.
@ -73,6 +78,22 @@ IndentBlanklineContextChar *hl-IndentBlanklineContextChar*
highlight IndentBlanklineContextChar guifg=#00FF00 gui=nocombine
------------------------------------------------------------------------------
IndentBlanklineContextStart *hl-IndentBlanklineContextStart*
Highlight of the first line of the current context.
Only used when |g:indent_blankline_show_current_context_start| is active
Default: takes guifg color from 'Label' as guisp and adds underline ~
Note: You need to have set |gui-colors| for the default to work.
Example: >
highlight IndentBlanklineContextStart guisp=#00FF00 gui=underline
------------------------------------------------------------------------------
When defining the highlight group, it is important to set |nocombine| as a
gui option. This is to make sure the character does not inherit gui options
from the underlying text, like italic or bold.
@ -87,16 +108,42 @@ see:
|g:indent_blankline_space_char_blankline_highlight_list|
==============================================================================
3. VARIABLES *indent-blankline-variables*
3. SETUP *indent-blankline-setup*
To configure indent-blankline, either run the setup function, or set variables
manually.
The setup function has a single table as argument, keys of the table match the
|indent-blankline-variables| without the `indent_blankline_` part.
Example: >
require("indent_blankline").setup {
-- for example, context is off by default, use this to turn it on
show_current_context = true,
show_current_context_start = true,
}
==============================================================================
4. VARIABLES *indent-blankline-variables*
All variables can be set gobally |g:var|, per tab |t:var|, or per buffer |b:var|
------------------------------------------------------------------------------
g:indent_blankline_char *g:indent_blankline_char*
Specifies the character to be used as indent line.
Not used if |g:indent_blankline_char_list| is not empty.
When set explicitly to empty string (""), no indentation character is
displayed at all, even when |g:indent_blankline_char_list| is not empty.
This can be useful in combination with
|g:indent_blankline_space_char_highlight_list| to only rely on different
highlighting of different indentation levels without needing to show a
special character.
Also set by |g:indentLine_char|
Default: '|' ~
Default: '' ~
Example: >
@ -119,7 +166,7 @@ g:indent_blankline_char_list *g:indent_blankline_char_list*
------------------------------------------------------------------------------
g:indent_blankline_char_highlight_list*g:indent_blankline_char_highlight_list*
g:indent_blankline_char_highlight_list *g:indent_blankline_char_highlight_list*
Specifies the list of character highlights for each indentation level.
Ignored if the value is an empty list.
@ -131,26 +178,12 @@ g:indent_blankline_char_highlight_list*g:indent_blankline_char_highlight_list*
let g:indent_blankline_char_highlight_list = ['Error', 'Function']
------------------------------------------------------------------------------
g:indent_blankline_space_char *g:indent_blankline_space_char*
Specifies the character to be used as the space value in between indent
lines.
Default: The listchars space value ~
Example: >
let g:indent_blankline_space_char = ' '
------------------------------------------------------------------------------
g:indent_blankline_space_char_blankline*g:indent_blankline_space_char_blankline*
g:indent_blankline_space_char_blankline *g:indent_blankline_space_char_blankline*
Specifies the character to be used as the space value in between indent
lines when the line is blank.
Also set by |g:indent_blankline_space_char|
Default: The listchars space value ~
Default: An empty space character ~
Example: >
@ -158,7 +191,7 @@ g:indent_blankline_space_char_blankline*g:indent_blankline_space_char_blankline*
------------------------------------------------------------------------------
g:indent_blankline_space_char_highlight_list*g:indent_blankline_space_char_highlight_list*
g:indent_blankline_space_char_highlight_list *g:indent_blankline_space_char_highlight_list*
Specifies the list of space character highlights for each indentation
level.
@ -172,7 +205,7 @@ g:indent_blankline_space_char_highlight_list*g:indent_blankline_space_char_highl
------------------------------------------------------------------------------
g:indent_blankline_space_char_blankline_highlight_list*g:indent_blankline_space_char_blankline_highlight_list*
g:indent_blankline_space_char_blankline_highlight_list *g:indent_blankline_space_char_blankline_highlight_list*
Specifies the list of space character highlights for each indentation
level when the line is empty.
@ -187,7 +220,6 @@ g:indent_blankline_space_char_blankline_highlight_list*g:indent_blankline_space_
let g:indent_blankline_space_char_blankline_highlight_list = ['Error', 'Function']
------------------------------------------------------------------------------
g:indent_blankline_use_treesitter *g:indent_blankline_use_treesitter*
Use treesitter to calculate indentation when possible.
@ -213,7 +245,20 @@ g:indent_blankline_indent_level *g:indent_blankline_indent_level*
let g:indent_blankline_indent_level = 4
------------------------------------------------------------------------------
g:indent_blankline_show_first_indent_level*g:indent_blankline_show_first_indent_level*
g:indent_blankline_max_indent_increase *g:indent_blankline_max_indent_increase*
The maximum indent level increase from line to line.
Set this option to 1 to make aligned trailing multiline comments not
create indentation.
Default: g:indent_blankline_indent_level ~
Example: >
let g:indent_blankline_max_indent_increase = 1
------------------------------------------------------------------------------
g:indent_blankline_show_first_indent_level *g:indent_blankline_show_first_indent_level*
Displays indentation in the first column.
@ -224,7 +269,7 @@ g:indent_blankline_show_first_indent_level*g:indent_blankline_show_first_indent_
let g:indent_blankline_show_first_indent_level = v:false
------------------------------------------------------------------------------
g:indent_blankline_show_trailing_blankline_indent*g:indent_blankline_show_trailing_blankline_indent*
g:indent_blankline_show_trailing_blankline_indent *g:indent_blankline_show_trailing_blankline_indent*
Displays a trailing indentation guide on blank lines, to match the
indentation of surrounding code.
@ -266,10 +311,13 @@ g:indent_blankline_show_foldtext *g:indent_blankline_show_foldtext*
------------------------------------------------------------------------------
g:indent_blankline_enabled *g:indent_blankline_enabled*
Turns this plugin on or off globally.
Turns this plugin on or off.
Also set by |g:indentLine_enabled|
Note: the buffer version of this variable overwrites all other
enabled/disalbed checks.
Default: v:true ~
Example: >
@ -277,17 +325,17 @@ g:indent_blankline_enabled *g:indent_blankline_enabled*
let g:indent_blankline_enabled = v:false
------------------------------------------------------------------------------
b:indent_blankline_enabled *b:indent_blankline_enabled*
g:indent_blankline_disable_with_nolist *g:indent_blankline_disable_with_nolist*
Turns this plugin on or off for the buffer.
When true, automatically turns this plugin off when |nolist| is set.
When false, setting |nolist| will keep displaying indentation guides but
removes whitespace characters set by |listchars|.
Also set by |b:indentLine_enabled|
Default: v:true ~
Default: v:false ~
Example: >
let b:indent_blankline_enabled = v:false
let g:indent_blankline_disable_with_nolist = v:true
------------------------------------------------------------------------------
g:indent_blankline_filetype *g:indent_blankline_filetype*
@ -363,7 +411,7 @@ g:indent_blankline_strict_tabs *g:indent_blankline_strict_tabs*
let g:indent_blankline_strict_tabs = v:true
------------------------------------------------------------------------------
g:indent_blankline_show_current_context*g:indent_blankline_show_current_context*
g:indent_blankline_show_current_context *g:indent_blankline_show_current_context*
When on, use treesitter to determine the current context. Then show the
indent character in a different highlight.
@ -379,7 +427,68 @@ g:indent_blankline_show_current_context*g:indent_blankline_show_current_context*
let g:indent_blankline_show_current_context = v:true
------------------------------------------------------------------------------
g:indent_blankline_context_highlight_list*g:indent_blankline_context_highlight_list*
g:indent_blankline_show_current_context_start *g:indent_blankline_show_current_context_start*
Applies the |hl-IndentBlanklineContextStart| highlight group to the first
line of the current context.
By default this will underline.
Note: You need to have set |gui-colors| and it depends on your terminal
emulator if this works as expected.
If you are using kitty and tmux, take a look at this article to
make it work
http://evantravers.com/articles/2021/02/05/curly-underlines-in-kitty-tmux-neovim/
Default: v:false ~
Example: >
let g:indent_blankline_show_current_context_start = v:true
------------------------------------------------------------------------------
g:indent_blankline_show_current_context_start_on_current_line *g:indent_blankline_show_current_context_start_on_current_line*
Shows |g:indent_blankline_show_current_context_start| even when the cursor
is on the same line
Default: v:true ~
Example: >
let g:indent_blankline_show_current_context_start_on_current_line = v:false
------------------------------------------------------------------------------
g:indent_blankline_context_char *g:indent_blankline_context_char*
Specifies the character to be used for the current context indent line.
Not used if |g:indent_blankline_context_char_list| is not empty.
Useful to have a greater distinction between the current context indent
line and others.
Also useful in combination with |g:indent_blankline_char| set to empty string
(""), as this allows only the current context indent line to be shown.
Default: g:indent_blankline_char ~
Example: >
let g:indent_blankline_context_char = '┃'
------------------------------------------------------------------------------
g:indent_blankline_context_char_list *g:indent_blankline_context_char_list*
Equivalent of |g:indent_blankline_char_list| for
|g:indent_blankline_context_char|.
Default: [] ~
Example: >
let g:indent_blankline_context_char_list = ['┃', '║', '╬', '█']
------------------------------------------------------------------------------
g:indent_blankline_context_highlight_list *g:indent_blankline_context_highlight_list*
Specifies the list of character highlights for the current context at
each indentation level.
@ -411,6 +520,22 @@ g:indent_blankline_context_patterns *g:indent_blankline_context_patterns*
let g:indent_blankline_context_patterns = ['^if']
------------------------------------------------------------------------------
g:indent_blankline_context_pattern_highlight *g:indent_blankline_context_pattern_highlight*
Specifies a map of patterns set in
|g:indent_blankline_context_patterns| to highlight groups.
When the current matching context pattern is in the map, the context
will be highlighted with the corresponding highlight group.
Only used when |g:indent_blankline_show_current_context| is active
Default: {} ~
Example: >
let g:indent_blankline_context_pattern_highlight = {'function': 'Function'}
------------------------------------------------------------------------------
g:indent_blankline_viewport_buffer *g:indent_blankline_viewport_buffer*
@ -424,7 +549,7 @@ g:indent_blankline_viewport_buffer *g:indent_blankline_viewport_buffer*
let g:indent_blankline_viewport_buffer = 20
------------------------------------------------------------------------------
g:indent_blankline_disable_warning_message*g:indent_blankline_disable_warning_message*
g:indent_blankline_disable_warning_message *g:indent_blankline_disable_warning_message*
Turns deprecation warning messages off.
@ -446,8 +571,9 @@ g:indent_blankline_debug *g:indent_blankline_debug*
let g:indent_blankline_debug = v:true
==============================================================================
4. COMMANDS *indent-blankline-commands*
5. COMMANDS *indent-blankline-commands*
------------------------------------------------------------------------------
:IndentBlanklineRefresh[!] *IndentBlanklineRefresh*
Refreshes the indent guides for the current buffer.
@ -457,19 +583,34 @@ g:indent_blankline_debug *g:indent_blankline_debug*
With bang (IndentBlanklineRefresh!) refreshes the indent guides globally.
By default it is run for:
1. |VimEnter| * [bang]
2. |FileChangedShellPost| *
3. |TextChanged| *
4. |TextChangedI| *
5. |WinScrolled| *
6. |BufWinEnter| *
7. |Filetype| *
8. |OptionSet| shiftwidth,tabstop,expandtab
1. |FileChangedShellPost| *
2. |TextChanged| *
3. |TextChangedI| *
4. |CompleteChanged| *
5. |BufWinEnter| *
6. |Filetype| *
7. |OptionSet| shiftwidth,tabstop,expandtab
Example: >
autocmd User ALEFixPost IndentBlanklineRefresh
------------------------------------------------------------------------------
:IndentBlanklineRefreshScroll[!] *IndentBlanklineRefreshScroll*
Refreshes the indent guides for the current buffer. But tries to reuse as
indent guides that already exist. Only used if we are sure the buffer
content did not change.
With bang (IndentBlanklineRefresh!) refreshes the indent guides globally.
By default it is run for:
1. |WinScrolled| *
Example: >
autocmd WinScrolled * IndentBlanklineRefreshScroll
------------------------------------------------------------------------------
:IndentBlanklineEnable[!] *IndentBlanklineEnable*
@ -494,7 +635,139 @@ g:indent_blankline_debug *g:indent_blankline_debug*
With bang (IndentBlanklineToggle!) toggles globally
==============================================================================
5. CHANGELOG *indent-blankline-changelog*
6. CHANGELOG *indent-blankline-changelog*
2.11.0
* Add |g:indent_blankline_show_current_context_start_on_current_line|
2.10.6
* Update example setup in the readme and docs
2.10.5
* Run refresh without autocmds
* Check that the window is valid before returning to it after refresh
2.10.4
* Remove `nocombine` from |hl-IndentBlanklineContextStart| again..
2.10.3
* Fix context start highlight column for files indent with tab
* Fix context start highlight on lines with no indent
2.10.2
* Apply context start highlight after indentation
2.10.1
* Remove `nocombine` from |hl-IndentBlanklineContextStart|
2.10.0
* Add |g:indent_blankline_show_current_context_start|
* Add |hl-IndentBlanklineContextStart|
2.9.3
* Fix indent cache for scrolling
* Fix documentation tags
2.9.2
* Fix refresh argument types for 0.5
2.9.1
* Fix horizontal scroll update
2.9.0
* Add |g:indent_blankline_context_char|
* Add |g:indent_blankline_context_char_list|
2.8.0
* Add |IndentBlanklineRefreshScroll|
2.7.0
* Add support for 0 width |g:indent_blankline_char|
2.6.4
* Remove memo from `find_indent`, it made the performance worse
2.6.3
* Fix issue when calling setup more than once
2.6.2
* Memoize the find indent function
* Run init on VimEnter to initialize indents in all open windows
* Run init on plugin load to work with lazy loading
2.6.1
* Wait until buffer is loaded before doing anything
2.6.0
* Add |g:indent_blankline_context_pattern_highlight|
2.5.7
* Update the README to not overwrite all listchars
* Handle listchars without a tab character
2.5.6
* Fix trailing space for blanklines
2.5.5
* Fix typo in readme
* Fix initialization of |g:indent_blankline_space_char_blankline_highlight_list|
* Refactor `find_indent`
2.5.4
* Fix wrong indent for empty lines with only extra
2.5.3
* Remove old reference to `indent_blankline_space_char`
2.5.2
* Fix background highlight example
2.5.1
* Only load treesitter libs if needed
2.5.0
* Add |g:indent_blankline_max_indent_increase|
2.4.0
* Remove `indent_blankline_respect_list`
* Add |g:indent_blankline_disable_with_nolist|
2.3.0
* Add |g:indent_blankline_respect_list| option
2.2.2
* Remove old vimscript code
2.2.1
* Fix first indent on a line with whitespace less than the current shift
width
2.2.0
* Correctly display listchars under the indent guides
Huge thanks to @Daxtorim
* Remove options:
`indent_blankline_space_char` - listchars is used to get the correct space
character
2.1.4
* Fix race condition in `is_indent_blankline_enabled`
2.1.3
* Refresh on |CompleteChanged|
2.1.2
* Fix lazy loading
2.1.1
* Fix bug were setup function is not run
2.1.0
* Added setup function
* Added buffer variables
* Fix horizontal scroll
2.0.1
* Fix typo in docs
2.0.0
* Complete lua rewrite
@ -571,7 +844,7 @@ g:indent_blankline_debug *g:indent_blankline_debug*
* First release
==============================================================================
6. LICENSE *indent-blankline-license*
7. LICENSE *indent-blankline-license*
The MIT Licence
http://www.opensource.org/licenses/mit-license.php

View File

@ -1,12 +1,15 @@
local M = {}
M.refresh = function(bang)
M.refresh = function(bang, scroll)
scroll = scroll or false
if bang then
local win = vim.api.nvim_get_current_win()
vim.cmd [[windo call indent_blankline#Refresh()]]
vim.api.nvim_set_current_win(win)
vim.cmd(string.format([[noautocmd windo call indent_blankline#Refresh(v:%s)]], tostring(scroll)))
if vim.api.nvim_win_is_valid(win) then
vim.api.nvim_set_current_win(win)
end
else
vim.cmd [[call indent_blankline#Refresh()]]
vim.cmd(string.format([[call indent_blankline#Refresh(v:%s)]], tostring(scroll)))
end
end
@ -14,7 +17,7 @@ M.enable = function(bang)
if bang then
vim.g.indent_blankline_enabled = true
local win = vim.api.nvim_get_current_win()
vim.cmd [[windo call indent_blankline#Refresh()]]
vim.cmd [[noautocmd windo call indent_blankline#Refresh()]]
vim.api.nvim_set_current_win(win)
else
vim.b.indent_blankline_enabled = true

View File

@ -1,5 +1,3 @@
local ts_status, ts_query = pcall(require, "nvim-treesitter.query")
local ts_status, ts_indent = pcall(require, "nvim-treesitter.indent")
local utils = require "indent_blankline/utils"
local M = {}
@ -8,149 +6,417 @@ local space_char_highlight = "IndentBlanklineSpaceChar"
local space_char_blankline_highlight = "IndentBlanklineSpaceCharBlankline"
local context_highlight = "IndentBlanklineContextChar"
M.setup = function()
vim.g.indent_blankline_namespace = vim.api.nvim_create_namespace("indent_blankline")
M.init = function()
if not vim.g.indent_blankline_namespace then
vim.g.indent_blankline_namespace = vim.api.nvim_create_namespace "indent_blankline"
end
utils.reset_highlights()
require("indent_blankline.commands").refresh(true)
end
local refresh = function()
M.setup = function(options)
if options == nil then
options = {}
end
local o = utils.first_not_nil
vim.g.indent_blankline_char = o(options.char, vim.g.indent_blankline_char, vim.g.indentLine_char, "")
vim.g.indent_blankline_char_list = o(
options.char_list,
vim.g.indent_blankline_char_list,
vim.g.indentLine_char_list
)
vim.g.indent_blankline_context_char = o(
options.context_char,
vim.g.indent_blankline_context_char,
vim.g.indent_blankline_char
)
vim.g.indent_blankline_context_char_list = o(options.context_char_list, vim.g.indent_blankline_context_char_list)
vim.g.indent_blankline_char_highlight_list = o(
options.char_highlight_list,
vim.g.indent_blankline_char_highlight_list
)
vim.g.indent_blankline_space_char_highlight_list = o(
options.space_char_highlight_list,
vim.g.indent_blankline_space_char_highlight_list
)
vim.g.indent_blankline_space_char_blankline = o(
options.space_char_blankline,
vim.g.indent_blankline_space_char_blankline,
" "
)
vim.g.indent_blankline_space_char_blankline_highlight_list = o(
options.space_char_blankline_highlight_list,
vim.g.indent_blankline_space_char_blankline_highlight_list,
options.space_char_highlight_list,
vim.g.indent_blankline_space_char_highlight_list
)
vim.g.indent_blankline_indent_level = o(options.indent_level, vim.g.indent_blankline_indent_level, 20)
vim.g.indent_blankline_enabled = o(options.enabled, vim.g.indent_blankline_enabled, true)
vim.g.indent_blankline_disable_with_nolist = o(
options.disable_with_nolist,
vim.g.indent_blankline_disable_with_nolist,
false
)
vim.g.indent_blankline_filetype = o(options.filetype, vim.g.indent_blankline_filetype, vim.g.indentLine_fileType)
vim.g.indent_blankline_filetype_exclude = o(
options.filetype_exclude,
vim.g.indent_blankline_filetype_exclude,
vim.g.indentLine_fileTypeExclude
)
vim.g.indent_blankline_bufname_exclude = o(
options.bufname_exclude,
vim.g.indent_blankline_bufname_exclude,
vim.g.indentLine_bufNameExclude
)
vim.g.indent_blankline_buftype_exclude = o(
options.buftype_exclude,
vim.g.indent_blankline_buftype_exclude,
vim.g.indentLine_bufTypeExclude
)
vim.g.indent_blankline_viewport_buffer = o(options.viewport_buffer, vim.g.indent_blankline_viewport_buffer, 10)
vim.g.indent_blankline_use_treesitter = o(options.use_treesitter, vim.g.indent_blankline_use_treesitter, false)
vim.g.indent_blankline_max_indent_increase = o(
options.max_indent_increase,
vim.g.indent_blankline_max_indent_increase,
options.indent_level,
vim.g.indent_blankline_indent_level
)
vim.g.indent_blankline_show_first_indent_level = o(
options.show_first_indent_level,
vim.g.indent_blankline_show_first_indent_level,
true
)
vim.g.indent_blankline_show_trailing_blankline_indent = o(
options.show_trailing_blankline_indent,
vim.g.indent_blankline_show_trailing_blankline_indent,
true
)
vim.g.indent_blankline_show_end_of_line = o(
options.show_end_of_line,
vim.g.indent_blankline_show_end_of_line,
false
)
vim.g.indent_blankline_show_foldtext = o(options.show_foldtext, vim.g.indent_blankline_show_foldtext, true)
vim.g.indent_blankline_show_current_context = o(
options.show_current_context,
vim.g.indent_blankline_show_current_context,
false
)
vim.g.indent_blankline_show_current_context_start = o(
options.show_current_context_start,
vim.g.indent_blankline_show_current_context_start,
false
)
vim.g.indent_blankline_show_current_context_start_on_current_line = o(
options.show_current_context_start_on_current_line,
vim.g.indent_blankline_show_current_context_start_on_current_line,
true
)
vim.g.indent_blankline_context_highlight_list = o(
options.context_highlight_list,
vim.g.indent_blankline_context_highlight_list
)
vim.g.indent_blankline_context_patterns = o(
options.context_patterns,
vim.g.indent_blankline_context_patterns,
{ "class", "function", "method" }
)
vim.g.indent_blankline_context_pattern_highlight = o(
options.context_pattern_highlight,
vim.g.indent_blankline_context_pattern_highlight
)
vim.g.indent_blankline_strict_tabs = o(options.strict_tabs, vim.g.indent_blankline_strict_tabs, false)
vim.g.indent_blankline_disable_warning_message = o(
options.disable_warning_message,
vim.g.indent_blankline_disable_warning_message,
false
)
vim.g.indent_blankline_debug = o(options.debug, vim.g.indent_blankline_debug, false)
if vim.g.indent_blankline_show_current_context then
vim.cmd [[
augroup IndentBlanklineContextAutogroup
autocmd!
autocmd CursorMoved * IndentBlanklineRefresh
augroup END
]]
end
vim.g.__indent_blankline_setup_completed = true
end
local refresh = function(scroll)
local v = utils.get_variable
local bufnr = vim.api.nvim_get_current_buf()
if not vim.api.nvim_buf_is_loaded(bufnr) then
return
end
if
not utils.is_indent_blankline_enabled(
vim.b.indent_blankline_enabled,
vim.g.indent_blankline_enabled,
v "indent_blankline_disable_with_nolist",
vim.opt.list:get(),
vim.bo.filetype,
vim.g.indent_blankline_filetype,
vim.g.indent_blankline_filetype_exclude,
v "indent_blankline_filetype" or {},
v "indent_blankline_filetype_exclude" or {},
vim.bo.buftype,
vim.g.indent_blankline_buftype_exclude,
vim.g.indent_blankline_bufname_exclude,
vim.fn["bufname"]("")
v "indent_blankline_buftype_exclude" or {},
v "indent_blankline_bufname_exclude" or {},
vim.fn["bufname"] ""
)
then
then
if vim.b.__indent_blankline_active then
vim.schedule_wrap(utils.clear_buf_indent)(bufnr)
end
vim.b.__indent_blankline_active = false
return
else
vim.b.__indent_blankline_active = true
end
local bufnr = vim.api.nvim_get_current_buf()
local offset = math.max(vim.fn.line("w0") - 1 - vim.g.indent_blankline_viewport_buffer, 0)
local range =
math.min(vim.fn.line("w$") + vim.g.indent_blankline_viewport_buffer, vim.api.nvim_buf_line_count(bufnr))
local win_start = vim.fn.line "w0"
local win_end = vim.fn.line "w$"
local offset = math.max(win_start - 1 - v "indent_blankline_viewport_buffer", 0)
local win_view = vim.fn.winsaveview()
local left_offset = win_view.leftcol
local lnum = win_view.lnum
local left_offset_s = tostring(left_offset)
local range = math.min(win_end + v "indent_blankline_viewport_buffer", vim.api.nvim_buf_line_count(bufnr))
if not vim.b.__indent_blankline_ranges then
vim.b.__indent_blankline_ranges = {}
end
if scroll then
local updated_range
if vim.b.__indent_blankline_ranges[left_offset_s] then
local blankline_ranges = vim.b.__indent_blankline_ranges[left_offset_s]
local need_to_update = true
-- find a candidate that could contain the window
local idx_candidate = utils.binary_search_ranges(blankline_ranges, { win_start, win_end })
local candidate_start, candidate_end = unpack(blankline_ranges[idx_candidate])
-- check if the current window is contained or if a new range needs to be created
if candidate_start <= win_start then
if candidate_end >= win_end then
need_to_update = false
else
table.insert(blankline_ranges, idx_candidate + 1, { offset, range })
end
else
table.insert(blankline_ranges, idx_candidate, { offset, range })
end
if not need_to_update then
return
end
-- merge ranges and update the variable, strategies are: contains or extends
updated_range = utils.merge_ranges(blankline_ranges)
else
updated_range = { { offset, range } }
end
-- we can't assign directly to a table key, so we update the reference to the variable
local new_ranges = vim.b.__indent_blankline_ranges
new_ranges[left_offset_s] = updated_range
vim.b.__indent_blankline_ranges = new_ranges
else
vim.b.__indent_blankline_ranges = { [left_offset_s] = { { offset, range } } }
end
local lines = vim.api.nvim_buf_get_lines(bufnr, offset, range, false)
local char = vim.g.indent_blankline_char
local char_list = vim.g.indent_blankline_char_list
local char_highlight_list = vim.g.indent_blankline_char_highlight_list
local space_char_highlight_list = vim.g.indent_blankline_space_char_highlight_list
local space_char_blankline_highlight_list = vim.g.indent_blankline_space_char_blankline_highlight_list
local space_char = vim.g.indent_blankline_space_char
local space_char_blankline = vim.g.indent_blankline_space_char_blankline
local max_indent_level = vim.g.indent_blankline_indent_level
local char = v "indent_blankline_char"
local char_list = v "indent_blankline_char_list" or {}
local context_char = v "indent_blankline_context_char"
local context_char_list = v "indent_blankline_context_char_list" or {}
local char_highlight_list = v "indent_blankline_char_highlight_list" or {}
local space_char_highlight_list = v "indent_blankline_space_char_highlight_list" or {}
local space_char_blankline_highlight_list = v "indent_blankline_space_char_blankline_highlight_list" or {}
local space_char_blankline = v "indent_blankline_space_char_blankline"
local list_chars = {}
local no_tab_character = false
-- No need to check for disable_with_nolist as this part would never be executed if "true" && nolist
if vim.opt.list:get() then
-- list is set, get listchars
local tab_characters
local space_character = vim.opt.listchars:get().space or " "
if vim.opt.listchars:get().tab then
-- tab characters can be any UTF-8 character, Lua 5.1 cannot handle this without external libraries
tab_characters = vim.fn.split(vim.opt.listchars:get().tab, "\\zs")
else
no_tab_character = true
tab_characters = { "^", "I" }
end
list_chars = {
space_char = space_character,
trail_char = vim.opt.listchars:get().trail or space_character,
lead_char = vim.opt.listchars:get().lead or space_character,
tab_char_start = tab_characters[1] or space_character,
tab_char_fill = tab_characters[2] or space_character,
tab_char_end = tab_characters[3],
eol_char = vim.opt.listchars:get().eol,
}
else
-- nolist is set, replace all listchars with empty space
list_chars = {
space_char = " ",
trail_char = " ",
lead_char = " ",
tab_char_start = " ",
tab_char_fill = " ",
tab_char_end = nil,
eol_char = nil,
}
end
local max_indent_level = v "indent_blankline_indent_level"
local max_indent_increase = v "indent_blankline_max_indent_increase"
local expandtab = vim.bo.expandtab
local use_ts_indent = vim.g.indent_blankline_use_treesitter and ts_status and ts_query.has_indents(vim.bo.filetype)
local first_indent = vim.g.indent_blankline_show_first_indent_level
local trail_indent = vim.g.indent_blankline_show_trailing_blankline_indent
local end_of_line = vim.g.indent_blankline_show_end_of_line
local end_of_line_char = vim.fn["indent_blankline#helper#GetListChar"]("eol", "")
local strict_tabs = vim.g.indent_blankline_strict_tabs
local foldtext = vim.g.indent_blankline_show_foldtext
local use_ts_indent = false
local ts_indent
if v "indent_blankline_use_treesitter" then
local ts_query_status, ts_query = pcall(require, "nvim-treesitter.query")
local ts_indent_status
ts_indent_status, ts_indent = pcall(require, "nvim-treesitter.indent")
use_ts_indent = ts_query_status and ts_indent_status and ts_query.has_indents(vim.bo.filetype)
end
local first_indent = v "indent_blankline_show_first_indent_level"
local trail_indent = v "indent_blankline_show_trailing_blankline_indent"
local end_of_line = v "indent_blankline_show_end_of_line"
local strict_tabs = v "indent_blankline_strict_tabs"
local foldtext = v "indent_blankline_show_foldtext"
local tabs = vim.bo.shiftwidth == 0 or not expandtab
local space = utils._if(tabs, vim.bo.tabstop, vim.bo.shiftwidth)
local shiftwidth = utils._if(tabs, utils._if(no_tab_character, 2, vim.bo.tabstop), vim.bo.shiftwidth)
local context_highlight_list = vim.g.indent_blankline_context_highlight_list
local context_status, context_start, context_end = false, 0, 0
if vim.g.indent_blankline_show_current_context then
context_status, context_start, context_end = utils.get_current_context(vim.g.indent_blankline_context_patterns)
local context_highlight_list = v "indent_blankline_context_highlight_list" or {}
local context_pattern_highlight = v "indent_blankline_context_pattern_highlight" or {}
local context_status, context_start, context_end, context_pattern = false, 0, 0, nil
local show_current_context_start = v "indent_blankline_show_current_context_start"
local show_current_context_start_on_current_line = v "indent_blankline_show_current_context_start_on_current_line"
if v "indent_blankline_show_current_context" then
context_status, context_start, context_end, context_pattern = utils.get_current_context(
v "indent_blankline_context_patterns"
)
end
local get_virtual_text = function(indent, extra, blankline, context_active, context_indent)
local virtual_text = {}
for i = 1, math.min(math.max(indent, 0), max_indent_level) do
local space_count = space
local context = context_active and context_indent == i
if i ~= 1 or first_indent then
space_count = space_count - 1
table.insert(
virtual_text,
{
utils._if(
i == 1 and blankline and end_of_line and #end_of_line_char > 0,
end_of_line_char,
local get_virtual_text =
function(indent, extra, blankline, context_active, context_indent, prev_indent, virtual_string)
local virtual_text = {}
local current_left_offset = left_offset
local local_max_indent_level = math.min(max_indent_level, prev_indent + max_indent_increase)
for i = 1, math.min(math.max(indent, 0), local_max_indent_level) do
local space_count = shiftwidth
local context = context_active and context_indent == i
local show_indent_char = (i ~= 1 or first_indent) and char ~= ""
local show_context_indent_char = context and (i ~= 1 or first_indent) and context_char ~= ""
local show_end_of_line_char = i == 1 and blankline and end_of_line and list_chars["eol_char"]
local show_indent_or_eol_char = show_indent_char or show_context_indent_char or show_end_of_line_char
if show_indent_or_eol_char then
space_count = space_count - 1
if current_left_offset > 0 then
current_left_offset = current_left_offset - 1
else
table.insert(virtual_text, {
utils._if(
#char_list > 0,
utils.get_from_list(char_list, i - utils._if(not first_indent, 1, 0)),
char
)
),
utils._if(
context,
utils._if(
#context_highlight_list > 0,
utils.get_from_list(context_highlight_list, i),
context_highlight
show_end_of_line_char,
list_chars["eol_char"],
utils._if(
context,
utils.get_from_list(
context_char_list,
i - utils._if(not first_indent, 1, 0),
context_char
),
utils.get_from_list(char_list, i - utils._if(not first_indent, 1, 0), char)
)
),
utils._if(
#char_highlight_list > 0,
utils.get_from_list(char_highlight_list, i),
char_highlight
)
)
}
)
end
table.insert(
virtual_text,
{
utils._if(blankline, space_char_blankline, space_char):rep(space_count),
utils._if(
blankline,
context,
utils._if(
context_pattern_highlight[context_pattern],
context_pattern_highlight[context_pattern],
utils.get_from_list(context_highlight_list, i, context_highlight)
),
utils.get_from_list(char_highlight_list, i, char_highlight)
),
})
end
end
if current_left_offset > 0 then
local current_space_count = space_count
space_count = space_count - current_left_offset
current_left_offset = current_left_offset - current_space_count
end
if space_count > 0 then
-- ternary operator below in table.insert() doesn't work because it would evaluate each option regardless
local tmp_string
local index = 1 + (i - 1) * shiftwidth
if show_indent_or_eol_char then
if table.maxn(virtual_string) >= index + space_count then
-- first char was already set above
tmp_string = table.concat(virtual_string, "", index + 1, index + space_count)
end
else
if table.maxn(virtual_string) >= index + space_count - 1 then
tmp_string = table.concat(virtual_string, "", index, index + space_count - 1)
end
end
table.insert(virtual_text, {
utils._if(
#space_char_blankline_highlight_list > 0,
utils.get_from_list(space_char_blankline_highlight_list, i),
space_char_blankline_highlight
tmp_string,
tmp_string,
utils._if(blankline, space_char_blankline, list_chars["lead_char"]):rep(space_count)
),
utils._if(
#space_char_highlight_list > 0,
utils.get_from_list(space_char_highlight_list, i),
space_char_highlight
)
)
}
)
end
blankline,
utils.get_from_list(space_char_blankline_highlight_list, i, space_char_blankline_highlight),
utils.get_from_list(space_char_highlight_list, i, space_char_highlight)
),
})
end
end
if ((blankline or extra) and trail_indent) and (first_indent or #virtual_text > 0) then
local index = math.ceil(#virtual_text / 2) + 1
table.insert(
virtual_text,
{
local extra_context_active = context_active and context_indent == index
if
(char ~= "" or (extra_context_active and context_char ~= ""))
and ((blankline or extra) and trail_indent)
and (first_indent or #virtual_text > 0)
and current_left_offset < 1
and indent < local_max_indent_level
then
table.insert(virtual_text, {
utils._if(
#char_list > 0,
utils.get_from_list(char_list, index - utils._if(not first_indent, 1, 0)),
char
extra_context_active,
utils.get_from_list(context_char_list, index - utils._if(not first_indent, 1, 0), context_char),
utils.get_from_list(char_list, index - utils._if(not first_indent, 1, 0), char)
),
utils._if(
context_active and context_indent == index,
utils._if(
#context_highlight_list > 0,
utils.get_from_list(context_highlight_list, index),
context_highlight
),
utils._if(
#char_highlight_list > 0,
utils.get_from_list(char_highlight_list, index),
char_highlight
)
)
}
)
extra_context_active,
utils.get_from_list(context_highlight_list, index, context_highlight),
utils.get_from_list(char_highlight_list, index, char_highlight)
),
})
end
return virtual_text
end
return virtual_text
end
local prev_indent
local next_indent
local next_extra
local empty_line_counter = 0
@ -160,103 +426,177 @@ local refresh = function()
utils.clear_line_indent(bufnr, i + offset)
else
local async
async =
vim.loop.new_async(
function()
local blankline = lines[i]:len() == 0
local context_active = false
if context_status then
context_active = offset + i > context_start and offset + i <= context_end
end
async = vim.loop.new_async(function()
local blankline = lines[i]:len() == 0
local whitespace = string.match(lines[i], "^%s+") or ""
local only_whitespace = whitespace == lines[i]
local context_active = false
local context_first_line = false
if context_status then
context_active = offset + i > context_start and offset + i <= context_end
context_first_line = offset + i == context_start
end
if blankline and use_ts_indent then
vim.schedule_wrap(
function()
local indent = ts_indent.get_indent(i + offset)
if not indent or indent == 0 then
utils.clear_line_indent(bufnr, i + offset)
return
end
indent = indent / space
if offset + i == context_start then
context_indent = (indent or 0) + 1
end
if blankline and use_ts_indent then
vim.schedule_wrap(function()
local indent = ts_indent.get_indent(i + offset) or 0
utils.clear_line_indent(bufnr, i + offset)
local virtual_text =
get_virtual_text(indent, false, blankline, context_active, context_indent)
utils.clear_line_indent(bufnr, i + offset)
xpcall(
vim.api.nvim_buf_set_extmark,
utils.error_handler,
bufnr,
vim.g.indent_blankline_namespace,
i - 1 + offset,
0,
{virt_text = virtual_text, virt_text_pos = "overlay", hl_mode = "combine"}
)
end
)()
return async:close()
end
local indent, extra
if not blankline then
indent, extra = utils.find_indent(lines[i], space, strict_tabs)
elseif empty_line_counter > 0 then
empty_line_counter = empty_line_counter - 1
indent = next_indent
extra = next_extra
else
if i == #lines then
indent = 0
extra = false
else
local j = i + 1
while (j < #lines and lines[j]:len() == 0) do
j = j + 1
empty_line_counter = empty_line_counter + 1
end
indent, extra = utils.find_indent(lines[j], space, strict_tabs)
end
next_indent = indent
next_extra = extra
end
if offset + i == context_start then
context_indent = (indent or 0) + 1
end
if not indent or indent == 0 then
vim.schedule_wrap(utils.clear_line_indent)(bufnr, i + offset)
return async:close()
end
local virtual_text = get_virtual_text(indent, extra, blankline, context_active, context_indent)
vim.schedule_wrap(
function()
utils.clear_line_indent(bufnr, i + offset)
if
context_first_line
and show_current_context_start
and (show_current_context_start_on_current_line or lnum ~= context_start)
then
xpcall(
vim.api.nvim_buf_set_extmark,
utils.error_handler,
bufnr,
vim.g.indent_blankline_namespace,
i - 1 + offset,
0,
{virt_text = virtual_text, virt_text_pos = "overlay", hl_mode = "combine"}
context_start - 1,
#whitespace,
{
end_col = #lines[i],
hl_group = "IndentBlanklineContextStart",
priority = 10000,
}
)
end
)()
if indent == 0 then
return
end
indent = indent / shiftwidth
if context_first_line then
context_indent = indent + 1
end
local virtual_text = get_virtual_text(
indent,
false,
blankline,
context_active,
context_indent,
max_indent_level,
{}
)
xpcall(
vim.api.nvim_buf_set_extmark,
utils.error_handler,
bufnr,
vim.g.indent_blankline_namespace,
i - 1 + offset,
0,
{ virt_text = virtual_text, virt_text_pos = "overlay", hl_mode = "combine" }
)
end)()
return async:close()
end
)
local indent, extra
local virtual_string = {}
if not blankline then
indent, extra, virtual_string = utils.find_indent(
whitespace,
only_whitespace,
shiftwidth,
strict_tabs,
list_chars
)
elseif empty_line_counter > 0 then
empty_line_counter = empty_line_counter - 1
indent = next_indent
extra = next_extra
else
if i == #lines then
indent = 0
extra = false
else
local j = i + 1
while j < #lines and lines[j]:len() == 0 do
j = j + 1
empty_line_counter = empty_line_counter + 1
end
local j_whitespace = string.match(lines[j], "^%s+")
local j_only_whitespace = j_whitespace == lines[j]
indent, extra, _ = utils.find_indent(
j_whitespace,
j_only_whitespace,
shiftwidth,
strict_tabs,
list_chars
)
end
next_indent = indent
next_extra = extra
end
if context_first_line then
context_indent = indent + 1
end
vim.schedule_wrap(utils.clear_line_indent)(bufnr, i + offset)
if
context_first_line
and show_current_context_start
and (show_current_context_start_on_current_line or lnum ~= context_start)
then
vim.schedule_wrap(function()
xpcall(
vim.api.nvim_buf_set_extmark,
utils.error_handler,
bufnr,
vim.g.indent_blankline_namespace,
context_start - 1,
#whitespace,
{
end_col = #lines[i],
hl_group = "IndentBlanklineContextStart",
priority = 10000,
}
)
end)()
end
if indent == 0 and #virtual_string == 0 and not extra then
prev_indent = 0
return async:close()
end
if not prev_indent or indent + utils._if(extra, 1, 0) <= prev_indent + max_indent_increase then
prev_indent = indent
end
local virtual_text = get_virtual_text(
indent,
extra,
blankline,
context_active,
context_indent,
prev_indent - utils._if(trail_indent, 0, 1),
virtual_string
)
vim.schedule_wrap(function()
xpcall(
vim.api.nvim_buf_set_extmark,
utils.error_handler,
bufnr,
vim.g.indent_blankline_namespace,
i - 1 + offset,
0,
{ virt_text = virtual_text, virt_text_pos = "overlay", hl_mode = "combine" }
)
end)()
return async:close()
end)
async:send()
end
end
end
M.refresh = function()
xpcall(refresh, utils.error_handler)
M.refresh = function(scroll)
xpcall(refresh, utils.error_handler, scroll)
end
return M

View File

@ -1,71 +1,72 @@
local M = {}
M.memo =
setmetatable(
{
put = function(cache, params, result)
local node = cache
for i = 1, #params do
local param = vim.inspect(params[i])
node.children = node.children or {}
node.children[param] = node.children[param] or {}
node = node.children[param]
end
node.result = result
end,
get = function(cache, params)
local node = cache
for i = 1, #params do
local param = vim.inspect(params[i])
node = node.children and node.children[param]
if not node then
return nil
end
end
return node.result
M.memo = setmetatable({
put = function(cache, params, result)
local node = cache
for i = 1, #params do
local param = vim.inspect(params[i])
node.children = node.children or {}
node.children[param] = node.children[param] or {}
node = node.children[param]
end
},
{
__call = function(memo, func)
local cache = {}
node.result = result
end,
get = function(cache, params)
local node = cache
for i = 1, #params do
local param = vim.inspect(params[i])
node = node.children and node.children[param]
if not node then
return nil
end
end
return node.result
end,
}, {
__call = function(memo, func)
local cache = {}
return function(...)
local params = {...}
local result = memo.get(cache, params)
if not result then
result = {func(...)}
memo.put(cache, params, result)
end
return unpack(result)
return function(...)
local params = { ... }
local result = memo.get(cache, params)
if not result then
result = { func(...) }
memo.put(cache, params, result)
end
return unpack(result)
end
}
)
end,
})
M.error_handler = function(err)
if vim.g.indent_blankline_debug then
vim.cmd("echohl Error")
vim.cmd "echohl Error"
vim.cmd('echomsg "' .. err .. '"')
vim.cmd("echohl None")
vim.cmd "echohl None"
end
end
M.is_indent_blankline_enabled =
M.memo(
M.is_indent_blankline_enabled = M.memo(
function(
b_enabled,
g_enabled,
disable_with_nolist,
opt_list,
filetype,
filetype_include,
filetype_exclude,
buftype,
buftype_exclude,
bufname_exclude,
bufname)
bufname
)
if b_enabled ~= nil then
return b_enabled
end
if g_enabled == 0 then
if g_enabled ~= true then
return false
end
if disable_with_nolist and not opt_list then
return false
end
@ -104,7 +105,14 @@ M.clear_line_indent = function(buf, lnum)
xpcall(vim.api.nvim_buf_clear_namespace, M.error_handler, buf, vim.g.indent_blankline_namespace, lnum - 1, lnum)
end
M.get_from_list = function(list, i)
M.clear_buf_indent = function(buf)
xpcall(vim.api.nvim_buf_clear_namespace, M.error_handler, buf, vim.g.indent_blankline_namespace, 0, -1)
end
M.get_from_list = function(list, i, default)
if not list or #list == 0 then
return default
end
return list[((i - 1) % #list) + 1]
end
@ -116,27 +124,56 @@ M._if = function(bool, a, b)
end
end
M.find_indent = function(line, shiftwidth, strict_tabs)
M.find_indent = function(whitespace, only_whitespace, shiftwidth, strict_tabs, list_chars)
local indent = 0
local spaces = 0
for ch in line:gmatch(".") do
if ch == " " then
if strict_tabs and indent == 0 and spaces ~= 0 then
return 0, false
local tab_width
local virtual_string = {}
if whitespace then
for ch in whitespace:gmatch "." do
if ch == "\t" then
if strict_tabs and indent == 0 and spaces ~= 0 then
return 0, false, {}
end
indent = indent + math.floor(spaces / shiftwidth) + 1
spaces = 0
-- replace dynamic-width tab with fixed-width string (ta..ab)
tab_width = shiftwidth - table.maxn(virtual_string) % shiftwidth
-- check if tab_char_end is set, see :help listchars
if list_chars["tab_char_end"] then
if tab_width == 1 then
table.insert(virtual_string, list_chars["tab_char_end"])
else
table.insert(virtual_string, list_chars["tab_char_start"])
for _ = 1, (tab_width - 2) do
table.insert(virtual_string, list_chars["tab_char_fill"])
end
table.insert(virtual_string, list_chars["tab_char_end"])
end
else
table.insert(virtual_string, list_chars["tab_char_start"])
for _ = 1, (tab_width - 1) do
table.insert(virtual_string, list_chars["tab_char_fill"])
end
end
else
if strict_tabs and indent ~= 0 then
-- return early when no more tabs are found
return indent, true, virtual_string
end
if only_whitespace then
-- if the entire line is only whitespace use trail_char instead of lead_char
table.insert(virtual_string, list_chars["trail_char"])
else
table.insert(virtual_string, list_chars["lead_char"])
end
spaces = spaces + 1
end
indent = indent + math.floor(spaces / shiftwidth) + 1
spaces = 0
elseif ch == " " then
if strict_tabs and indent ~= 0 then
return indent, true
end
spaces = spaces + 1
else
break
end
end
indent = indent + math.floor(spaces / shiftwidth)
return indent, spaces % shiftwidth ~= 0
return indent + math.floor(spaces / shiftwidth), table.maxn(virtual_string) % shiftwidth ~= 0, virtual_string
end
M.get_current_context = function(type_patterns)
@ -149,7 +186,7 @@ M.get_current_context = function(type_patterns)
if node_type:find(rgx) then
local node_start, _, node_end, _ = cursor_node:range()
if node_start ~= node_end then
return true, node_start + 1, node_end + 1
return true, node_start + 1, node_end + 1, rgx
end
node_start, node_end = nil, nil
end
@ -161,38 +198,116 @@ M.get_current_context = function(type_patterns)
end
M.reset_highlights = function()
local whitespace_highlight = vim.fn.synIDtrans(vim.fn.hlID("Whitespace"))
local label_highlight = vim.fn.synIDtrans(vim.fn.hlID("Label"))
local whitespace_highlight = vim.fn.synIDtrans(vim.fn.hlID "Whitespace")
local label_highlight = vim.fn.synIDtrans(vim.fn.hlID "Label")
local whitespace_fg = {
vim.fn.synIDattr(whitespace_highlight, "fg", "gui"),
vim.fn.synIDattr(whitespace_highlight, "fg", "cterm")
vim.fn.synIDattr(whitespace_highlight, "fg", "cterm"),
}
local label_fg = {
vim.fn.synIDattr(label_highlight, "fg", "gui"),
vim.fn.synIDattr(label_highlight, "fg", "cterm")
vim.fn.synIDattr(label_highlight, "fg", "cterm"),
}
for highlight_name, highlight in pairs(
{
IndentBlanklineChar = whitespace_fg,
IndentBlanklineSpaceChar = whitespace_fg,
IndentBlanklineSpaceCharBlankline = whitespace_fg,
IndentBlanklineContextChar = label_fg
}
) do
for highlight_name, highlight in pairs {
IndentBlanklineChar = whitespace_fg,
IndentBlanklineSpaceChar = whitespace_fg,
IndentBlanklineSpaceCharBlankline = whitespace_fg,
IndentBlanklineContextChar = label_fg,
IndentBlanklineContextStart = label_fg,
} do
local current_highlight = vim.fn.synIDtrans(vim.fn.hlID(highlight_name))
if vim.fn.synIDattr(current_highlight, "fg") == "" and vim.fn.synIDattr(current_highlight, "bg") == "" then
vim.cmd(
string.format(
"highlight %s guifg=%s ctermfg=%s gui=nocombine cterm=nocombine",
highlight_name,
M._if(highlight[1] == "", "NONE", highlight[1]),
M._if(highlight[2] == "", "NONE", highlight[2])
if
vim.fn.synIDattr(current_highlight, "fg") == ""
and vim.fn.synIDattr(current_highlight, "bg") == ""
and vim.fn.synIDattr(current_highlight, "sp") == ""
then
if highlight_name == "IndentBlanklineContextStart" then
vim.cmd(
string.format(
"highlight %s guisp=%s gui=underline cterm=underline",
highlight_name,
M._if(highlight[1] == "", "NONE", highlight[1])
)
)
)
else
vim.cmd(
string.format(
"highlight %s guifg=%s ctermfg=%s gui=nocombine cterm=nocombine",
highlight_name,
M._if(highlight[1] == "", "NONE", highlight[1]),
M._if(highlight[2] == "", "NONE", highlight[2])
)
)
end
end
end
end
M.first_not_nil = function(...)
for _, value in pairs { ... } do
return value
end
end
M.get_variable = function(key)
if vim.b[key] ~= nil then
return vim.b[key]
end
if vim.t[key] ~= nil then
return vim.t[key]
end
return vim.g[key]
end
M.merge_ranges = function(ranges)
local merged_ranges = { { unpack(ranges[1]) } }
for i = 2, #ranges do
local current_end = merged_ranges[#merged_ranges][2]
local next_start, next_end = unpack(ranges[i])
if current_end >= next_start - 1 then
if current_end < next_end then
merged_ranges[#merged_ranges][2] = next_end
end
else
table.insert(merged_ranges, { next_start, next_end })
end
end
return merged_ranges
end
M.binary_search_ranges = function(ranges, target_range)
local exact_match = false
local idx_start = 1
local idx_end = #ranges
local idx_mid
local range_start
local target_start = target_range[1]
while idx_start < idx_end do
idx_mid = math.ceil((idx_start + idx_end) / 2)
range_start = ranges[idx_mid][1]
if range_start == target_start then
exact_match = true
break
elseif range_start < target_start then
idx_start = idx_mid -- it's important to make the low-end inclusive
else
idx_end = idx_mid - 1
end
end
-- if we don't have an exact match, choose the smallest index
if not exact_match then
idx_mid = idx_start
end
return idx_mid
end
return M

View File

@ -4,37 +4,6 @@ if exists('g:loaded_indent_blankline') || !has('nvim-0.5.0')
endif
let g:loaded_indent_blankline = 1
let g:indent_blankline_char = get(g:, 'indent_blankline_char', get(g:, 'indentLine_char', '|'))
let g:indent_blankline_char_list = get(g:, 'indent_blankline_char_list', get(g:, 'indentLine_char_list', []))
let g:indent_blankline_char_highlight_list = get(g:, 'indent_blankline_char_highlight_list', [])
let g:indent_blankline_space_char = get(g:, 'indent_blankline_space_char', indent_blankline#helper#GetListChar('space', ' '))
let g:indent_blankline_space_char_highlight_list = get(g:, 'indent_blankline_space_char_highlight_list', [])
let g:indent_blankline_space_char_blankline = get(g:, 'indent_blankline_space_char_blankline', g:indent_blankline_space_char)
let g:indent_blankline_space_char_blankline_highlight_list = get(g:, 'indent_blankline_space_char_blankline_highlight_list', g:indent_blankline_space_char_highlight_list)
let g:indent_blankline_indent_level = get(g:, 'indent_blankline_indent_level', get(g:, 'indentLine_indentLevel', 20))
let g:indent_blankline_enabled = get(g:, 'indent_blankline_enabled', get(g:, 'indentLine_enabled', v:true))
let g:indent_blankline_filetype = get(g:, 'indent_blankline_filetype', get(g:, 'indentLine_fileType', []))
let g:indent_blankline_filetype_exclude = get(g:, 'indent_blankline_filetype_exclude', get(g:, 'indentLine_fileTypeExclude', []))
let g:indent_blankline_bufname_exclude = get(g:, 'indent_blankline_bufname_exclude', get(g:, 'indentLine_bufNameExclude', []))
let g:indent_blankline_buftype_exclude = get(g:, 'indent_blankline_buftype_exclude', get(g:, 'indentLine_bufTypeExclude', []))
let g:indent_blankline_viewport_buffer = get(g:, 'indent_blankline_viewport_buffer', 10)
let g:indent_blankline_use_treesitter = get(g:, 'indent_blankline_use_treesitter', v:false)
let g:indent_blankline_debug = get(g:, 'indent_blankline_debug', v:false)
let g:indent_blankline_disable_warning_message = get(g:, 'indent_blankline_disable_warning_message', v:false)
let g:indent_blankline_show_first_indent_level = get(g:, 'indent_blankline_show_first_indent_level', v:true)
let g:indent_blankline_show_trailing_blankline_indent = get(g:, 'indent_blankline_show_trailing_blankline_indent', v:true)
let g:indent_blankline_show_end_of_line = get(g:, 'indent_blankline_show_end_of_line', v:false)
let g:indent_blankline_show_foldtext = get(g:, 'indent_blankline_show_foldtext', v:true)
let g:indent_blankline_show_current_context = get(g:, 'indent_blankline_show_current_context', v:false)
let g:indent_blankline_context_highlight_list = get(g:, 'indent_blankline_context_highlight_list', [])
let g:indent_blankline_context_patterns = get(g:, 'indent_blankline_context_patterns', ['class', 'function', 'method'])
let g:indent_blankline_strict_tabs = get(g:, 'indent_blankline_strict_tabs', v:false)
lua require("indent_blankline").setup()
function s:try(cmd)
try
execute a:cmd
@ -44,30 +13,29 @@ function s:try(cmd)
endfunction
command! -bang IndentBlanklineRefresh call s:try('lua require("indent_blankline.commands").refresh("<bang>" == "!")')
command! -bang IndentBlanklineRefreshScroll call s:try('lua require("indent_blankline.commands").refresh("<bang>" == "!", true)')
command! -bang IndentBlanklineEnable call s:try('lua require("indent_blankline.commands").enable("<bang>" == "!")')
command! -bang IndentBlanklineDisable call s:try('lua require("indent_blankline.commands").disable("<bang>" == "!")')
command! -bang IndentBlanklineToggle call s:try('lua require("indent_blankline.commands").toggle("<bang>" == "!")')
function s:IndentBlanklineInit()
if exists(':IndentLinesEnable') && !g:indent_blankline_disable_warning_message
echohl Error
echom 'indent-blankline does not require IndentLine anymore, please remove it.'
echohl None
endif
IndentBlanklineRefresh!
endfunction
if exists(':IndentLinesEnable') && !g:indent_blankline_disable_warning_message
echohl Error
echom 'indent-blankline does not require IndentLine anymore, please remove it.'
echohl None
endif
if !exists('g:__indent_blankline_setup_completed')
lua require("indent_blankline").setup {}
endif
lua require("indent_blankline").init()
augroup IndentBlanklineAutogroup
autocmd!
autocmd OptionSet shiftwidth,tabstop,expandtab IndentBlanklineRefresh
autocmd FileChangedShellPost,TextChanged,TextChangedI,WinScrolled,BufWinEnter,Filetype * IndentBlanklineRefresh
autocmd VimEnter * call s:IndentBlanklineInit()
autocmd OptionSet list,shiftwidth,tabstop,expandtab IndentBlanklineRefresh
autocmd FileChangedShellPost,TextChanged,TextChangedI,CompleteChanged,BufWinEnter,Filetype * IndentBlanklineRefresh
autocmd WinScrolled * IndentBlanklineRefreshScroll
autocmd ColorScheme * lua require("indent_blankline.utils").reset_highlights()
autocmd VimEnter * lua require("indent_blankline").init()
augroup END
if g:indent_blankline_show_current_context
augroup IndentBlanklineContextAutogroup
autocmd!
autocmd CursorMoved * IndentBlanklineRefresh
augroup END
endif

View File

@ -0,0 +1,4 @@
line_endings = "Unix"
indent_type = "Spaces"
indent_width = 4
no_call_parentheses = true