Vai a X byte da qui


9

Come posso spostare X byte in avanti, partendo dalla posizione corrente del cursore (comprese le interruzioni di riga)?

[count]gopotrebbe essere utilizzato per spostare in avanti X byte dall'inizio del buffer. Ho provato Shift + V, G, [count]go(supponendo che [count]goavrebbe iniziato a contare dall'inizio della mia selezione), ma sfortunatamente non ha funzionato neanche perché goinizia a contare solo dall'inizio del buffer.

Ho anche provato :set rulerformat=%oa visualizzare l'offset di byte corrente (come suggerito Passando a un offset di byte e visualizzando la posizione come offset di byte ), ho aggiunto i numeri nella mia testa e infine rilasciato [count]go. Funziona, ma non è molto pratico ...


Se tutto è su una riga, puoi usare Xl(dov'è Xil numero di caratteri) o il numero di caratteri seguito dalla freccia destra.
Lekensteyn,

Risposte:


9

Questa ricerca sposta avanti di 40 caratteri (non byte):

/\_.\{40}/e

cercando esattamente 40 caratteri ( \{40}) di qualsiasi tipo, incluso newline ( \_.), e posizionando il cursore alla fine della ricerca ( /e). Vedere: http://vimregex.com/#Non-Greedy , :help search-offsete:help \_

Inoltre, vedi :h 23.4per l'editing binario.


Aggiornamento: in base a questa risposta, ecco una funzione che passa all'offset byte:

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>"

Può essere usato in questo modo:

:JumpToOffset 400

o digitando la mappatura della tastiera mappata, con un conteggio:

40CTRL-C

Se non si utilizza un conteggio, viene riutilizzato il numero di conteggio precedente. Quindi puoi fare: 40CTRL-C CTRL-C CTRL-C 30CTRL-C CTRL-Csaltare 40, 40, 40, 30, 30 byte ecc.

Premi Ctrl-Oper tornare indietro (vedi commenti all'interno della funzione).


Grazie per la risposta. Sto davvero cercando di avanzare di X byte, non di caratteri però. Potresti spiegare cosa fa il tuo modello di ricerca, possibilmente con riferimenti alla documentazione?
Rob W,

Fatto. È anche possibile automatizzare il [count]goprocesso tramite una funzione vim (leggere l'offset di byte corrente, aggiungere il numero desiderato, golì).
VanLaser,

... aggiunta funzione e comando automatici.
VanLaser,

Grazie per l'aggiornamento, questo inizia a sembrare buono! Ci sono due piccole differenze tra [count]goe il tuo metodo: 1) [count]goaggiunge un elemento alla jump list, quindi posso usare Ctrl+Oper tornare rapidamente alla mia posizione precedente. 2) [count]gopuò essere utilizzato senza :, è possibile introdurre un nuovo [count]GOche fa la tua cosa. Potresti modificare la tua risposta per abbinare anche quel comportamento di go?
Rob W,

modificato per entrambi i punti
VanLaser,

9

Ho finito per usare la seguente soluzione, che implementa la logica della mia domanda.

  • [count]GOper spostare i [count]byte in avanti.
  • [count]Goper spostare i [count]byte all'indietro.

Aggiungi questo al tuo .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>"

Grazie a VanLaser per la sua implementazione iniziale, che mi ha messo nella giusta direzione.


Una domanda, dove hai bisogno esattamente di questa funzionalità? (A proposito ho finito per combinare la tua soluzione con il riutilizzo del conteggio precedente se non ne viene fornito nessuno).
VanLaser,

1
@VanLaser Stavo leggendo i contenuti non elaborati di un file PDF, al fine di comprendere meglio il formato del file PDF. Un file PDF è composto da molti oggetti e molti di questi oggetti hanno un prefisso di lunghezza. Essere in grado di saltare X byte in avanti è stato utile per il debug. E prima che tu mi chieda perché sto modificando file PDF non elaborati: sto sviluppando una nuova funzionalità per PDF.js che richiede una conoscenza più approfondita del formato del file PDF.
Rob W,

Grazie per la risposta (e buona fortuna)! La versione combinata è qui, se interessata: pastebin.com/7sVyiA85
VanLaser

@VanLaser Ho aggiornato la mia risposta con una versione finale. Si scopre che il tuo metodo di conteggio delle linee originale andava bene, ma c'era un bug in Vim. Ho inviato una patch che è stata accettata , quindi nell'ultima versione di Vim, anche la tua risposta funzionerà come previsto.
Rob W,

Sembra che tu abbia fatto dei veri scavi lì (andando alla fonte) - congratulazioni!
VanLaser,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.