Skip to content

Commit

Permalink
refactor: add henkan_list.vim to separate functions
Browse files Browse the repository at this point in the history
  • Loading branch information
kawarimidoll committed Dec 1, 2023
1 parent 741bbaa commit f3d161d
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 105 deletions.
111 changes: 111 additions & 0 deletions henkan_list.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
" TODO このユーティリティは別ファイルに分けたい
function! s:is_same_line_right_col(target) abort
let [pos_l, pos_c] = get(b:, $'{a:target}_start_pos', [0, 0])
let [cur_l, cur_c] = getcharpos('.')[1:2]
return pos_l ==# cur_l && pos_c <= cur_c
endfunction

function! s:parse_henkan_list(lines, jisyo) abort
if empty(a:lines)
return []
endif

let henkan_list = []

for line in a:lines
" よみ /変換1/変換2/.../
" stridxがバイトインデックスなのでstrpartを使う
let space_idx = stridx(line, ' /')
let yomi = strpart(line, 0, space_idx)
let henkan_str = strpart(line, space_idx+1)
for v in split(henkan_str, '/')
" ;があってもなくても良いよう_restを使う
let [word, info; _rest] = split(v, ';') + ['']
" :h complete-items
call add(henkan_list, {
\ 'word': word,
\ 'menu': $'{a:jisyo.mark}{info}',
\ 'info': $'{a:jisyo.mark}{info}',
\ 'user_data': { 'yomi': trim(yomi), 'path': a:jisyo.path }
\ })
endfor
endfor

return henkan_list
endfunction

function! henkan_list#update_async(str) abort
call utils#debug_log($'async start {a:str}')
let str = substitute(a:str, '', '(ゔ|う゛)', 'g')

let s:latest_async_henkan_list = []
let s:run_job_list = []

for jisyo in opts#get('jisyo_list')
let cmd = substitute(jisyo.grep_cmd, ':q:', $'{str}[^!-~]* /', '')
let job_id = job#start(cmd, { 'exit': funcref('s:on_exit') })
call add(s:run_job_list, [job_id, jisyo])
call utils#debug_log($'start {job_id}')
endfor
endfunction

let s:async_result_dict = {}

function! s:on_exit(data, job_id) abort
let s:async_result_dict[a:job_id] = a:data
" call utils#debug_log($'on_exit {a:job_id}')
" call utils#debug_log($'list {s:run_job_list->copy()->map("v:val[0]")->join(" ")} / {s:async_result_dict->keys()->join(" ")}')

" 手動変換がスタートしていたら自動補完はキャンセルする
if s:is_same_line_right_col('select')
call utils#debug_log('manual select is started')
return
endif

" 蓄積された候補を辞書リストの順に並び替える
let henkan_list = []
let is_finished = v:true
for [job_id, jisyo] in s:run_job_list
if !has_key(s:async_result_dict, job_id)
" 検索が終わっていない辞書がある場合は早期終了
" call utils#debug_log($'{job_id} is not finished')
" return
let is_finished = v:false
continue
endif

call extend(henkan_list, s:parse_henkan_list(s:async_result_dict[job_id], jisyo))
endfor
" call utils#debug_log('create henkan list')
" call utils#debug_log(henkan_list)

if is_finished
" すべての辞書の検索が終わったら蓄積変数をクリア
let s:async_result_dict = {}
endif
if empty(henkan_list)
return
endif

let s:latest_async_henkan_list = henkan_list
call feedkeys("\<c-r>=k#autocompletefunc()\<cr>", 'n')
endfunction

function! henkan_list#update_manual(str) abort
let str = substitute(a:str, '', '(ゔ|う゛)', 'g')
let henkan_list = []
for jisyo in opts#get('jisyo_list')
let cmd = substitute(jisyo.grep_cmd, ':q:', $'{str} /', '')
let lines = systemlist(substitute(cmd, ':query:', $'{str} ', 'g'))
call extend(henkan_list, s:parse_henkan_list(lines, jisyo))
endfor
let s:latest_henkan_list = henkan_list
endfunction

function! henkan_list#get(async = v:false) abort
return a:async ? s:latest_async_henkan_list : s:latest_henkan_list
endfunction

function! henkan_list#insert(item) abort
return insert(s:latest_henkan_list, a:item)
endfunction
115 changes: 10 additions & 105 deletions k.vim
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ source ./google_cgi.vim
source ./job.vim
source ./utils.vim
source ./opts.vim
source ./henkan_list.vim

function! s:is_completed() abort
return get(complete_info(), 'selected', -1) >= 0
Expand Down Expand Up @@ -183,7 +184,7 @@ function! s:get_insert_spec(key, henkan = v:false) abort
let preceding_str = s:get_preceding_str('henkan', v:false)
" echomsg 'okuri-ari:' preceding_str .. a:key

call k#update_henkan_list(preceding_str .. a:key)
call henkan_list#update_manual(preceding_str .. a:key)

let s:next_okuri = v:false

Expand Down Expand Up @@ -213,102 +214,6 @@ function! s:get_insert_spec(key, henkan = v:false) abort
return get(kana_dict, '', a:key)
endfunction

function! s:parse_henkan_list(lines, jisyo) abort
if empty(a:lines)
return []
endif

let henkan_list = []

