2012-06-13 9 views
9

¿Es posible reutilizar el rango de comandos ex en VIM?Reutilización del rango anterior en comandos ex en VIM

A modo de ejemplo, puedo escribir (copiar) las líneas 4 a 10 de mi archivo actual a un nuevo archivo con el siguiente comando:

:4,10w foo/bar.txt 

Pero lo que realmente quiero hacer es mover las líneas a un nuevo archivo. Puedo hacer esto así:

:4,10w foo/bar.txt 
:4,10d 

Pero es un poco molesto tener que escribir 4,10 en ambas ocasiones.

así que tengo dos preguntas:

  1. general, ¿Hay una manera de hacer referencia al rango utilizado previamente en los comandos ex?
  2. Específicamente, si no hay una manera de hacerlo (1), ¿hay alguna manera más fácil de cortar y pegar varias líneas de un archivo a uno nuevo?

Respuesta

1

En general, lo que hago es eliminar las líneas de un archivo, cambiar al otro archivo y pegar.

Además, generalmente uso marcas. En lugar de escribir los números reales, presiono mb para marcar la línea de inicio, luego voy a la línea final y presiono d'b para borrar de nuevo a la línea marcada como b. Pero se puede usar mb para marcar una línea comenzar, y me para marcar una línea de fondo, a continuación, ejecute un ex comando:

:'b,'e w somefile.txt<Enter> 

Por supuesto se puede utilizar todas las letras de a través z para sus marcas; Usualmente uso b y e pero puede usar lo que quiera.

Cómo me gustaría mover las líneas:

m'b 
<navigate to end line> 
d'b 
:n somefile.txt<Enter> 
p 
Ctrl+^ 

Ctrl +^interruptores del archivo abierto actual al abrir el archivo anterior. (También podría simplemente abrir un panel y cambiar los paneles, si lo prefiere. Los paneles no funcionan en modo vi simple, pero sí funcionan en vim)

Lo anterior supone que ha configurado la opción autowrite. Con autowrite, el comando :n y Ctrl +^ambos simplemente escriben el archivo actual y luego cambian de archivos, en lugar de quejarse de que el archivo ha sido cambiado sin que usted lo haya guardado. También puede hacer lo anterior y simplemente escribir explícitamente el archivo antes de usar :n o Ctrl + ^.

Por cierto, uso Ctrl +^tanto que lo mapeé en K. Es más fácil escribir, pero tuve ese hábito hace mucho tiempo cuando solía tener que usar una terminal tonta que no podía escribir Ctrl + ^.

Por cierto, cuando elimina líneas, entran en el "buffer sin nombre". En vim, el búfer sin nombre se conserva cuando se cambian los archivos. En la vi original, el buffer sin nombre se borra. Entonces lo anterior no funcionará con VI viejo. Puede hacer que funcione borrando en un buffer nombrado, luego pegando desde el buffer nombrado; eso funciona en cualquier versión de vi.

m'b 
<navigate to end line> 
"ad'b 
:n somefile.txt<Enter> 
"ap 
Ctrl+^ 

Lo anterior elimina en el búfer llamado a, a continuación, pastas de a en el otro archivo. Esto funciona en vim, por supuesto; es solo que no lo necesitas.

4

No tengo conocimiento de una respuesta a (1), pero para responder (2), hay varias maneras diferentes de hacerlo que no requieren volver a seleccionar las líneas a mano. En el modo visual que esto funcionará:

4GV10G 
:w foo/bar.txt 
gvd 

porque gv vuelve a seleccionar la selección anterior, que es casi lo que quiera, sin necesidad de utilizar un rango ex.

Pero sólo podía convertir el problema en su cabeza, y tratar:

:4,10d 
:sp foo/bar.txt 
pZZ 

a cortar, a continuación, pegar en un nuevo archivo, y luego cerrarla.

0

Usted puede hacer el borrado primero, y luego abrir una nueva pestaña y pegar el contenido - por lo :4,10d, entonces :tabe foo/bar.txt, seguido de p ... Qué le parece mejor?

3

Aparte del uso de la historia Vim (:del cursor hacia arriba, q:) y la eliminación de la orden anterior de manera que se mantiene sólo la gama, no hay manera de volver a utilizar la última gama, ninguna variable mágica.

Si usara esta combinación líneas se mueven más a menudo, me gustaría escribir un comando personalizado para ello:

command! -bang -range -nargs=1 -complete=file MoveWrite <line1>,<line2>write<bang> <args> | <line1>,<line2>delete _ 

es necesario especificar el rango de una sola vez y salvar a escribir.

Puede escribir algo como esto para otras combinaciones, también. El principal desafío es especificar todos los atributos de comando (explosión, rango, finalización) y, más tarde, recordar el nombre del comando personalizado.

2

Aquí hay una asignación de línea de comandos que logra esto. Lo he vinculado a CTRL-G CTRL-U, ya que realiza una acción similar a CTRL-U. (Pero se puede cambiar eso, por supuesto!)

" c_CTRL-G_CTRL-U Remove all characters between the cursor position and 
"   the closest previous |:range| given to a command. When 
"   directly after a range, remove it. 
"   Useful to repeat a recalled command line with the same 
"   range, but a different command. 
let s:singleRangeExpr = '\%(\d\+\|[.$%]\|''\S\|\\[/?&]\|/[^/]*/\|?[^?]*?\)\%([+-]\d*\)\?' 
let s:rangeExpr = s:singleRangeExpr.'\%([,;]'.s:singleRangeExpr.'\)\?' 
let s:upToRangeExpr = '^\%(.*\\\@<!|\)\?\s*' . s:rangeExpr . '\ze\s*\h' 
" Note: I didn't take over the handling of command prefixes (:verbose, :silent, 
" etc.) to avoid making this overly complex. 
function! s:RemoveAllButRange() 
    let l:cmdlineBeforeCursor = strpart(getcmdline(), 0, getcmdpos() - 1) 
    let l:cmdlineAfterCursor = strpart(getcmdline(), getcmdpos() - 1) 

    let l:upToRange = matchstr(l:cmdlineBeforeCursor, s:upToRangeExpr) 
    if empty(l:upToRange) 
     return getcmdline() 
    else 
     call setcmdpos(strlen(l:upToRange) + 1) 
     return l:upToRange . l:cmdlineAfterCursor 
    endif 
endfunction 
cnoremap <C-g><C-u> <C-\>e(<SID>RemoveAllButRange())<CR> 
1

También puede hacer algo como esto para escribir el contenido del registro anónimo para file2.txt

:4,10d | :call writefile(split(@@, "\n", 1), 'file2.txt') 
5

lo general el uso de gato que hacer esto:

:4,10!cat > foo/bar.txt 

esto funciona porque estás tuberías de las líneas a través de gato y su sustitución por la salida resultante, que no es nada. Y, por supuesto, puede agregar al final de un archivo existente haciendo >> en lugar de>.

+0

¡Esa es una manera interesante de manejarlo! Tipo de elegante. – steveha

Cuestiones relacionadas