Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

popup_menu()のcallbackに追加で引数を渡したい

$
0
0

はじめに

popup_menu()のコールバックに(globalに置くような無茶な渡し方などをせずに)上手く追加で値を受け渡す方法を探していて、一つ答えが見つかったのでそのシェアになります。

自分が困ったケース

Vim scriptで選択肢のユーザーインターフェースといえばinputlist()があったと思いますが、最近の機能追加でpopup_menu()が追加され、ポップアップメニューの中からユーザーに選ばせるという選択も増えました。

↓↓popup_menu()の例
スクリーンショット 2019-11-28 1.57.48.png

自分のプラグイン(spelunker.vim)もこれまでinputlist()を使っていたのですが、今回新たにpopup_menu()も利用できるように修正を行おうと思ったのですが、下記のような問題があり、これまでのinputlist()をそのまま置き換えるような修正はできなさそうでした。

これまでのinputlist()の実装例

" ユーザーが選ぶfunction select(arg)letl:list =['111','222','333']letl:selected = inputlist(l:list)" このあとl:selectedを使ってなんかするendfunction

popup_menu()を使う場合の実装例

function select(arg)" ユーザーが選ぶとコールバックが呼ばれるletl:list =['111','222','333']call popup_menu(l:list, #{            \ callback:'callbackFunction',            \ pos:'topleft',            \ line:'cursor+1',            \col:'cursor'            \})endfunctionfunction calbackFunction(id, selected)" a:selectedを使ってなんかするendfunction

ポップアップメニュー選択後、コールバックが呼び出されるようになります。
こうなってくるとselect()の関数内で持っている変数で(a:argなど)、このあとの処理でも使いたい変数はどうやってcalbackFunction()に受け渡せばいいのか...などなど、これは設計にも影響してきそうです。

コールバックに追加で引数を渡す

こちらの記事のクロージャの項目の内容的なアプローチを取ってみます。
https://vim-jp.org/vim-users-jp/2010/08/13/Hack-167.html

" argをコールバックに渡したい!functions:select(arg)" 記事中のクロージャの項目の内容的なアプローチ" https://vim-jp.org/vim-users-jp/2010/08/13/Hack-167.htmlletl:callback ={'arg':a:arg}functionl:callback.funcall(id, selected) dict
        call Popup_callback(a:id,a:selected, self.arg)endfunctionletl:list =['111','222','333']call popup_menu(l:list, #{                \ callback:l:callback.funcall,                \ pos:'topleft',                \ line:'cursor+1',                \col:'cursor'                \})endfunctionfunction Popup_callback(id, selected,arg)" ここでもs:select()のarg(a:arg)を使える!endfunction

引数が上手く追加できましたね。
また、これは簡単にするとこうにもなります。

functions:select(arg)letl:callback ={'arg':a:arg}functionl:callback.funcall(id, selected) dict
        " callbackとしてやりたかった内容をここに移動します" self.argもa:id, a:selectedも使えますendfunctionletl:list =['111','222','333']call popup_menu(l:list, #{                \ callback:l:callback.funcall,                \ pos:'topleft',                \ line:'cursor+1',                \col:'cursor'                \})endfunction

これで一応、popup_menu()の呼び出し元のスコープにある変数の受け渡しができました🙌


Viewing all articles
Browse latest Browse all 5608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>