マクロで挿入モード補完を使用するにはどうすればよいですか?


11

ランダムな単語のリストをすばやく生成するマクロを定義しようとしています。
マクロでこれを次のようなリストに変換したい

a
b
c
d
e

これに

arezzo
bywords
czars
détente
eyrie

これまでのところ:

  • カーソルを文字の上に置く a
  • マクロの記録を開始 qq
  • a 挿入モードに入る
  • <C-x><C-k> - perform dictionary completion on the character before cursor - in this case the lettera`
  • <C-p>表示される補完リストの最後の項目を選択しますarezzo。私のシステムではその単語です。(注意:完了時にこのように動作するために必要な設定にlongest含めました:)。'completeopt'<C-p>'set completeopt=longest,menuone,preview'
  • <C-y> 完了を受け入れる
  • ^[^[ 挿入モードを終了
  • j 次の行に移動して、次の行で同じ操作を実行する準備ができました
  • q 録音を停止

マクロを作成して手順を手動で実行すると、すべてが正常に動作しますが、マクロを実行すると、コマンドラインで次のようなメッセージが点滅します。

辞書ファイルのスキャン

そして、何も起こりません。マクロのコマンドのみjが実行されます。つまり、カーソルは行の下に移動しますが、完了コマンドは実行されません。
マクロで挿入モードの補完を使用することは可能ですか?可能な場合、どうすれば実行できますか?


私はあなたを理解していません<C-p>...ステップを私はvimの中で、それだけでメッセージを与えることを行うときback at original-最後の項目を選択していません..私は最後の単語(私の場合を選択するために二回、矢印キーを使用azures)、入力して押され、次にEsc+j+q..マクロを実行すると非常にうまく機能します
Sundeep

1
@spasicああ良い点、私は言及すべきだったが、私はすぐに挿入する原因となるset completeopt=longest,menuone,previewそのlongestオプションを使用 しています<C-p>。文字列longestから削除すると、completeoptあなたと同じ動作になります。また、はい、矢印キーが機能しました!おかげで(補完リストをナビゲートするためにそれらを使用できることを忘れていました)
the_velour_fog

たぶん、ポップアップメニューが邪魔をしているかもしれません。おそらく試みる:set completeopt=a<c-x><c-k><esc>jマクロなど。
アントニー

@Antony <Cp>が機能しなかった理由はわかりませんが、方向矢印キーは機能しました。
the_velour_fog

回答:


2

編集:本当にあなたは辞書の完成後です。これを行うために必ずしも挿入モード(Ctrl + Xモード)は必要ありません。あなたが発見したように、それはマクロでの作業を本当に苦痛にします。以下のスクリプトを使用して、挿入モードなしでディクショナリの補完を行うことができるため、マクロ内で簡単に繰り返すことができます。

以下のコードを.vimrcファイルに追加し、vimウィンドウを閉じて再度開き、新しい関数のソースを取得してから、交互に押し<C-k>て完了を実行jし、次の行に移動することを記録します。longestオプションのチェックを追加しました。それが無効になっている場合は、システムのランダム時間を使用してランダムなエントリを選択します。longestオプションが見つかると、手動でディクショナリから最長一致エントリを検索し、それを挿入します。

<C-k>マッピングが気に入らない場合は、必要に応じて自由に変更してください。それはあなたが好きなマッピングで動作するはずです。

また、評価するマッピングの式を返すコマンド\<esc>は、最後に文字を追加します。これにより、各挿入後に挿入モードを自動的に終了0cwし、最初に挿入モードに入り、最初に単語全体を上書きすることを確認します。正しく。希望する正確な動作に応じて(単語が各行の先頭にうまく配置されていない場合)bcw、代わりに使用して実際の単語の先頭を見つけることができます。ただし、その行を開始する単語に戻ると、いくつかの奇妙なことがわかります。行末を無視して両方を同時に実行するためのより高度なコマンドがあると思われますが、見つかりませんでした。

map <expr> <C-k> CompleteDictionary()
fun! CompleteDictionary()
    let cword = expand(“<cword>”)
    let res = []
    for m in readfile(&dictionary)
        if m =~ '^' . cword
            call add(res, m)
        endif
    endfor
    if &completeopt =~ 'longest'
        let max = 0
        let maxindex = 0
        let index = 0
        for item in res
            if strlen(item) > max
                let max = strlen(item)
                let maxindex = index
            endif
            let index = index + 1
        endfor
        return "0cw" . res[maxindex] . "\<esc>"
    else
        return "0cw" . res[system('@echo %RANDOM%') % len(res)] . "\<esc>"
    endif
endfun

さらに、ここでロジックを拡張して、挿入モードが提供する機能を実行する代替のマッピングを(たとえば、関数パラメーターを使用して)作成することは難しくありません。時間があれば、このような要件を支援し、このスクリプトを更新していきます。


これは問題のもっともらしい説明のように聞こえますが、私は両方の提案された解決策を試しましたが、どちらも役に立たなかったようです。
リッチ

sleepコマンドも試しましたか?
Tim、

はい。ただし、推奨値の5秒のみです。どちらのソリューションもうまく機能しましたか?手順の完全なリストを投稿できますか?
リッチ

私は質問を書いた人ではありません。しかし、私がすることができ、問題を再現:あなたが追加する必要が最長にするcompleteopt(ではなく、私が再び)コメントで説明したように。編集:おっと、ステップに'longest'必要ですctrl-p:なしctrl-y。それでも手順はで私のために質問アスカーの作品で説明vim -Nu NONEしてcompleteopt編集しました。
リッチ

私は解決策を見つけたと思います。答えを更新するのに数分かかります。
Tim、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.