我创建了一个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}
。
答案 0 :(得分:2)
我已经使用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的例子)b$
?)
norm V
(请参阅评论)编辑我将此行为与此简单映射进行了比较:
xnoremap <silent>in ?\\item<CR>o/\\item\\|\\end{itemize}<CR>b$
<子> 1 免责声明:我不知道LateX 子>