Skip to content

Commit

Permalink
Use HashMap<usize, String> as LinesTruncatedMap (#443)
Browse files Browse the repository at this point in the history
* Use HashMap<VimLineNumber, OriginLine> for LinesTruncatedMap

* Rename to get_line_at()

* Fix test

* .

* Remove needless fuzzy-matcher dep

* Catch preview exception
  • Loading branch information
liuchengxu committed May 25, 2020
1 parent 75e9906 commit 9bfec30
Show file tree
Hide file tree
Showing 11 changed files with 77 additions and 57 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

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

34 changes: 13 additions & 21 deletions autoload/clap/api.vim
Expand Up @@ -34,21 +34,19 @@ function! clap#api#has_externalfilter() abort
\ || has_key(g:clap.context, 'externalfilter')
endfunction

function! clap#api#into_origin_line(possible_truncated_line) abort
if has_key(g:__clap_lines_truncated_map, a:possible_truncated_line)
return g:__clap_lines_truncated_map[a:possible_truncated_line]
endif
" Rebuild the complete line info with icon
if g:clap_enable_icon
let icon = a:possible_truncated_line[:3]
let real_cur_line = a:possible_truncated_line[4:]
else
let real_cur_line = a:possible_truncated_line
endif
if has_key(g:__clap_lines_truncated_map, real_cur_line)
return icon.g:__clap_lines_truncated_map[real_cur_line]
" Returns the original full line with icon if g:clap_enable_icon is on given
" the lnum of display buffer.
function! clap#api#get_origin_line_at(lnum) abort
if exists('g:__clap_lines_truncated_map') && has_key(g:__clap_lines_truncated_map, a:lnum)
let t_line = g:__clap_lines_truncated_map[a:lnum]
" NOTE: t_line[3] is not 100% right
if g:clap_enable_icon && t_line[3] !=# ' '
return getbufline(g:clap.display.bufnr, a:lnum)[0][:3] . t_line
else
return t_line
endif
else
return a:possible_truncated_line
return get(getbufline(g:clap.display.bufnr, a:lnum), 0, '')
endif
endfunction

Expand Down Expand Up @@ -218,13 +216,7 @@ function! s:init_display() abort
endfunction

function! display.getcurline() abort
let cur_line = get(getbufline(self.bufnr, g:__clap_display_curlnum), 0, '')
" g:__clap_lines_truncated_map can't store the truncated item with icon as the json_decode can fail.
if exists('g:__clap_lines_truncated_map')
return clap#api#into_origin_line(cur_line)
else
return cur_line
endif
return clap#api#get_origin_line_at(g:__clap_display_curlnum)
endfunction

function! display.deletecurline() abort
Expand Down
2 changes: 1 addition & 1 deletion autoload/clap/filter.vim
Expand Up @@ -53,7 +53,7 @@ if s:can_use_python
try
return clap#filter#sync#python#(a:query, a:candidates, winwidth(g:clap.display.winid), s:enable_icon(), s:content_filtering())
catch
call clap#helper#echo_error(v:exception)
call clap#helper#echo_error(v:exception.', throwpoint:'.v:throwpoint)
return clap#filter#sync#viml#(a:query, a:candidates)
endtry
endfunction
Expand Down
24 changes: 10 additions & 14 deletions autoload/clap/impl/on_move.vim
Expand Up @@ -10,14 +10,6 @@ let s:on_move_delay = get(g:, 'clap_on_move_delay', 300)
" Note: must use v:true/v:false for json_encode
let s:enable_icon = g:clap_enable_icon ? v:true : v:false

function! s:into_filename(line) abort
if g:clap_enable_icon
return a:line[4:]
else
return a:line
endif
endfunction

function! s:filer_handle(decoded) abort
if has_key(a:decoded, 'type') && a:decoded.type ==# 'preview'
if empty(a:decoded.lines)
Expand Down Expand Up @@ -47,18 +39,22 @@ function! clap#impl#on_move#daemon_handle(msg) abort
return
endif

if decoded.provider_id ==# 'filer'
call s:filer_handle(decoded)
if has_key(decoded, 'error')
call clap#helper#echo_error('[daemon_handle] '.decoded.error)
return
endif

if has_key(decoded, 'error')
echoerr decoded.error
if decoded.provider_id ==# 'filer'
call s:filer_handle(decoded)
return
endif

if has_key(decoded, 'lines')
call g:clap.preview.show(decoded.lines)
try
call g:clap.preview.show(decoded.lines)
catch
return
endtry
if has_key(decoded, 'fname')
call g:clap.preview.set_syntax(clap#ext#into_filetype(decoded.fname))
endif
Expand All @@ -72,7 +68,7 @@ endfunction

function! s:send_preview_request() abort
let s:req_id += 1
let curline = s:into_filename(g:clap.display.getcurline())
let curline = g:clap.display.getcurline()
let msg = json_encode({
\ 'id': s:req_id,
\ 'method': 'client.on_move',
Expand Down
2 changes: 1 addition & 1 deletion autoload/clap/provider/grep.vim
Expand Up @@ -163,7 +163,7 @@ function! s:grep_exit() abort
endfunction

function! s:matchlist(line, pattern) abort
if s:icon_appended
if s:icon_appended && a:line[3] ==# ' '
return matchlist(a:line, '^.* '.a:pattern)
else
return matchlist(a:line, '^'.a:pattern)
Expand Down
7 changes: 2 additions & 5 deletions autoload/clap/selection.vim
Expand Up @@ -12,10 +12,7 @@ function! clap#selection#get_sink_or_sink_star_params() abort
let selected = clap#sign#get()
if s:multi_select_enabled && !empty(selected)
let Sink = g:clap.provider.sink_star
let sink_args = map(selected, 'getbufline(g:clap.display.bufnr, v:val)[0]')
if exists('g:__clap_lines_truncated_map')
let sink_args = map(sink_args, 'clap#api#into_origin_line(v:val)')
endif
let sink_args = map(selected, 'clap#api#get_origin_line_at(v:val)')
else
let Sink = g:clap.provider.sink
let sink_args = g:clap.display.getcurline()
Expand All @@ -27,7 +24,7 @@ function! clap#selection#get_action_or_action_star_params() abort
let selected = clap#sign#get()
if len(selected) > 1
let Action = g:clap.provider._()['action*']
let action_args = map(selected, 'getbufline(g:clap.display.bufnr, v:val)[0]')
let action_args = map(selected, 'clap#api#get_origin_line_at(v:val)')
else
let Action = g:clap.provider._().action
let action_args = g:clap.display.getcurline()
Expand Down
1 change: 0 additions & 1 deletion crates/maple_cli/Cargo.toml
Expand Up @@ -21,7 +21,6 @@ structopt = "0.3"
bytecount = "0.6"
itertools = "0.9"
serde_json = "1.0"
fuzzy-matcher = "0.3.1"
crossbeam-channel = "0.4"
tokio = { version = "0.2.20", features = ["fs"] }
indicatif = "0.14.0"
Expand Down
9 changes: 4 additions & 5 deletions crates/maple_cli/src/cmd/filter/mod.rs
Expand Up @@ -5,8 +5,7 @@ pub use dynamic::dyn_fuzzy_filter_and_rank as dyn_run;
use anyhow::Result;
use fuzzy_filter::{fuzzy_filter_and_rank, subprocess, Algo, ContentFiltering, Source};
use icon::{IconPainter, ICON_LEN};
use printer::truncate_long_matched_lines;
use std::collections::HashMap;
use printer::{truncate_long_matched_lines, LinesTruncatedMap};
use std::path::PathBuf;
use structopt::StructOpt;

Expand Down Expand Up @@ -118,13 +117,13 @@ fn process_top_items<T>(
top_list: impl IntoIterator<Item = (String, T, Vec<usize>)>,
winwidth: usize,
icon_painter: Option<IconPainter>,
) -> (Vec<String>, Vec<Vec<usize>>, HashMap<String, String>) {
) -> (Vec<String>, Vec<Vec<usize>>, LinesTruncatedMap) {
let (truncated_lines, truncated_map) = truncate_long_matched_lines(top_list, winwidth, None);
let mut lines = Vec::with_capacity(top_size);
let mut indices = Vec::with_capacity(top_size);
if let Some(painter) = icon_painter {
for (text, _, idxs) in truncated_lines {
let iconized = if let Some(origin_text) = truncated_map.get(&text) {
for (idx, (text, _, idxs)) in truncated_lines.iter().enumerate() {
let iconized = if let Some(origin_text) = truncated_map.get(&(idx + 1)) {
format!("{} {}", painter.get_icon(origin_text), text)
} else {
painter.paint(&text)
Expand Down
14 changes: 13 additions & 1 deletion crates/maple_cli/src/cmd/rpc/types.rs
Expand Up @@ -42,20 +42,32 @@ impl TryFrom<Message> for PreviewEnv {
.and_then(|x| x.as_str())
.unwrap_or("Unknown provider id");

let enable_icon = msg
.params
.get("enable_icon")
.and_then(|x| x.as_bool())
.unwrap_or(false);

let cwd = String::from(
msg.params
.get("cwd")
.and_then(|x| x.as_str())
.unwrap_or("Missing cwd when deserializing into FilerParams"),
);

let fname = String::from(
let fname_with_icon = String::from(
msg.params
.get("curline")
.and_then(|x| x.as_str())
.unwrap_or("Missing fname when deserializing into FilerParams"),
);

let fname = if enable_icon {
fname_with_icon.chars().skip(2).collect()
} else {
fname_with_icon
};

let size = msg
.params
.get("preview_size")
Expand Down
25 changes: 20 additions & 5 deletions crates/printer/src/lib.rs
Expand Up @@ -2,8 +2,20 @@ use std::collections::HashMap;

pub const DOTS: &str = "..";

/// Map of truncated line to original line.
pub type LinesTruncatedMap = HashMap<String, String>;
/// Line number of Vim is 1-based.
pub type VimLineNumber = usize;

/// Map of truncated line number to original full line.
///
/// Can't use HashMap<String, String> since we can't tell the original lines in the following case:
///
/// //  ..{ version = "1.0", features = ["derive"] }
/// //  ..{ version = "1.0", features = ["derive"] }
/// //  ..{ version = "1.0", features = ["derive"] }
/// //  ..{ version = "1.0", features = ["derive"] }
///
pub type LinesTruncatedMap = HashMap<VimLineNumber, String>;

/// Tuple of (matched line text, filtering score, indices of matched elements)
pub type FuzzyMatchedLineInfo = (String, i64, Vec<usize>);

Expand Down Expand Up @@ -39,9 +51,11 @@ pub fn truncate_long_matched_lines<T>(
skipped: Option<usize>,
) -> (Vec<(String, T, Vec<usize>)>, LinesTruncatedMap) {
let mut truncated_map = HashMap::new();
let mut lnum = 0usize;
let lines = lines
.into_iter()
.map(|(line, score, indices)| {
lnum += 1;
if !indices.is_empty() {
let last_idx = indices.last().expect("indices are non-empty; qed");
if *last_idx > winwidth {
Expand Down Expand Up @@ -73,7 +87,7 @@ pub fn truncate_long_matched_lines<T>(
};
let offset = line_len - truncated.len();
let truncated_indices = indices.iter().map(|x| x - offset).collect::<Vec<_>>();
truncated_map.insert(truncated.clone(), line);
truncated_map.insert(lnum, line);
(truncated, score, truncated_indices)
} else {
(line, score, indices)
Expand Down Expand Up @@ -134,13 +148,14 @@ mod tests {

let (truncated_lines, truncated_map) =
truncate_long_matched_lines(ranked, winwidth, skipped);
for (truncated_line, _score, truncated_indices) in truncated_lines.iter() {
for (idx, (truncated_line, _score, truncated_indices)) in truncated_lines.iter().enumerate()
{
println!("truncated: {}", "-".repeat(winwidth));
println!(
"truncated: {}",
wrap_matches(&truncated_line, &truncated_indices)
);
println!("raw_line: {}", truncated_map.get(truncated_line).unwrap());
println!("raw_line: {}", truncated_map.get(&(idx + 1)).unwrap());
}
}

Expand Down
15 changes: 13 additions & 2 deletions pythonx/clap/fuzzymatch-rs/src/lib.rs
Expand Up @@ -55,8 +55,12 @@ fn substr_scorer(niddle: &str, haystack: &str) -> Option<(f64, Vec<usize>)> {
))
}

#[pyfunction]
/// Filter the candidates given query using the fzy algorithm
///
/// NOTE: TruncatedMap is ought to be HashMap<usize, String>,
/// but there is an issue when converting to call result to Vim Dict in python dynamic call,
/// therefore hereby has to use HashMap<String, String> instead.
#[pyfunction]
fn fuzzy_match(
query: &str,
candidates: Vec<String>,
Expand Down Expand Up @@ -98,7 +102,14 @@ fn fuzzy_match(
filtered.push(text);
}

Ok((indices, filtered, truncated_map))
Ok((
indices,
filtered,
truncated_map
.into_iter()
.map(|(k, v)| (k.to_string(), v))
.collect(),
))
}

/// This module is a python module implemented in Rust.
Expand Down

0 comments on commit 9bfec30

Please sign in to comment.