Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Vim Tatsuhiro Ujihisa RailsDM 2018-07-14

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

Topics ● オススメのVimの使い方 ○ これを入れるだけで生産性7倍 ○ EP, FPなどの重要なコンセプト ○ 目でみたとこにカーソルが移動し、入力を全く 阻害しないなめらかなVimさばきの技法 ● if_ruby完全活用方法 ● vimのC実装のrestart_edit 変数

Slide 6

Slide 6 text

src/main.c

Slide 7

Slide 7 text

Topics ● オススメのVimの使い方 ○ これを入れるだけで生産性7倍 ○ EP, FPなどの重要なコンセプト ○ 目でみたとこにカーソルが移動し、入力を全く 阻害しないなめらかなVimさばきの技法 ● if_ruby完全活用方法 ● vimのC実装のrestart_edit 変数

Slide 8

Slide 8 text

Topic ● オススメのVimの使い方 ○ これを入れるだけで生産性7倍 ○ EP, FPなどの重要なコンセプト ○ 目でみたとこにカーソルが移動し、入力を全く 阻害しないなめらかなVimさばきの技法 ● if_ruby完全活用方法 ● vimのC実装のrestart_edit 変数

Slide 9

Slide 9 text

Topic ● オススメのVimの使い方 ○ これを入れるだけで生産性7倍 ○ EP, FPなどの重要なコンセプト ○ 目でみたとこにカーソルが移動し、入力を全く 阻害しないなめらかなVimさばきの技法 ● if_ruby完全活用方法 ● vimのC実装のrestart_edit 変数 ○ vimの挿入モード (Insert mode)の仕様 ○ vimの挿入モードに入る実装

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

Vimとは ● Text editor ○ ○ ○ ○ ● 人生

Slide 13

Slide 13 text

Vimとは ● Text editor (not text inputter) ○ ○ ○ ○ ● 人生

Slide 14

Slide 14 text

Vimとは ● Text editor (not text inputter) ○ モード遷移 ■ ○ Vim scriptランタイム ○ ファイル・バッファ操作 ○ 画面レンダリング ● 人生

Slide 15

Slide 15 text

Vimとは ● Text editor (not text inputter) ○ モード遷移 ■ (ノーマルモード、挿入モードなど) ■ 有限状態機械 ○ Vim scriptランタイム ○ ファイル・バッファ操作 ○ 画面レンダリング ● 人生

Slide 16

Slide 16 text

Vimのモード ● 起動時はNormal mode ● iとかaとかするとInsert modeに入る ○ ● とかとかするとNormal modeに戻る

Slide 17

Slide 17 text

Vimのモード ● 起動時はNormal mode ● iとかaとかするとInsert modeに入る ○ Q. Insert modeに入るキーは全部で何種類 か ● とかとかするとNormal modeに戻る

Slide 18

Slide 18 text

Vimのモード ● 起動時はNormal mode ● iとかaとかするとInsert modeに入る ○ Q. Insert modeに入るキーは全部で何種類か ○ 9 ○ a, A, , i, I, gI, gi, o, O ● とかとかするとNormal modeに戻る

Slide 19

Slide 19 text

Normal modeからInsert modeに入る9つの四天王 ● a カーソルの後に挿入 ● A 行末に挿入 (:startinsert!) ● iと同じ ● i カーソルの前に挿入 (:startinsert) ● I (インデントのあとの)行先頭に挿入 ● gI 行先頭に挿入 ● gi 最後に入力あった場所に挿入 ● o 下の行を作ってそこに挿入 ● O 上の行を作ってそこに挿入

Slide 20

Slide 20 text

Insert modeからnormal modeに入るには ● escと同じ ● はい ● abbrとかInsertLeaveイベントを無視 ● 前回入力したものを入れて ○ と同じ ○ 互換性のためにあるっぽいので忘れていい ■ 現代人ならnormap modeで.でリピート ● normal modeの命令一つだけできる特 殊状態に遷移 (後述)

Slide 21

Slide 21 text

Insert modeのについて詳しく :h i_CTRL-o ● 何か一個だけコマンドできる ○ hjkl移動とか (1回だけ) ○ :からのex command実行とか ● 大抵の場合key mapping用 ○ :call your_function() ○ とかをmapして 挿入モードの関数呼び出しとか

Slide 22

Slide 22 text

ドットリピート ● . で直前のテキスト編集を繰り返す ● Insert modeでの一連の入力を再現 ○ 一連の、とは →デモ

Slide 23

Slide 23 text

Vimのcountの概念 ● countは至るところにある ● 任意の何かに付与可能 ○ motion ○ operation ○ command ○ ex command ○ →デモ

Slide 24

Slide 24 text