for line in a:lines
" よみ /変換1/変換2/.../
" stridxがバイトインデックスなのでstrpartを使う
let space_idx = stridx(line, ' /')
let yomi = strpart(line, 0, space_idx)
let henkan_str = strpart(line, space_idx+1)
for v in split(henkan_str, '/')
" ;があってもなくても良いよう_restを使う
let [word, info; _rest] = split(v, ';') + ['']
" :h complete-items
call add(henkan_list, {
\ 'word': word,
\ 'menu': $'{a:jisyo.mark}{info}',
\ 'info': $'{a:jisyo.mark}{info}',
\ 'user_data': { 'yomi': trim(yomi), 'path': a:jisyo.path }
\ })
endfor
endfor

return henkan_list
endfunction

let s:async_result_dict = {}
function! k#async_update_list(str) abort
call utils#debug_log($'async start {a:str}')
let str = substitute(a:str, '', '(ゔ|う゛)', 'g')

let s:latest_henkan_list = []
let s:run_job_list = []

for jisyo in opts#get('jisyo_list')
let cmd = substitute(jisyo.grep_cmd, ':q:', $'{str}[^!-~]* /', '')
let job_id = job#start(cmd, { 'exit': funcref('s:on_exit') })
call add(s:run_job_list, [job_id, jisyo])
call utils#debug_log($'start {job_id}')
endfor
endfunction

function! s:on_exit(data, job_id) abort
let s:async_result_dict[a:job_id] = a:data
call utils#debug_log($'on_exit {a:job_id}')
call utils#debug_log($'list {s:run_job_list->copy()->map("v:val[0]")->join(" ")} / {s:async_result_dict->keys()->join(" ")}')

" 手動変換がスタートしていたら自動補完はキャンセルする
if s:is_same_line_right_col('select')
call utils#debug_log('manual select is started')
return
endif

" 蓄積された候補を辞書リストの順に並び替える
let henkan_list = []
let is_finished = v:true
for [job_id, jisyo] in s:run_job_list
if !has_key(s:async_result_dict, job_id)
" 検索が終わっていない辞書がある場合は早期終了
" call utils#debug_log($'{job_id} is not finished')
" return
let is_finished = v:false
continue
endif

call extend(henkan_list, s:parse_henkan_list(s:async_result_dict[job_id], jisyo))
endfor
" call utils#debug_log('create henkan list')
" call utils#debug_log(henkan_list)

if is_finished
" すべての辞書の検索が終わったら蓄積変数をクリア
let s:async_result_dict = {}
endif
if empty(henkan_list)
return
endif

let s:latest_henkan_list = henkan_list
call feedkeys("\<c-r>=k#autocompletefunc()\<cr>", 'n')
endfunction

function! k#update_henkan_list(str) abort
let str = substitute(a:str, '', '(ゔ|う゛)', 'g')
let henkan_list = []
for jisyo in opts#get('jisyo_list')
let cmd = substitute(jisyo.grep_cmd, ':q:', $'{str} /', '')
let lines = systemlist(substitute(cmd, ':query:', $'{str} ', 'g'))
call extend(henkan_list, s:parse_henkan_list(lines, jisyo))
endfor
let s:latest_henkan_list = henkan_list
endfunction

let s:latest_auto_complete_str = ''
function! s:auto_complete() abort
let preceding_str = s:get_preceding_str('henkan', v:false)
Expand All @@ -327,7 +232,7 @@ function! s:auto_complete() abort
let s:latest_auto_complete_str = preceding_str

if need_update
call k#async_update_list(preceding_str)
call henkan_list#update_async(preceding_str)
else
call feedkeys("\<c-r>=k#autocompletefunc()\<cr>", 'n')
endif
Expand All @@ -337,7 +242,7 @@ function! k#autocompletefunc()
let start_col = s:char_col_to_byte_col(b:henkan_start_pos)

" yomiの前方一致で絞り込む
let comp_list = copy(s:latest_henkan_list)
let comp_list = copy(henkan_list#get(1))
\ ->filter($"v:val.user_data.yomi =~# '^{s:latest_auto_complete_str}'")

call complete(start_col, comp_list)
Expand All @@ -353,7 +258,7 @@ function! k#completefunc(suffix_key = '')
let preceding_str = s:get_preceding_str('henkan') .. a:suffix_key

let google_exists = v:false
let comp_list = copy(s:latest_henkan_list)
let comp_list = copy(henkan_list#get())
if a:suffix_key ==# ''
for comp_item in comp_list
if type(comp_item.user_data) == v:t_dict &&
Expand Down Expand Up @@ -452,7 +357,7 @@ function! k#henkan(fallback_key) abort
let preceding_str = s:get_preceding_str('henkan')
" echomsg preceding_str

call k#update_henkan_list(preceding_str)
call henkan_list#update_manual(preceding_str)

return "\<c-r>=k#completefunc()\<cr>"
endfunction
Expand Down Expand Up @@ -487,7 +392,7 @@ function! s:complete_done_pre(complete_info, completed_item) abort
return
endif

call insert(s:latest_henkan_list, {
call henkan_list#insert({
\ 'word': henkan_result,
\ 'menu': '[Google]',
\ 'info': '[Google]',
Expand Down Expand Up @@ -537,12 +442,12 @@ function! s:buf_enter_try_user_henkan() abort

call k#enable()

call k#update_henkan_list(b:jisyo_touroku_ctx.yomi)
if empty(s:latest_henkan_list)
call henkan_list#update_manual(b:jisyo_touroku_ctx.yomi)
if empty(henkan_list#get())
return
endif

let henkan_result = s:latest_henkan_list[0].word
let henkan_result = henkan_list#get()[0].word
call feedkeys(repeat("\<bs>", strcharlen(b:jisyo_touroku_ctx.yomi)) .. henkan_result, 'n')

if b:jisyo_touroku_ctx.suffix_key !=# ''
Expand Down

0 comments on commit f3d161d

Please sign in to comment.