Ir a X bytes desde aquí


9

¿Cómo puedo mover X bytes hacia adelante, comenzando desde la ubicación actual del cursor (incluidos los saltos de línea)?

[count]gopodría usarse para avanzar X bytes desde el inicio del búfer. Lo intenté Shift + V, G, [count]go(suponiendo que [count]gocomenzaría a contar desde el comienzo de mi selección), pero desafortunadamente tampoco funcionó porque gosolo comienza a contar desde el comienzo del búfer.

También he tratado :set rulerformat=%ode mostrar el desplazamiento de bytes actual (como lo sugiere Saltar a un desplazamiento de bytes, y mostrar la posición como desplazamiento de bytes ), agregué los números en mi cabeza y finalmente emití [count]go. Esto funciona, pero no es muy práctico ...


Si todo está en una línea, puede usar Xl(donde Xestá el número de caracteres) o el número de caracteres seguido de la flecha Derecha.
Lekensteyn

Respuestas:


9

Esta búsqueda mueve 40 caracteres (no bytes), sin embargo:

/\_.\{40}/e

buscando exactamente 40 caracteres ( \{40}) de cualquier tipo, incluida la nueva línea ( \_.), y colocando el cursor al final de la búsqueda ( /e). Ver: http://vimregex.com/#Non-Greedy , :help search-offsety:help \_

Además, vea :h 23.4para la edición binaria.


Actualización: según esta respuesta, aquí hay una función que salta al desplazamiento de bytes:

let s:last_jump_bytes = 0

function! JumpTo(byte_nr)
    let crt_byte = line2byte(line('.')) + col('.')
    if (a:byte_nr == 0)
        let dst_byte = crt_byte + s:last_jump_bytes
    else
        let dst_byte = crt_byte + a:byte_nr
        let s:last_jump_bytes = a:byte_nr
    endif
    let dst_line = byte2line(dst_byte)
    let dst_col = dst_byte -line2byte(dst_line)
    "remove next line if you don't want to record this for `Ctrl-O`
    execute "normal " . dst_line . "G"
    call setpos('.', [0, dst_line, dst_col])
endfunction

command! -nargs=1 JumpToOffset :call JumpTo(<f-args>)

" silly mapping to Ctrl-C (demo)
nnoremap <expr> <silent> <c-c> ":<c-u>call JumpTo(" . v:count . ")<cr>"

Se puede usar así:

:JumpToOffset 400

o escribiendo la asignación de teclado asignada, con un recuento:

40CTRL-C

Si no usa un conteo, el número de conteo anterior se reutiliza. Entonces puedes hacer: 40CTRL-C CTRL-C CTRL-C 30CTRL-C CTRL-Csaltar 40, 40, 40, 30, 30 bytes, etc.

Presiona Ctrl-Opara saltar hacia atrás (ver comentarios dentro de la función).


Gracias por la respuesta. Realmente estoy buscando avanzar X bytes, no caracteres. ¿Podría explicar qué hace su patrón de búsqueda, posiblemente con referencias a la documentación?
Rob W

Hecho. También es posible automatizar el [count]goproceso aunque en una función vim (leer el desplazamiento de bytes actual, agregar el número deseado, goallí).
VanLaser

... agregada función y comando automatizados.
VanLaser

Gracias por la actualización, ¡esto comienza a verse bien! Hay dos pequeñas diferencias entre [count]goy su método: 1) [count]goagrega un elemento a la lista de salto, por lo que puedo usar Ctrl+Opara volver rápidamente a mi posición anterior. 2) [count]gose puede usar sin :, ¿es posible introducir una nueva [count]GOque haga lo suyo? ¿Podría editar su respuesta para que también coincida con ese comportamiento de go?
Rob W

editado para ambos puntos
VanLaser

9

Terminé usando la siguiente solución, que implementa la lógica de mi pregunta.

  • [count]GOpara mover [count]bytes hacia adelante.
  • [count]Gopara mover [count]bytes hacia atrás.

Agregue esto a su .vimrc:

function! JumpToByte(byte_nr)
    " See https://vi.stackexchange.com/a/3911/2720 for the byte counting bug
    let crt_byte = line2byte(line('.')) + col('.') - 1
    if version < 781 && &l:binary == 1 && &l:eol == 0
        let crt_byte += 1
        let crt_byte += line('.') == 1
    endif
    let dst_byte = crt_byte + a:byte_nr
    execute "normal " . dst_byte . "go"
endfunction
nnoremap <expr> <silent> GO ":<c-u>call JumpToByte(" . v:count . ")<cr>"
nnoremap <expr> <silent> Go ":<c-u>call JumpToByte(-" . v:count . ")<cr>"

Gracias a VanLaser por su implementación inicial, que me puso en la dirección correcta.


Una pregunta, ¿dónde exactamente necesita esta funcionalidad? (Por cierto, terminé combinando su solución con la reutilización del recuento anterior si no se proporciona ninguno).
VanLaser

1
@VanLaser Estaba leyendo el contenido en bruto de un archivo PDF, para comprender mejor el formato del archivo PDF. Un archivo PDF consta de muchos objetos, y muchos de estos objetos tienen un prefijo de longitud. Ser capaz de saltar X bytes hacia adelante fue útil para la depuración. Y antes de preguntar por qué estoy editando archivos PDF sin procesar: estoy desarrollando una nueva característica para PDF.js que requiere un conocimiento más profundo del formato de archivo PDF.
Rob W

Gracias por la respuesta (y buena suerte)! La versión combinada está aquí, si está interesado: pastebin.com/7sVyiA85
VanLaser

@VanLaser He actualizado mi respuesta con una versión final. Resulta que su método original de conteo de líneas estaba bien, pero había un error en Vim. He enviado un parche que fue aceptado , por lo que en la última versión de Vim, su respuesta también funcionará según lo previsto.
Rob W

Parece que has cavado realmente allí (yendo a la fuente) - ¡felicidades!
VanLaser
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.