osyo-manga / vital-over

18 stars 3 forks source link

<A-[> がうまく split されない #121

Closed osyo-manga closed 9 years ago

osyo-manga commented 9 years ago

ping @haya14busa

特殊文字も対応した Over.String.split_by_keys() ですが、次のような場合に正しく分割されませんでした。

echo vital#of("vital").import("Over.String").split_by_keys("aa\<A-[>aa\<C-a>")
" => ['a', 'a', 'Û', '<fd>', 'Q', 'a', 'a', '^A']

期待する出力しては以下のようなものです。

['a', 'a', 'Û<fd>Q', 'a', 'a', '^A']
osyo-manga commented 9 years ago

ちなみに(当然ではありますが)以前やっていた手動で分割するやり方では問題なく動作しました。

function! s:_split(str, pat)
    let pat = (exists("+regexpengine") ? '\%#=2' : '') . a:pat
    let list = split(a:str,  pat . '\zs')
    return s:List.flatten(map(list, 'v:val == a:pat ? a:pat : v:val =~ pat . ''$'' ? split(v:val, pat) + [a:pat] : v:val'))
endfunction

function! s:_split_keystring(str, pats, ...)
    if a:str =~ '^<Over>(.\{-})$'
\   || a:str =~ "^\<Plug>(.\\{-})$"
        return [a:str]
    endif
    let pats = a:pats
    let index = get(a:, 1, 0)
    if !exists("+regexpengine")
\   || index > len(pats)
\   || len(filter(copy(pats), 'a:str =~ ''\%#=2'' . v:val')) == 0
        if len(filter(copy(pats), 'a:str ==# v:val')) == 0
            return split(a:str, '\zs')
        else
            return [a:str]
        endif
    endif
    if len(filter(copy(pats), 'a:str == v:val')) == 1
        return [a:str]
    endif

    let result = []
    let pat = pats[index]
    let list = s:_split(a:str, pat)
    let result += eval(join(map(list, "s:_split_keystring(v:val, pats, index+1)"), "+"))
    return result
endfunction

let s:special_keys = [
\   "\<BS>",
\   "\<Down>",
\   "\<Up>",
\   "\<Left>",
\   "\<Right>",
\   "\<Home>",
\   "\<End>",
\   "\<Insert>",
\   "\<Delete>",
\   "\<PageUp>",
\   "\<PageDown>",
\   "\<F1>",
\   "\<F2>",
\   "\<F3>",
\   "\<F4>",
\   "\<F5>",
\   "\<F6>",
\   "\<F7>",
\   "\<F8>",
\   "\<F9>",
\   "\<F10>",
\   "\<F11>",
\   "\<F12>",
\   "\<A-BS>",
\   "\<A-Down>",
\   "\<A-Up>",
\   "\<A-Left>",
\   "\<A-Right>",
\   "\<A-Home>",
\   "\<A-End>",
\   "\<A-Insert>",
\   "\<A-Delete>",
\   "\<A-PageUp>",
\   "\<A-PageDown>",
\   "\<A-F1>",
\   "\<A-F2>",
\   "\<A-F3>",
\   "\<A-F4>",
\   "\<A-F5>",
\   "\<A-F6>",
\   "\<A-F7>",
\   "\<A-F8>",
\   "\<A-F9>",
\   "\<A-F10>",
\   "\<A-F11>",
\   "\<A-F12>",
\   "\<A-Tab>",
\   "\<A-[>",
\   "\<C-BS>",
\   "\<C-Down>",
\   "\<C-Up>",
\   "\<C-Left>",
\   "\<C-Right>",
\   "\<C-Home>",
\   "\<C-End>",
\   "\<C-Insert>",
\   "\<C-Delete>",
\   "\<C-PageUp>",
\   "\<C-PageDown>",
\   "\<C-Tab>",
\   "\<C-F1>",
\   "\<C-F2>",
\   "\<C-F3>",
\   "\<C-F4>",
\   "\<C-F5>",
\   "\<C-F6>",
\   "\<C-F7>",
\   "\<C-F8>",
\   "\<C-F9>",
\   "\<C-F10>",
\   "\<C-F11>",
\   "\<C-F12>",
\   "\<S-Down>",
\   "\<S-Up>",
\   "\<S-Left>",
\   "\<S-Right>",
\   "\<S-Home>",
\   "\<S-Insert>",
\   "\<S-PageUp>",
\   "\<S-PageDown>",
\   "\<S-F1>",
\   "\<S-F2>",
\   "\<S-F3>",
\   "\<S-F4>",
\   "\<S-F5>",
\   "\<S-F6>",
\   "\<S-F7>",
\   "\<S-F8>",
\   "\<S-F9>",
\   "\<S-F10>",
\   "\<S-F11>",
\   "\<S-F12>",
\   "\<S-Tab>",
\]

" Issues #45
" \ "\<S-End>",
" \ "\<S-Delete>",
function! s:split_by_keys(str)
    return s:_split_keystring(a:str, s:special_keys)
endfunction

echo s:split_by_keys("aa\<A-[>aa\<C-a>")
" => ['a', 'a', 'Û<fd>Q', 'a', 'a', '^A']
osyo-manga commented 9 years ago

ちなみに Vim の <C-v> から <A-[>を挿入しようとすると Û だけが挿入されます。

osyo-manga commented 9 years ago

うーん、なんか Vim 側の仕様なような気がしてきた…。 ただ、 if a:cmdline.is_input("\<A-[>") みたいなのが動作しないのはツライ気もしますねぇ…。

haya14busa commented 9 years ago

oh...正規表現が対応してなかったっぽい...?

haya14busa commented 9 years ago

他に探した結果もうひとつだけ見つけました

echo s:S.split_by_keys("\<A-[>") | " ['Û', '<fd>', 'Q']
echo s:S.split_by_keys("\<A-@>") | " ['À', '<fe>', 'X']
haya14busa commented 9 years ago

前の方法に戻さなくても一応この2つの対応は正規表現ハードコードで行けるといえばいける

haya14busa commented 9 years ago

最初が特殊文字じゃないのどういうことなんだ...

osyo-manga commented 9 years ago

これですが <C-v><A-[> で挿入できないのも気になりますねぇ。

haya14busa commented 9 years ago

それはVim本体含めという話ですかね

osyo-manga commented 9 years ago

です>Vim本体含め

osyo-manga commented 9 years ago

例えば nr2char(char2nr("\<A-[>", 1), 1) == "\<A-[>"0 になりますね。

haya14busa commented 9 years ago

例えば nr2char(char2nr("<A-[>", 1), 1) == "<A-[>" は 0 になりますね。

確かに...しかしこれVimを超えてキーコードか何かの仕様という可能性もありそう

osyo-manga commented 9 years ago

とりあえず、Vim 本体の問題なの?という疑問はありますが、本件自体は対応してもらったので閉じますね。 ありがとうございました。