skk.vim狙え版の更新(20081227)

はじめに

私はVim上でのSKK実装であるskk.vimを使用している。素晴しい実装とは言わないまでも普段使うのに十分な実装であり、私がVimをインストールする際に真っ先に導入するプラグインでもある。

しかし、skk.vimにはいくつかの欠点があると思っていて、以前、私はそれを補うためにパッチを書いた。今日は、そのパッチを修正したので公開する。

機能・変更点

skk.vim狙え版(以下、狙え版とする)」に追加される機能や変更点は以下のようになる。

skk.vim狙え版に追加される機能(括弧は変数名)
  • sticky shift(skk_sticky_key)
  • 確定キー(skk_kakutei_key)
  • モードごとのカーソル色(skk_use_color_cursor,skk_cursor_*_clor)
  • モードごとの文字列(skk_*_mode_string)
前回のパッチからの変更点
  • モードごとのカーソル色がabbrev modeで不正な動作をしていたのを修正
  • skk_*_mode_stringの既定値をskk.vimの既定値に修正
  • 日付入力機能を削除
  • タブの置換を廃止
  • 全角英数変換ルールがおかしかったのを修正

今回の一番の目的はabbrev modeでのカーソル色を修正すること。その変更自体は1行だったが、せっかくなので以前から気になっていた点をいくつか修正した。

パッチのダウンロード

パッチ自体は「続きを読む」からコピペするか、以下のURLからどうぞ。

http://khkh.o0o0.jp/vim/skk.vim.patch.20081227

これはオリジナルのskk.vimからの差分です。パッチを当てる際はオリジナルのskk.vimに対して行ってください。

参考(関連リンク)

--- skk.vim	Wed Oct 11 18:27:06 2006
+++ skk.vim.new	Sat Dec 27 00:00:00 2008
@@ -4,7 +4,7 @@
 "
 " Author: Noriaki Yagi <no_yag@yahoo.co.jp>
 " Version: $Id: skk.vim,v 0.22 2006/10/11 09:26:53 noriaki Exp noriaki $
-" Last Change: 11-Oct-2006.
+" Last Change: 27-Dec-2008.
 "
 " 使い方:
 " skk_jisyo および skk_large_jisyo を適宜変更する。
@@ -566,6 +566,71 @@
 	\. "~〜\<NL>"
 endif
 
+" アスキーモードを示す文字列
+if !exists('g:skk_latin_mode_string')
+  let g:skk_latin_mode_string = 'SKK:aA'
+endif
+
+" かなモードを示す文字列
+if !exists('g:skk_hiragana_mode_string')
+  let g:skk_hiragana_mode_string = 'SKK:あ'
+endif
+
+" カナモードを示す文字列
+if !exists('g:skk_katakana_mode_string')
+  let g:skk_katakana_mode_string = 'SKK:ア'
+endif
+
+" 全英モードを示す文字列
+if !exists('g:skk_jisx0208_latin_mode_string')
+  let g:skk_jisx0208_latin_mode_string = 'SKK:A'
+endif
+
+" SKK abbrev モードを示す文字列
+if !exists('g:skk_abbrev_mode_string')
+  let g:skk_abbrev_mode_string = 'SKK:aあ'
+endif
+
+" カーソルに色付けする
+if !exists('g:skk_use_color_cursor')
+  let g:skk_use_color_cursor = 0
+endif
+
+" かなモードを示すカーソル色
+if !exists('g:skk_cursor_hiragana_color')
+  let g:skk_cursor_hiragana_color = ''
+endif
+
+" カナモードを示すカーソル色
+if !exists('g:skk_cursor_katakana_color')
+  let g:skk_cursor_katakana_color = ''
+endif
+
+" 全英モードを示すカーソル色
+if !exists('g:skk_cursor_jisx0208_color')
+  let g:skk_cursor_jisx0208_color = ''
+endif
+
+" アスキーモードを示すカーソル色
+if !exists('g:skk_cursor_latin_color')
+  let g:skk_cursor_latin_color = ''
+endif
+
+" SKK abbrev モードを示すカーソル色
+if !exists('g:skk_cursor_abbrev_color')
+  let g:skk_cursor_abbrev_color = ''
+endif
+
+" 入力されたら▽モードにするキー(sticky key)
+if !exists('g:skk_sticky_key')
+  let g:skk_sticky_key = ""
+endif
+
+" 明示的な確定動作を行うキー
+" 入力された文字列と直接比較されるので \ が必要
+if !exists('g:skk_kakutei_key')
+  let g:skk_kakutei_key = "\<C-j>"
+endif
 " }}}
 
 " script variables {{{
@@ -789,6 +854,44 @@
   return result == "" ? result : result . '/'
 endfunction
 
+" b:skk_mode, b:skk_abbrev_mode_on に合わせて、カーソルの色を変更する
+" NOTE: 暫定的にWin32 && gVim限定でカーソル色を変更する
+function! s:SkkSetCursorColor()
+  if has('win32') && has('gui') && g:skk_use_color_cursor
+    if b:skk_abbrev_mode_on
+      " royalblue:#4169e1
+      let color = (&background == 'light' ? '#4169e1' : '#4169e1')
+      if g:skk_cursor_abbrev_color != ''
+	let color = g:skk_cursor_abbrev_color
+      endif
+    elseif b:skk_mode == 'hira'
+      " coral4:#8b3e2f, pink:#ffc0cb
+      let color = (&background == 'light' ? '#8b3e2f' : '#ffc0cb')
+      if g:skk_cursor_hiragana_color != ''
+	let color = g:skk_cursor_hiragana_color
+      endif
+    elseif b:skk_mode == 'kata'
+      " forestgreen:#228b22, green:#00ff00
+      let color = (&background == 'light' ? '#228b22' : '#00ff00')
+      if g:skk_cursor_katakana_color != ''
+	let color = g:skk_cursor_katakana_color
+      endif
+    elseif b:skk_mode == 'zenei'
+      " gold:#ffd700
+      let color = (&background == 'light' ? '#ffd700' : '#ffd700')
+      if g:skk_cursor_jisx0208_color != ''
+	let color = g:skk_cursor_jisx0208_color
+      endif
+    elseif b:skk_mode == 'ascii'
+      " ivory4:#8b8b83, gray:#bebebe
+      let color = (&background == 'light' ? '#8b8b83' : '#bebebe')
+      if g:skk_cursor_latin_color != ''
+	let color = g:skk_cursor_latin_color
+      endif
+    endif
+    execute 'highlight lCursor guibg=' . color
+  endif
+endfunction
 " }}}
 
 " Initialization {{{
