vimrc function to search filename using literal `*

2019-09-11 04:17发布

问题:

I have a large file called index.txt which has all absolute path of all files listed say,

common/mac_get.c
common/addr/addr_main_set_clear_config.c
common/addr/mac/mac_load_done.c

Need to write vimrc function to search only last word in each line of index.txt with delimiter as / (i.e search only basename ) and not match for foldername also it should accept * as a part of argument in search.

say If I pass argument mac*.c then It should search file starting with mac & ending with .c then return results as,

common/mac_get.c
common/addr/mac/mac_load_done.c

say If I pass argument mac*done.c then It should search file starting with mac and ending with done.c then return results as,

common/addr/mac/mac_load_done.c  

say If I pass argument *main*.c or *main*set*.c then It should return results as,

common/addr/addr_main_set_clear_config.c  

This is what I've tried so far :

function! searchFname(fname)
   execute "silent! grep!" a:fname "~/index.txt"
endfunction

command! -nargs=* Fname call SearchFname('<args>')

Any help would be greatly appreciated.

回答1:

grep uses * as a quantifier that matches the preceding element zero or more times, but you're requiring to use it as a wildcard that matches any characters.

Even though grep doesn't use wildcards, you can build equivalent regular expressions, e.g:

  • * is equivalent to .*
  • ? is equivalent to .

To match only filenames (excluding the path), it's necessary to replace . with [^/] as follows:

function! SearchFname(fname)
    execute 'silent! grep! "^\(.*\/\)\?' . substitute(substitute(substitute(a:fname,'\*','[^/]*','g'),'\.','\\.','g'),'?','[^/]','g') . '$"' "~/index.txt"
endfunction

command! -nargs=* Fname call SearchFname('<args>')

But grep's output will still be shown on the terminal Vim was started up. To get rid of it you can use the :vimgrep command instead, but you need to use a pattern as in Vim search (see :help :vimgrep for details):

function! SearchFname(fname)
    execute 'silent! vimgrep /^\(.*\/\)\?' . substitute(substitute(substitute(a:fname,'\*','[^\/]*','g'),'\.','\.','g'),'?','[^\/]','g') . "$/j" "~/index.txt"
endfunction

command! -nargs=* Fname call SearchFname('<args>')


标签: vim grep