vim вызывает функцию изнутри vmap - PullRequest
2 голосов
/ 02 декабря 2011

Я создал текстовый объект vmap для выделения текста одного LaTeX \ item:

vmap im ?\\item<CR>o/\\item\\|\\end{itemize}<CR>b$

Но это раздражает тем, что я теряю свой текущий поисковый запрос. Я читал, что условия поиска восстанавливаются, когда поиск происходит внутри вызова функции, поэтому я хотел преобразовать карту, чтобы просто вызвать функцию, которая будет выполнять поиск:

function! ItemizeTextObject()
  ?\\item
  normal o
  /\\item|\\end{itemize}
  normal b$
endfunction

vmap in :call ItemizeTextObject()<CR>

К сожалению, это не работает: я получаю сообщение об ошибке («Шаблон не найден: \ item | \ end {itemize}»), текст вообще не выделен, и новая строка вставлена ​​ниже строки, на которой находится мой курсор на. Я попробовал несколько вариантов этого, но безуспешно.

Я думаю, что основная проблема заключается в том, что я должен сохранить визуальный режим при вызове функции (o в моей команде должен переключаться на другой конец выделения, но вместо этого вставляется новая строка), но я не знаю как.

Обновление:

Я пытаюсь получить следующее поведение: В таком тексте:

\begin{itemize}
  \item lorem ipsum...
  \item piece of text I want to select,
   the *CURSOR* is here, and there is more text
   that follows
  \item lorem ipsum...
\end{itemize}

Я хочу нажать vin, и тогда текстовый блок в середине должен быть выделен:

  \item piece of text I want to select,
   the *CURSOR* is here, and there is more text
   that follows

означает текст с начала предыдущего \item, но не включая следующие \item или \end{itemize}.

1 Ответ

2 голосов
/ 02 декабря 2011

Я использовал документ на operatorfunc, чтобы придумать следующее, что должно быть (близко) к тому, что вы хотите 1 :

function! ItemizeTextObject(type, ...)
    let sel_save = &selection
    let &selection = "inclusive"
    let reg_save = @@

    if a:0  " Invoked from Visual mode, use '< and '> marks.
        silent! 1,+1?\\item
        norm v | " use V for linewise visual mode
        "" use V for linewise visual mode:
        "norm V
        silent! /\\item\|\\end{itemize}
    "elseif a:type == 'line'
    "elseif a:type == 'block'
    else
       silent! 1,+1?\\item
       norm v
       silent! /\\item
    endif

    norm b$

    let &selection = sel_save
    let @@ = reg_save
endfunction

silent! unmap in

xnoremap <silent> in :<C-U>call ItemizeTextObject(visualmode(), 1)<CR>

Если вы хотите, чтобы отображение в обоих режимах visual и выбирало , вам следует использовать vnoremap

Примечания к адресу:

  • Теперь вы можете реализовать движение из другого режима (заполните ветви в функции)
  • если wrapscan включен, поиск не должен переноситься (возможно, временно установлен nowrapscan?)
  • вы можете захотеть, чтобы оператор повторял, чтобы вы могли расширить выбор , сказав vininin (см. https://stackoverflow.com/a/7292271/85371 для примера)
  • похоже, что вам нужно поведение 'linewise' (из-за b$?)
    • рассмотрите возможность использования norm V (см. Комментарий)

Редактировать Я сравнил поведение с этим простым отображением:

xnoremap <silent>in ?\\item<CR>o/\\item\\|\\end{itemize}<CR>b$

1 Отказ от ответственности: я не знаю, LateX

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