2010/06/18


tyruさんが絶賛開発中の new generation of skk.vim : "eskk.vim" を試して見ようとしたのですが、autoloadを使っているのでいかんせんpluginフォルダに入れないと動かない。
よくgithubからvimscriptアプリケーションを落として、ちょっとだけ試したい場合には困ります。
そこで以下の様なスクリプト書いた。
ベースはthincaさんのこれ

function! s:load_optional_rtp(loc)
  let loc = expand(a:loc)
  exe "set rtp+=".loc
  let files = split(globpath(loc, '**/*.vim'), "\n")
  for i in reverse(filter(files, 'filereadable(v:val)'))
    if i !~ '/tests\?/'
      source `=i`
    endif
  endfor
endfunction

これをvimrcに書いておいて call s:load_optional_rtp("~/dev/eskk.vim")
とかすればよろし。
外したくなったらcallの行をコメントアウト。ソースリポジトリを直接指せばいいんです。

注意
ちなみにeskk.vimを入れたくないって言ってるんじゃないので!
家のマシンがショボいので軽く使いたいのです。
Posted at by




tyruさんが既に記事にしてくれてますが、こちらでも。
mattnさんが前の記事にコードで回答してくれた - おつあり

mattnさんが前の記事にコードで回答してくれた Vim mattn’s libcallex-vim at master - GitHub こんなリポジトリが作られたので十中八九僕のlibcall()...

http://d.hatena.ne.jp/tyru/20100518/cool_mattn
通常 libcall は引数が1つしか扱えないのですが、内部でJSONでやりとりしてC言語で書いた呼び出しproxyを介して外部ライブラリ(DLL等)の関数を呼び出せます。
とはいってもvimで扱える型しか対応していませんが、ちょっと無茶すればいろんな事が出来ます。
例えばuser32.dllのMessageBoxAを実行したり... so ../libcallex.vim

silent unlet! lib

let lib = libcallex.load('msvcrt.dll')
let username = lib.call('getenv', ["USERNAME"], 'string')
call libcallex.free(lib)

let lib = libcallex.load("user32.dll")
if lib.call('MessageBoxA', [0, "Hello ".username."\r\nCan you see this message?", 'Hello World', 4]) == 6
  call lib.call('MessageBoxA', [0, 'You clicked "YES"', 'Hello World', 0])
else
  call lib.call('MessageBoxA', [0, 'You clicked "NO". Are you all right?', 'Hello World', 0])
endif
call libcallex.free(lib)
バッファを引数に取る関数を呼び出してWindowsのSystemディレクトリを取得したり... so ../libcallex.vim

silent unlet! lib

let lib = libcallex.load('kernel32.dll')

let buf = repeat(' ', 255)
let args = [buf, 255]
call lib.call('GetWindowsDirectoryA', args, 'number')
let dir = args[0]
echo "your windows directory: " . dir

let buf = repeat(' ', 255)
let args = [buf, 255]
call lib.call('GetSystemDirectoryA', args, 'number')
let dir = args[0]
echo "your system directory : " . dir

call libcallex.free(lib)
無理やりlongのポインタ作ってバッファ書き込み数を参照渡しで扱う関数を呼び出したり... so ../libcallex.vim

silent unlet! msvcrt
silent unlet! advapi32

let msvcrt = libcallex.load('msvcrt.dll')
let advapi32 = libcallex.load('advapi32.dll')

" make address of variable which is stored 256
let ptr = float2nr(eval(msvcrt.call('malloc', [4], 'number')))
call msvcrt.call('memset', [ptr, 0, 4], 'number')
call msvcrt.call('memset', [ptr+1, 1, 1], 'number')

let buf = repeat(' ', 256)
let args = [buf, ptr]
call advapi32.call('GetUserNameA', args, 'number')
let username = args[0]

call msvcrt.call('free', [ptr], 'number')

call libcallex.free(advapi32)
call libcallex.free(msvcrt)

echo username
出来ます。(まぁ最後のはやりすぎとして)
分かる人は想像通りですが、簡単なインラインアセンブラで実現してます。
いままでvimからDLL呼び出しが出来ないと悩んでおられた方には有用かもしれません。

えっ?mattnとtyruさんだけだって?
Posted at by



2010/03/24


もう既出感丸出しですが...
リロード如きでソケットサーバとか使うの嫌だったのでWindows API使った。

function! s:UpdateBrowser()
  python<<EOM
import win32gui,win32api,win32con
hwnd = win32gui.FindWindow("MozillaUIWindowClass", None)
hwnd = win32gui.FindWindowEx(hwnd, 0, "MozillaWindowClass", None)
win32gui.SendMessage(hwnd, win32con.WM_KEYDOWN, win32con.VK_F5, 0)
EOM
endfunction

function! s:StartEditing()
  augroup HtmlEditing
    au!
    autocmd BufWritePost,FileWritePost *.html call s:UpdateBrowser()
  augroup END
  exec "!start c:/progra~1/mozill~1/firefox.exe " . expand('%:p')
endfunction

function! s:StopEditing()
  augroup HtmlEditing
    au!
  augroup END
endfunction

command! HtmlStartEditing call s:StartEditing()
command! HtmlStopEditing call s:StopEditing()
Windowsで、しかもFirefoxでしか動かない。「:HtmlStartEditing」で開始、「:HtmlStopEditing」で停止です。ファイルが更新される度にブラウザ(Firefox)にF5を送信します。Firefoxのパスとか適当に...
書いて5分程使ってみたけど、まぁまぁな感じ。いつかもうちょっと弄って使うかも。

同じ方法でchromeも出来るかもしれない。
Posted at by