liuchengxu/vim-clap

`:Clap files --path <p>` should include `<p>` in it's output

fievel opened this issue · 6 comments

fievel commented

For example if you have a directory structure like this one:

<my dir>/src/mylib/a.cxx
<my dir>/inc/b.cxx

Vim CWD is <my dir>.

:Clap files --> lists:

src/mylib/a.cxx
inc/b.cxx

Everything look and works fine (preview, edit, fuzzy match).

Now, I would want to list only files in src (because in my dev environment the "editable" headers are in src but are copied by the build outside, I don't want to check everytime I open the right one).

As suggested in #987 comments: :Clap files --no-cwd --path src, list only one file in my basic example: mylib/a.cxx. It's what I want.

But now I cannot open or preview because it tries to open mylib/a.cxx relative path (= absolute: <my dir>/mylib/a.cxx) instead of src/mylib/a.cxx (= absolute: <my dir>/src/mylib/a.cxx).

IMHO :Clap files should include the path value in its output for it to work.

This worked with < 0.45.

Environment:

  • OS: Windows
  • vim-clap version: 0.45
  • Have you reproduced with a minimal vimrc: Yes (I use g:clap_disable_run_rooter = 1 but I tried with it set to 0)
  • Have you updated to the latest plugin version: Yes
  • Have you upgraded to/compiled the latest Rust binary: I use my own build of the latest version

Clap debug

            has ctags: Universal Ctags 5.9.0(787811b) (+json)
            has cargo: 1
            has maple: C:\Workdir\devtools\vimfiles\plugged\vim-clap/target/release/maple.exe
           maple info: version 0.1.45, compiled at: 2023-07-03 12:06:42.679091800 +02:00, built for x86_64-pc-windows-msvc by rustc 1.70.0 (90c541806 2023-05-31).

        rustc version: rustc 1.70.0 (90c541806 2023-05-31)

     Current FileType: cpp
Third Party Providers: []
       Global Options:
    let g:clap#autoload_dir = 'C:\Workdir\devtools\vimfiles\plugged\vim-clap\autoload'
    let g:clap#popup#display = {'shrink': function('352'), 'open': function('<SNR>159_create_display'), 'width': 104, 'shrink_if_undersize': function('351')}
    let g:clap#popup#preview = {'line_count': function('<SNR>158__line_count'), 'show': function('353'), 'hide': function('354'), 'clear': function('355'), 'add_highlight': function('357'), 'get_lines': function('<SNR>158__get_lines'), 'getbufvar': function('<SNR>158__getbufvar'), 'setbufvar_batch': function('<SNR>158__setbufvar_batch'), 'setbufvar': function('<SNR>158__setbufvar'), 'winid': 1012, 'win_is_valid': function('<SNR>158__win_is_valid'), 'goto_win': function('<SNR>158__goto_win'), 'set_syntax': function('356'), 'bufnr': 16}
    let g:clap#provider_alias = {'gfiles': 'git_files', 'hist:': 'command_history', 'hist/': 'search_history'}
    let g:clap_actions = ['open-config', 'generate-toc', 'update-toc', 'delete-toc']
    let g:clap_background_shadow_blend = 50
    let g:clap_disable_bottom_top = 0
    let g:clap_disable_matches_indicator = v:false
    let g:clap_disable_run_rooter = 1
    let g:clap_enable_background_shadow = v:false
    let g:clap_enable_debug = v:false
    let g:clap_enable_icon = 0
    let g:clap_forerunner_status_sign = {'done': '•', 'running': '!', 'using_cache': '*'}
    let g:clap_indicator_winid = 1013
    let g:clap_insert_mode_only = v:false
    let g:clap_multi_selection_warning_silent = 0
    let g:clap_no_matches_msg = 'NO MATCHES FOUND'
    let g:clap_open_action = {'ctrl-v': 'vsplit', 'ctrl-x': 'split', 'ctrl-t': 'tab split'}
    let g:clap_open_preview = 'always'
    let g:clap_popup_border = 'rounded'
    let g:clap_preview_direction = 'AUTO'
    let g:clap_preview_size = 5
    let g:clap_project_root_markers = ['.svn', '.svn/', '.git', '.git/', '.root', 'init.def']
    let g:clap_providers_relaunch_code = '@@'
    let g:clap_search_box_border_style = 'curve'
    let g:clap_search_box_border_symbols = {'nil': ['', ''], 'curve': ['', ''], 'arrow': ['', '']}
    let g:clap_spinner_winid = 1015
  Provider Variables:
                     []

This patch should fix the files provider for this partcular case. However, I'm still thinking about whether such a design is reasonable (--no-cwd --path [PATH]) and if there is a better straightforward way to satisfy the requirements.

diff --git a/autoload/clap/rooter.vim b/autoload/clap/rooter.vim
index 576eba2..517b241 100644
--- a/autoload/clap/rooter.vim
+++ b/autoload/clap/rooter.vim
@@ -41,8 +41,9 @@ endfunction

 function! s:run_from_target_dir(target_dir, Run, run_args) abort
   let save_cwd = getcwd()
+  let target_dir = type(a:target_dir) == v:t_list ? a:target_dir[0] : a:target_dir
   try
-    execute 'lcd' a:target_dir
+    execute 'lcd' target_dir
     let l:result = call(a:Run, [a:run_args])
   catch
     call clap#helper#echo_error(
@@ -55,7 +56,7 @@ function! s:run_from_target_dir(target_dir, Run, run_args) abort
   finally
     " If the sink function changes cwd intentionally? Then we
     " should not restore to the current cwd after executing the sink function.
-    if getcwd(winnr()) ==# a:target_dir
+    if getcwd(winnr()) ==# target_dir
       execute 'lcd' save_cwd
     endif
   endtry
diff --git a/crates/maple_core/src/stdio_server/provider/files.rs b/crates/maple_core/src/stdio_server/provider/files.rs
index 5362ece..747ddad 100644
--- a/crates/maple_core/src/stdio_server/provider/files.rs
+++ b/crates/maple_core/src/stdio_server/provider/files.rs
@@ -1,7 +1,9 @@
+use crate::paths::AbsPathBuf;
 use crate::stdio_server::provider::{ClapProvider, Context, SearcherControl};
 use anyhow::Result;
 use clap::Parser;
 use matcher::{Bonus, MatchScope};
+use serde_json::json;
 use std::path::PathBuf;
 use std::sync::atomic::AtomicBool;
 use std::sync::Arc;
@@ -108,8 +110,31 @@ impl FilesProvider {
 impl ClapProvider for FilesProvider {
     async fn on_initialize(&mut self, ctx: &mut Context) -> Result<()> {
         let query = ctx.vim.context_query_or_input().await?;
+        if self.args.base.no_cwd && !self.args.paths.is_empty() {
+            let new_working_dir = &self.args.paths[0];
+            if let Ok(path) = ctx.vim.expand(new_working_dir.to_string_lossy()).await {
+                let new_cwd = match AbsPathBuf::try_from(path.as_str()) {
+                    Ok(abs_path) => {
+                        ctx.cwd = abs_path.clone();
+                        abs_path
+                    }
+                    Err(_) => {
+                        ctx.cwd = ctx
+                            .cwd
+                            .join(path)
+                            .try_into()
+                            .expect("Failed to convert to absolute path");
+                        ctx.cwd.clone()
+                    }
+                };
+
+                ctx.vim.set_var("g:__clap_provider_cwd", json!([new_cwd]))?;
+            }
+        }
+
         // All files will be collected if query is empty
         self.process_query(query, ctx);
+
         Ok(())
     }
fievel commented

Thanks, I will test it. I think it's a usual workflow (at least some plugins that have same feature as :Clap files like fzf or ctrl-p have a similar feature).
Now an alternative maybe to add a way to specify on the command line a query:
Imagine having a feature like :Clap files --query src\ which will do something like this:
image
It's perhaps even more flexible.

--query is already supported in grep provider that I use a lot, :Clap grep --query=foo. However, it requires some more work to make it universally available, another reason to push --query for each provider :P, thanks for the idea.

fievel commented

Applied the patch and tested it and it seems to work. Thanks for this (I tried to fix it myself but well I'm c++ dev and I don't know rust sufficiently to find quickly a solution).
Indeed the query option as for grep would solve my workflow in a better way (because due to the fuzzy nature of the finder I will have still access to files outside my src directory without having to relaunch another finder, right now I have a map with the --path src and another one without, with --query I can have only one and just erase the default query if needed).

The patch above has been included in #998, it also adds the support of --query for all providers, please have a try. @fievel

fievel commented

@liuchengxu I tested Clap files --query and it's exactly what I wanted. Thanks.