Summary
Vim / Neovim / MacVim
ノーマルモードに戻るときに自動的に英語モードにする
insert normal
------------------------------
Input Source any -> en
結論
Python(PyObjC)
でかいた
Neovim / MacVim では普通にストレスなくできるようになった
Vim では遅すぎて実際には使用できない
作成したプラグイン
作成した関数
: SwitchEnglish('')
Python にて作成
Neovim の Remote pluginにて使用する
MacVim, Vimのばあいはnvim-yarpを併用して使用する
使い方
- Pythonのライブラリをダウンロード
$ pip3 install pyobjc-core
$ pip3 install pyobjc-framework-Cocoa
- vimのプラグインをダウンロード他 (ここはお好みのダウンローダーで)
$ git clone --depth 1 https://github.com/callmekohei/switcher.nvim
$ nvim .vimrc
set runtimepath+=/path/to/switcher.nvim
- プラグインを登録する
$ nvim
:UpdateRemotePlugins
- vimrcに下記を書く
autocmd InsertLeave * :call SwitchEnglish('')
課題
現在のインプットソース ( current input sources ) を確認する方法を見つけたい
理由;すべてを en にしてるが、Japanese のときだけ en にする処理をしたいから
carbon.foo
で現在のインプットソースを見ようとしてもうまくいかない。。。
# import Carbon by now
# これはうまくいかない!
carbon = ctypes.cdll.LoadLibrary(ctypes.util.find_library('Carbon'))
print(carbon.TISGetInputSourceProperty(carbon.TISCopyCurrentKeyboardInputSource() , carbon.kTISPropertyInputModeID) )
HITool.h
を利用すると現在のインプットソースを見れるが、carbon.foo
と混ぜると2回目以降?効かなくなる。
# use HITToolbox's functions
HIToolbox_bundle = NSBundle.bundleWithIdentifier_("com.apple.HIToolbox")
# bundle many...
HIToolbox_functions = [ ('TISGetInputSourceProperty', b'@@@'), ('TISCopyCurrentKeyboardInputSource', b'@') ]
HIToolbox_constants = [('kTISPropertyInputModeID', b'@') ]
objc.loadBundleFunctions(HIToolbox_bundle, globals(), HIToolbox_functions)
objc.loadBundleVariables(HIToolbox_bundle, globals(), HIToolbox_constants)
print(TISGetInputSourceProperty(TISCopyCurrentKeyboardInputSource() , kTISPropertyInputModeID))
どうでもいいこと
macOSXのAPIの名前が、Carbon(炭火焼き)とかCocoa(ココア)とか美味しそうでお腹へるやん。。。
OSXのことまったく何も知らない状態で2日でここまでこれるの、本当にインターネットのおかげ〜
インターネットすごい!
というか Python よりも Objective-C とか Swift の情報が圧倒的に多くて嫌になっちゃう
いや別に Python が好きとかそんなことは一切ないですけどねwww
Great references
pudquick/input_sources.py
Khande/auto_switch_kb.py
How can we reading / coerce CFArray and CFString etc values from within OS X JXA?
ここからしたは過去の記事
追記 (2018/08/16/07:20 )
パイソン(objective-c)で書いてみました。vimrc
から切り出してプラグインにしてみました。というかつらかった。つらかった。2日でここまで書いた僕えらいwww というかmacOSX
はぜんぜんわからない。(他もわからないけど・・・)
速度ですが、Neovim
はストレスを感じないレベルです。Vim
はもさっとしてます。切り替えはおさ(osascript
)をつかってるのでここをpyobjc(object-c)
で書き直したら結構いい感じになりそうだな〜と思ってます。思ってますが、わかりません!www 調べてわかり次第書き直したいと思います!
(追記ここまでっ)
最初に書いた記事
こんな感じ
vimとNeovimとではちょっとやり方が変わります
vimの場合
help通りにやる( :h japanese )
function g:ImActivateFunc(active) abort
if !a:active
call system( 'osascript -e "tell application \"System Events\" to key code 102" &' )
endif
endfunction
function! g:ImStatusFunc() abort
let l:cmd = 'ObjC.import("Carbon") ;var current_source = $.TISCopyCurrentKeyboardInputSource(); ;var cfs = $.TISGetInputSourceProperty(current_source, $.kTISPropertyInputSourceID); ;ObjC.bindFunction("CFMakeCollectable", [ "id", [ "void *" ] ]); ;Ref.prototype.toNS = function () { return $.CFMakeCollectable(this) } ;cfs.toNS()'
let l:foo = system( 'osascript -l JavaScript -e "' . l:cmd . '" &' )
if stridx(l:foo, 'Japanese')
return 1
endif
endfunction
set iminsert=2
set imsearch=2
set imcmdline
set imstatusfunc=g:ImStatusFunc
set imactivatefunc=g:ImActivateFunc
Neovimの場合
function! s:imStatusFunc() abort
let l:cmd = 'ObjC.import("Carbon") ;var current_source = $.TISCopyCurrentKeyboardInputSource(); ;var cfs = $.TISGetInputSourceProperty(current_source, $.kTISPropertyInputSourceID); ;ObjC.bindFunction("CFMakeCollectable", [ "id", [ "void *" ] ]); ;Ref.prototype.toNS = function () { return $.CFMakeCollectable(this) } ;cfs.toNS()'
let l:foo = system( 'osascript -l JavaScript -e "' . l:cmd . '" &' )
if stridx(l:foo, 'Japanese')
return 1
endif
return 0
endfunction
function s:imDeactivateFunc() abort
call system( 'osascript -e "tell application \"System Events\" to key code 102" &' )
endfunction
autocmd callmekohei-vimrc InsertLeave * if s:imStatusFunc() | :call s:imDeactivateFunc() | endif
Vim/Neovim共通
noremap <silent><nowait><ESC><ESC>
\ :nohlsearch<CR><C-l>
\ :<C-u>call <SID>imDeactivateFunc()<CR>
みどころ
IMEの状態を見る関数
13時間ほどぶっ続けでやって結局は stack overflow に書いてあったみたいな(泣)
JavaScriptもOSXのObjective-Cとかもぜんぜんわからずにアタックしましたよwww
辛すぎ〜
see also:How can we reading / coerce CFArray and CFString etc values from within OS X JXA?
// Carbonをインポート;古いAPIを使えるようにする
ObjC.import('Carbon')
var current_source = $.TISCopyCurrentKeyboardInputSource();
var cfs = $.TISGetInputSourceProperty(current_source, $.kTISPropertyInputSourceID);
ObjC.bindFunction('CFMakeCollectable', [ 'id', [ 'void *' ] ]);
Ref.prototype.toNS = function () {
return $.CFMakeCollectable(this)
}
cfs.toNS()
動作的に
日本語切り替えを入れると全体的に動作がもさっとします。とくにインサートからノーマルにいくときに、:w
を押す癖がついてるのですが、これができなくなるのですよ。たぶん0.3秒ほどウエイトがかかるんですけどそこにちょっと、あああな感じですけど慣れるしかないんでしょうね・・・。うん、でもそれ以外は今のところ快適ですね。
できれば・・・
いまはIME
の状態チェックでおさを(osascript)。切り替えるときにもおさを(osascript)。もったいないですよね。ここ。なんとか一つにしたいと思ってるところです。どたなたやってみませんか?
参考
⌨️キーボード配列の取得 - みずぴー日記
Apple Developer Documentation
Building OS X Apps with JavaScript by Tyler Gaw
Cocoaからのライブ変換(LiveConversion)の変更と監視 — MindTo01s
Complete list of AppleScript key codes
Examples overview — PyObjC - the Python to Objective-C bridge
Home · JXA-Cookbook/JXA-Cookbook Wiki
InputMethodKit | Apple Developer Documentation
JavaScript for OSX Automation AppleScriptの代替をJavaScriptでやるサンプル Advent Calendar 2014 - Qiita
Mac : JavaScript for Automation (JXA) 例文辞典
Nullege: A Search Engine for Python source code
objective c - How can we reading / coerce CFArray and CFString etc values from within OS X JXA? - Stack Overflow
objective-c - JXA: Доступ к константам CFString из CoreServices
osx yosemite の入力環境が色々とかったるいので、考えてみた - ばかもりだし
pyobjc-framework-InputMethodKit · PyPI
SubCandidates/main.m at master · dougalg/SubCandidates
Swift uses InputMethodKit to write an input method | R0uter's Blog
Working with System Frameworks in Python and Objective-C.key - psumac2015-62-Working_with_System_Frameworks_in_Python_and_Objective-C.pdf
xkbswitch-macosx/main.m at master · myshov/xkbswitch-macosx
鳶嶋工房 / AppleScript / JavaScript for Automation (JXA)