ここまでのまとめ ● Vimはいろんな方法でInsert modeに入れる ● いろんな方法でNormal modeに戻れる ● バッファ書き換えの単位の概念がある ○ .でリピートしたり、countで複数回同じのやった り

Slide 25

Slide 25 text

突然のクイズ ● 3gihelloworld ● 結果どうなる?

Slide 26

Slide 26 text

突然のクイズ ● 3gihellohworld ● 結果どうなる? 3gi 後続するgiからまでを3回やる gi 最後に挿入したとこからinsert mode突入 一瞬normal modeに入り、あとでinsert mode に戻る h 左に1文字移動

Slide 27

Slide 27 text

正解 helworldlo countの3は無視される :h i

Slide 28

Slide 28 text

ここまで全部 :h に載ってる :h inserting ↑ででてくる insert.txt はとりあえず通読した方がいいかも https://vim-jp.org/vimdoc-ja/insert.html

Slide 29

Slide 29 text

ここから 実装レベルに入る 具体的なパッチとかも例に

Slide 30

Slide 30 text

https://github.com/vim/vim

Slide 31

Slide 31 text

src/main.c

Slide 32

Slide 32 text

int main(int argc, char **argv) { return vim_main2(); } int vim_main2(void) { main_loop(FALSE, FALSE); } void main_loop(int cmdwin, int noexmode) { oparg_T oa; while(...) { if(...) { normal_cmd(&oa, TRUE); }} } src/main.c (超要約バージョン)

Slide 33

Slide 33 text

int main(int argc, char **argv) { return vim_main2(); } int vim_main2(void) { main_loop(FALSE, FALSE); } void main_loop(int cmdwin, int noexmode) { oparg_T oa; while(...) { if(...) { normal_cmd(&oa, TRUE); }} } src/main.c (超要約バージョン)

Slide 34

Slide 34 text

void normal_cmd(oparg_T *oap, int toplevel UNUSED) { cmdarg_T ca; int idx; if (...) { idx = find_command(ca.cmdchar); ca.arg = nv_cmds[idx].cmd_arg; (nv_cmds[idx].cmd_func)(&ca); } } src/normal.c (超要約バージョン)

Slide 35

Slide 35 text

void normal_cmd(oparg_T *oap, int toplevel UNUSED) { cmdarg_T ca; int idx; if (...) { idx = find_command(ca.cmdchar); ca.arg = nv_cmds[idx].cmd_arg; (nv_cmds[idx].cmd_func)(&ca); } } src/normal.c (超要約バージョン)

Slide 36

Slide 36 text

void normal_cmd(oparg_T *oap, int toplevel UNUSED) { cmdarg_T ca; int idx; if (...) { idx = find_command(ca.cmdchar); ca.arg = nv_cmds[idx].cmd_arg; (nv_cmds[idx].cmd_func)(&ca); } } src/normal.c (超要約バージョン)

Slide 37

Slide 37 text

void normal_cmd(oparg_T *oap, int toplevel UNUSED) { cmdarg_T ca; int idx; if (...) { idx = find_command(ca.cmdchar); ca.arg = nv_cmds[idx].cmd_arg; (nv_cmds[idx].cmd_func)(&ca); } } src/normal.c

Slide 38

Slide 38 text

void normal_cmd(oparg_T *oap, int toplevel UNUSED) { cmdarg_T ca; int idx; if (...) { idx = find_command(ca.cmdchar); ca.arg = nv_cmds[idx].cmd_arg; (nv_cmds[idx].cmd_func)(&ca); } } src/normal.c

Slide 39

Slide 39 text

void normal_cmd(oparg_T *oap, int toplevel UNUSED) { cmdarg_T ca; int idx; if (...) { idx = find_command(ca.cmdchar); ca.arg = nv_cmds[idx].cmd_arg; (nv_cmds[idx].cmd_func)(&ca); } } src/normal.c {'A', nv_edit, 0, 0}, {'I', nv_edit, 0, 0}, {'a', nv_edit, NV_NCH, 0}, {'i', nv_edit, NV_NCH, 0}, {K_INS, nv_edit, 0, 0}, {K_KINS, nv_edit, 0, 0}, {K_PS, nv_edit, 0, 0}, {'O', nv_open, 0, 0}, {'o', nv_open, 0, 0},

Slide 40

Slide 40 text

src/normal.c

Slide 41

Slide 41 text

src/normal.c

Slide 42

Slide 42 text

src/normal.c invoke_edit( cap, FALSE, cap->cmdchar, FALSE); // in invoke_edit() edit( cmd, startln, cap->count1)

Slide 43

Slide 43 text

src/normal.c invoke_edit( cap, FALSE, cap->cmdchar, FALSE); // in invoke_edit() edit( cmd, startln, cap->count1) 以下1300行くらい

