Skip to content

Commit

Permalink
Support tree-sitter highlight for provider preview (#1019)
Browse files Browse the repository at this point in the history
* Try identifying the buffer language from filetype

* Skip serde if Vec::is_empty

* Minor refactoring: merge syntax and fname into VimSyntaxInfo

* provider: implement tree-sitter highlight for preview

Close #532

* Remove todo!()

* Remove coloreyre

* Minor refactorings

* Add more language support

* clippy fixes

* Update to rust 1.74

* clippy fixes

* Rename to sublime-syntax-color-scheme

* Skip serialization if VimSyntaxInfo::is_empty()

* Add TODO

* Fix typo

* Define g:clap_provider_clap_actions if g:clap_plugin_experimental is on

* Nits

* docs

* Add ClapAction command
  • Loading branch information
liuchengxu authored Nov 18, 2023
1 parent 9fa56f9 commit 64423a4
Show file tree
Hide file tree
Showing 23 changed files with 568 additions and 248 deletions.
126 changes: 66 additions & 60 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ tokio = { version = "1.31", features = ["rt"] }

cli = { path = "crates/cli" }
upgrade = { path = "crates/upgrade" }
color-eyre = "0.6.2"

[build-dependencies]
built = { package = "built", version = "0.6", features = ["git2"] }
Expand Down
17 changes: 16 additions & 1 deletion autoload/clap/helper.vim
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,22 @@ function! clap#helper#complete(ArgLead, CmdLine, P) abort
if !exists('s:autoload_providers')
let s:autoload_providers = map(split(globpath(&runtimepath, 'autoload/clap/provider/*.vim'), "\n"), 'fnamemodify(v:val, ":t:r")')
endif
return filter(uniq(sort(s:autoload_providers + keys(g:clap#provider_alias) + registered)), 'v:val =~# "^".a:ArgLead')
if !exists('s:user_providers')
let s:user_providers = map(clap#provider#providers#get_user_defined(), 'split(v:val, ":")[0]')
endif
return filter(uniq(sort(s:autoload_providers + s:user_providers + keys(g:clap#provider_alias) + registered)), 'v:val =~# "^".a:ArgLead')
endfunction

function! clap#helper#complete_actions(A, L, P) abort
if !exists('g:clap_actions')
echoerr '`g:clap_actions` not found'
return []
endif
if empty(a:A)
return g:clap_actions
else
return filter(g:clap_actions, printf('v:val =~ "^%s"', a:A))
endif
endfunction

function! clap#helper#echo_message(msg) abort
Expand Down
31 changes: 22 additions & 9 deletions autoload/clap/highlighter.vim
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,12 @@ else

" lnum is 0-based.
function! s:add_ts_highlight_at(bufnr, lnum, col, length, hl_group) abort
call prop_add(a:lnum+1, a:col+1, {'length': a:length, 'type': a:hl_group, 'bufnr': a:bufnr})
try
call prop_add(a:lnum+1, a:col+1, {'length': a:length, 'type': a:hl_group, 'bufnr': a:bufnr})
catch
" Not sure why, but I keep run into error: Invalid line number, neovim
" does not have this issue.
endtry
endfunction

function! s:add_display_highlights(hl_lines) abort
Expand Down Expand Up @@ -148,6 +153,21 @@ function! clap#highlighter#highlight_line(bufnr, lnum, token_highlights) abort
endfor
endfunction

" Highlight a list of lines.
function! clap#highlighter#add_sublime_highlights(bufnr, line_highlights) abort
for [lnum, line_highlight] in a:line_highlights
call clap#highlighter#highlight_line(a:bufnr, lnum, line_highlight)
endfor
endfunction

function! clap#highlighter#disable_tree_sitter(bufnr) abort
if has('nvim')
call nvim_buf_clear_namespace(a:bufnr, s:tree_sitter_ns_id, 0, -1)
elseif !empty(s:ts_types)
call prop_remove({ 'types': s:ts_types, 'all': v:true, 'bufnr': a:bufnr } )
endif
endfunction

function! clap#highlighter#add_ts_highlights(bufnr, to_replace_line_ranges, highlights) abort
if has('nvim')
" All old highlights need to be replaced.
Expand All @@ -163,7 +183,7 @@ function! clap#highlighter#add_ts_highlights(bufnr, to_replace_line_ranges, high
call prop_remove({ 'types': s:ts_types, 'all': v:true, 'bufnr': a:bufnr } )
else
for [start, end] in a:to_replace_line_ranges
call prop_remove({ 'types': s:ts_types, 'all': v:true, 'bufnr': a:bufnr }, start + 1, end - 1)
call prop_remove({ 'types': s:ts_types, 'all': v:true, 'bufnr': a:bufnr }, start, end)
endfor
endif
endif
Expand All @@ -181,12 +201,5 @@ function! clap#highlighter#add_ts_highlights(bufnr, to_replace_line_ranges, high
endfor
endfunction

" Highlight a list of lines.
function! clap#highlighter#highlight_lines(bufnr, line_highlights) abort
for [lnum, line_highlight] in a:line_highlights
call clap#highlighter#highlight_line(a:bufnr, lnum, line_highlight)
endfor
endfunction

let &cpoptions = s:save_cpo
unlet s:save_cpo
40 changes: 23 additions & 17 deletions autoload/clap/provider/providers.vim
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,28 @@ function! s:providers.sink(selected) abort
call timer_start(0, {-> clap#_for(provider)})
endfunction

function! clap#provider#providers#get_user_defined() abort
let user_providers = []
" `description` is required, otherwise we can't distinguish whether the variable name
" like `g:clap_provider_yanks_history` is a name of some provider or merely a control
" variable of a provider.
let maybe_user_var_providers = filter(keys(g:), 'v:val =~# "^clap_provider_"')
for maybe_var_provider in maybe_user_var_providers
try
let evaled = eval('g:'.maybe_var_provider)
if type(evaled) == v:t_dict
let provider_id = matchstr(maybe_var_provider, 'clap_provider_\zs\(.*\)')
let description = get(evaled, 'description', '')
call add(user_providers, provider_id.': '.description)
endif
catch
echom 'Failed to fetch user defined clap providers: '.v:exception
return user_providers
endtry
endfor
return user_providers
endfunction

function! s:providers.source() abort
if !exists('s:global_source')
let s:global_source = []
Expand All @@ -31,23 +53,7 @@ function! s:providers.source() abort
endif
endfor

" `description` is required, otherwise we can't distinguish whether the variable name
" like `g:clap_provider_yanks_history` is a name of some provider or merely a control
" variable of a provider.
let maybe_user_var_providers = filter(keys(g:), 'v:val =~# "^clap_provider_"')
for maybe_var_provider in maybe_user_var_providers
try
let evaled = eval('g:'.maybe_var_provider)
if type(evaled) == v:t_dict
let provider_id = matchstr(maybe_var_provider, 'clap_provider_\zs\(.*\)')
let description = get(evaled, 'description', '')
call add(s:global_source, provider_id.': '.description)
endif
catch
echom 'Failed to fetch user defined clap providers: 'v:exception
return g:global_source
endtry
endfor
call extend(s:global_source, clap#provider#providers#get_user_defined())
endif
return s:global_source
endfunction
Expand Down
17 changes: 11 additions & 6 deletions autoload/clap/state.vim
Original file line number Diff line number Diff line change
Expand Up @@ -114,18 +114,23 @@ function! clap#state#render_preview(preview) abort
call g:clap.preview.show(['Error occurred while showing the preview:', v:exception, '', string(a:preview.lines)])
return
endtry
if has_key(a:preview, 'syntax')
call g:clap.preview.set_syntax(a:preview.syntax)
elseif has_key(a:preview, 'fname')
call g:clap.preview.set_syntax(clap#ext#into_filetype(a:preview.fname))
elseif has_key(a:preview, 'syntax_highlights')
for [lnum, line_highlight] in a:preview.syntax_highlights
if has_key(a:preview, 'sublime_syntax_highlights')
for [lnum, line_highlight] in a:preview.sublime_syntax_highlights
try
call clap#highlighter#highlight_line(g:clap.preview.bufnr, lnum, line_highlight)
catch
" Ignore any potential errors as the line might be truncated.
endtry
endfor
elseif has_key(a:preview, 'tree_sitter_highlights')
call clap#highlighter#add_ts_highlights(g:clap.preview.bufnr, [], a:preview.tree_sitter_highlights)
elseif has_key(a:preview, 'vim_syntax_info')
let vim_syntax_info = a:preview.vim_syntax_info
if !empty(vim_syntax_info.syntax)
call g:clap.preview.set_syntax(vim_syntax_info.syntax)
elseif !empty(vim_syntax_info.fname)
call g:clap.preview.set_syntax(clap#ext#into_filetype(vim_syntax_info.fname))
endif
endif
call clap#preview#highlight_header()

Expand Down
2 changes: 1 addition & 1 deletion crates/maple_core/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ pub struct ProviderConfig {
///
/// If the theme is not found and the engine is [`HighlightEngine::SublimeSyntax`],
/// the default theme (`Visual Studio Dark+`) will be used.
pub preview_color_scheme: Option<String>,
pub sublime_syntax_color_scheme: Option<String>,

/// Whether to share the input history of each provider.
pub share_input_history: bool,
Expand Down
Loading

0 comments on commit 64423a4

Please sign in to comment.