¿Puedo usar "gf" (o similar) para abrir un archivo y saltar a un término de búsqueda?


9

¿Hay alguna manera de obtener el gfcomando de vim (o algo similar) para reconocer un +{cmd}argumento para las rutas de archivo?

Se puede iniciar vim e ir directamente a un término de búsqueda haciendo:

$ vim +/coding_effort ~/project/file

Del mismo modo, en modo comando puede hacer:

:e +/coding_effort ~/project/file

A menudo tomo notas y me refiero a otros archivos como este:

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

Me encantaría poder seleccionar +/coding_effort ~/project/file, escribir algo parecido gfy hacer que vim haga lo correcto.


No creo que haya ninguna forma de hacerlo de forma predeterminada, pero probablemente podría crear un complemento que lo haga.
— EvergreenTree

Respuestas:


6

No, el primer problema es que el espacio necesario entre el comando y el nombre de archivo no es parte de la isfname'opción ' , y agregarlo significaría que los bordes del archivo no podrían reconocerse en absoluto. Debería usar siempre una selección visual (tanto de comando como de nombre de archivo) o implementar un análisis personalizado en una gfsobrecarga de comandos.

En segundo lugar, el incorporado gfno reconoce la +{cmd}sintaxis, por lo que realmente no hay forma de implementar su propia asignación personalizada. Esto es ciertamente posible (usando funciones como expand('<cfile>'), getline()etc.), pero probablemente tome algunas líneas de la función Vimscript.

Si elige una sintaxis diferente ( filename:+command), puede mantener los gfcomandos originales e implementar la división en un :autocmd, similar a lo que hace el muy relacionado archivo: plugin de líneafilespec:linenumber ).


2

Aquí hay una función que debería replicar el gfcomportamiento incorporado , y también busca trabajos que comiencen y +luego pasen a: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>

Los comentarios deberían explicar lo que hace la función con más detalle ... Escribí esto en el tren la mañana, y (obviamente) no lo probé extensamente ;-)


1

Una opción sería (suponiendo que +cmd file/pathse selecciona) para tirar la selección a un registro, luego insertar ese registro en el símbolo del sistema. Hice esto con el siguiente mapeo:

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


1

Esta notación funciona ( 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/

con función y mapeo a continuación.

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.