Slide 44

Slide 44 text

ここまでのまとめ ● Vimはモードがあってiとかとかで切替 ● Vim起動したらまず初期化 ● main_loop()内で無限ループ ● normal_cmd()内で ○ キー入力に対応する関数を探索 ○ 探索には配列nv_cmdsを使用 ( ● i とは、nv_edit() → invoke_edit() → edit()

Slide 45

Slide 45 text

src/README.txt に書いてる このスライドできてから気づいた

Slide 46

Slide 46 text

本題 ● restart_edit ● vim頻出単語 ● $ git grep '\brestart_edit\b' | wc -l ○ 116 ● undocumented (.txtに書かれてない)

Slide 47

Slide 47 text

の前に ちょっとCM 提供: VimConf準備会

Slide 48

Slide 48 text

VimConf https://vimconf.org/2018

Slide 49

Slide 49 text

https://vimconf.org/2018

Slide 50

Slide 50 text

https://vimconf.org/2018 VimConf 2018 ● 2018-11-24 ● 秋葉原 ● 国際カンファレンス (英日も日英も全発表に対して 同時通訳あり) ● スポンサー急募中 ● 発表募集中

Slide 51

Slide 51 text

https://vimconf.org/2018 VimConf 2018 ● 2018-11-24 ● 秋葉原 ● 国際カンファレンス (英日も日英も全発表に対して 同時通訳あり) ● スポンサー急募中 ● 発表募集中

Slide 52

Slide 52 text

https://vimconf.org/2018 VimConf 2018 ● 2018-11-24 ● 秋葉原 ● 国際カンファレンス (英日も日英も全発表に対して 同時通訳あり) ● スポンサー急募中 ● 発表募集中 https://vimconf.org/2018 https://vimconf.org/2018 https://vimconf.org/2018 https://vimconf.org/2018 https://vimconf.org/2018

Slide 53

Slide 53 text

https://twitter.com/supermomonga/status/100887008 3215613954

Slide 54

Slide 54 text

本題 ● restart_edit ● vim頻出単語 ● $ git grep '\brestart_edit\b' | wc -l ○ 116 ● undocumented (.txtに書かれてない)

Slide 55

Slide 55 text

src/edit.c

Slide 56

Slide 56 text

src/edit.c

Slide 57

Slide 57 text

src/edit.c

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

EXTERN int restart_edit INIT(= 0); /* call edit when next cmd finished */ (src/globals.h) // とかじゃなくて普通のNormal mode restart_edit = 0; // iの中でしたとき restart_edit = 'i'; // 一欄 0, 'i', 'I', 'a', 'A', 'R', 'V'

Slide 60

Slide 60 text

https://github.com/vim-jp/issues/issues/1147

Slide 61

Slide 61 text

https://vim-jp.slack.com/archives/C83UXKU86/p15 28776532000106

Slide 62

Slide 62 text

https://twitter.com/fatih/status/10072503322 61519360

Slide 63

Slide 63 text

Suggested solution ● mode(): 現在のモードを返す関数 ○ mode(1) で詳細 ● 現在、normal modeでも, insert modeからの 、どちらもmode()返り値は"n" ● 提案: Insert modeからのは ○ mode() = "n" (互換性保つ) ○ mode(1) = "ni"

Slide 64

Slide 64 text

https://github.com/vim/vim/pull/3000

Slide 65

Slide 65 text

No content

Slide 66

Slide 66 text

ujihisa ● https://twitter.com/ujm ● https://github.com/ujihisa ● VimConf主催者 ● 元Hootsuiteソフトウェアエンジニア ○ Twitterクライアントのあれ ● 元Fablicソフトウェアエンジニア ○ FRILとかラクマのあれ

Slide 67

Slide 67 text

ujihisa 最近の活動 ● 明日: 友人宅で2~4kgの魚を捌く予定 ● 明々後日: asakusa.rbで同上 ● 再来週: 隅田川花火大会で同上 ● 一ヶ月くらい就活中

Slide 68

Slide 68 text

Vim Tatsuhiro Ujihisa RailsDM 2018-07-14

Slide 69

Slide 69 text

ujihisa's past talks ● 2017 ○ 「高濃度雑談」大江戸 Ruby会議 ○ 「Vim」TokyuRuby会議11 (LT) ○ 「How to develop CRuby easily with Vim」RubyKaigi 2017 (LT) ● 2015 ○ 「Vim + Clojure」VmConf 2015 ● 2014 ○ 「PM2」VimConf 2014 ● 2013 ○ 「vital.ProcessManager」VimConf 2013 ● Older ○ RubyConf 2009 ○ RubyKaigi 2009 ○ RubyKaigi 2008