Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VIM:撤销功能后恢复位置_Vim - Fatal编程技术网

VIM:撤销功能后恢复位置

VIM:撤销功能后恢复位置,vim,Vim,为了在vim中编辑LaTeX,我记录了一些有用的宏,并将它们包装到函数/命令中。我有一个,可以改变乳胶环境的类型,例如,当我有: \begin{itemize} \item First \item Second \end{itemize} 我只需输入:changeev enumerate,将光标放在环境中的某个位置,即可从逐项列出更改为枚举 我的ftplugin/tex.vim中的代码如下所示: function! ChangeEnv(newenv) let l:s

为了在vim中编辑LaTeX,我记录了一些有用的宏,并将它们包装到函数/命令中。我有一个,可以改变乳胶环境的类型,例如,当我有:

\begin{itemize}
     \item First
     \item Second
\end{itemize}
我只需输入
:changeev enumerate
,将光标放在环境中的某个位置,即可从逐项列出更改为枚举

我的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>)
函数!更改环境(新环境)
让l:save=@e
设@e=a:newenv
让l:line=getline('.'))
“假更改以恢复撤消”
普通ix
正态x
如果匹配(l:行,'\\开始{')!=-1
正规mz_u%f{lci}e'zf{l.`z:delma z
其他的
正常我的?\\begin{^M_mz%f{lci}^Re^['zf{l.`y:delma yz
恩迪夫
让@e=l:save
端功能
命令-nargs=1 changenv:silent call changenv()
第一部分(在
if match(…
)之后,如果光标位于环境的
\begin{…}
部分,则该部分工作正常。到目前为止,我可以进行更改并撤消它,光标将停留在它应该停留的位置

第二部分用于环境内部,也很有用,但是当更改撤消时,光标会跳到\begin行的第一个字符

normal ix
normal x
部分旨在确保在und之后恢复光标位置(我从这里得到了这个:)

我的问题是,为什么它不适用于第二个宏?是否有错误

为避免解构宏,请执行以下步骤:

  • my
    -在当前位置设置
    y
    标记
  • ?\\begin{^M
    -向后搜索环境的开头并跳到那里
  • \u mz
    -转到该行的第一个字符并设置
    z
    标记
  • %
    -跳转到环境的匹配
    \end{…
    (这是matchit vim插件的一部分,随vim一起提供,但默认情况下不处于活动状态)
  • f{l
    -向前跳转到
    {
    并向右跳转一个字符
  • ci}
    -更改内部{…}
  • ^Re^[
    -插入存储新环境名称的
    e
    寄存器的内容,并返回到正常模式
  • 'z'
    -跳转到
    z
    标记的行首(即
    \begin{…
  • f{l.
    -前进到
    {
    ,向右走一步,重复最后一次更改
  • `y
    -跳转到
    y
    标记,即初始位置
  • :delma yz
    -删除
    y
    z
    标记
撤销行为不是一个破坏交易的行为,不过,我至少想知道它为什么会这样做


提前感谢您。

通常,当您进行多个更改时,每个更改都会单独撤消。但是在函数中,所有更改都集中在一个更改中

您在开始时(光标尚未移动时)进行此虚拟更改的目的是,光标在撤消后返回到该点

然而,我认为Vim将在
changeev()
中完成的整个更改视为一个大的修改,它返回到更改行范围的开头(标记
”[
),就像撤消内置命令时一样"没关系,重要的是更改的行的范围。当您的第二个分支向后搜索到
\begin
并在那里进行更改时,这就是撤消后光标的位置。我认为没有办法解决这个问题;撤消不能受脚本的影响,因为这可能会导致不一致


您可以做的是在做了更改后设置一个标记(在函数末尾:
:normal!m'
),这样您就可以快速跳回那里(通过
`
)。

有趣的是,对于第一个makro,当我点击
u
时,更改被撤消,光标停留在原处(想要的行为)。对于第二个宏,跳转发生在撤消之后。我假设它与第二个宏中的搜索命令有关,但还不确定。
使我回到撤消后的位置,无需附加标记。