VIM: восстановить положение после отмены функции - PullRequest
0 голосов
/ 12 сентября 2018

Для моего редактирования LaTeX в vim я записал несколько полезных макросов и обернул их в функции / команды.У меня есть один, который меняет тип среды Latex, например, когда у меня есть:

\begin{itemize}
     \item First
     \item Second
\end{itemize}

Я просто ввожу :ChangeEnv enumerate с курсором где-то в среде, чтобы перейти от itemize к перечислению.

Код в моем ftplugin / tex.vim выглядит следующим образом:

function! ChangeEnv(newenv)
    let l:save = @e
    let @e = a:newenv

    let l:line = getline('.')

    " Fake change to restore undo
    normal ix
    normal x

    if match(l:line, '\\begin{') != -1
        normal mz_%f{lci}e'zf{l.`z:delma   z
    else
        normal my?\\begin{^M_mz%f{lci}^Re^['zf{l.`y:delma    yz
    endif

    let @e = l:save
endfunction

command -nargs=1 ChangeEnv :silent call ChangeEnv(<f-args>)

Первая часть (после if match(...), предназначенная, если курсор находится на \begin{...} части среды, работает отличнопока я могу внести изменение и отменить его, курсор остается там, где и должен.

Вторая часть, предназначенная для внутренней среды, также прекрасно работает, но когда изменение отменено, курсор переходит напервый символ строки \ begin.

Часть normal ix и normal x предназначена для того, чтобы гарантировать, что позиция курсора восстанавливается после und (у меня это здесь: Restor Cursor Position )

Мой вопрос: почему он не работает для второго макроса?Есть ли какая-то ошибка?

Чтобы избавить вас от деконструкции макроса, выполните следующие действия:

  • my - установите отметку y в текущей позиции
  • ?\\begin{^M - поиск назад в начале среды и переходить туда
  • _mz - перейти к первому символу этой строки и установить z метку
  • % - Перейтив соответствие \end{... окружения (это часть плагина matchit vim, поставляется с vim, но не активна по умолчанию).
  • f{l - Перейти к { и на один символ вправо
  • ci} - Изменить внутренний {...}
  • ^Re^[ - Вставить содержимое регистра e, в котором сохранено имя нового окружения, и вернуться в обычный режим
  • 'z' - перейти к началу строки знака z (\begin{...)
  • f{l. - перейти к {, на один шаг вправо и повторить последнее изменение
  • `y - перейти к отметке y, начальная позиция
  • :delma yz - удалить y и z mark

Отмена действий не является нарушением условий сделки, тем не менее, я бы по крайней мере хотел бы знать, почему она так себя ведет.

Заранее спасибо.

1 Ответ

0 голосов
/ 13 сентября 2018

Обычно при внесении нескольких изменений каждое из них отменяется отдельно. Но внутри функции все объединено в одно единственное изменение.

Ваше намерение сделать это фиктивное изменение в начале (когда курсор еще не был перемещен) состоит в том, что курсор возвращается к этой точке после отмены.

Тем не менее, я думаю, что поскольку Vim рассматривает весь набор изменений, выполненных в ChangeEnv(), как одну большую модификацию, он возвращается к началу диапазона измененных строк (знак '[), как это происходит при отмене встроенных команд. Какая команда изменения была выполнена «первой», не имеет значения, все, что имеет значение, это диапазон строк, которые были изменены. По мере того, как ваша вторая ветвь выполняет поиск назад к \begin и вносит в нее изменения, курсор находится после отмены. Я не думаю, что есть способ обойти это; сценарии не могут повлиять на отмену, поскольку это может привести к несоответствиям.

Что вы можете сделать, это установить метку после внесения изменений (в конце вашей функции: :normal! m'), чтобы вы могли быстро вернуться туда (через &#96;&#96; или <C-o>).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...