Чи можу я використовувати "gf" (або подібне) для відкриття файлу та переходу до пошукового терміну?


9

Чи є спосіб отримати gfкоманду vim (чи щось подібне) розпізнати +{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

Відповіді:


6

Ні, перша проблема полягає в тому, що необхідний пробіл між командою та іменем файлу не є частиною параметра " isfname', і додавання цього означатиме, що межі файлів взагалі не можуть бути розпізнані. Вам завжди доведеться використовувати візуальний вибір (як команди, так і імені файлу) або виконувати спеціальний аналіз при gfперевантаженні команд.

По-друге, вбудований gfне розпізнає +{cmd}синтаксис, тому реально реалізувати власне власне відображення реально немає. Це , звичайно , можливо ( з використанням функцій , таких як expand('<cfile>'), getline()і т.д.), але , ймовірно , займає кілька рядків функції Vimscript.

Якщо ви вибрали інший синтаксис ( filename:+command), ви можете зберегти оригінальні gfкоманди та здійснити розбиття в :autocmd, подібному до того, що робить дуже пов'язаний файл: плагін рядка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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.