Редактор, който ще премине към даден знак въз основа на позиция от EOF?

Някой знае ли за редактор с команда, която ще прескочи курсора ви до даден байт/символ въз основа на позицията му в края на файла (EOF), вместо в началото на файла?

Нещо ми подсказва, че VI/VIM може да го направи, но моят Google-fu ме проваля в момента.


person Dan Berlyoung    schedule 15.04.2014    source източник
comment
Намирам това за неясно. Можете ли да дадете пример за поведение, което търсите? Това със сигурност може да се направи с няколко линии на elisp.   -  person Adobe    schedule 16.04.2014
comment
Трябва ли да броите байтовете за разделител на редове? напр. ако имате два реда, 123 и 456, тогава 4-тият знак от края ще бъде ли 3 или някъде между 3 и 4?   -  person Ben    schedule 16.04.2014
comment
Невидимите се броят, да. Имам спецификация на файл с данни, която говори за стойности, които са на N байта от края на файла.   -  person Dan Berlyoung    schedule 01.05.2014


Отговори (4)


Emacs може да направи това.

За да преминете към nия знак във файла, можете да използвате goto-char. Така че, ако искате да отидете до 1234-ия знак, изпълнете M-x goto-char и в следния ред можете да въведете 1234.

Но не работи за преминаване към nтия знак от края. За щастие можем да напишем метод!

(defun goto-char-from-end (characters-from-end)
  "Goes to the end of the buffer, then steps characters-from-end characters back."
  (interactive "Nhow many characters back? ")
  (end-of-buffer)
  (backward-char characters-from-end))

Това може да се използва по същия начин, с M-x goto-char-from-end. Също като goto-char, можете да използвате префиксни аргументи: въведете C-1 C-2 M-x goto-char-from-end и той ще отиде до дванадесетия знак от края, без да ви подкани.

За да заредите този код в Emacs, копирайте го в буфер, след това поставете курсора след последната скоба и напишете C-x C-e. Това изпълнява кода и поставя функцията в работещия в момента Emacs. Ако ви харесва и искате да го имате завинаги, начинът да направите това е да го поставите във вашия init файл.

person zck    schedule 15.04.2014
comment
Ако не греша, използването на (end-of-buffer) или (beginning-of-buffer) генерира съобщение (или поне преди), заявяващо, че е предимно за интерактивна употреба. Най-често срещаният начин да направите това неинтерактивно е (goto-char (point-max)) или (goto-char (point-min)). - person lawlist; 16.04.2014
comment
И не използвайте backward-char, за да стигнете до там. Просто използвайте (goto-char (- (point-max) characters-from-end)). (Разбира се, вероятно също искате да проверите дали аргументът не е по-голям от point-max.) - person Drew; 16.04.2014

Следното картографиране на Vim ще накара [count]gO да се държи като [count]go, но обратно от EOF:

nnoremap <silent> gO :<C-u>execute "normal!" (line2byte(line('$') + 1) - 1 - v:count) . "go"<CR>

line2byte(line('$') + 1) - 1 е броят на байтовете в буфера, а v:count е даденото [count] (по подразбиране е 0, така че gO е еквивалентно на G$).

person Nikita Kouevda    schedule 15.04.2014
comment
+1 Страхотна идея! Необходими са само <silent> и normal!, за да стане перфектен. - person Ingo Karkat; 16.04.2014
comment
Благодаря, че посочихте <silent>; Не можах да разбера, че :silent execute ... няма желания ефект, защото :silent не се отнася за самото картографиране. - person Nikita Kouevda; 16.04.2014

Вим

Да приемем, че искате да отидете на 13-ия знак от края на файла. Натиснете:

G$13<C-h>

подробности:

G$ - отидете до последния знак в буфера
13<C-h> - отидете наляво 13 знака, преминавайки през нов ред (<C-h> е Ctrl+h)

Вместо клавиша <C-h> можете също да използвате <left>, ако сте го активирали с настройката whichwrap.

person mihai    schedule 15.04.2014
comment
Обърнете внимание, че <Left> няма да премине през нов ред по подразбиране, докато <BS> (т.е. <C-h>) ще го направи. Вижте :help whichwrap за повече подробности. - person Nikita Kouevda; 16.04.2014
comment
@NikitaKouevda вярно, имах този заседнал в моя .vimrc от векове, забравих за него - person mihai; 16.04.2014

Една алтернатива с Emacs е да посъветвате goto-char, така че да интерпретира отрицателните аргументи по естествен начин:

(defadvice goto-char (before interpret-negative-argument activate)
  (when (and (called-interactively-p)
             (> 0 (ad-get-arg 0)))
    (ad-set-arg 0 (+ 1 (buffer-size) (ad-get-arg 0)))))

Сега правите напр. C-u-10M-gc, за да преминете към десетия знак от края.

Имайте предвид, че използвах buffer-size вместо point-max, за да отразявам начина, по който goto-char обикновено работи със стесняване.

person Sean    schedule 17.04.2014