1
1
let s: use_vim_textprops = has (' textprop' ) && ! has (' nvim' )
2
2
let s: use_nvim_highlight = exists (' *nvim_buf_add_highlight' ) && has (' nvim' )
3
+ let s: textprop_cache = ' vim-lsp-semantic-cache'
3
4
4
5
if s: use_nvim_highlight
5
6
let s: namespace_id = nvim_create_namespace (' vim-lsp-semantic' )
@@ -44,7 +45,7 @@ function! lsp#ui#vim#semantic#handle_semantic(server, data) abort
44
45
for l: info in a: data [' response' ][' params' ][' lines' ]
45
46
let l: linenr = l: info [' line' ]
46
47
let l: tokens = has_key (l: info , ' tokens' ) ? l: info [' tokens' ] : ' '
47
- call s: add_highlight (a: server , l: bufnr , l: linenr , s: tokens_to_hl_info ( l: tokens) )
48
+ call s: add_highlight (a: server , l: bufnr , l: linenr , l: tokens )
48
49
endfor
49
50
endfunction
50
51
@@ -62,28 +63,61 @@ function! s:init_highlight(server, buf) abort
62
63
63
64
silent ! call prop_type_add (s: get_textprop_name (a: server , l: scope_idx ), {' bufnr' : a: buf , ' highlight' : l: hl , ' combine' : v: true })
64
65
endfor
66
+
67
+ silent ! call prop_type_add (s: textprop_cache , {' bufnr' : a: buf })
65
68
endif
66
69
67
70
call setbufvar (a: buf , ' lsp_did_semantic_setup' , 1 )
68
71
endfunction
69
72
70
- function ! s: add_highlight (server, buf , line , highlights) abort
73
+ function ! s: hash (str) abort
74
+ let l: hash = 1
75
+
76
+ for l: char in split (a: str , ' \zs' )
77
+ let l: hash = (l: hash * 31 + char2nr (l: char )) % 2147483647
78
+ endfor
79
+
80
+ return l: hash
81
+ endfunction
82
+
83
+ function ! s: add_highlight (server, buf , line , tokens) abort
84
+ " Return quickly if the tokens for this line are already set correctly,
85
+ " according to the cached tokens.
86
+ " This only works for Vim at the moment, for Neovim, we need extended
87
+ " marks.
88
+ if s: use_vim_textprops
89
+ let l: props = filter (prop_list (a: line + 1 , {' bufnr' : a: buf }), {idx, prop - > prop[' type' ] == # s: textprop_cache })
90
+ let l: hash = s: hash (a: tokens )
91
+
92
+ if ! empty (l: props ) && l: props [0 ][' id' ] == l: hash
93
+ " No changes for this line, so just return.
94
+ return
95
+ endif
96
+ endif
97
+
71
98
let l: scopes = lsp#ui#vim#semantic#get_scopes (a: server )
99
+ let l: highlights = s: tokens_to_hl_info (a: tokens )
72
100
73
101
if s: use_vim_textprops
74
102
" Clear text properties from the previous run
75
103
for l: scope_idx in range (len (l: scopes ))
76
104
call prop_remove ({' bufnr' : a: buf , ' type' : s: get_textprop_name (a: server , l: scope_idx ), ' all' : v: true }, a: line + 1 )
77
105
endfor
78
106
79
- for l: highlight in a: highlights
107
+ " Clear cache from previous run
108
+ call prop_remove ({' bufnr' : a: buf , ' type' : s: textprop_cache , ' all' : v: true }, a: line + 1 )
109
+
110
+ " Add textprop for cache
111
+ call prop_add (a: line + 1 , 1 , {' bufnr' : a: buf , ' type' : s: textprop_cache , ' id' : l: hash })
112
+
113
+ for l: highlight in l: highlights
80
114
call prop_add (a: line + 1 , l: highlight [' char' ] + 1 , { ' length' : l: highlight [' length' ], ' bufnr' : a: buf , ' type' : s: get_textprop_name (a: server , l: highlight [' scope' ])})
81
115
endfor
82
116
elseif s: use_nvim_highlight
83
117
" Clear text properties from the previous run
84
118
call nvim_buf_clear_namespace (a: buf , s: namespace_id , a: line , a: line + 1 )
85
119
86
- for l: highlight in a : highlights
120
+ for l: highlight in l : highlights
87
121
call nvim_buf_add_highlight (a: buf , s: namespace_id , s: get_hl_name (a: server , l: scopes [l: highlight [' scope' ]]), a: line , l: highlight [' char' ], l: highlight [' char' ] + l: highlight [' length' ])
88
122
endfor
89
123
endif
0 commit comments