<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Vim-users.jp &#187; その他</title>
	<atom:link href="http://vim-users.jp/category/etc/feed/" rel="self" type="application/rss+xml" />
	<link>http://vim-users.jp</link>
	<description>日本の Vim ユーザのためのハブサイト</description>
	<lastBuildDate>Sun, 05 Feb 2012 10:51:53 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
	<atom:link rel='hub' href='http://vim-users.jp/?pushpress=hub'/>
		<item>
		<title>新年あけましておめでとうございます</title>
		<link>http://vim-users.jp/2012/01/happy-new-year-vim/</link>
		<comments>http://vim-users.jp/2012/01/happy-new-year-vim/#comments</comments>
		<pubDate>Sat, 31 Dec 2011 15:00:45 +0000</pubDate>
		<dc:creator>ujihisa</dc:creator>
				<category><![CDATA[その他]]></category>
		<category><![CDATA[Vim Advent Calendar]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=2713</guid>
		<description><![CDATA[新年あけましておめでとうございます。いまこの記事はAmtrak Cascadesという大陸縦断鉄道の中で執筆しています。さきほどカナダからの出国を済ませました。時刻は6:18amで、日の出は8:07amの予定なので、初日 [...]]]></description>
			<content:encoded><![CDATA[				<p>新年あけましておめでとうございます。いまこの記事はAmtrak Cascadesという大陸縦断鉄道の中で執筆しています。さきほどカナダからの出国を済ませました。時刻は6:18amで、日の出は8:07amの予定なので、初日の出までまだまだ時間があります。</p>
				
				<p><img src="http://cache.gyazo.com/a6aa9d66e5efed7aeced49cc1c260373.png" alt="amtrak cascades" /></p>
				
				<p>車内にはかなり安定したwifiがあり、ssh接続すら切れません。当然各席に電源があり、3時間程度しかバッテリのもたない初代MacBook Airでも平然と作業をすすめることができます。</p>
				
				<p><img src="http://www.yougottabehere.com/media/resampled/articleElement/1026/resampled_Jan_11_2010_amtrak_cascades_train_600.jpg" alt="amtrak cascades" /></p>
				
				<p>お腹が減ったら食堂車で朝食Vimをキメることも可能です。</p>
				
				<p><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/1/1d/AmtrakCascadesDiner.JPG/220px-AmtrakCascadesDiner.JPG" alt="amtrak cascades" /></p>
				
				<h2>スピリチュアルな話</h2>
				
				<p>をして感極まる元旦を迎えるというのも良いですが、あんまりそういう話は得意でないので、Vimの話をします。</p>
				
				<p>プログラミング関する何かを新たに学ぶとき、まずVimでそれをどのようにラクに行なうかを考える、ということは日常的に行なわれていることだと思います。たとえば普段はVim scriptとRubyしか書かない人が急にPythonをはじめるときは、neocomplcacheの自動補完やref.vimを駆使してVim内でPythonの学習を行なうでしょう。</p>
				
				<p>これにちなんで、ちょっと個人的な話と、プラギンの紹介を行ないます。</p>
				
				<h2>時代は低レイヤ</h2>
				
				<p>僕はRubyでらくらくスクリプト書きなぐりやHaskellで宣言的に書きなぐりといった高レイヤ部分ばかりに慣れ親しみすぎたため、アセンブラやそれ以前にCやJavaといった低水準言語すらもうまく使えない軟弱プログラマなのでした。最も低水準な言語はJavaScriptやVim scriptだったと思います。このままではまずいと思い、青木峰郎先生の<a href="http://www.amazon.co.jp/%E3%81%B5%E3%81%A4%E3%81%86%E3%81%AE%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9%E3%82%92%E3%81%A4%E3%81%8F%E3%82%8D%E3%81%86-%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86%E7%B3%BB%E3%82%92%E3%81%A4%E3%81%8F%E3%82%8A%E3%81%AA%E3%81%8C%E3%82%89%E5%AD%A6%E3%81%B6%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB%E3%81%A8%E5%AE%9F%E8%A1%8C%E7%92%B0%E5%A2%83%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF-%E9%9D%92%E6%9C%A8-%E5%B3%B0%E9%83%8E/dp/4797337958">ふつうのコンパイラ</a>などを片手にアセンブラやその周辺技術、とくにコンパイラの最適化あたりの勉強に集中することに決めました。</p>
				
				<p>大抵のC言語コンパイラは末尾再帰最適化を行なっているということは、低レイヤにあまり慣れ親しんでいない人でも、耳にしたことがあるのではないでしょうか。さて、最適化が行なわれたか否かを実際に確かめるには、実際にアセンブラを確認するとよいでしょう。</p>
				
				<pre><code>int f(int acc, int n)
{
  return n &lt; 0 ? acc : f(acc + n, n - 1);
}
</code></pre>
				
				<p>0からnまでの和を得る末尾再帰の関数です。f(0, 10) == 55です。</p>
				
				<pre><code>$ gcc a.c -S -m32 -O2 -o -

_f:
  pushl %ebp
  movl  %esp, %ebp
  movl  8(%ebp), %eax
  movl  12(%ebp), %edx
  testl %edx, %edx
  jns   L7
  jmp   L3
  .align 4,0x90
L9:
  movl  %ecx, %edx
L7:
  leal  -1(%edx), %ecx
  addl  %edx, %eax
  cmpl  $-1, %ecx
  jne   L9
L3:
  leave
  ret
</code></pre>
				
				<p>詳しい解説は省略しますが、ようするに再帰的に関数呼び出しを行なうかわりに、単なるループに変換されています。</p>
				
				<p>これはGCCでx86アセンブリ言語に変換するよりもClangでLLVM IRに変換する方が直感的で読みやすいでしょう。</p>
				
				<pre><code>$ clang -O3 a.c -S -emit-llvm -o -
define i32 @f(i32 %acc, i32 %n) nounwind uwtable readnone ssp {
entry:
  %cmp1 = icmp slt i32 %n, 0
  br i1 %cmp1, label %cond.end, label %cond.false.lr.ph

cond.false.lr.ph:                                 ; preds = %entry
  %0 = mul i32 %n, %n
  %1 = zext i32 %n to i33
  %2 = add i32 %n, -1
  %3 = zext i32 %2 to i33
  %4 = mul i33 %1, %3
  %5 = lshr i33 %4, 1
  %6 = trunc i33 %5 to i32
  %7 = add i32 %0, %acc
  %8 = sub i32 %7, %6
  br label %cond.end

cond.end:                                         ; preds = %cond.false.lr.ph, %entry
  %acc.tr.lcssa = phi i32 [ %8, %cond.false.lr.ph ], [ %acc, %entry ]
  ret i32 %acc.tr.lcssa
}
</code></pre>
				
				<p>要するにループに変換されています。</p>
				
				<p>つづいて、末尾再帰ではない形でも確認してみましょう。</p>
				
				<pre><code>int f(int n)
{
  return n &lt; 0 ? 0 : n + f(n - 1);
}
</code></pre>
				
				<p>実はこれでも先ほどとほとんど同じ結果が得られます。わざわざ人間が末尾再帰の形に変形する必要はないのでした。</p>
				
				<p>これらのような事実が実際に目で確認できることがわかりました。しかし毎回gccやclangコマンドをvimshellから入力するのは大変です。それどころか、さきほど記述したCのコードにファイル名を与えて保存することは大変で、そんなことをしていると学習以前に一年が過ぎてしまい、次の元旦を迎えてしまいます。このような事態に陥ったとき、訓練されたVim使いは「そうだquickrun、使おう」となります。</p>
				
				<pre><code>:QuickRun -type c/gcc  -exec '%c %o %s -S -o -' -cmdopt '-m32 -O2'
</code></pre>
				
				<p>これで動作することが分かるので、よし、<code>~/.vimrc</code>を開いて<code>g:quickrun_config</code>に・・・おっと、それだとclangの例を試せません。</p>
				
				<pre><code>:QuickRun -type c/clang  -exec '%c %o %s -S -emit-llvm -o -' -cmdopt '-O3'
</code></pre>
				
				<p>複数の候補から選択したい。<a href="http://vim-users.jp/2011/02/hack200/">Hack #200: 候補を選択し、実行する</a>にあるように、これはunite.vimの出番です。</p>
				
				<p>欲深いもので、Cという1つの言語だけをサポートするのではなく、RubyにはYARV instructionを、CoffeeScriptにはJavaScriptを、といった具合で、人間の煩悩が108あるように、複数の要求をすべて満たしてみたくなるものです。</p>
				
				<p>というわけでプラギンにしてみました。すばやく学習を支援するという意味で、quicklearn.vimという名前にしました。quickrunとquicklearnでrとlの発音をそれぞれ学習でき、一石二鳥です。</p>
				
				<ul>
				  <li><a href="https://github.com/ujihisa/quicklearn">https://github.com/ujihisa/quicklearn</a></li>
				</ul>
				
				<p>紹介動画</p>
				
				<p><object width="480" height="386" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000">
				  <param name="flashvars" value="vid=18198707&amp;autoplay=false" />
				  <param name="allowfullscreen" value="true" />
				  <param name="allowscriptaccess" value="always" />
				  <param name="src" value="http://www.ustream.tv/flash/viewer.swf" />
				  <embed flashvars="vid=18198707&amp;autoplay=false" width="480" height="386" allowfullscreen="true" allowscriptaccess="always" src="http://www.ustream.tv/flash/viewer.swf" type="application/x-shockwave-flash" />
				</object></p>
				
				<p><br /><a href="http://www.ustream.tv/" style="padding: 2px 0px 4px; width: 400px; background: #ffffff; display: block; color: #000000; font-weight: normal; font-size: 10px; text-decoration: underline; text-align: center;" target="_blank">Video streaming by Ustream</a></p>
				
				<p>以下の言語/処理系/中間言語をサポートしています。</p>
				
				<ul>
				  <li>C
				    <ul>
				      <li>Assembly language (gcc)</li>
				      <li>LLVM IR (clang)</li>
				    </ul>
				  </li>
				  <li>Haskell
				    <ul>
				      <li>Core (ghc)</li>
				    </ul>
				  </li>
				  <li>CoffeeScript
				    <ul>
				      <li>JavaScript</li>
				    </ul>
				  </li>
				  <li>Ruby
				    <ul>
				      <li>YARV Instructions (CRuby)</li>
				    </ul>
				  </li>
				</ul>
				
				<p>quicklearnは</p>
				
				<pre><code>:Unite quicklearn -immediately
</code></pre>
				
				<p>のようにして実行できます。筆者は</p>
				
				<pre><code>nnoremap &lt;space&gt;R :&lt;C-u&gt;Unite quicklearn -immediately&lt;Cr&gt;
</code></pre>
				
				<p>と<code>~/.vimrc</code>で設定し、<kbd>&lt;space&gt;R</kbd>で実行できるようにしています。なお、quickrunは<kbd>&lt;space&gt;r</kbd>にしています。</p>
				
				<p><code>-immediately</code>オプションがとても便利です。</p>
				
				<p>なお、quickrunはアセンブリ言語やLLVM IRをサポートしています。つまり、quicklearnによって生成させたアセンブリ言語やLLVM IRのバッファでさらにquickrunを行なうことで、それを実行することができ、とても便利です。</p>
				
				<h2>実装</h2>
				
				<p>たったの98行です。</p>
				
				<p>autoload/unite/sources/quicklearn.vim</p>
				
				<pre><code>let s:save_cpo = &amp;cpo
set cpo&amp;vim

" fmap([a, b, c], f) =&gt; [f(a), f(b), f(c)]
" fmap(a, f) =&gt; [f(a)]
function! s:fmap(xs, f)
  if type(a:xs) == type([])
    return map(a:xs, a:f)
  else
    return map([a:xs], a:f)
  endif
endfunction

let g:quicklearn_gcc_remote_url = get(g:, 'quicklearn_gcc_remote_url', 'localhost')

let s:quicklearn = {}
let s:source = {
      \ 'name': 'quicklearn',
      \ }
let s:quicklearn['c/clang/intermediate'] = {
      \ 'meta': {
      \   'parent': 'c/clang'},
      \ 'exec': '%c %o %s -S -emit-llvm -o -'}
let s:quicklearn['c/clang-O3/intermediate'] = {
      \ 'meta': {
      \   'parent': 'c/clang'},
      \ 'cmdopt': '-O3',
      \ 'exec': '%c %o %s -S -emit-llvm -o -'}
let s:quicklearn['c/gcc/intermediate'] = {
      \ 'meta': {
      \   'parent': 'c/gcc'},
      \ 'exec': '%c %o %s -S -o -'}
let s:quicklearn['c/gcc-32/intermediate'] = {
      \ 'meta': {
      \   'parent': 'c/gcc'},
      \ 'cmdopt': '-m32',
      \ 'exec': '%c %o %s -S -o -'}
let s:quicklearn['c/gcc-remote/intermediate'] = {
      \ 'meta': {
      \   'parent': 'c/gcc'},
      \ 'exec': 'ssh ' . g:quicklearn_gcc_remote_url . ' %c %o %s -S -o -'}
let s:quicklearn['haskell/ghc/intermediate'] = {
      \ 'meta': {
      \   'parent': 'haskell/ghc'},
      \ 'exec': [
      \   '%c %o -ddump-simpl -dsuppress-coercions %s',
      \   'rm %s:p:r %s:p:r.o %s:p:r.hi'],
      \ 'cmdopt': '-v0 --make'}
let s:quicklearn['coffee/intermediate'] = {
      \ 'meta': {
      \   'parent': '_'},
      \ 'exec': ['%c %o -cbp %s %a']}
let s:quicklearn['ruby/intermediate'] = {
      \ 'meta': {
      \   'parent': 'ruby'},
      \ 'cmdopt': '--dump=insns'}

" inheritance
for k in keys(s:quicklearn)
  let v = s:quicklearn[k]
  for item in ['command', 'exec', 'cmdopt', 'tempfile', 'eval_template']
    let ofParent = get(g:quickrun#default_config[v.meta.parent], item)
    if type(ofParent) != type(0) || ofParent != 0
      let s:quicklearn[k][item] = get(v, item, ofParent)
    endif
    unlet ofParent
  endfor
endfor

" build quickrun command
for k in keys(s:quicklearn)
  let v = s:quicklearn[k]
  let s:quicklearn[k].quickrun_command = printf(
        \ 'QuickRun %s %s %s -cmdopt %s',
        \ v.meta.parent == '_' ? '' : '-type ' . v.meta.parent,
        \ get(v, 'command') ? '-command ' . string(v.command) : '',
        \ join(s:fmap(get(v, 'exec', []), '"-exec " . string(v:val)'), ' '),
        \ string(get(v, 'cmdopt', '')))
endfor
lockvar s:quicklearn

function! unite#sources#quicklearn#define()
  return s:source
endfunction

function! s:source.gather_candidates(args, context)
  let configs = filter(copy(s:quicklearn), 'v:key =~ "^" . &amp;filetype . "/"')

  return values(map(configs, '{
        \ "word": substitute(v:key, "/intermediate$", "", ""),
        \ "source": s:source.name,
        \ "kind": ["command"],
        \ "action__command": v:val.quickrun_command,
        \ }'))
        "\ "action__type": ": ",
endfunction

let &amp;cpo = s:save_cpo
</code></pre>
				
				<p>適当な辞書を事前に作っておき、uniteから実際に実行させたいコマンド文字列を事前に生成しておきます。それを対応するfiletypeごとにs:source.gather_candidatesで適切な辞書の配列を返すことによって行なっています。uniteのkindはcommandです。</p>
				
				<p>冒頭のローカル関数fmapはfunctorっぽいものの実現です。対象が複数でも単数でも気にせず使えます。JavaScriptに詳しい方には、jQueryのアレ、といえば通じるかもしれません。</p>
				
				<h2>以上</h2>
				
				<p>Vim Advent Calendar 2011の32本目の記事でした。今年もよろしくお願いいたします。</p>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2012/01/happy-new-year-vim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ujihisa.vim#2が本日開催されます</title>
		<link>http://vim-users.jp/2011/11/ujihisa-vim-2-today/</link>
		<comments>http://vim-users.jp/2011/11/ujihisa-vim-2-today/#comments</comments>
		<pubDate>Sat, 19 Nov 2011 01:41:18 +0000</pubDate>
		<dc:creator>ujihisa</dc:creator>
				<category><![CDATA[その他]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=2698</guid>
		<description><![CDATA[http://vim-jp.org/ujihisa.vim-2/ 楽しみですね!]]></description>
			<content:encoded><![CDATA[				<p><a href="http://vim-jp.org/ujihisa.vim-2/">http://vim-jp.org/ujihisa.vim-2/</a></p>
				
				<p>楽しみですね!</p>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2011/11/ujihisa-vim-2-today/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vimテクニックバイブルが発売されました</title>
		<link>http://vim-users.jp/2011/09/vim-technique-bible-sold-a-lo/</link>
		<comments>http://vim-users.jp/2011/09/vim-technique-bible-sold-a-lo/#comments</comments>
		<pubDate>Fri, 23 Sep 2011 17:50:00 +0000</pubDate>
		<dc:creator>ujihisa</dc:creator>
				<category><![CDATA[その他]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=2634</guid>
		<description><![CDATA[数多くの人が購入し、すでに完読した方も多くいらっしゃることと思います。 感想をブログに書いた方は、その情報を共有するため、ぜひともこのエントリにトラックバックを送るなり、コメントでURLを貼付けるなどとしたいただけると、 [...]]]></description>
			<content:encoded><![CDATA[				<p><img src="http://www.jmorganmarketing.com/wp-content/uploads/2008/06/long-line.jpg" alt="longline" /></p>
				
				<p>数多くの人が購入し、すでに完読した方も多くいらっしゃることと思います。</p>
				
				<p>感想をブログに書いた方は、その情報を共有するため、ぜひともこのエントリにトラックバックを送るなり、コメントでURLを貼付けるなどとしたいただけると、大変便利です。</p>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2011/09/vim-technique-bible-sold-a-lo/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>非Vim使いが生産性を3倍高めるたった一つの方法</title>
		<link>http://vim-users.jp/2011/07/%e9%9d%9evim%e4%bd%bf%e3%81%84%e3%81%8c%e7%94%9f%e7%94%a3%e6%80%a7%e3%82%923%e5%80%8d%e9%ab%98%e3%82%81%e3%82%8b%e3%81%9f%e3%81%a3%e3%81%9f%e4%b8%80%e3%81%a4%e3%81%ae%e6%96%b9%e6%b3%95/</link>
		<comments>http://vim-users.jp/2011/07/%e9%9d%9evim%e4%bd%bf%e3%81%84%e3%81%8c%e7%94%9f%e7%94%a3%e6%80%a7%e3%82%923%e5%80%8d%e9%ab%98%e3%82%81%e3%82%8b%e3%81%9f%e3%81%a3%e3%81%9f%e4%b8%80%e3%81%a4%e3%81%ae%e6%96%b9%e6%b3%95/#comments</comments>
		<pubDate>Tue, 12 Jul 2011 04:45:08 +0000</pubDate>
		<dc:creator>ujihisa</dc:creator>
				<category><![CDATA[その他]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=2475</guid>
		<description><![CDATA[Vimを使う。]]></description>
			<content:encoded><![CDATA[				<p>Vimを使う。</p>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2011/07/%e9%9d%9evim%e4%bd%bf%e3%81%84%e3%81%8c%e7%94%9f%e7%94%a3%e6%80%a7%e3%82%923%e5%80%8d%e9%ab%98%e3%82%81%e3%82%8b%e3%81%9f%e3%81%a3%e3%81%9f%e4%b8%80%e3%81%a4%e3%81%ae%e6%96%b9%e6%b3%95/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>quickrunでquine</title>
		<link>http://vim-users.jp/2010/09/quickquine/</link>
		<comments>http://vim-users.jp/2010/09/quickquine/#comments</comments>
		<pubDate>Tue, 28 Sep 2010 19:39:15 +0000</pubDate>
		<dc:creator>ujihisa</dc:creator>
				<category><![CDATA[その他]]></category>
		<category><![CDATA[子ネタ]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=1940</guid>
		<description><![CDATA[一行目に #!cat と書きます。二行目以降は何を書いてもかまいません。 これで、quickrunを実行しますと、編集中ファイル自体が出力されます。かなり便利です。 文責: ujihisa]]></description>
			<content:encoded><![CDATA[				<p>一行目に</p>
				
				<pre><code>#!cat
</code></pre>
				
				<p>と書きます。二行目以降は何を書いてもかまいません。</p>
				
				<p>これで、quickrunを実行しますと、編集中ファイル自体が出力されます。かなり便利です。</p>
				
				<p>文責: ujihisa</p>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2010/09/quickquine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hack #167: Vimスクリプトで無名関数やクロージャを使う方法</title>
		<link>http://vim-users.jp/2010/08/hack167/</link>
		<comments>http://vim-users.jp/2010/08/hack167/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 15:00:17 +0000</pubDate>
		<dc:creator>hatena.ne.jp/tyru/</dc:creator>
				<category><![CDATA[Vim Hacks]]></category>
		<category><![CDATA[Vim script]]></category>
		<category><![CDATA[その他]]></category>
		<category><![CDATA[lv3]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=1793</guid>
		<description><![CDATA[無名関数 function! s:foo() let foo = {} function foo.funcall() dict echo 'lambda' endfunction return foo endfuncti [...]]]></description>
			<content:encoded><![CDATA[				<h2>無名関数</h2>
				
				<pre><code>function! s:foo()
    let foo = {}
    function foo.funcall() dict
        echo 'lambda'
    endfunction
    return foo
endfunction

call s:foo().funcall()
</code></pre>
				
				<h2>クロージャ</h2>
				
				<pre><code>function! s:foo(num)
    let foo = {'i': a:num}
    function foo.funcall() dict
        let self.i += 1
        return self.i
    endfunction
    return foo
endfunction

echo s:foo(1).funcall()
let s:clos = s:foo(5)
" 6
echo s:clos.funcall()
" 7
echo s:clos.funcall()
" 8
echo s:clos.funcall()
</code></pre>
				
				<h2>説明</h2>
				
				<p>Vimスクリプトでは辞書型に関数をキーとして代入することができます。<br />
				その場合関数はほぼ無名のような存在になります。<br />
				また辞書型に格納した「dict」つきの関数からはその辞書を「self」という変数で参照できるので<br />
				辞書に関数内で使う変数などを辞書に保存しておけば関数内からその変数を参照できる、いわば疑似的なクロージャを実現することができます。</p>
				
				<ol>
				<li>自分で変数を渡す必要がある</li>
				<li>obj.funcall() を自分で呼ぶ必要がある</li>
				</ol>
				
				<p>などなど他言語と比べかなりプリミティブですが、これを駆使すればVimスクリプトでも現実的に無名関数やクロージャが扱えることがわかるでしょう。</p>
				
				<p>またVimスクリプトでは辞書型を使ったプロトタイプ指向によりクラスなども扱うことができます。<br />
				そこまでしなくても辞書型を活用することでモジュールを分けられるのでいろんな活用方法があります。</p>
				
				<address class="hack-author">tyru</address>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2010/08/hack167/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hack #163: VimをVimスクリプトインタプリタとして使う</title>
		<link>http://vim-users.jp/2010/07/hack163/</link>
		<comments>http://vim-users.jp/2010/07/hack163/#comments</comments>
		<pubDate>Fri, 23 Jul 2010 15:00:21 +0000</pubDate>
		<dc:creator>hatena.ne.jp/tyru/</dc:creator>
				<category><![CDATA[Vim Hacks]]></category>
		<category><![CDATA[Vim script]]></category>
		<category><![CDATA[その他]]></category>
		<category><![CDATA[iex]]></category>
		<category><![CDATA[lv2]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=1772</guid>
		<description><![CDATA[viの前身であるedは、シェルスクリプトなどで文字列置き換えのために使うことができます。 (fileというファイルの中身を全行逆転させる例です) ed - file &#60;&#60;EOS g/^/m0 write qa [...]]]></description>
			<content:encoded><![CDATA[				<p>viの前身であるedは、シェルスクリプトなどで文字列置き換えのために使うことができます。
				(fileというファイルの中身を全行逆転させる例です)</p>
				
				<pre><code>ed - file &lt;&lt;EOS
g/^/m0
write
qall!
EOS
</code></pre>
				
				<p><code>g/^/m0</code>は<code>^</code>にマッチする行に対して<code>:m0</code>という操作を適用するコマンドです。
				<code>:m0</code>は分かりやすく書くと<code>:move 0</code>で、引数の行の下に現在の行を持っていくという動作をします。
				<code>^</code>はどの行にもマッチするので、<code>:m0</code>で全部の行に対して上からマッチした順に1行目に持っていきます。
				操作が終わると全行が逆になっているというわけです。</p>
				
				<p>また<code>:write</code>と<code>:qall!</code>は全行逆になったバッファを<code>file</code>に書き込むために必要です。</p>
				
				<p>VimについてくるexというコマンドはedのVim版とも言えるものですのでもちろん上のようなことができます。
				しかしデフォルトでは.vimrcやプラグインなども読み込んでしまうため、
				「素のex」として使いたい場合は「-u NORC &#8211;noplugin」を指定する必要があります。
				さらにVimmerとしてはVimの機能が使えず戸惑わないように「-N」も指定する必要があります。
				よってexをVimスクリプトインタプリタとして使うには以下のように起動すればできそうです。</p>
				
				<pre><code>ex -N -u NORC --noplugin
</code></pre>
				
				<p>冒頭の例のex版はこのようになります。</p>
				
				<pre><code>ex -N -u NORC --noplugin file &lt;&lt;EOS
g/^/m0
write
qall!
EOS
</code></pre>
				
				<p>デフォルトでもこのようにVimスクリプトインタプリタのように使えなくはないのですが、以下のような難点があります。</p>
				
				<ol>
				<li>ファイルに対して実行するには末尾に必ず<code>:write</code>と<code>:qall!</code>をつけなければならず面倒</li>
				<li>ファイルに対して実行する際に元のデータを壊してしまう</li>
				<li>いくつかの定型的なオプションを付けるのが面倒</li>
				<li>標準入力からスクリプトを読み込むのでファイルを標準入力から読み込めない</li>
				</ol>
				
				<h2>解決</h2>
				
				<p><a href="http://github.com/tyru/iex">iex</a>を使います。
				これはVimスクリプトをPerl、Ruby、Pythonなどの多くのLLのインタプリタと同じ感覚でVimスクリプトを実行させることができる優れ物です。</p>
				
				<pre><code>$ echo 'g/^/m0' &gt;reverse.vim
$ cat ~/.vimrc | iex reverse.vim -

# -eオプションで指定することも可能
$ cat ~/.vimrc | iex -e 'g/^/m0' -

$ iex    # /bin/exが開く
</code></pre>
				
				<p>詳しくは<code>iex -h</code>を見てください。</p>
				
				<h2>いくつかのVimスクリプト</h2>
				
				<p>おまけとしていくつかのUNIXコマンドをVimスクリプトで実装します。</p>
				
				<h3>tac</h3>
				
				<pre><code>$ cat tac.vim
g/^/m0
$ iex tac.vim file
</code></pre>
				
				<h3>sort</h3>
				
				<pre><code>$ cat sort.vim
sort
$ iex sort.vim file
</code></pre>
				
				<h3>sort -u (sort | uniq)</h3>
				
				<pre><code>$ cat uniq.vim
sort u
$ iex uniq.vim file
</code></pre>
				
				<h3>grep</h3>
				
				<pre><code>$ cat grep.vim
edit `=ARGS[1]`
execute 'v/' . ARGS[2] . '/d'
$ iex -s grep.vim ~/.vimrc vim

("vim"のみを含んだ行が表示される)
</code></pre>
				
				<p>また<code>-e</code>オプションを使ったやり方を示すと</p>
				
				<pre><code>$ iex -s -e 'edit `=ARGS[1]' -e 'execute "v/" . ARGS[2] . "/d"' ~/.vimrc vim
</code></pre>
				
				<p>のようになります。<br />
				これは一般のLLインタプリタと同じようにワンライナーのようなものを書くのに適しています。</p>
				
				<p>また<code>-s</code>を与えることで引数の扱いを変えています。<br />
				<code>-s</code>を与えると中身を読み込まずに<code>g:ARGS</code>というListに代入するだけにします。<br />
				その他細かい違いなどは<code>iex -h</code>を見てください。</p>
				
				<address class="hack-author">tyru</address>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2010/07/hack163/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vim 7.3の新機能まとめ</title>
		<link>http://vim-users.jp/2010/07/version-73/</link>
		<comments>http://vim-users.jp/2010/07/version-73/#comments</comments>
		<pubDate>Fri, 23 Jul 2010 08:02:43 +0000</pubDate>
		<dc:creator>hatena.ne.jp/tyru/</dc:creator>
				<category><![CDATA[その他]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=1802</guid>
		<description><![CDATA[とりあえず自分も今調べている最中なので:help version7.3をそのまま紹介する形にします。 他にもこれは紹介するべきというものや間違い等があったらどんどん追加/修正お願いします。 >Vim Hacksのメンバー [...]]]></description>
			<content:encoded><![CDATA[				<p>とりあえず自分も今調べている最中なので<code>:help version7.3</code>をそのまま紹介する形にします。<br />
				他にもこれは紹介するべきというものや間違い等があったらどんどん追加/修正お願いします。 >Vim Hacksのメンバー</p>
				
				<h2>Persistent undo</h2>
				
				<p><a href="http://vim-users.jp/2010/07/hack162/">Hack #162: Vimを終了しても undo 履歴を復元する</a>ですでに紹介されていますが、Vimを終了してもundo履歴が復元できる機能です。</p>
				
				<h2>ファイル暗号化方式の追加</h2>
				
				<p>ファイルを暗号化して保存する際、従来はPkZip方式での暗号化が行われていましたが、<br />
				新たにBlowfish方式での暗号化も選べるようになりました(:help &#8216;cryptmethod&#8217;)。</p>
				
				<h2>conceal</h2>
				
				<p>シンタックスハイライトで特定のハイライトグループを見た目「消す」ことができます。<br />
				すでに最新版のVimをインストールすると、<code>syntax/help.vim</code>がこの機能を使っていて単語を囲んでいる<code>*</code>や<code>|</code>などの文字が消えています。</p>
				
				<p>シンタックスハイライトで文字を隠すことができるようになったわけで、いろいろと応用できそうです。<br />
				プラグイン開発者にとって見逃せない新機能となっています。</p>
				
				<p>例としてすでにsyntax/markdown.vimでこの機能を使い</p>
				
				<pre><code>[リンク](URL)
</code></pre>
				
				<p>というmarkdownの記法を</p>
				
				<pre><code>リンク
</code></pre>
				
				<p>に見た目を変えてしまうパッチが<a href="http://groups.google.com/group/vim_dev/browse_thread/thread/eb05308417b17a5b/">メーリングリストに投げられました</a>。</p>
				
				<p>またオプションとして<code>conceallevel</code>が加えられています。</p>
				
				<h2>Luaインターフェース</h2>
				
				<p>LuaでVimプラグインが書けるようになりました。<br />
				詳しくは<code>:help lua</code>を。</p>
				
				<h2>Python3インターフェース</h2>
				
				<p>Pythonインターフェースに加えPython3インターフェースが加えられたようです。<br />
				両者はコマンドが分かれていて、それぞれ<code>:python</code>, <code>:python3</code>となっています。</p>
				
				<h2>&#8216;encoding&#8217;をmodelineで変更することの禁止</h2>
				
				<p>modelineでencodingを変更することができなくなりました。</p>
				
				<h2>&#8216;relativenumber&#8217;オプション</h2>
				
				<p>これはオンにしてみれば分かりやすいと思いますが、相対的な行番号を表示します。<br />
				つまり現在行の横に「0」と表示されて、一行上と一行下は「1」、二行上と二行下は「2」と表示されるようになります。<br />
				このオプションがセットされたとき&#8217;number&#8217;の値はリセットされます。<br />
				この機能は、jkに数値を付けて移動する場合(13jなど)のために追加されました。</p>
				
				<p>詳しくは<code>:help 'relativenumber'</code>を。</p>
				
				<h2>いくつかの関数追加</h2>
				
				<pre><code>More floating point functions: |acos()|, |asin()|, |atan2()|, |cosh()|,
|exp()|, |fmod()|, |log()|, |sinh()|, |tan()|, |tanh()|.  (Bill McCarthy)

Added the |gettabvar()| and |settabvar()| functions. (Yegappan Lakshmanan)

Added the |strchars()|, |strwidth()| and |strdisplaywidth()| functions.
</code></pre>
				
				<p>詳しくは<code>:help added-7.3</code>を。</p>
				
				<h2>新機能の解説</h2>
				
				<p>また以下のサイトで</p>
				
				<ol>
				<li>&#8216;cursorbind&#8217;</li>
				<li>conceal</li>
				<li>:ownsyntax</li>
				</ol>
				
				<p>の3つの新機能の解説があります。
				英語ですがスクリーンショットなどもありなかなか分かりやすいです。</p>
				
				<p><a href="http://sites.google.com/site/vincenegri/concealownsyntaxforvim">http://sites.google.com/site/vincenegri/concealownsyntaxforvim</a></p>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2010/07/version-73/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hack #159: オプションの値を気にせずsplit, vsplitする</title>
		<link>http://vim-users.jp/2010/07/hack159/</link>
		<comments>http://vim-users.jp/2010/07/hack159/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 15:00:16 +0000</pubDate>
		<dc:creator>hatena.ne.jp/tyru/</dc:creator>
				<category><![CDATA[Vim Hacks]]></category>
		<category><![CDATA[その他]]></category>
		<category><![CDATA[lv1]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=1731</guid>
		<description><![CDATA[Vimの標準のコマンドである:splitや:vsplit、 またはそのマッピング版である&#60;C-w&#62;sと&#60;C-w&#62;vは それぞれ&#38;splitbelowと&#38;splitrightに依存し [...]]]></description>
			<content:encoded><![CDATA[				<p>Vimの標準のコマンドである<code>:split</code>や<code>:vsplit</code>、
				またはそのマッピング版である<code>&lt;C-w&gt;s</code>と<code>&lt;C-w&gt;v</code>は
				それぞれ<code>&amp;splitbelow</code>と<code>&amp;splitright</code>に依存しており、
				自分の思った通りの方向にウインドウを開いてくれない場合があります。</p>
				
				<p>そこで、このようなマッピングを定義します。</p>
				
				<pre><code>nmap spj &lt;SID&gt;(split-to-j)
nmap spk &lt;SID&gt;(split-to-k)
nmap sph &lt;SID&gt;(split-to-h)
nmap spl &lt;SID&gt;(split-to-l)

nnoremap &lt;SID&gt;(split-to-j) :&lt;C-u&gt;execute 'belowright' (v:count == 0 ? '' : v:count) 'split'&lt;CR&gt;
nnoremap &lt;SID&gt;(split-to-k) :&lt;C-u&gt;execute 'aboveleft'  (v:count == 0 ? '' : v:count) 'split'&lt;CR&gt;
nnoremap &lt;SID&gt;(split-to-h) :&lt;C-u&gt;execute 'topleft'    (v:count == 0 ? '' : v:count) 'vsplit'&lt;CR&gt;
nnoremap &lt;SID&gt;(split-to-l) :&lt;C-u&gt;execute 'botright'   (v:count == 0 ? '' : v:count) 'vsplit'&lt;CR&gt;
</code></pre>
				
				<p>こうすることでいつでも自分の思った通りの方向にウインドウを開くことができます。</p>
				
				<p>また</p>
				
				<pre><code>nmap spj &lt;SID&gt;(split-to-j)
nmap spk &lt;SID&gt;(split-to-k)
nmap sph &lt;SID&gt;(split-to-h)
nmap spl &lt;SID&gt;(split-to-l)
</code></pre>
				
				<p>の部分は自分の好きなように変えてください。
				筆者は上のようにそれぞれ<code>spj</code>, <code>spk</code>, <code>sph</code>, <code>spl</code>に割り当てています。</p>
				
				<p>追記:
				kana氏の指摘によりコードを大幅修正しました。</p>
				
				<p>追記2:
				[count]を取れるようにしました。30sphなどとすると30の幅を持つウインドウが左に開きます。
				ちなみに現在筆者はマッピングを<code>&lt;Space&gt;sj</code>, <code>&lt;Space&gt;sk</code>, <code>&lt;Space&gt;sh</code>, <code>&lt;Space&gt;sl</code>に変更しました。
				押しやすいマッピングはVimmerの数だけあるので、各人押しやすいマッピングを常に追求しましょう。
				ちょっとでも押しにくいと感じたら積極的に他のマッピングを検討すべきです。</p>
				
				<address class="hack-author">tyru</address>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2010/07/hack159/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vim Quiz 1</title>
		<link>http://vim-users.jp/2010/06/quiz1/</link>
		<comments>http://vim-users.jp/2010/06/quiz1/#comments</comments>
		<pubDate>Sat, 26 Jun 2010 21:54:47 +0000</pubDate>
		<dc:creator>ujihisa</dc:creator>
				<category><![CDATA[その他]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=1725</guid>
		<description><![CDATA[以下のようにウインドウが分割されています。 これを以下のように配置しなおすにはどうすればよいでしょうか。 文責: ujihisa]]></description>
			<content:encoded><![CDATA[				<p>以下のようにウインドウが分割されています。</p>
				
				<p><img src="http://gyazo.com/1b3ca7c6784ae815a6c598cc86f093d3.png" alt="1" /></p>
				
				<p>これを以下のように配置しなおすにはどうすればよいでしょうか。</p>
				
				<p><img src="http://gyazo.com/f88fad07e97d41076e79be7ff70d383d.png" alt="2" /></p>
				
				<p>文責: <a href="http://ujihisa.blogspot.com">ujihisa</a></p>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2010/06/quiz1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

