执行普通命令后如何恢复光标位置?


13

我正在尝试编写一个函数,用美元符号($)替换当前行第六列中的字符,但是我希望光标保持在调用该函数之前的位置。

因此,我尝试存储当前列,执行更改,然后返回以下函数:

function! DollarSplit()
   let col_number=col(".")     "stores the current column number of the cursor
   normal! 6|r$                " replaces the 6th caracter in line with a $
   execute col_number."|" 
endfunction

我可能对execute命令有一些误解...或者我应该创建一个包含要执行的命令的字符串?

Answers:


19

您应该使用getpos()

要将您的排名保存在变量中:

let save_pos = getpos(".")

getpos()以一个标记作为参数,这里"."表示光标的当前位置。

并还原它:

call setpos('.', save_pos)

在这里,第一个参数表示您将移动光标当前位置的标记(因此移动当前位置),第二个参数是放置标记的位置(先前保存的位置)。

您的函数如下所示:

function! DollarSplit()
   let save_pos = getpos(".")
   normal! 6|r$                " replaces the 6th caracter in line with a $
   call setpos(".", save_pos)
endfunction

有关更多详细信息,请参见::h getpos():h setpos()


有关execute:用法的更多详细信息,此函数将使用字符串并执行它。您的字符串只能是双引号或变量内容之间的硬编码字符。

当你写

execute col_number."|"

如果您位于第12列,则扩展字符串将为12|。Execute会尝试执行此命令,但是它12|不是vimscript函数,而是普通模式命令,因此将无法运行。

要从vimscript中执行它,您必须说“执行它,就像我在正常模式下键入它一样”,这就是正常的用途。

因此,如果没有执行,您将编写:

normal 12|

现在,要使execute呼叫正常工作,您必须将normal关键字添加到扩展的字符串中,如下所示:

execute "normal " . col_number . "|"

感谢您提供此解决方案(这是我将要使用的解决方案),但是还有其他方法可以使用我的“ col_number”变量吗?那将使我更好地了解如何执行/正常工作。
菲夫

1
@Feffe:我的更新应该澄清这一点:-)
statox

3

此功能还保留您的搜索注册。因此,您可以将命令作为参数传递给它。

if !exists('*Preserve')
    function! Preserve(command)
        try
            " Preparation: save last search, and cursor position.
            let l:win_view = winsaveview()
            let l:old_query = getreg('/')
            silent! execute 'keepjumps' . a:command
        finally
            " try restore / reg and cursor position
            call winrestview(l:win_view)
            call setreg('/', l:old_query)
        endtry
    endfunction
endif

一些解释

let .......... used to set a variable
l:somevar .... local variable
winsaveview()  get information about window view
winrestview(lwinview) restores window view to its last status
getreg('/')    used to store the last search in a variable
keepjumps      used to performe any change without change jumplis
. a:command    concatenates any given command with keepjumps

例如:

"Reident file without moving cursor position
:call Preserve('normal! gg=G')

"Reindent command using 'Preserve()'
command! -nargs=0 Reindent :call Preserve('exec "normal! gg=G"')

"If you have any change log at your file header
:call Preserve('1,5s/Last Change: \zs.*/\=strftime("%c")/e')

"Close all buffers but current one
" https://bitbucket.org/snippets/sergio/9nbyGy
command! BufOnly silent! call Preserve("exec '%bd|e#|bd#'")

来源:https : //technotales.wordpress.com/2010/03/31/preserve-a-vim-function-that-keeps-your-state/


1
欢迎来到我们的网站!回答时,尝试在答案中给出一些解释,而不仅仅是指向其他页面的链接。链接可能会消失,并且可能有很多不相关的信息需要分类。
Tumbler41年

1
正如我在SO副本中所说的那样,恢复应该在一个整体中进行finally。否则,如果a:command失败,将无法恢复任何内容。
卢克·赫米特

正如您提到的那样,
SergioAraujo,

很好的例子-非常有用。
查理·达萨斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.