多用するのでプラグイン作ってみた。class
って書いたりpackage ... {
って括弧書いたり面倒だよね。
超適当配布なので VimScript 1ファイル製。
仕様
変換ルール
記法 | 変換 | 備考 |
---|---|---|
. foo | package foo | html の class 属性のイメージで . にした |
# foo | namespace foo | html の id 属性のイメージで # にした |
+ Foo | class Foo | |
- Foo | enum Foo | |
* Foo | interface Foo | |
空行 | 捨てられる | 実装辛くてどーでも良くなってしまった |
それ以外 | そのまま | 線とかコメントとか |
HTML のリスト記法のイメージなので、
. foo
+ FooId
# FooType
が
package foo {
class FooId
enum FooType
}
になるってこと。
ソース
command! PlantVim call PlantVim()function! PlantVim()call s:init(getline(1,'$'))let node = s:subs(0)
execute 'normal ggdG'call s:put('@startuml')call s:put('')call s:indentingSetLine(node,'')call s:put('')call s:put('@enduml')
execute 'normal Gddgg0'endfunctionfunction! s:init(input)letg:n=0letg:input = filter(a:input,'v:val != ""')letg:max = len(g:input)-1endfunctionfunction! s:subs(depth)let xs = []whileg:n<=g:max && s:depth(g:input[g:n])>=a:depthletg:n=g:n+1if s:depth(g:input[g:n-1])==a:depthif s:needParse(g:input[g:n-1])=='true'let parsed = s:parse(g:input[g:n-1])let parsed['subs'] = s:subs(a:depth +1)let xs = xs + [parsed]elselet xs = xs + [{'line': g:input[g:n-1],'output': 'raw','subs': []}]endifendifendwhilereturn xsendfunctionfunction! s:depth(line)letx=0forcin split(a:line,'\zs')ifc==' 'letx=x+1elsebreakendifendforreturnx / 2endfunctionfunction! s:parse(line)let type = {'.': 'package','#': 'namespace','+': 'class','-': 'enum','*': 'interface'}[split(a:line,'^ ')[0][0]]let containable = get({'package': 'containable','namespace': 'containable'}, type,'no_contains')let content = split(a:line,' ')[1]return {'line': type . ' ' . content,'output': containable}endfunctionfunction! s:needParse(line)return(a:line =~'\.\|#\|+\|- \|\*')==1 ? 'true' : 'false'endfunctionfunction! s:indentingSetLine(node, pad)for elm ina:nodeif elm['output'] =='containable'call s:put(a:pad . elm['line'] . ' {')call s:indentingSetLine(elm['subs'],a:pad . ' ')call s:put(a:pad . '}')elseif elm['output'] =='no_contains'call s:put(a:pad . elm['line'])elsecall s:put(elm['line'])endifendforendfunctionfunction! s:put(line)call append(line('$')-1,a:line)endfunction
導入
上のファイルをplant.vim
という名前で保存して、vi を起動して:so ~/Downloads/plant.vim
をする。(パスは読み替えて)
インデント略記が書き終わったら:PlantVim
とすると変換される。
デモ
おしまい
while
とかグローバル変数と添字アクセスとか数年ぶりに書いた。ちょー辛い、もう二度とやりたくない。
本当は改行を保ちたいとか不可逆だしファイルを書き換えちゃうのでやり直しが効かないとか対応したかったけど、これ以上を VimScript 1ファイルでやるのはもう無理。
気に入って、かつ機能追加したくなったらメインロジックは全部 haskell か何かに移して VimScript はすっかすかにする。
ノシ