我可以使用“ gf”(或类似名称)打开文件并跳到搜索词吗?


9

有没有办法让vim的gf命令(或类似的东西)识别+{cmd}文件路径的参数?

您可以执行以下操作来启动vim并直接转到搜索词:

$ vim +/coding_effort ~/project/file

同样,在命令模式下,您可以执行以下操作:

:e +/coding_effort ~/project/file

我经常记笔记并参考其他文件,例如:

For more info see +/coding_effort ~/project/file where there's a detailed discussion.

我希望能够选择+/coding_effort ~/project/file,输入类似内容gf,并且让vim做正确的事情。


我认为默认情况下没有任何方法可以执行此操作,但是您可以创建一个可以执行此操作的插件。
EvergreenTree

Answers:


6

不,第一个问题是命令和文件名之间的必需空格不是' isfname'选项的一部分,而添加它意味着根本无法识别文件边界。您要么必须始终使用视觉选择(包括命令和文件名),要么在gf命令重载中实现自定义解析。

其次,内置程序gf无法识别+{cmd}语法,因此实际上没有办法实现自己的自定义映射。这当然是可能的(使用功能,如expand('<cfile>')getline()等),但可能需要Vimscript中的函数几行。

如果您选择其他语法(filename:+command),则可以保留原始gf命令并在中实现拆分:autocmd,类似于非常相关的file:line插件对进行的操作filespec:linenumber


2

这是一个应复制内置gf行为的函数,并且扫描+从其开始的作品,然后将其传递给:edit

fun! GotoWithCommand()
        let l:file = expand('<cfile>')

        " Replace ~ with the home directory
        let l:file = substitute(l:file, '^\~', $HOME, '')

        " File doesn't exist; return
        if !filereadable(l:file)
                echohl ErrorMsg
                echomsg "E447: Can't find file \"" . l:file . '" in path'
                echohl None
                return 0
        endif

        " Save cursor postion
        let l:save_cursor = getpos(".")

        " Make sure we go to the previous word (B on the first character of the
        " filename goes to the previous word, B anywhere else goes to the start of
        " the filename)
        call search('\(\s\|^\)', 'b')

        " Try to find argument to be executed; these start with a `+'
        let l:commands = ''
        while 1
                " Go one WORD backwards
                normal! B

                " Not a +; stop the loop
                if getline('.')[col('.') - 1] != '+'
                        break
                endif

                let l:commands .= ' ' . expand('<cWORD>')
        endwhile

        " Restore cursor postion
        call setpos('.', l:save_cursor)

        " Now, open the new file...
        execute ':edit ' . l:commands . ' ' . l:file
endfun

nnoremap <Leader>gf :call GotoWithCommand()<CR>

这些注释应该更详细地解释该函数的功能……我是早上在火车上写的,(显然)没有对它进行广泛的测试;-)


1

一种选择是(假设+cmd file/path选中了)将选择拉到一个寄存器,然后将该寄存器插入命令提示符。我使用以下映射做到了这一点:

vnoremap gsf "0y:e <c-r>0<cr>


1

该符号有效(file name+ trailing :+ / pat /

/usr/include/stdio.h:/int printf/  -- `file name` + `:` + `/ pat /`
/usr/include/stdio.h:+/int printf/
/usr/include/stdio.h: /int printf/
/usr/include/stdio.h: /#define\s/
/usr/include/stdio.h: /^#define\sSEEK/

下面的功能和映射。

nn gf :<C-u>call Gf_search()<CR>

func! Gf_search() abort
    let word = expand('<cWORD>')
    let idx = stridx(word, ':')
    if idx != -1
        let remline = strpart(getline('.'),col('.'))
        let pat = substitute(remline, '.*[:+ ]/\([^/]*\)/.*', '\1', "")
        if pat != remline
            let pat = substitute(pat, '\\', '\\\\', 'g')
            let pat = substitute(pat, ' ', '\\ ', 'g')
            let filename = expand('<cfile>')
            exec 'e +/'.pat filename
            return
        endif
    endif
    " fallback to builtin gF
    norm! gF
endfunc
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.