Звідси перейдіть до байтів X


9

Як я можу перемістити Х байт вперед, починаючи з поточного місця розташування курсора (включаючи розриви рядків)?

[count]goможе використовуватися для переміщення вперед X байтів від початку буфера. Я спробував Shift + V, G, [count]go(припускаючи, що [count]goпочнеться підрахунок з початку мого вибору), але, на жаль, це не вийшло, тому що goпочинається підрахунок лише з початку буфера.

Я також спробував :set rulerformat=%oвідобразити поточне зміщення байтів (як це запропонував Стрибок до зміщення байтів, і відображення позиції як зміщення байтів ), додав цифри в голові і нарешті видав [count]go. Це працює, але це не дуже практично ...


Якщо все в одному рядку, ви можете використовувати Xl(де Xкількість символів) або кількість символів, слідом за стрілкою праворуч.
Лекенштейн

Відповіді:


9

Цей пошук рухається на 40 символів (але не байтів) вперед:

/\_.\{40}/e

шляхом пошуку рівно 40 символів ( \{40}) будь-якого типу, включаючи новий рядок ( \_.), та розміщення курсору в кінці пошуку ( /e). Див: http://vimregex.com/#Non-Greedy , :help search-offsetі:help \_

Також див. :h 23.4Бінарне редагування.


Оновлення: Виходячи з цієї відповіді, ось функція, яка переходить до зміщення байтів:

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

Можна використовувати так:

:JumpToOffset 400

або набравши зіставлене відображення на клавіатурі з підрахунком:

40CTRL-C

Якщо ви не використовуєте лічильник, попередній номер підрахунку повторно використовується. Отже, ви можете зробити: 40CTRL-C CTRL-C CTRL-C 30CTRL-C CTRL-Cперестрибнути 40, 40, 40, 30, 30 байт тощо.

Натисніть, Ctrl-Oщоб відскочити назад (див. Коментарі всередині функції).


Дякую за відповідь. Я справді шукаю рухатись вперед X байтами, а не символами. Чи можете ви пояснити, що робить ваша схема пошуку, можливо, із посиланням на документацію?
Роб Ш

Зроблено. Можливо також автоматизувати [count]goпроцес, хоча у функції vim (прочитайте поточне зміщення байтів, додайте потрібне число go).
VanLaser

... додані автоматизовані функції та команди.
VanLaser

Дякуємо за оновлення, це починає виглядати добре! Існує дві невеликі відмінності між [count]goвашим методом: 1) [count]goдодає елемент до списку стрибків, тому я можу скористатися Ctrl+Oдля швидкого переходу до попередньої позиції. 2) [count]goможна використовувати без :, чи можна ввести нове, [count]GOщо робить вашу справу. Чи можете ви відредагувати свою відповідь, щоб вона також відповідала такій поведінці go?
Роб Ш

відредаговано для обох пунктів
VanLaser

9

Я закінчив, використовуючи наступне рішення, яке реалізує логіку мого запитання.

  • [count]GOдля переміщення [count]байтів вперед.
  • [count]Goдля переміщення [count]байтів назад.

Додайте це до свого .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>"

Дякую VanLaser за його первісну реалізацію, яка направила мене в правильному напрямку.


Одне запитання, де саме вам потрібна ця функціональність? (До речі, я закінчив поєднувати ваше рішення з повторним використанням попереднього рахунку, якщо такого не передбачено).
VanLaser

1
@VanLaser Я читав вихідний вміст файлу PDF, щоб краще зрозуміти формат файлу PDF. PDF-файл складається з багатьох об’єктів, і багато з цих об'єктів мають префікс довжини. Уміння стрибати на X байт вперед було корисно для налагодження. І перш ніж запитати, чому я редагую необроблені PDF-файли: я розробляю нову функцію для PDF.js, яка вимагає більш глибокого знання формату PDF-файлу.
Роб Ш

Дякую за відповідь (і удачі)! Комбінована версія тут, якщо вас цікавить: pastebin.com/7sVyiA85
VanLaser

@VanLaser Я оновив свою відповідь остаточною версією. Виявляється, ваш оригінальний метод підрахунку рядків був нормальним, але у Vim виникла помилка. Я представив виправлення, яке прийняли , тому в останній версії Vim ваша відповідь також буде працювати за призначенням.
Роб Ш

Ви, здається, зробили там справжнє копання (підходите до джерела) - вітаємо!
VanLaser
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.