通常のコマンドを実行した後、カーソルの位置を復元する方法は?


13

現在の行の6列目の文字をドル記号($)に置き換える関数をコーディングしようとしていますが、カーソルを関数を呼び出す前の位置に残したいのです。

そこで、現在の列を保存し、変更を実行してから、次の関数を使用して戻ってきました。

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コマンドについて何かを誤解しています...または、実行したいコマンドを含む文字列を作成する必要がありますか?

回答:


19

あなたが使用する必要がありますgetpos()

変数の位置を保存するには:

let save_pos = getpos(".")

getpos()引数としてマークを取り"."ます。ここでは、カーソルの現在位置を表します。

そしてそれを復元するには:

call setpos('.', save_pos)

ここで、最初の引数はカーソルの現在位置のマークを移動することを示し(したがって現在位置)、2番目はマークを置く場所(以前に保存した位置)を示します。

関数は次のようになります。

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の使用目的です。

したがって、実行がなければ、次のように書くことになります。

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
当サイトへようこそ!回答するときは、他のページへのリンクだけでなく、回答内で説明を行ってください。リンクは消滅する可能性があり、ソートするために多くの無関係な情報を持っている場合があります。
タンブラー41 16

1
SO複製で述べたように、復元はfinallyブロックで行われる必要があります。それ以外の場合、a:command失敗すると、何も復元されません。
リュックエルミット


素晴らしい例-非常に便利です。
チャーリーダルサス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.