Hatena::ブログ(Diary)

くふくふん このページをアンテナに追加 RSSフィード

2017-04-28

2009-07-19

新ダイアリーに移動します

今日、かねてから希望していた新規アカウント(id:emanon001)を取得しました。

それに伴ない、

ダイアリー http://d.hatena.ne.jp/kuhukuhun/ から

ダイアリー http://d.hatena.ne.jp/emanon001/ に移動して記事を書くことにします。


諸所の事情により、基本的に旧ダイアリーの記事は新ダイアリーに移動していません。

ダイアリーの記事は消さずに残しておきますが、これから旧ダイアリーに対してコメントやトラックバックがあった場合、それに対する反応は現在より遅れます。あらかじめご了承ください。

2009-07-12

指定したスクリプトファイルのスクリプトローカル変数を取得する

3ヶ月ぶりに Vim と戯れるということで、どうにも勘が戻ってこなかった。

  • 文字列連結が上手くいかず5分くらい悩んでいた。文字列連結は + ではなく . だった。
  • インクリメントが上手くいかず5分くらい悩んでいた。let を付けていなかった。

Vimmer を名乗ったら

autocmd BufWritePre * qall!

されるレベル。

ソースコード

以下のソースコードを設定ファイルに記述する。

function! GetScriptVariableSource()
  return "function! s:__get_script_variables()\n
        \   return s:\n
        \ endfunction"
endfunction

function! GetScriptVariables(snr)
  return eval('<SNR>{a:snr}___get_script_variables()')
endfunction

function! GetScriptVariable(snr, var_name)
  let d = GetScriptVariables(a:snr)
  if !has_key(d, a:var_name)
    throw 'GetScriptVariable: not found script variable "' . a:var_name . '".'
  endif
  return get(d, a:var_name)
endfunction

使い方

スクリプトファイルは、ファイル内のスクリプトローカル変数に対する外部からの取得を許可する場合、以下のソースコードを記述する。

execute GetScriptVariableSource()

あるスクリプトファイルのスクリプトローカル変数全て(s: そのもの)を取得したい場合、スクリプトファイルの持つスクリプト番号(:scriptnames で表示される番号)を関数引数として渡す。

let d = GetScriptVariables(snr)

あるスクリプトファイルの特定のスクリプトローカル変数を取得したい場合、スクリプトファイルの持つスクリプト番号と、スクリプトローカル変数名を関数引数として渡す。

let v = GetScriptVariable(snr, var_name)

スクリプト番号の取得方法がわからない場合や、取得するのが面倒だという場合は以下の関数を使えば少しは楽になるかもしれない。

function! FilePathToScriptNumber(path)
  redir => _
  silent! scriptnames
  redir END

  let names = split(_, "\n")
  call filter(names, "matchstr(v:val, '^\\s*\\d*: \\zs.*') ==# a:path")

  if empty(names)
    throw 'FilePathToScriptNumber: not convert the path "' . a:path . '".'
  endif
  return str2nr(matchstr(names[0], '^\s*\d*'))
endfunction

スクリプトファイルのフルパスを関数引数として渡すと、スクリプト番号に変換する。

let path = expand('%:p')
let snr = FilePathToScriptNumber(path)

その他

使いどころ

ない。

工夫

特になし。結局それかよみたいな作り。

いちいち取得を許可するためにソースコードを記述するのは面倒。autocmd でどうにかできそうならどうにかしたいのだが、どうにもできなかった。SourcePre とか SourceCmd とか。

注意

とても危険。スクリプトローカル変数をコピーせずそのまま返しているので、取得した側で何でもできてしまう。特に GetScriptVariables() が危険。s: をそのまま返しているのでフリーダムな操作ができてしまう。おすすめ。

変更履歴

修正(2009-07-14)
  • 関数 FilePathToScriptNumber() が正常に動かなかったのを修正。(アバウトすぎる)

2009-03-26

scratch_bufferというプラグインを書いたよー

『あるバッファに関連した処理の出力結果を表示するための作業用バッファ』というものが欲しかったので、そういうものを作ってみました。*1


概要