@@ -815,6 +918,7 @@
   if !exists("b:skk_map_silent")
     let b:skk_map_silent = 2	" <silent> 付きでマップしたか?
   endif
+  call s:SkkSetCursorColor() " カーソル色の設定
 endfunction
 
 " SkkRuleCompile
@@ -1034,6 +1138,7 @@
 function! SkkHiraMode(kana)
   let kana = a:kana . s:SkkKakutei()
   let b:skk_mode = 'hira'
+  call s:SkkSetCursorColor()
   return kana
 endfunction
 
@@ -1042,6 +1147,7 @@
 function! SkkKataMode(kana)
   let kana = a:kana . s:SkkKakutei()
   let b:skk_mode = 'kata'
+  call s:SkkSetCursorColor()
   return kana
 endfunction
 
@@ -1050,6 +1156,7 @@
 function! SkkZeneiMode(kana)
   let kana = a:kana . s:SkkKakutei()
   let b:skk_mode = 'zenei'
+  call s:SkkSetCursorColor()
   return kana
 endfunction
 
@@ -1058,6 +1165,7 @@
 function! SkkAsciiMode(kana)
   let kana = a:kana . s:SkkKakutei()
   let b:skk_mode = 'ascii'
+  call s:SkkSetCursorColor()
   return kana
 endfunction
 
@@ -1068,6 +1176,7 @@
   endif
   let kana = SkkSetHenkanPoint1(a:kana)
   let b:skk_abbrev_mode_on = 1
+  call s:SkkSetCursorColor()
   return kana
 endfunction
 
@@ -1083,15 +1192,15 @@
   elseif m == 2 && s:skk_in_cmdline == 0
     let str = " "
   elseif b:skk_abbrev_mode_on == 1
-    let str = "[SKK:aあ]"
+    let str = "[" . g:skk_abbrev_mode_string . "]"
   elseif b:skk_mode == "hira"
-    let str = "[SKK:あ]"
+    let str = "[" . g:skk_hiragana_mode_string . "]"
   elseif b:skk_mode == "kata"
-    let str = "[SKK:ア]"
+    let str = "[" . g:skk_katakana_mode_string . "]"
   elseif b:skk_mode == "zenei"
-    let str = "[SKK:A]"
+    let str = "[" . g:skk_jisx0208_latin_mode_string . "]"
   else
-    let str = "[SKK:aA]"
+    let str = "[" . g:skk_latin_mode_string . "]"
   endif
   if exists("b:skk_autofill") && b:skk_autofill && str != " "
     let str = str . "FILL"
@@ -1449,8 +1558,35 @@
     return s:SkkInsertZenei(a:char)
   else		" hira|kata
     try
-      if b:skk_henkan_mode == 3
+      if b:skk_henkan_mode != 0 && a:char == g:skk_kakutei_key
+	call s:SkkKakutei()
+	return ''
+      elseif b:skk_henkan_mode == 3
 	return SkkHenkan(a:char)
+      elseif b:skk_henkan_mode == 0 && a:char == g:skk_sticky_key
+	return SkkSetHenkanPoint('')
+      elseif b:skk_henkan_mode == 1 && a:char == g:skk_sticky_key
+	if !s:SkkCheckMarker(g:skk_marker_white, b:skk_hstart)
+	  let b:skk_henkan_mode = 0
+	  throw "skk cannot find " . g:skk_marker_white . " mark"
+	endif
+	" g:skk_sticky_key 連続押下で g:skk_sticky_key 自体を返す
+	" ;; で ▽* 、;k; で ▽* ではなく、; になるように
+	let kana = s:SkkCleanRom() " kana は n の場合に ん になる
+	if kana == '' && s:SkkCursorCol() == b:skk_hstart +
+	      \ strlen(g:skk_marker_white)
+	  call s:SkkKakutei() " ▽の削除 ( 確定 )
+	  return g:skk_sticky_key
+	endif
+	if b:skk_rstart == 0 || b:skk_line != s:SkkCursorLine()
+	  let b:skk_line = s:SkkCursorLine()
+	  let b:skk_rstart = s:SkkCursorCol()
+	endif
+	let b:skk_ostart = strlen(kana) + b:skk_rstart
+	let b:skk_rstart = strlen(kana) + b:skk_rstart +
+	      \ strlen(g:skk_marker_okuri)
+	let b:skk_henkan_mode = 2
+	return kana . g:skk_marker_okuri
       elseif stridx(g:skk_henkan_point_keys, a:char) != -1 && b:skk_abbrev_mode_on == 0
 	return SkkSetHenkanPoint(a:char)
       elseif b:skk_henkan_mode == 1 && a:char ==# g:skk_start_henkan_key
@@ -1888,6 +2024,7 @@
   let b:skk_romv = ''
   let b:skk_rstart = 0
   let b:skk_abbrev_mode_on = 0
+  call s:SkkSetCursorColor()
   return kana
 endfunction