Редактор, который будет переходить к заданному персонажу в зависимости от позиции из EOF?

Кто-нибудь знает редактор с командой, которая переместит ваш курсор на заданный байт/символ в зависимости от его положения в конец файла (EOF), а не в начало файла?

Что-то мне подсказывает, что VI/VIM может это сделать, но мой гугл-фу в данный момент меня не подводит.


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. Если вам это нравится и вы хотите, чтобы оно было у вас навсегда, вы можете поместить его в свой файл инициализации.

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