作業用のバッファ(スクラッチバッファ)を作成し、ユーザが指定したバッファに関連付けます。

ユーザは指定したバッファに対して、複数の作業用バッファを関連付けることができます。

また、作業用バッファに対して開閉と削除を行なうことができます。


ソースコード

以下のリンク先で閲覧・入手できます。

OpenID transaction in progress


使い方

中途半端に書いたヘルプファイルに丸投げ。

http://bitbucket.org/emanon001/scratch_buffer-vim/src/tip/doc/scratch_buffer.jax

関数とかキーマッピングとかの説明が書けていないのですが、それらはコマンド名と対応しているので、コマンドの説明を読んで頂ければ大体理解できると思います。


……と言いたいところですが、よく使うものを紹介しておきます。

指定したバッファの暗黙的な作業用バッファ名を設定する
scratch_buffer#default_bufname([{bufnr} [, {bufname}]])

バッファ番号 {bufnr} の暗黙的な作業用バッファ名として、バッファ名 {bufname} を設定する。

関数引数に何も与えられなかった場合、カレントバッファの暗黙的な作業用バッファ名として、空文字列が設定される。

指定したバッファの作業用バッファを開く
scratch_buffer#open([{bufnr} [, {bufname}, ...]])

バッファ番号 {bufnr} に関連付けられた作業用バッファから、作業用バッファ名 {bufname} に該当するバッファを開く。

関連付けられた作業用バッファが存在しない場合、{bufname} という名前の作業用バッファを新たに作成し、バッファ番号 {bufnr} に関連付け、それを開く。

関数引数に何も与えられなかった場合、カレントバッファに関連付けられた作業用バッファから、暗黙的な作業用バッファ名に該当するバッファを開く。

カレントバッファの暗黙的な作業用バッファに対して開閉をトグルするキーマッピング
<Plug>(scratch_buffer-toggle-keep)

カレントバッファの暗黙的な作業用バッファ名に該当するバッファに対して、開閉をトグルするキーマッピング

作業用バッファを開いた際に、カーソルを作業用バッファに移動しない。


サンプル

カレントバッファRubyコードを実行した結果を作業用バッファに表示させる。

function! s:preview_ruby_output()
  let r = system('ruby ' . expand('%:p'))

  let n = 'ruby_output'
  call scratch_buffer#open(bufnr(''), n)

  silent 1,$delete_
  call setline(1, split(r, '\n'))

  wincmd p
endfunction

参考

今さらスクラッチ(scratch)を作ってみる - くまのりくふん - vimグループ

「今さらスクラッチ(scratch)を作ってみる」の続き - くまのりくふん - vimグループ

実は半年以上前から作っていました。この頃と比べると、インターフェースは結構変わっていますし、コードなんて殆ど変わっていますね。

*1プレビューウィンドウは本来の用途とは異なる上に、1つのタブに1つだけしか開くことができないので駄目。

2009-03-20

VimスクリプトでBrainfuckの処理系を書いたよー

一ヶ月ぶりのVimスクリプト。一ヶ月ぶりのプログラミング。よってリハビリ。Brainfuck

ソースコード

以下のリンク先で閲覧・入手できます。

Repository deleted — Bitbucket

また、サンプルとして、'Hello, world!' を出力する Brainfuck のソースファイルを置いています。

Hello worldプログラムの一覧 - Wikipediaソースコードそのままです。


使い方

コマンドから使う
:Brainfuck {source_file_path}

単純に、コマンドの引数Brainfuck のソースファイルのパスを指定するだけです。ファイルパスは補完が効くので、c_CTRL-D とか c_<Tab> とかを使えばいいんじゃないかと思います。

関数から使う
call brainfuck#run({source_code})

単純に、関数引数Brainfuckソースコードを渡すだけです。

" Hello, world!
call brainfuck#run('+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.
      \             ------------.<++++++++.--------.+++.------.--------.>+.')

Brainfuckソースコード中にはスペース、Tab文字、改行が含まれていても問題ありません。


参考

明日は VimMいってきまーす - kei-os2007 against the machine!!

BrainF*ck in Vim - 永遠に未完成

所々参考にさせて頂きました。先人に感謝。