aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Smeding <tom@tomsmeding.com>2024-07-05 11:45:48 +0200
committerTom Smeding <tom@tomsmeding.com>2024-07-05 11:45:48 +0200
commit04944f4de1b2020464ef506cdaf33a1ea65068a9 (patch)
treefdfde26344178a5d463ec0e2e0a9b70968da1440
Initial
-rw-r--r--japanese.vim79
1 files changed, 79 insertions, 0 deletions
diff --git a/japanese.vim b/japanese.vim
new file mode 100644
index 0000000..621cd17
--- /dev/null
+++ b/japanese.vim
@@ -0,0 +1,79 @@
+function s:append_at_cursor(text)
+ let y = line(".")
+ let x = charcol(".")
+ let ln = getline(".")
+ call setline(".", strcharpart(ln, 0, x - 1) . a:text . strcharpart(ln, x - 1))
+ call setcursorcharpos(y, x + strcharlen(a:text))
+endfunction
+
+function s:isvowel(c)
+ return strcharlen(a:c) == 1 && stridx("aiueo", a:c) != -1
+endfunction
+
+function s:isconsonant(c)
+ return strcharlen(a:c) == 1 && stridx("kgsztdnhmyrw", a:c) != -1
+endfunction
+
+let s:punctuation = {
+ \ '.': "。",
+ \ ',': "、",
+ \ '(': "(",
+ \ ')': ")",
+ \ '{': "{",
+ \ '}': "}",
+ \ '[': "「",
+ \ ']': "」",
+ \ '/': "・",
+ \ '~': "〜",
+ \ ':': ":",
+ \ '!': "!",
+ \ '?': "?"
+ \ }
+
+function s:renderkana(s)
+ if len(a:s) == 0
+ return ""
+ endif
+
+ " echom "renderkana:" a:s strcharpart(a:s, 0, 1) s:isvowel(strcharpart(a:s, 0, 1))
+
+ let c0 = strcharpart(a:s, 0, 1)
+ let c1 = strcharpart(a:s, 1, 1)
+ let tail1 = strcharpart(a:s, 1)
+ let tail2 = strcharpart(a:s, 2)
+ if s:isvowel(c0)
+ return digraph_get(c0 . "5") . s:renderkana(tail1)
+ elseif s:isconsonant(c0) && s:isvowel(c1)
+ return digraph_get(c0 . c1) . s:renderkana(tail2)
+ elseif c0 ==# "-"
+ return "ー" . s:renderkana(tail1)
+ elseif has_key(s:punctuation, c0)
+ return get(s:punctuation, c0) . s:renderkana(tail1)
+ else
+ return c0 . s:renderkana(tail1)
+ endif
+endfunction
+
+function s:jpkey(key)
+ " call s:insert_at_cursor("key " . a:key)
+ let y = line(".")
+ let x = charcol(".") - 1
+ let fullline = getline(".")
+
+ let fragment = strcharpart(fullline, max([0, x - 2]), x) . a:key
+
+ " call s:append_at_cursor("<" . fragment . ">")
+ while len(fragment) > 0 && strgetchar(fragment, 0) > 127
+ let fragment = strcharpart(fragment, 1)
+ endwhile
+ " call s:append_at_cursor("<" . fragment . ">")
+
+ let result = s:renderkana(fragment)
+ " echom result
+ call setline(".", strcharpart(fullline, 0, x + 1 - strcharlen(fragment)) . result . strcharpart(fullline, x))
+ call setcursorcharpos(y, x + 1 - strcharlen(fragment) + strcharlen(result) + 1)
+endfunction
+
+for c in "abcdefghijklmnopqrstuvwxyz-.,(){}[]/~:!?"
+ execute "inoremap <buffer> <silent> " . c . " <Cmd>call <SID>jpkey('" . c . "')<CR>"
+endfor