チュートリアルアニメーション
のプラグインを作りました。
基本操作を、vim上のpopupなどでアニメーションさせるものです。
ちょっと紹介
最初にテスト用ドキュメントを開きます。
時間を直接指定して、⚪︎秒後にポップアップ、、等をしているだけ。
let s:training_popup_cursor1_winid = 0
let s:training_popup_cursor2_winid = 0
let s:training_popup_window1_winid = 0
let s:training_popup_window2_winid = 0
let s:training_popup_mode1_winid = 0
let s:training_popup_mode2_winid = 0
let s:training_popup_search_winid = 0
let s:training_popup_opeobj_winid = 0
let s:training_popup_tips_winid = 0
let s:training_popup_tips_win_flg = 0
let s:training_popup_tips_win_tid = 0
fu! s:trainingWheelsPopupsActivate()
cal s:trainingWheelsPracticeFileCreate()
cal s:trainingWheelsPopupsAllClose()
let s:training_info_idx = 0
hi TrainingNotification ctermfg=green guifg=green
hi Traininginfo ctermfg=cyan guifg=cyan cterm=BOLD gui=BOLD
cal popup_notification([
\' = Infomation = ',
\' Training Wheels Protocol Activated.',
\' ↓Create and Open practice file. ',
\' ~/practice.md. ',
\' ',
\' To DeActivate',
\' :TrainingWheelsProtocol deactive'
\],#{border:[],
\zindex:999,
\highlight:'TrainingNotification',
\time:3000})
cal timer_start(1000, function('s:trainingInfo'))
cal timer_start(6000, function('s:trainingInfo'))
cal timer_start(6500, function('s:trainingPopupCursor1'))
cal timer_start(6500, function('s:trainingPopupCursor1SampleMv'))
cal timer_start(10000, function('s:trainingInfo'))
cal timer_start(10500, function('s:trainingPopupCursor2'))
cal timer_start(10500, function('s:trainingPopupCursor2SampleMv'))
cal timer_start(15000, function('s:trainingInfo'))
cal timer_start(15500, function('s:trainingPopupWindow1'))
cal timer_start(15500, function('s:trainingPopupWindow1SampleMv'))
cal timer_start(20000, function('s:trainingInfo'))
cal timer_start(20500, function('s:trainingPopupWindow2'))
cal timer_start(20500, function('s:trainingPopupWindow2SampleMv'))
cal timer_start(26000, function('s:trainingInfo'))
cal timer_start(29000, function('s:trainingInfo'))
cal timer_start(29500, function('s:trainingPopupMode1'))
cal timer_start(32000, function('s:trainingInfo'))
cal timer_start(35000, function('s:trainingInfo'))
cal timer_start(35500, function('s:trainingPopupMode2'))
cal timer_start(35500, function('s:trainingPopupMode2SampleMv'))
cal timer_start(38000, function('s:trainingInfo'))
cal timer_start(38500, function('s:trainingPopupSearch'))
cal timer_start(38500, function('s:trainingPopupSearchSampleMv'))
cal timer_start(42000, function('s:trainingInfo'))
cal timer_start(45000, function('s:trainingInfo'))
cal timer_start(45500, function('s:trainingPopupOpeObj'))
cal timer_start(45500, function('s:trainingPopupOpeObjSampleMv'))
cal timer_start(49000, function('s:trainingInfo'))
let s:training_popup_tips_win_tid = timer_start(49500, function('s:trainingPopupTips'))
cal timer_start(49500, function('s:trainingPopupTipsCursor'))
cal timer_start(52000, function('s:trainingInfo'))
endf
といった感じ。各関数では、呼び出されると
ポップアップ表示に加えて、実際のテスト用ドキュメントに操作を行います。
例えば一番最初にカーソルの動かし方をポップアップしますが
cal timer_start(6500, function('s:trainingPopupCursor1'))
cal timer_start(6500, function('s:trainingPopupCursor1SampleMv'))
ここで呼び出している関数は以下のようになっています。
" cursor move
fu! s:trainingPopupCursor1(timer)
let s:training_popup_cursor1_winid = popup_create([
\' ↑ k ',
\' h ← → l ',
\' j ↓ ',
\],#{title: ' cursor move ',
\border: [], zindex: 1,
\line: 3,
\col: &columns - 46
\})
cal matchaddpos("Identifier", [[1,10],[2,2],[2,14],[3,4]], 16, -1, #{window: s:training_popup_cursor1_winid})
endf
fu! s:trainingPopupCursor1SampleMv(timer)
execute("norm gg")
cal cursor(26, 6)
cal timer_start(600, function('s:trainingPopupCursor1SampleMv1'))
cal timer_start(1200, function('s:trainingPopupCursor1SampleMv2'))
cal timer_start(1800, function('s:trainingPopupCursor1SampleMv3'))
cal timer_start(2400, function('s:trainingPopupCursor1SampleMv4'))
endf
fu! s:trainingPopupCursor1SampleMv1(timer)
execute("norm h")
echo("h cursor move")
endf
fu! s:trainingPopupCursor1SampleMv2(timer)
execute("norm j")
echo("j cursor move")
endf
fu! s:trainingPopupCursor1SampleMv3(timer)
execute("norm l")
echo("l cursor move")
endf
fu! s:trainingPopupCursor1SampleMv4(timer)
execute("norm k")
echo("k cursor move")
endf
このように、ポップアップ(+色付け)の表示後に、
execute("norm h")
のようにしてサンプル操作を行います。
ほんとは動かすタイミングで、ポップアップの色付けも押してるキーの色だけつける、とかしたかったんですが
長いので断念しました。。
完成イメージ
左側が空いてるので、実際の操作をしながらチートシートを見られる感じ。
結構殴り書きで作った感じがあるので、本当に初心者がチュートリアルにできるのかは分からないです、、あくまでネタ的なものですね。。
キーマップ多すぎ問題改善系
忘れる、というより久しぶりに使うときにパッとキーを思い出せずにストレスなことがあるのではないでしょうか?
いつもは使わないが、ここぞという時に使いたいものを
メニューにまとめてしまおうということでプラグインに。
もともと自分用にvimrcにいたものをプラグインに吐き出しただけでもあります。
IDE メニュー
※README等いろいろ置き去りになってて、今ではもっと機能が多いです
基本的に、IDE系にするプラグインではLSPの機能が多すぎて
全てをkeymapするのは無理です。
だいたいみなさん
- ファイラ
<leader>f
- エクスプローラ
<leader>e
- 定義元に飛ぶ
gd
<leader>d
- 参照元一覧だす
gr
<leader>r
- 次/前のエラーに
<leader>,
<leader>.
- 関数のドキュメント見る
<leader>?
などしてると思います。私はほぼこれの通りにしてます。
では
- フォーマット
- リネーム
はというと、
format
のf
はファイラと被り、rename
のr
も参照元と被りです。
けどいうほどフォーマッタもリネームもしないと思いますので、メニューから呼び出すでよくね?という思想。
ついでに、スニペットの編集やプログラム実行、デバッグも入れちゃいました。
依存プラグイン等、詳細はREADMEを参照ください。
どういう内容?
メニューのリストと、選んだ時どうするかを
popup_menu
にしているだけ。
let s:idemenu = #{
\ pmenu_default: [],
\ menuid: 0, mttl: ' IDE MENU (j / k) Enter choose ',
\ menu: [
\ '[⚖️ Format] format CocActionAsync',
\ '[♻️ ReName] rename CocActionAsync',
\ '[🎨 Snippet] ultisnips edit',
\ '[⚡️ Run] quickrun',
\ '[⚙️ Debug] vimspector',
\ ],
\ }
fu! s:idemenu.open() abort
let self.menuid = popup_menu(self.menu, #{title: self.mttl, border: [], borderchars: ['─','│','─','│','╭','╮','╯','╰'],
\ callback: 's:idemenu_exe'})
cal setwinvar(self.menuid, '&wincolor', 'String')
hi DarkRed ctermfg=204
cal matchadd('DarkRed', '\[.*\]', 16, -1, #{window: self.menuid})
let self.pmenu_default = execute('hi PmenuSel')[1:]->split(' ')->filter({_,v->stridx(v, '=')!=-1})
hi PmenuSel ctermbg=232 ctermfg=114
endf
fu! s:idemenu_exe(_, idx) abort
if a:idx == 1
cal CocActionAsync('format')
elseif a:idx == 2
cal CocActionAsync('rename')
elseif a:idx == 3
exe 'UltiSnipsEdit'
elseif a:idx == 4
let args = input('stdin>')
cal system('touch .quickrun.tmp.stdin.txt && echo "'.args.'" > .quickrun.tmp.stdin.txt')
sil! exe 'QuickRun <.quickrun.tmp.stdin.txt'
cal system('rm .quickrun.tmp.stdin.txt')
elseif a:idx == 5
cal vimspector#LaunchWithSettings({'configuration': &filetype})
endif
exe 'hi PmenuSel '.join(s:idemenu.pmenu_default, ' ')
retu 0
あとは、これを増やしたければどんどん増やすだけです。
作っては無いですが
メニュー内容をjsonとかで別ファイルに持ち、読み込むようにすれば
汎用的なメニュー作成プラグインとなりますが
まぁ需要がそこまでなさそくなので各自フォークしてソースいじった方がはやそう。
さらにデバッグメニュー
ついでに作りました。
※これもREADME等いろいろ置き去りになってて、今ではもっと機能が多いです
input outputファイルがある時等、競技プログラミングみたいな状況だと便利なので用意しました。
これは特に汎用的ではないですが、acc
oj
コマンドの呼び出しインターフェースとして作った機能がvimrc
の中に溜まっていて行数かさんでいたので、外だししました。
結局これらも
- vim内でコマンド作ったが覚えてないので呼び出せない
- にしてはキーマップも、余っているキーがない
のでメニューにしたという流れ。
機能の詳細はやっぱりレポを参照ください。
(紹介)which-key
キーを押して、「あれ、次何押すんだっけ?」
としている間にメニューが出てくれます。
自分用のkeymapチートシートなんて作る必要がなくなります!
(紹介)コマンドパレット
VSCodeやchrome等のdevツールのように、コマンドをfuzzy検索して実行できるというもの。
キーバインドというより、増えすぎて思い出しにくいコマンドを呼ぶ時に便利。
最後に
自分用に機能を作ると、vimrcが膨れ上がるので
積極的にプラグインにして[vim-plug](https://github.com/junegunn/vim-plug)
などで管理しましょう。