Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add icon support for proj_tags #461

Merged
merged 10 commits into from
Jun 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ CHANGELOG
### Added

- Implement async preview for `blines`, `tags` and `proj_tags` provider. ([#457](https://github.com/liuchengxu/vim-clap/pull/457))
- Add icon support for `proj_tags` provider. ([#461](https://github.com/liuchengxu/vim-clap/pull/461))
- Add `g:clap_preview_size` for configuring the number of preview lines. ([#444](https://github.com/liuchengxu/vim-clap/pull/444))
- Add `g:clap_provider_buffers_cur_tab_only`. ([#439](https://github.com/liuchengxu/vim-clap/pull/439))

Expand Down
25 changes: 20 additions & 5 deletions autoload/clap.vim
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,8 @@ if !s:has_features
endif

let s:cur_dir = fnamemodify(resolve(expand('<sfile>:p')), ':h')
let s:builtin_providers = map(
\ split(globpath(s:cur_dir.'/clap/provider', '*'), '\n'),
\ 'fnamemodify(v:val, '':t:r'')'
\ )

let g:clap#autoload_dir = s:cur_dir
let g:clap#builtin_providers = s:builtin_providers

let g:__t_func = 0
let g:__t_string = 1
Expand Down Expand Up @@ -87,6 +82,16 @@ let g:clap_multi_selection_warning_silent = get(g:, 'clap_multi_selection_warnin

let g:clap_popup_border = get(g:, 'clap_popup_border', 'rounded')

function! clap#builtin_providers() abort
if !exists('s:builtin_providers')
let s:builtin_providers = map(
\ split(globpath(s:cur_dir.'/clap/provider', '*'), '\n'),
\ 'fnamemodify(v:val, '':t:r'')'
\ )
endif
return s:builtin_providers
endfunction

function! s:inject_default_impl_is_ok(provider_info) abort
let provider_info = a:provider_info

Expand Down Expand Up @@ -280,7 +285,17 @@ function! clap#for(provider_id_or_alias) abort

call clap#selection#init()

" This flag is used to slience the autocmd events for NeoVim, e.g., on_typed.
" Vim doesn't have these issues as it uses noautocmd in most cases.
"
" Without this flag, the on_typed hook can be triggered when relaunching
" some provider. To reproduce:
" 1. :Clap
" 2. Choose proj_tags
" 3. proj_tags ontyped hook will be triggered.
let g:__clap_open_win_pre = v:true
call g:clap.open_win()
let g:__clap_open_win_pre = v:false
endfunction

if !exists('g:clap')
Expand Down
5 changes: 4 additions & 1 deletion autoload/clap/api.vim
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function! clap#api#has_externalfilter() abort
\ || has_key(g:clap.context, 'externalfilter')
endfunction

let s:has_no_icons = ['blines', 'proj_tags']
let s:has_no_icons = ['blines']

" Returns the original full line with icon if g:clap_enable_icon is on given
" the lnum of display buffer.
Expand Down Expand Up @@ -341,6 +341,9 @@ function! s:init_provider() abort

" After you have typed something
function! provider.on_typed() abort
if get(g:, '__clap_open_win_pre', v:false)
return
endif
try
call self._().on_typed()
catch
Expand Down
3 changes: 3 additions & 0 deletions autoload/clap/client.vim
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ let s:should_send_source_fpath = ['tags', 'blines']
function! clap#client#send_request_on_move() abort
let s:req_id += 1
let curline = g:clap.display.getcurline()
if empty(curline)
return
endif
let msg = {
\ 'id': s:req_id,
\ 'session_id': s:session_id,
Expand Down
3 changes: 1 addition & 2 deletions autoload/clap/debugging.vim
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ function! s:get_global_variables() abort
call filter(variable_list, 'v:val !~# ''^clap#icon#''')
call filter(variable_list, 'v:val !~# ''clap#floating_win''')
call filter(variable_list, 'v:val !~# ''clap#display_win''')
call filter(variable_list, 'v:val !~# ''clap#builtin_providers''')
call filter(variable_list, 'v:val !~# ''clap#themes#''')

call sort(variable_list)
Expand All @@ -31,7 +30,7 @@ endfunction

function! s:get_third_party_providers() abort
let all_providers = split(globpath(&runtimepath, 'autoload/clap/provider/*.vim'), "\n")
let third_party_providers = filter(all_providers, 'index(g:clap#builtin_providers, v:val) != -1')
let third_party_providers = filter(all_providers, 'index(clap#builtin_providers(), v:val) != -1')
return third_party_providers
endfunction

Expand Down
10 changes: 8 additions & 2 deletions autoload/clap/filter/async/dyn.vim
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,14 @@ endfunction
function! clap#filter#async#dyn#from_tempfile(tempfile) abort
let s:last_query = g:clap.input.get()

if g:clap_enable_icon && index(['files', 'git_files'], g:clap.provider.id) > -1
let enable_icon_opt = ['--icon-painter=File']
if g:clap_enable_icon
if index(['files', 'git_files'], g:clap.provider.id) > -1
let enable_icon_opt = ['--icon-painter=File']
elseif 'proj_tags' ==# g:clap.provider.id
let enable_icon_opt = ['--icon-painter=ProjTags']
else
let enable_icon_opt = []
endif
else
let enable_icon_opt = []
endif
Expand Down
5 changes: 5 additions & 0 deletions autoload/clap/maple.vim
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,11 @@ endfunction

function! clap#maple#tags_forerunner_command() abort
let global_opt = has_key(g:clap.context, 'no-cache') ? ['--no-cache'] : []

if g:clap_enable_icon
call add(global_opt, '--icon-painter=ProjTags')
endif

return [s:maple_bin] + global_opt + ['tags', '', clap#rooter#working_dir(), '--forerunner']
endfunction

Expand Down
38 changes: 38 additions & 0 deletions crates/icon/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,44 @@ pub static EXACTMATCH_ICON_TABLE: &[(&str, char)] = &[
("readme", ''),
("rust-toolchain", ''),
];
pub static TAGKIND_ICON_TABLE: &[(&str, char)] = &[
("augroup", 'פּ'),
("class", ''),
("const", ''),
("constant", ''),
("default", ''),
("enum", ''),
("enumerator", ''),
("field", ''),
("fields", ''),
("func", ''),
("function", ''),
("functions", ''),
("implementation", ''),
("interface", ''),
("macro", ''),
("macros", ''),
("map", 'פּ'),
("member", ''),
("method", ''),
("module", ''),
("modules", ''),
("namespace", ''),
("package", ''),
("packages", ''),
("property", '襁'),
("struct", ''),
("subroutine", '羚'),
("target", ''),
("type", ''),
("typeParameter", ''),
("typedef", ''),
("types", ''),
("union", '鬒'),
("var", ''),
("variable", ''),
("variables", ''),
];

pub fn bsearch_icon_table(c: &str, table: &[(&str, char)]) -> Option<usize> {
table.binary_search_by(|&(key, _)| key.cmp(&c)).ok()
Expand Down
22 changes: 21 additions & 1 deletion crates/icon/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod constants;

pub use constants::{bsearch_icon_table, EXACTMATCH_ICON_TABLE, EXTENSION_ICON_TABLE};
pub use constants::*;

use std::path::Path;
use structopt::clap::arg_enum;
Expand Down Expand Up @@ -62,6 +62,14 @@ pub fn prepend_filer_icon(path: &Path, line: &str) -> String {
format!("{} {}", icon_for_filer(path), line)
}

fn get_tagkind_icon(line: &str) -> Icon {
pattern::extract_proj_tags_kind(line)
.and_then(|kind| {
bsearch_icon_table(kind, TAGKIND_ICON_TABLE).map(|idx| TAGKIND_ICON_TABLE[idx].1)
})
.unwrap_or(DEFAULT_ICON)
}

#[inline]
fn grep_icon_for(line: &str) -> Icon {
pattern::extract_fpath_from_grep_line(line)
Expand All @@ -80,6 +88,7 @@ arg_enum! {
pub enum IconPainter {
File,
Grep,
ProjTags
}
}

Expand All @@ -89,6 +98,7 @@ impl IconPainter {
match *self {
Self::File => prepend_icon(raw_str),
Self::Grep => prepend_grep_icon(raw_str),
Self::ProjTags => format!("{} {}", get_tagkind_icon(raw_str), raw_str),
}
}

Expand All @@ -97,6 +107,7 @@ impl IconPainter {
match *self {
Self::File => icon_for(text),
Self::Grep => grep_icon_for(text),
Self::ProjTags => get_tagkind_icon(text),
}
}
}
Expand All @@ -121,4 +132,13 @@ mod tests {
}
}
}

#[test]
fn test_tagkind_icon() {
let line = r#"Blines:19 [implementation@crates/maple_cli/src/cmd/blines.rs] impl Blines {"#;
let icon_for = |kind: &str| {
bsearch_icon_table(kind, TAGKIND_ICON_TABLE).map(|idx| TAGKIND_ICON_TABLE[idx].1)
};
assert_eq!(icon_for("implementation").unwrap(), get_tagkind_icon(line));
}
}
38 changes: 38 additions & 0 deletions crates/icon/tagkind_map.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"func": "\uf794",
"function": "\uf794",
"functions": "\uf794",
"var": "\uf71b",
"variable": "\uf71b",
"variables": "\uf71b",
"const": "\uf888",
"constant": "\uf888",
"method": "\uf6a6",
"package": "\ue612",
"packages": "\ue612",
"enum": "\uf702",
"enumerator": "\uf702",
"module": "\uf136",
"modules": "\uf136",
"type": "\uf7fd",
"typedef": "\uf7fd",
"types": "\uf7fd",
"field": "\uf30b",
"fields": "\uf30b",
"macro": "\uf8a3",
"macros": "\uf8a3",
"map": "\ufb44",
"class": "\uf0e8",
"augroup": "\ufb44",
"struct": "\uf318",
"union": "\ufacd",
"member": "\uf02b",
"target": "\uf893",
"property": "\ufab6",
"interface": "\uf7fe",
"namespace": "\uf475",
"subroutine": "\uf9af",
"implementation": "\uf776",
"typeParameter": "\uf278",
"default": "\uf29c"
}
9 changes: 9 additions & 0 deletions crates/icon/update_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@
lines.append('pub static EXACTMATCH_ICON_TABLE: &[(&str, char)] = &[%s];' %
joined_tuples)

with open('tagkind_map.json', 'r') as f:
disordered = json.load(f)
sorted_dict = {k: disordered[k] for k in sorted(disordered)}

joined_tuples = ','.join(
map(lambda kv: '("%s", \'%s\')' % (kv[0], kv[1]), sorted_dict.items()))
lines.append('pub static TAGKIND_ICON_TABLE: &[(&str, char)] = &[%s];' %
joined_tuples)

lines.append('''
pub fn bsearch_icon_table(c: &str, table: &[(&str, char)]) ->Option<usize> {
table.binary_search_by(|&(key, _)| key.cmp(&c)).ok()
Expand Down
2 changes: 1 addition & 1 deletion crates/maple_cli/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl Maple {
match self.command {
Cmd::Version | Cmd::Upgrade(_) => unreachable!(),
Cmd::Helptags(helptags) => helptags.run()?,
Cmd::Tags(tags) => tags.run(self.no_cache)?,
Cmd::Tags(tags) => tags.run(self.no_cache, self.icon_painter)?,
Cmd::RPC => {
stdio_server::run_forever(std::io::BufReader::new(std::io::stdin()));
}
Expand Down
12 changes: 9 additions & 3 deletions crates/maple_cli/src/cmd/tags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,20 @@ fn create_tags_cache(args: &[&str], dir: &PathBuf) -> Result<(PathBuf, usize)> {
}

impl Tags {
pub fn run(&self, no_cache: bool) -> Result<()> {
pub fn run(&self, no_cache: bool, icon_painter: Option<icon::IconPainter>) -> Result<()> {
// In case of passing an invalid icon-painter option.
let icon_painter = icon_painter.map(|_| icon::IconPainter::ProjTags);

let mut cmd_args = BASE_TAGS_ARGS.to_vec();

let lang = if let Some(ref languages) = self.languages {
format!("--languages={}", languages)
} else {
String::from("")
};

cmd_args.push(&lang);

if self.forerunner {
let (cache, total) = if no_cache {
create_tags_cache(&cmd_args, &self.dir)?
Expand All @@ -113,7 +119,7 @@ impl Tags {
} else {
create_tags_cache(&cmd_args, &self.dir)?
};
send_response_from_cache(&cache, total, SendResponse::Json, None);
send_response_from_cache(&cache, total, SendResponse::Json, icon_painter);
return Ok(());
} else {
crate::cmd::filter::dynamic::dyn_fuzzy_filter_and_rank(
Expand All @@ -122,7 +128,7 @@ impl Tags {
None,
Some(30),
None,
None,
icon_painter,
LineSplitter::TagNameOnly,
)?;
}
Expand Down
6 changes: 6 additions & 0 deletions crates/pattern/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ pub fn extract_proj_tags(line: &str) -> Option<(usize, &str)> {
Some((lnum, fpath))
}

pub fn extract_proj_tags_kind(line: &str) -> Option<&str> {
let cap = PROJ_TAGS.captures(line)?;
let kind = cap.get(3).map(|x| x.as_str())?;
Some(kind)
}

pub fn extract_buf_tags_lnum(line: &str) -> Option<usize> {
let cap = BUFFER_TAGS.captures(line)?;
cap.get(1)
Expand Down
2 changes: 1 addition & 1 deletion crates/stdio_server/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub fn initialize_global(msg: Message) {
}

pub fn has_icon_support(provider_id: &str) -> bool {
provider_id != "proj_tags" && provider_id != "blines"
provider_id != "blines"
}

pub fn should_skip_leading_icon(provider_id: &str) -> bool {
Expand Down
4 changes: 3 additions & 1 deletion crates/upgrade/src/github.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use super::{REPO, USER};
use anyhow::{anyhow, Result};
use curl::easy::{Easy, List};
use serde::{Deserialize, Serialize};

const USER: &str = "liuchengxu";
const REPO: &str = "vim-clap";

#[derive(Serialize, Deserialize, Debug)]
pub struct RemoteRelease {
pub tag_name: String,
Expand Down
3 changes: 0 additions & 3 deletions crates/upgrade/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ mod github;
use anyhow::{anyhow, Context, Result};
use structopt::StructOpt;

const USER: &str = "liuchengxu";
const REPO: &str = "vim-clap";

/// This command is only invoked when user uses the prebuilt binary, more specifically, exe in
/// vim-clap/bin/maple.
#[derive(StructOpt, Debug, Clone)]
Expand Down
Loading