Przejdź do X bajtów stąd


9

Jak mogę przenieść bajty X do przodu, zaczynając od bieżącej lokalizacji kursora (łącznie z podziałami linii)?

[count]gomoże być użyty do przesunięcia X bajtów do przodu od początku bufora. Próbowałem Shift + V, G, [count]go(zakładając, [count]goże zacznie się odliczanie od początku mojego wyboru), ale niestety to też nie zadziałało, ponieważ gozaczyna się odliczanie od początku bufora.

Próbowałem również :set rulerformat=%owyświetlić bieżące przesunięcie bajtu (jak sugeruje Przeskok do przesunięcia bajtu i wyświetlanie pozycji jako przesunięcie bajtu ), dodałem liczby w mojej głowie i ostatecznie wydałem [count]go. To działa, ale nie jest zbyt praktyczne ...


Jeśli wszystko jest w jednym wierszu, możesz użyć Xl(gdzie Xjest liczba znaków) lub liczby znaków, a następnie strzałki w prawo.
Lekensteyn,

Odpowiedzi:


9

To wyszukiwanie przesuwa 40 znaków (ale nie bajtów) do przodu:

/\_.\{40}/e

wyszukując dokładnie 40 znaków \{40}dowolnego rodzaju (w tym newline ( \_.) i umieszczając kursor na końcu wyszukiwania ( /e). Zobacz: http://vimregex.com/#Non-Greedy , :help search-offseti:help \_

Zobacz także :h 23.4edycję binarną.


Aktualizacja: Na podstawie tej odpowiedzi, oto funkcja, która przeskakuje do przesunięcia bajtu:

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

Można użyć w następujący sposób:

:JumpToOffset 400

lub wpisując mapowane mapowanie klawiatury z liczbą:

40CTRL-C

Jeśli nie użyjesz licznika, poprzedni numer zostanie ponownie użyty. Więc możesz zrobić: 40CTRL-C CTRL-C CTRL-C 30CTRL-C CTRL-Cprzeskoczyć 40, 40, 40, 30, 30 bajtów itp.

Naciśnij, Ctrl-Oaby przeskoczyć do tyłu (patrz komentarze wewnątrz funkcji).


Dziękuję za odpowiedź. Naprawdę szukam do przodu X bajtów, ale nie znaków. Czy mógłbyś wyjaśnić, co robi Twój wzorzec wyszukiwania, ewentualnie z odniesieniami do dokumentacji?
Rob W

Gotowy. Możliwe jest również zautomatyzowanie [count]goprocesu za pomocą funkcji vim (odczyt aktualnego przesunięcia bajtu, dodaj żądaną liczbę, gotam).
VanLaser,

... dodano automatyczne funkcje i polecenia.
VanLaser,

Dzięki za aktualizację, wygląda to dobrze! Istnieją dwie małe różnice pomiędzy [count]goi twoją metodą: 1) [count]gododaje element do listy skoków, dzięki czemu mogę Ctrl+Oszybko wrócić do poprzedniej pozycji. 2) [count]gomożna używać bez :, czy można wprowadzić nowy, [count]GOktóry spełni twoje oczekiwania. Czy możesz edytować swoją odpowiedź, aby pasowała również do tego zachowania go?
Rob W

edytowane dla obu punktów
VanLaser,

9

Skończyło się na użyciu następującego rozwiązania, które implementuje logikę z mojego pytania.

  • [count]GOaby przenieść [count]bajty do przodu.
  • [count]Goaby przenieść [count]bajty do tyłu.

Dodaj to do .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>"

Dzięki VanLaser za jego początkową implementację, która skierowała mnie we właściwym kierunku.


Jedno pytanie, gdzie dokładnie potrzebujesz tej funkcjonalności? (BTW Skończyło się na tym, że połączyłem twoje rozwiązanie z ponownym użyciem poprzedniego licznika, jeśli nie podano żadnego).
VanLaser,

1
@ VanLaser Czytałem surową zawartość pliku PDF, aby lepiej zrozumieć format pliku PDF. Plik PDF składa się z wielu obiektów, a wiele z nich ma prefiks długości. Możliwość przeskakiwania do przodu o X bajtów była przydatna podczas debugowania. Zanim zapytasz, dlaczego edytuję nieprzetworzone pliki PDF: opracowuję nową funkcję dla pliku PDF.js, która wymaga głębszej znajomości formatu pliku PDF.
Rob W

Dzięki za odpowiedź (i powodzenia)! Wersja łączona jest dostępna, jeśli zainteresowany: pastebin.com/7sVyiA85
VanLaser

@ VanLaser Zaktualizowałem swoją odpowiedź do ostatecznej wersji. Okazuje się, że twoja pierwotna metoda liczenia linii była w porządku, ale w Vimie był błąd. Przesłałem łatkę, która została zaakceptowana , więc w najnowszej wersji Vima twoja odpowiedź również będzie działać zgodnie z przeznaczeniem.
Rob W

Wygląda na to, że wykonałeś tam prawdziwe kopanie (przechodząc do źródła) - gratulacje!
VanLaser,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.