├── README.md ├── after └── ftplugin │ └── ruby │ └── monster.vim ├── autoload ├── monster.vim └── monster │ ├── cache.vim │ ├── completion.vim │ ├── completion │ ├── rcodetools.vim │ ├── rcodetools │ │ ├── async_rct_complete.vim │ │ └── rct_complete.vim │ ├── solargraph.vim │ └── solargraph │ │ ├── async_solargraph_suggest.vim │ │ └── solargraph_suggest.vim │ ├── context.vim │ └── debug.vim ├── doc └── monster.jax └── plugin └── monster.vim /README.md: -------------------------------------------------------------------------------- 1 | # monster.vim 2 | 3 | Ruby のコード補完プラグイン 4 | 5 | 6 | ## Requirement 7 | 8 | どちらかをインストールします。 9 | 10 | * __gem__ 11 | * `gem install rcodetools` 12 | * `gem install solargraph` 13 | 14 | solargraph を使う場合は以下を設定します。 15 | 16 | ```vim 17 | let g:monster#completion#backend = 'solargraph' 18 | ``` 19 | 20 | ## Screencapture 21 | 22 | ![monster](https://cloud.githubusercontent.com/assets/214488/3964723/7bc02e7e-278c-11e4-8578-1785aabecf85.gif) 23 | 24 | ## Using 25 | 26 | `` でコード補完を開始します。 27 | 28 | ## Setting 29 | 30 | ```vim 31 | " Use neocomplete.vim 32 | let g:neocomplete#sources#omni#input_patterns = { 33 | \ "ruby" : '[^. *\t]\.\w*\|\h\w*::', 34 | \} 35 | ``` 36 | 37 | ## Setting by async completion 38 | 39 | * Requirement 40 | * [vimproc.vim](https://github.com/Shougo/vimproc.vim) 41 | 42 | ```vim 43 | " Set async completion. 44 | let g:monster#completion#rcodetools#backend = "async_rct_complete" 45 | " Or let g:monster#completion#solargraph#backend = "async_solargraph_suggest" 46 | 47 | " With neocomplete.vim 48 | let g:neocomplete#sources#omni#input_patterns = { 49 | \ "ruby" : '[^. *\t]\.\w*\|\h\w*::', 50 | \} 51 | 52 | " With deoplete.nvim 53 | let g:monster#completion#rcodetools#backend = "async_rct_complete" 54 | " Or let g:monster#completion#solargraph#backend = "async_solargraph_suggest" 55 | let g:deoplete#sources#omni#input_patterns = { 56 | \ "ruby" : '[^. *\t]\.\w*\|\h\w*::', 57 | \} 58 | ``` 59 | -------------------------------------------------------------------------------- /after/ftplugin/ruby/monster.vim: -------------------------------------------------------------------------------- 1 | 2 | " if !monster#rcodetools#rct_complete#check() 3 | " finish 4 | " endif 5 | 6 | setlocal omnifunc=monster#omnifunc 7 | 8 | 9 | " augroup monster-ftplugin-ruby 10 | " autocmd! * 11 | " autocmd InsertLeave call monster#rcodetools#async_rct_complete#cancel() 12 | " augroup END 13 | 14 | -------------------------------------------------------------------------------- /autoload/monster.vim: -------------------------------------------------------------------------------- 1 | scriptencoding utf-8 2 | let s:save_cpo = &cpo 3 | set cpo&vim 4 | 5 | 6 | let g:monster#debug = get(g:, "monster#debug", 1) 7 | 8 | 9 | function! monster#errmsg(errors) 10 | if type(a:errors) != type([]) 11 | return monster#errmsg(split("[monster.vim] " . a:errors, '[\n\r]')) 12 | endif 13 | echohl ErrorMsg 14 | try 15 | for text in a:errors 16 | echom substitute(text, "\t", " ", "g") 17 | endfor 18 | finally 19 | echohl NONE 20 | endtry 21 | endfunction 22 | 23 | 24 | let s:log_data_list = [] 25 | function! monster#debug_log(text) 26 | return monster#debug#echo(a:text) 27 | endfunction 28 | 29 | 30 | function! monster#get_debug_log() 31 | return monster#debug#log() 32 | endfunction 33 | 34 | function! monster#clear_debug_log() 35 | return monster#debug#clear_log() 36 | endfunction 37 | 38 | 39 | function! monster#current_context(...) 40 | return call("monster#context#get_current", a:000) 41 | endfunction 42 | 43 | 44 | function! s:tempfile(ext) 45 | return strftime("monster-vim-%Y-%m-%d-%H-%M-%S.") . a:ext 46 | endfunction 47 | 48 | 49 | function! s:make_tempfile(bufnr, ...) 50 | let ext = get(a:, 1, expand("#" . a:bufnr . ":e")) 51 | let filename = expand("#" . a:bufnr . ":p:h") . "/" . s:tempfile(ext) 52 | let filename = substitute(filename, '\', '/', "g") 53 | if writefile(getbufline(a:bufnr, 1, "$"), filename) == -1 54 | return "" 55 | else 56 | return filename 57 | endif 58 | endfunction 59 | 60 | 61 | function! monster#make_tempfile(...) 62 | return call("s:make_tempfile", a:000) 63 | endfunction 64 | 65 | 66 | function! monster#start_complete(...) 67 | let force = get(a:, 1, 0) 68 | let base = get(a:, 2, get(s:, "start_complete_context", {})) 69 | let context = extend(monster#context#get_current(), base) 70 | 71 | if mode() !~# 'i' && !force 72 | return -1 73 | endif 74 | if mode() !~# 'i' 75 | startinsert! 76 | let s:start_complete_context = base 77 | call feedkeys("\=monster#start_complete()?'':''\", "n") 78 | return 0 79 | endif 80 | 81 | let baseline = getline(".")[context.start_col : col(".")] 82 | " if baseline =~ '\s' 83 | " return "" 84 | " endif 85 | 86 | let items = monster#completion#complete(context) 87 | call filter(items, 'v:val.word =~ ''^'' . baseline') 88 | if empty(items) 89 | return -1 90 | endif 91 | 92 | call complete(context.start_col + 1, items) 93 | return 0 94 | endfunction 95 | 96 | 97 | 98 | let g:monster#enable_neocomplete = get(g:, "monster#enable_neocomplete", 0) 99 | 100 | let g:monster#enable = get(g:, "monster#enable", 1) 101 | 102 | function! monster#omnifunc(findstart, base) 103 | if g:monster#enable == 0 104 | return 0 105 | endif 106 | if a:findstart == 0 107 | if empty(get(s:, "result", {})) 108 | return [] 109 | endif 110 | try 111 | return filter(copy(s:result), 'v:val.word =~ ''^'' . a:base') 112 | finally 113 | echo "monster.vim - finish completion" 114 | unlet! s:result 115 | endtry 116 | endif 117 | unlet! s:result 118 | 119 | " let failed = g:monster#enable_neocomplete ? -1 : -3 120 | let failed = -1 121 | " PP! monster#debug#callstack() 122 | " if monster#debug#callstack()[0] == "monster#omnifunc" 123 | " let failed = -3 124 | " else 125 | " let failed = -1 126 | " endif 127 | 128 | " コメント時は補完しない 129 | if synIDattr(synIDtrans(synID(line("."), col(".")-1, 1)), 'name') ==# "Comment" 130 | echo "monster.vim - failed completion" 131 | return failed 132 | endif 133 | 134 | echo "monster.vim - start completion" 135 | let context = monster#context#get_current() 136 | let s:result = monster#completion#complete(context) 137 | if empty(s:result) 138 | echom "monster.vim - empty completion" 139 | return -2 140 | endif 141 | return context.start_col 142 | endfunction 143 | 144 | 145 | 146 | let &cpo = s:save_cpo 147 | unlet s:save_cpo 148 | -------------------------------------------------------------------------------- /autoload/monster/cache.vim: -------------------------------------------------------------------------------- 1 | scriptencoding utf-8 2 | let s:save_cpo = &cpo 3 | set cpo&vim 4 | 5 | 6 | let s:cache = {} 7 | 8 | function! monster#cache#add(context, data) 9 | let s:cache[a:context.cache_keyword] = a:data 10 | return a:data 11 | endfunction 12 | 13 | 14 | function! monster#cache#clear(context) 15 | unlet! s:cache[a:context.cache_keyword] 16 | endfunction 17 | 18 | 19 | function! monster#cache#clear_all() 20 | let s:cache = {} 21 | endfunction 22 | 23 | 24 | function! monster#cache#is_exists(context) 25 | return has_key(s:cache, a:context.cache_keyword) 26 | endfunction 27 | 28 | 29 | function! monster#cache#get(context) 30 | if monster#cache#is_exists(a:context) 31 | return s:cache[a:context.cache_keyword] 32 | endif 33 | return [] 34 | endfunction 35 | 36 | 37 | 38 | augroup monster-cache 39 | autocmd! 40 | autocmd InsertEnter * call monster#cache#clear_all() 41 | augroup END 42 | 43 | 44 | let &cpo = s:save_cpo 45 | unlet s:save_cpo 46 | -------------------------------------------------------------------------------- /autoload/monster/completion.vim: -------------------------------------------------------------------------------- 1 | scriptencoding utf-8 2 | let s:save_cpo = &cpo 3 | set cpo&vim 4 | 5 | 6 | let g:monster#completion#backend = get(g:, "monster#completion#backend", "rcodetools") 7 | 8 | 9 | function! monster#completion#complete(context) 10 | if monster#cache#is_exists(a:context) 11 | return monster#cache#get(a:context) 12 | endif 13 | let result = monster#completion#{g:monster#completion#backend}#complete(a:context) 14 | if empty(result) 15 | return [] 16 | endif 17 | return monster#cache#add(a:context, result) 18 | endfunction 19 | 20 | 21 | let &cpo = s:save_cpo 22 | unlet s:save_cpo 23 | -------------------------------------------------------------------------------- /autoload/monster/completion/rcodetools.vim: -------------------------------------------------------------------------------- 1 | scriptencoding utf-8 2 | let s:save_cpo = &cpo 3 | set cpo&vim 4 | 5 | let g:monster#completion#rcodetools#backend = get(g:, "monster#completion#rcodetools#backend", "rct_complete") 6 | 7 | let g:monster#completion#rcodetools#complete_command = get(g:, "monster#completion#rcodetools#complete_command", "rct-complete") 8 | 9 | function! s:parse(text) 10 | let parsed = split(a:text, '\t') 11 | return { 12 | \ "word" : get(parsed, 0, ""), 13 | \ "menu" : get(parsed, 1, ""), 14 | \ "info" : a:text, 15 | \ } 16 | endfunction 17 | 18 | 19 | function! monster#completion#rcodetools#parse(result) 20 | return map(split(a:result, '[\r\n]'), "s:parse(v:val)") 21 | endfunction 22 | 23 | 24 | function! monster#completion#rcodetools#complete(context) 25 | return monster#completion#rcodetools#{g:monster#completion#rcodetools#backend}#complete(a:context) 26 | endfunction 27 | 28 | 29 | let &cpo = s:save_cpo 30 | unlet s:save_cpo 31 | -------------------------------------------------------------------------------- /autoload/monster/completion/rcodetools/async_rct_complete.vim: -------------------------------------------------------------------------------- 1 | scriptencoding utf-8 2 | let s:save_cpo = &cpo 3 | set cpo&vim 4 | 5 | 6 | function! s:then(context, channel) 7 | let output = "" 8 | while ch_status(a:channel, {"part": "out"}) == "buffered" 9 | let output .= substitute(ch_read(a:channel), "\xff", "", "g") 10 | endwhile 11 | if output == "" 12 | return 13 | endif 14 | try 15 | call monster#cache#add(a:context, monster#completion#rcodetools#parse(output)) 16 | catch 17 | return 18 | endtry 19 | echo "monster.vim - finish async completion" 20 | if monster#context#get_current().cache_keyword !=# a:context.cache_keyword 21 | return 22 | endif 23 | if monster#start_complete(0, a:context) == 0 24 | if &completeopt !~ '\(noinsert\|noselect\)' 25 | call feedkeys("\") 26 | endif 27 | endif 28 | endfunction 29 | 30 | 31 | function! monster#completion#rcodetools#async_rct_complete#complete(context) 32 | call monster#completion#rcodetools#async_rct_complete#cancel() 33 | if !executable("rct-complete") 34 | call monster#errmsg("No executable 'rct-complete' command.") 35 | call monster#errmsg("Please install 'gem install rcodetools'.") 36 | return [] 37 | endif 38 | 39 | let tempfile = monster#make_tempfile(a:context.bufnr, "rb") 40 | let command = monster#completion#rcodetools#rct_complete#command(a:context, tempfile) 41 | let process = job_start(command, { 42 | \ 'close_cb': {ch -> [s:then(a:context, ch), delete(tempfile)]} 43 | \}) 44 | 45 | call monster#debug_log( 46 | \ "[async_rct_complete.vm] rct-complete command : " . command . "\n" 47 | \ ) 48 | 49 | let s:process = process 50 | 51 | return [] 52 | endfunction 53 | 54 | 55 | function! monster#completion#rcodetools#async_rct_complete#is_alive_process() 56 | return !(exists("s:process") && job_status(s:process) == "run") 57 | endfunction 58 | 59 | 60 | function! monster#completion#rcodetools#async_rct_complete#cancel() 61 | if !exists("s:process") 62 | return 63 | endif 64 | echo "monster.vim - cancel async completion" 65 | call job_stop(s:process, 'kill') 66 | unlet s:process 67 | endfunction 68 | 69 | 70 | function! monster#completion#rcodetools#async_rct_complete#test() 71 | let start_time = reltime() 72 | let context = monster#context#get_current() 73 | let old_debug = g:monster#debug#enable 74 | let g:monster#debug#enable = 1 75 | call monster#debug#clear_log() 76 | try 77 | call monster#completion#rcodetools#async_rct_complete#complete(context) 78 | while job_status(s:process) == "run" 79 | sleep 100m 80 | endwhile 81 | let result = monster#cache#get(context) 82 | return { "context" : context, "result" : result, "log" : monster#debug#log() } 83 | finally 84 | let g:monster#debug#enable = old_debug 85 | echom "Complete time " . reltimestr(reltime(start_time)) 86 | endtry 87 | endfunction 88 | 89 | 90 | augroup monster-completion-rcodetools-async_rct_complete 91 | autocmd! 92 | autocmd InsertEnter,InsertLeave * call monster#completion#rcodetools#async_rct_complete#cancel() 93 | augroup END 94 | 95 | 96 | let &cpo = s:save_cpo 97 | unlet s:save_cpo 98 | -------------------------------------------------------------------------------- /autoload/monster/completion/rcodetools/rct_complete.vim: -------------------------------------------------------------------------------- 1 | scriptencoding utf-8 2 | let s:save_cpo = &cpo 3 | set cpo&vim 4 | 5 | 6 | function! monster#completion#rcodetools#rct_complete#command(context, file) 7 | return printf(g:monster#completion#rcodetools#complete_command . " --completion-class-info --dev --fork --line=%d --column=%d %s", a:context.line, a:context.complete_pos, a:file) 8 | endfunction 9 | 10 | 11 | function! monster#completion#rcodetools#rct_complete#check() 12 | return executable("rct-complete") 13 | endfunction 14 | 15 | 16 | function! monster#completion#rcodetools#rct_complete#complete(context) 17 | if !executable(g:monster#completion#rcodetools#complete_command) 18 | call monster#errmsg("No executable 'rct-complete' command.") 19 | call monster#errmsg("Please install 'gem install rcodetools'.") 20 | return 21 | endif 22 | try 23 | " echo "monster.vim - start rct-complete" 24 | let file = monster#make_tempfile(a:context.bufnr, "rb") 25 | let command = monster#completion#rcodetools#rct_complete#command(a:context, file) 26 | let result = system(command) 27 | finally 28 | call delete(file) 29 | endtry 30 | call monster#debug_log( 31 | \ "[rct_complete.vim] rct-complete command : " . command . "\n" 32 | \ . "[rct_complete.vim] rct-complete result : \n" . result 33 | \ ) 34 | if v:shell_error != 0 35 | " call monster#errmsg(command) 36 | " call monster#errmsg(result) 37 | " echo "monster.vim - failed rct-complete" 38 | return [] 39 | endif 40 | echo "monster.vim - finish rct-complete" 41 | return monster#completion#rcodetools#parse(result) 42 | endfunction 43 | 44 | 45 | function! monster#completion#rcodetools#rct_complete#test() 46 | let start_time = reltime() 47 | let context = monster#context#get_current() 48 | let old_debug = g:monster#debug#enable 49 | let g:monster#debug#enable = 1 50 | call monster#debug#clear_log() 51 | 52 | try 53 | let result = monster#completion#rcodetools#rct_complete#complete(context) 54 | return { "context" : context, "result" : result, "log" : monster#debug#log() } 55 | finally 56 | let g:monster#debug#enable = old_debug 57 | echom "Complete time " . reltimestr(reltime(start_time)) 58 | endtry 59 | endfunction 60 | 61 | let &cpo = s:save_cpo 62 | unlet s:save_cpo 63 | -------------------------------------------------------------------------------- /autoload/monster/completion/solargraph.vim: -------------------------------------------------------------------------------- 1 | scriptencoding utf-8 2 | let s:save_cpo = &cpo 3 | set cpo&vim 4 | 5 | let g:monster#completion#solargraph#http_port = get(g:, "monster#completion#solargraph#http_port", 7657) 6 | 7 | let g:monster#completion#solargraph#backend = get(g:, "monster#completion#solargraph#backend", "solargraph_suggest") 8 | 9 | let g:monster#completion#solargraph#complete_command = get(g:, "monster#completion#solargraph#complete_command", "solargraph" . (has('win32') ? ".bat" : "")) 10 | 11 | function! s:item(value) 12 | return { 13 | \ "word" : a:value.insert, 14 | \ "menu" : a:value.kind, 15 | \ } 16 | endfunction 17 | 18 | 19 | function! monster#completion#solargraph#parse(result) 20 | let obj = json_decode(a:result) 21 | if obj.status != "ok" 22 | echomsg obj.message 23 | return [] 24 | endif 25 | return map(json_decode(a:result).suggestions, "s:item(v:val)") 26 | endfunction 27 | 28 | 29 | function! monster#completion#solargraph#complete(context) 30 | return monster#completion#solargraph#{g:monster#completion#solargraph#backend}#complete(a:context) 31 | endfunction 32 | 33 | 34 | let &cpo = s:save_cpo 35 | unlet s:save_cpo 36 | -------------------------------------------------------------------------------- /autoload/monster/completion/solargraph/async_solargraph_suggest.vim: -------------------------------------------------------------------------------- 1 | scriptencoding utf-8 2 | let s:save_cpo = &cpo 3 | set cpo&vim 4 | 5 | 6 | function! s:then(context, channel) 7 | let output = "" 8 | while ch_status(a:channel, {"part": "out"}) == "buffered" 9 | let output .= substitute(ch_read(a:channel), "\xff", "", "g") 10 | endwhile 11 | if output == "" 12 | return 13 | endif 14 | try 15 | call monster#cache#add(a:context, monster#completion#solargraph#parse(output)) 16 | catch 17 | return 18 | endtry 19 | echo "monster.vim - finish async completion" 20 | if monster#context#get_current().cache_keyword !=# a:context.cache_keyword 21 | return 22 | endif 23 | if monster#start_complete(0, a:context) == 0 24 | if &completeopt !~ '\(noinsert\|noselect\)' 25 | call feedkeys("\") 26 | endif 27 | endif 28 | endfunction 29 | 30 | 31 | function! monster#completion#solargraph#async_solargraph_suggest#complete(context) 32 | call monster#completion#solargraph#async_solargraph_suggest#cancel() 33 | if !executable(g:monster#completion#solargraph#complete_command) 34 | call monster#errmsg("No executable 'solargraph' command.") 35 | call monster#errmsg("Please install 'gem install solargraph'.") 36 | return [] 37 | endif 38 | if !exists('s:job') || job_status(s:job) != "run" 39 | let command = g:monster#completion#solargraph#complete_command 40 | let args = [command, "server", "--port=".g:monster#completion#solargraph#http_port] 41 | let s:job = job_start(args) 42 | augroup MonsterSolargraph 43 | au! 44 | au VimLeave * call job_stop(s:job) 45 | augroup END 46 | endif 47 | 48 | let tempfile = monster#make_tempfile(a:context.bufnr, "rb") 49 | let command = monster#completion#solargraph#solargraph_suggest#command(a:context, tempfile) 50 | let process = job_start(command, { 51 | \ 'close_cb': {ch -> [s:then(a:context, ch), delete(tempfile)]} 52 | \}) 53 | 54 | call monster#debug_log( 55 | \ "[async_solargraph_suggest.vim] solargraph command : " . command . "\n" 56 | \ ) 57 | 58 | let s:process = process 59 | 60 | return [] 61 | endfunction 62 | 63 | 64 | function! monster#completion#solargraph#async_solargraph_suggest#is_alive_process() 65 | return !(exists("s:process") && job_status(s:process, "run")) 66 | endfunction 67 | 68 | 69 | function! monster#completion#solargraph#async_solargraph_suggest#cancel() 70 | if !exists("s:process") 71 | return 72 | endif 73 | echo "monster.vim - cancel async completion" 74 | call job_stop(s:process, 'kill') 75 | unlet s:process 76 | endfunction 77 | 78 | 79 | function! monster#completion#solargraph#async_solargraph_suggest#test() 80 | let start_time = reltime() 81 | let context = monster#context#get_current() 82 | let old_debug = g:monster#debug#enable 83 | let g:monster#debug#enable = 1 84 | call monster#debug#clear_log() 85 | try 86 | call monster#completion#solargraph#async_solargraph_suggest#complete(context) 87 | while job_status(s:process) == "run" 88 | sleep 100m 89 | endwhile 90 | let result = monster#cache#get(context) 91 | return { "context" : context, "result" : result, "log" : monster#debug#log() } 92 | finally 93 | let g:monster#debug#enable = old_debug 94 | echom "Complete time " . reltimestr(reltime(start_time)) 95 | endtry 96 | endfunction 97 | 98 | 99 | augroup monster-completion-solargraph-async_solargraph_suggest 100 | autocmd! 101 | autocmd InsertEnter,InsertLeave * call monster#completion#solargraph#async_solargraph_suggest#cancel() 102 | augroup END 103 | 104 | 105 | let &cpo = s:save_cpo 106 | unlet s:save_cpo 107 | -------------------------------------------------------------------------------- /autoload/monster/completion/solargraph/solargraph_suggest.vim: -------------------------------------------------------------------------------- 1 | scriptencoding utf-8 2 | let s:save_cpo = &cpo 3 | set cpo&vim 4 | 5 | 6 | function! monster#completion#solargraph#solargraph_suggest#command(context, file) 7 | return printf( 8 | \ "curl -s -d line=%d -d column=%d -d filename=%s --data-urlencode text@%s http://localhost:%d/suggest", 9 | \ a:context.line-1, 10 | \ a:context.complete_pos, 11 | \ a:file, 12 | \ a:file, 13 | \ g:monster#completion#solargraph#http_port) 14 | endfunction 15 | 16 | 17 | function! monster#completion#solargraph#solargraph_suggest#check() 18 | return executable(g:monster#completion#solargraph#complete_command) && executable("curl") 19 | endfunction 20 | 21 | 22 | function! monster#completion#solargraph#solargraph_suggest#complete(context) 23 | if !executable(g:monster#completion#solargraph#complete_command) 24 | call monster#errmsg("No executable 'solargraph' command.") 25 | call monster#errmsg("Please install 'gem install solargraph'.") 26 | return 27 | endif 28 | if !exists('s:job') || job_status(s:job) != "run" 29 | let command = g:monster#completion#solargraph#complete_command 30 | let args = [command, "server", "--port=".g:monster#completion#solargraph#http_port] 31 | let s:job = job_start(args) 32 | augroup MonsterSolargraph 33 | au! 34 | au VimLeave * call job_stop(s:job) 35 | augroup END 36 | endif 37 | try 38 | " echo "monster.vim - start solargraph" 39 | let file = monster#make_tempfile(a:context.bufnr, "rb") 40 | let command = monster#completion#solargraph#solargraph_suggest#command(a:context, file) 41 | let result = system(command) 42 | finally 43 | call delete(file) 44 | endtry 45 | call monster#debug_log( 46 | \ "[solargraph_suggest.vim] solargraph command : " . command . "\n" 47 | \ . "[solargraph_suggest.vim] solargraph result : \n" . result 48 | \ ) 49 | if v:shell_error != 0 50 | " call monster#errmsg(command) 51 | " call monster#errmsg(result) 52 | " echo "monster.vim - failed solargraph" 53 | return [] 54 | endif 55 | echo "monster.vim - finish solargraph" 56 | return monster#completion#solargraph#parse(result) 57 | endfunction 58 | 59 | 60 | function! monster#completion#solargraph#solargraph_suggest#test() 61 | let start_time = reltime() 62 | let context = monster#context#get_current() 63 | let old_debug = g:monster#debug#enable 64 | let g:monster#debug#enable = 1 65 | call monster#debug#clear_log() 66 | 67 | try 68 | let result = monster#completion#solargraph#solargraph_suggest#complete(context) 69 | return { "context" : context, "result" : result, "log" : monster#debug#log() } 70 | finally 71 | let g:monster#debug#enable = old_debug 72 | echom "Complete time " . reltimestr(reltime(start_time)) 73 | endtry 74 | endfunction 75 | 76 | let &cpo = s:save_cpo 77 | unlet s:save_cpo 78 | -------------------------------------------------------------------------------- /autoload/monster/context.vim: -------------------------------------------------------------------------------- 1 | scriptencoding utf-8 2 | let s:save_cpo = &cpo 3 | set cpo&vim 4 | 5 | 6 | function! monster#context#get_current(...) 7 | let base = get(a:, 1, {}) 8 | let complete_pos = strwidth(matchstr(getline("."), '\zs.\{-}\ze\w*$')) 9 | let start_col = getline(".") == "" ? 1 : complete_pos 10 | return extend({ 11 | \ "bufnr" : bufnr("%"), 12 | \ "col" : col("."), 13 | \ "start_col" : start_col, 14 | \ "complete_pos" : complete_pos, 15 | \ "line" : line("."), 16 | \ "cache_keyword" : printf("%d-%d-%d-%s", bufnr("%"), complete_pos, line("."), getline(".")[:start_col-1]), 17 | \ }, base) 18 | endfunction 19 | 20 | 21 | function! monster#current_context(...) 22 | return call("s:current_context", a:000) 23 | endfunction 24 | 25 | 26 | 27 | let &cpo = s:save_cpo 28 | unlet s:save_cpo 29 | -------------------------------------------------------------------------------- /autoload/monster/debug.vim: -------------------------------------------------------------------------------- 1 | scriptencoding utf-8 2 | let s:save_cpo = &cpo 3 | set cpo&vim 4 | 5 | 6 | let g:monster#debug#enable = get(g:, "monster#debug#enable", 0) 7 | 8 | 9 | let s:log_data_list = [] 10 | function! monster#debug#echo(text) 11 | if !g:monster#debug#enable 12 | return 13 | endif 14 | let log = "" 15 | let log .= "---- " . strftime("%c", localtime()) . ' ---- | ' . "\n" 16 | let log .= (type(a:text) == type("") ? a:text : string(a:text)) 17 | call add(s:log_data_list, log) 18 | endfunction 19 | 20 | 21 | function! monster#debug#log() 22 | return join(s:log_data_list, "\n") 23 | endfunction 24 | 25 | 26 | function! monster#debug#clear_log() 27 | let s:log_data_list = [] 28 | endfunction 29 | 30 | 31 | function! monster#debug#callstack() 32 | try 33 | throw 'abc' 34 | catch /^abc$/ 35 | return split(matchstr(v:throwpoint, 'function \zs.*\ze,.*'), '\.\.')[ : -2] 36 | endtry 37 | endfunction 38 | 39 | 40 | let s:name = "homu" 41 | function! monster#debug#{s:name}() 42 | echo "mami" 43 | endfunction 44 | 45 | 46 | 47 | let &cpo = s:save_cpo 48 | unlet s:save_cpo 49 | -------------------------------------------------------------------------------- /doc/monster.jax: -------------------------------------------------------------------------------- 1 | *monster.txt* rcodetools/solargraph を利用した Ruby のコード補完を行う 2 | 3 | 4 | ============================================================================== 5 | 概要 *monster-introduction* 6 | 7 | *monster* は rcodetools 又は solargraph を利用した Ruby のコード補完を行うプラ 8 | グインです。 9 | 10 | - Requires 11 | - gem 12 | $ gem install rcodetools 13 | $ gem install solargraph 14 | - plugin 15 | vimproc.vim - https://github.com/Shougo/vimproc.vim 16 | NOTE: 非同期で補完を行う場合にのみ必要 17 | 18 | 19 | 20 | ============================================================================== 21 | 使い方 *monster-usage* 22 | 23 | でコード補完を開始します。 24 | また、|neocomplete.vim| を利用して自動補完を行う場合は 25 | > 26 | let g:neocomplete#sources#omni#input_patterns = { 27 | \ "ruby" : '[^. *\t]\.\w*\|\h\w*::', 28 | \} 29 | < 30 | と、設定します。rcodecools の代わりに solargraph を使う場合は 31 | > 32 | let g:monster#completion#backend = 'solargraph' 33 | < 34 | と、設定します。 35 | また、非同期でコード補完を行ないたい場合は、以下のように設定を行う必要がありま 36 | す。 37 | > 38 | " Set async completion. 39 | let g:monster#completion#rcodetools#backend = "async_rct_complete" 40 | " Or let g:monster#completion#solargraph#backend = "async_solargraph_suggest" 41 | 42 | " Use neocomplete.vim 43 | let g:neocomplete#sources#omni#input_patterns = { 44 | \ 'ruby' : '[^. *\t]\.\|\h\w*::', 45 | \} 46 | < 47 | 48 | 非同期でコード補完を行うときの流れは以下のようになります。 49 | 50 | 1.|g:neocomplete#sources#omni#input_patterns| にマッチしたパターンを入力すると 51 | 補完開始 52 | 2.非同期で処理が行われるので補完中は処理がブロックされずに続けて入力する事 53 | ができる 54 | 3.入力中、もしくは |CursorHoldI| 時に補完処理が終了していれば補完結果が出力さ 55 | れる 56 | 57 | この時に |CursorHoldI| が 'updatetime' に依存していることに注意してください。 58 | 59 | 60 | ============================================================================== 61 | vim:tw=78:fo=tcq2mM:ts=8:ft=help:norl 62 | -------------------------------------------------------------------------------- /plugin/monster.vim: -------------------------------------------------------------------------------- 1 | scriptencoding utf-8 2 | if exists('g:loaded_monster') 3 | finish 4 | endif 5 | let g:loaded_monster = 1 6 | 7 | let s:save_cpo = &cpo 8 | set cpo&vim 9 | 10 | command! -bar MonsterDebugLog echo monster#get_debug_log() 11 | 12 | let &cpo = s:save_cpo 13 | unlet s:save_cpo 14 | --------------------------------------------------------------------------------