2010-11-30 1 views
7

状況#1:テキストブロックを選択しました。次に、「:Command」と入力すると、何らかの関数が呼び出されます。コマンドによって呼び出された関数からVimに現在アクティブなビジュアル選択があるかどうかを確認します。

状況2:現在のところ、視覚的な選択はありません(編集セッションで以前にこのような選択をしている可能性があります)。私は ":Command"とタイプし、(同じ)機能を呼び出します。

上記の2つの状況を機能内から区別する(堅牢な)方法はありますか?私はmode()を試しましたが、問題はどちらの場合もコマンドモードですが、最初のケースではビジュアルモードからコマンドモードに入りましたが、2番目はノーマルモードからでした。おそらく検査の結果、a:firstline/a:lastline/v:count


更新 - ユースケースの例: ":Sum"。現在の視覚的な選択、例えば数字の列(ブロック選択)または数字だけを含む範囲の範囲がある場合、このコマンドは数字の合計をエコーする。そうでなければ、スペースで区切られた数字のリストを引数として期待し、それらの数字の合計をエコーし​​ます。基本フレームワーク:

command! -nargs="*" -range Sum :call CalcSum(<f-args>) 
function! CalcSum(...) range 
    " 1. collect numbers from visual selection if there is a current active selection 
    " 2. otherwise, if len(args) > 0, collect numbers from args 
    " 3. other cases (i.e., no selection and no args or both selection and args) handled reasonably 
    " 4. sum collection of numbers 
    " 5. return/echo result 
endfunction 

手順(2)〜(5)は簡単です。私は(1)に問題があります。 「<"/">」マーカーを使用して、視覚的な選択肢から数値を収集し直します。しかし、私はの場合にのみの視覚的選択が現在強調表示されている/アクティブである場合、これを行うだけです。

多分私のロジック全体が間違っていて、この機能を設計する良い方法がありますか?

答えて

6

コマンドを使用する必要がある場合は、私が見る唯一の方法は、a:firstline/a:lastlineを検査することである。

" Assuming that you have passed -range=% when defining command 
if a:firstline==1 && a:lastline==line('$') 
    " Do something 
endif 

いますが、バッファ全体を選択したときに、これはケースを保持していません。私はあなたが表現のマッピングを使用することをお勧め:

function DoCommand() 
    if mode()!~#"^[vV\<C-v>]" 
     " Do something. For example, set global variable (and unset it in :Command) 
    endif 
    return ':Command' 
endfunction 
noremap <expr> {lhs} DoCommand() 

更新:ビジュアルモードは決してアクティブコマンドモードでです。決して。コマンドモードがビジュアルモードではないからです。マッピングを使うことはあなたが望むことを達成するための唯一の方法であり、2つのアプローチがあります:すべてのモードで全く同じexprマッピングを使用し、mode()をこの式のどこかにチェックするか、異なるモードに異なるマッピングを定義し、どのモードで呼び出されますか。

+0

ありがとうございました。これは可能な唯一のアプローチのように見えます。 – Jeet

関連する問題