<?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</title>
	<atom:link href="http://vim-users.jp/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/02/english/</link>
		<comments>http://vim-users.jp/2012/02/english/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 10:50:37 +0000</pubDate>
		<dc:creator>ujihisa</dc:creator>
				<category><![CDATA[告知]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=2717</guid>
		<description><![CDATA[プログラマにとって必要な素養は1に英語力と言われて久しいものです (*1)。 その英語力を簡単に、それもあっけないくらいに、大幅に向上する学習法があります。 この学習法を採用したプログラマの方は、現在は英語圏の会社で、英 [...]]]></description>
			<content:encoded><![CDATA[				<p>プログラマにとって必要な素養は1に英語力と言われて久しいものです (*1)。</p>
				
				<p>その英語力を簡単に、それもあっけないくらいに、大幅に向上する学習法があります。</p>
				
				<p>この学習法を採用したプログラマの方は、現在は英語圏の会社で、英語に何不自由することなくバリバリと働いているとのことです。</p>
				
				<p>一般に英語学習は費用がかさむことで有名です。しかし、この学習法を用いれば、費用はいっさいかかりません。</p>
				
				<div class="figure">
				<img src="http://rst.gsfc.nasa.gov/Sect16/full-20earth2.jpg" alt="earth" />
				</div>
				
				<h2 id="&#26041;&#27861;">方法</h2>
				
				<p><a href="https://github.com/shougo/vimshell">vimshell</a>のドキュメントの翻訳プロジェクトに参加します。</p>
				
				<p>vimshellのドキュメントは以下の2つのファイルから構成されています。</p>
				
				<ul>
				<li>doc/vimshell.jax</li>
				<li>doc/vimshell.txt</li>
				</ul>
				
				<p>前者は日本語の、後者は英語の同一の内容のファイルです。いや、同一の内容であることを目指してある状態です。実際には英語版、vimshell.txtは大量の&quot;TODO&quot;とだけ書かれたセンテンスでいっぱいです。</p>
				
				<p>この翻訳作業をおこなっていただく方を大募集しています。現時点でのVim力は不問、明るく楽しい職場 (* 2)です。 英語力だけでなくVim力も向上でき、一石二鳥です。学生の方は、この活動のおかげで就職もできるかもしれません。</p>
				
				<p>参加するには、いきなり翻訳し、github上でpull requestを送ります。他の人と同じ部分を翻訳してしまうとその作業が若干もったいないため、なるべく細かい単位でさくっと翻訳してさくっとpull requestを送るのがよいでしょう。</p>
				
				<p>翻訳にあたって元の文書の意味がよくわからないときなど、質問があれば、 <a href="http://lingr.com/room/vim">lingr</a>で聞いてみたり、やtwitter上で #vimshell ハッシュタグをつけて発言してみましょう。</p>
				
				<div class="figure">
				<img src="http://images.paraorkut.com/img/pics/images/a/airplane-13372.jpg" alt="airplane" />
				</div>
				
				<p>世界をまたにかけたVim使いへの第一歩です。</p>
				
				<ul>
				<li>*1 実際に必要な素養はVim力です</li>
				<li>*2 http://lingr.com/room/vim</li>
				</ul>
				
				<address class="hack-author">
				ujihisa
				</address>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2012/02/english/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>Hack #241: Haskellで使いたい関数を使ってからそのモジュールをimportする</title>
		<link>http://vim-users.jp/2011/12/hack241/</link>
		<comments>http://vim-users.jp/2011/12/hack241/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 15:00:05 +0000</pubDate>
		<dc:creator>ujihisa</dc:creator>
				<category><![CDATA[Vim Hacks]]></category>
		<category><![CDATA[lv2]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=2708</guid>
		<description><![CDATA[Haskell Advent Calendar 2011への寄稿記事です。 問題 Haskellを書いていて、長いソースコードの末尾の方にて、急にとあるモジュールのとある関数を使いたい、そんなときはよくあります。ありがち [...]]]></description>
			<content:encoded><![CDATA[				<p><a href="http://partake.in/events/eaea52c2-61ef-46d5-a855-3a2dde459e3a">Haskell Advent Calendar 2011</a>への寄稿記事です。</p>
				
				<h2>問題</h2>
				
				<p>Haskellを書いていて、長いソースコードの末尾の方にて、急にとあるモジュールのとある関数を使いたい、そんなときはよくあります。ありがちなのがApplicativeの演算子いくつかと、Data.Function.onと、Data.Listのアレとコレと・・・。いくらでもあります。</p>
				
				<p>Haskellでは一般的に、モジュールのimportはソースコードのかなりはじめの方にまとめて記述します。importしたい関数を一度しか使わず、しかもソースコードの末尾の方に位置していようと、おかまい無しです。このとき、<kbd>gg</kbd>などでソースコード上部まで移動し、<a href="http://vim-users.jp/2011/04/hack211/">neco-ghc</a>などを駆使してmoduleとその関数を的確にimportし、そして<kbd>&lt;C-o&gt;</kbd>などでもといた場所に戻ることになると思います。<code>:sp</code>などで画面分割してから行ったり、あるいはmarkをつけるという方法もありますが、いずれにせよこれらの作業のため脳内の作業メモリがスタックオーバーフローするのは明らかでしょう。</p>
				
				<h2>解決</h2>
				
				<p>unite-haskellimportを用います。</p>
				
				<p><a href="https://github.com/ujihisa/unite-haskellimport">https://github.com/ujihisa/unite-haskellimport</a></p>
				
				<p>まずは上記プラギンをインストールします。依存プラギンはunite.vim、依存ツールは<code>hoogle</code>です。</p>
				
				<pre><code>$ cabal update &amp;&amp; cabal install hoogle &amp;&amp; hoogle data
</code></pre>
				
				<p>たとえば急に<code>==&gt;</code>という関数を使いたくなったとしましょう。</p>
				
				<pre><code>:Unite haskellimport
</code></pre>
				
				<p>としてunite窓を開き、<code>==&gt;</code>と打鍵しましょう。</p>
				
				<pre><code>Test.QuickCheck.Property (==&gt;) :: Testable prop =&gt; Bool -&gt; prop -&gt; Property
Test.QuickCheck (==&gt;) :: Testable prop =&gt; Bool -&gt; prop -&gt; Property
</code></pre>
				
				<p>インストールしているcabalパッケージにもよりますが、たとえば上記のような項目が選択肢にでてくることでしょう。実際にimportしたい側を選択します。</p>
				
				<p>候補を選択すると、unite-haskellimportはdefaultのactionとして:Haskellimportコマンドを発行します。これは、対象を、ソースコードのそれらしい場所に挿入するものです。既に他のimport文がある場合は、最後のimportのあとに挿入します。</p>
				
				<p>Before</p>
				
				<pre><code>import qualified Data.Text as T

f x = ...
</code></pre>
				
				<p>After</p>
				
				<pre><code>import qualified Data.Text as T
import Test.QuickCheck ((==&gt;))

f x = ...
</code></pre>
				
				<p>今回importしたのは記号からなる関数でした。が、もしも記号ではない関数、つまりVimの<code>&lt;cword&gt;</code>になるようなものならば、<code>:Unite</code>のかわりに</p>
				
				<pre><code>:UniteWithCursorWord haskellimport
</code></pre>
				
				<p>とするとよいでしょう。これを頻繁に行うようならば、適切なキーにマッピングしておくべきです。たとえば以下を <code>~/.vim/ftplugin/haskell.vim</code>に記述すると、<kbd>&lt;space&gt;I</kbd>と打鍵するだけでカーソル以下にある単語の関数をimportしてくれます。</p>
				
				<pre><code>nnoremap &lt;buffer&gt; &lt;space&gt;I :&lt;C-u&gt;UniteWithCursorWord haskellimport&lt;Cr&gt;
</code></pre>
				
				<address class="hack-author">ujihisa</address>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2011/12/hack241/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hack #240: &lt;C-[&gt; での誤爆を防止する</title>
		<link>http://vim-users.jp/2011/12/hack240/</link>
		<comments>http://vim-users.jp/2011/12/hack240/#comments</comments>
		<pubDate>Sun, 11 Dec 2011 15:00:06 +0000</pubDate>
		<dc:creator>thinca</dc:creator>
				<category><![CDATA[Vim Hacks]]></category>
		<category><![CDATA[lv2]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=2703</guid>
		<description><![CDATA[挿入モードから抜ける方法は多数ありますが、その中に &#60;C-[&#62; キーがあります。 しかしこの [ キーは、日本語キーボードではすぐ左に @ キーがあり、誤って &#60;C-@&#62; を押してしまうと直前に挿 [...]]]></description>
			<content:encoded><![CDATA[				<p>挿入モードから抜ける方法は多数ありますが、その中に &lt;C-[&gt; キーがあります。</p>
				
				<p>しかしこの [ キーは、日本語キーボードではすぐ左に @ キーがあり、誤って &lt;C-@&gt; を押してしまうと直前に挿入したテキストがさらに挿入されてから挿入モードを抜けるため、誤爆すると大惨事となります。</p>
				
				<h3>誤爆を防止する</h3>
				
				<p>誤爆をすると言うことは、本来行いたい操作があるということです。
				このような誤爆を簡単かつ確実に防止するには、対象の機能を本来押したいキーに置き換えてしまうのが効果的です。</p>
				
				<p>考えてみましょう。この &lt;C-@&gt; の機能「直前に挿入されたテキストをもう一度挿入し、挿入を終了する。」は、あなたにとって必要でしょうか?
				もし必要ないと判断したら、本来押したいキー、この場合は &lt;C-[&gt; に置き換えましょう。以下のようにします。</p>
				
				<pre><code>imap &lt;C-@&gt; &lt;C-[&gt;
</code></pre>
				
				<p>こうすることで誤爆を防ぐことができます。この @ は [ よりも近いため押し易く、しかもこの位置は英字キーボードと同じ位置であるため、英字キーボードに乗り換える練習にもなります。</p>
				
				<p>もし万が一 &lt;C-@&gt; の機能が使いたい場合、しかし誤爆は避けたい場合は、別の位置に &lt;C-@&gt; をマッピングするとよいでしょう。</p>
				
				<address class="hack-author">thinca</address>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2011/12/hack240/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>Hack #239: グローバル変数を安全に参照する</title>
		<link>http://vim-users.jp/2011/10/hack239/</link>
		<comments>http://vim-users.jp/2011/10/hack239/#comments</comments>
		<pubDate>Sat, 29 Oct 2011 15:00:07 +0000</pubDate>
		<dc:creator>ujihisa</dc:creator>
				<category><![CDATA[Vim Hacks]]></category>
		<category><![CDATA[lv3]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=2678</guid>
		<description><![CDATA[こんにちは、ujihisaです。以前からこのvim-users.jp上で告知していた、東京でのVimのカンファレンスであるujihisa.vim#2が、ついに一般参加者の募集をはじめたようです。 ujihisa.vim# [...]]]></description>
			<content:encoded><![CDATA[				<p>こんにちは、ujihisaです。以前からこのvim-users.jp上で告知していた、東京でのVimのカンファレンスである<a href="http://vim-jp.org/ujihisa.vim-2/">ujihisa.vim#2</a>が、ついに一般参加者の募集をはじめたようです。</p>
				
				<ul>
				  <li>ujihisa.vim#2 <a href="http://vim-jp.org/ujihisa.vim-2/">http://vim-jp.org/ujihisa.vim-2/</a></li>
				</ul>
				
				<p>このページの末尾から参加申し込みページにアクセスできるようです。なお、HootSuiteをお使いの方は、以下のリンクから簡単にujihisa.vim#2の宣伝ができるようで、とても便利です。</p>
				
				<ul>
				  <li><a href="http://tinyurl.com/3kq5ede">http://tinyurl.com/3kq5ede</a></li>
				</ul>
				
				<p>さて、本題です。</p>
				
				<h2>問題</h2>
				
				<p>Vim scriptを読んでいると以下のようなコードを比較的頻繁に見かけるのではないでしょうか。</p>
				
				<pre><code>if !exists('g:aaa_bbb')
  let g:aaa_bbb = 'something default'
endif
</code></pre>
				
				<p>特定のグローバル変数が存在しないときのみデフォルトの値を入れるときのパターンです。これは一行で宣言的に書きたいですよね。かといって、これのためだけに別の関数を用意するのも、健康的でなさそうです。</p>
				
				<h2>解決</h2>
				
				<p>実はグローバル変数の一覧を<code>g:</code>で取得することができます。同様にバッファローカル変数一覧は<code>b:</code>、スクリプトローカル変数一覧は<code>s:</code>など。これは変数名がキーで変数の値が値の辞書となっています。</p>
				
				<pre><code>echo g:hello
</code></pre>
				
				<p>は、実は以下のように書くことができます。</p>
				
				<pre><code>echo (g:).hello
echo (g:)['hello']
</code></pre>
				
				<p>いずれもそのキーがなければ実行時エラーをだしてしまいます。しかし、<code>get()</code>関数を用いれば、デフォルト値を使いつつその値に参照することができます。</p>
				
				<pre><code>echo get(g:, 'hello', 'the default value')
</code></pre>
				
				<p>これは<code>g:hello</code>が定義されていればその値を表示、定義されていなければ<code>the default value</code>を表示します。</p>
				
				<p>したがって、元々の問題は、</p>
				
				<pre><code>if !exists('g:aaa_bbb')
  let g:aaa_bbb = 'something default'
endif
</code></pre>
				
				<p>以下のように一行で記述することができます。</p>
				
				<pre><code>let g:aaa_bbb = get(g:, 'aaa_bbb', 'something default')
</code></pre>
				
				<p>美しいですね。これがVim script使いの生きる道といえるのではないでしょうか。</p>
				
				<address class="hack-author">ujihisa</address>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2011/10/hack239/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hack #238: neobundle.vim で plugin をモダンに管理する</title>
		<link>http://vim-users.jp/2011/10/hack238/</link>
		<comments>http://vim-users.jp/2011/10/hack238/#comments</comments>
		<pubDate>Mon, 24 Oct 2011 15:00:59 +0000</pubDate>
		<dc:creator>Shougo</dc:creator>
				<category><![CDATA[Vim Hacks]]></category>
		<category><![CDATA[lv2]]></category>
		<category><![CDATA[neobundle.vim]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[unite]]></category>
		<category><![CDATA[Vundle]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=2671</guid>
		<description><![CDATA[こんにちは。Shougoです。Vimテクニックバイブルの執筆で長らくお休みを頂いていました。 執筆が終わってからも、プラグインの更新で忙しいのが難点です。 とはいえ、あまりに間隔が空いているのは執筆者としてまずいと感じた [...]]]></description>
			<content:encoded><![CDATA[				<p>こんにちは。Shougoです。Vimテクニックバイブルの執筆で長らくお休みを頂いていました。
				執筆が終わってからも、プラグインの更新で忙しいのが難点です。
				とはいえ、あまりに間隔が空いているのは執筆者としてまずいと感じたため、久しぶりに復帰します。</p>
				
				<p>みなさん、Vimプラグイン管理には何をお使いでしょうか。残念ながら、Vimのプラグイン管理には良い方法がなく、
				各々が「自分の考える最強のプラグイン管理プラグイン」を作ってきました。
				つまり、長らくプラグイン管理プラグインは戦国時代の様相を呈していたわけです。
				実装が存在しないVimJoltsもその一つです:-)。
				しかし最近、Vimのプラグイン管理はVundleに一元化されることが多くなってきました。
				<a href="http://vim-users.jp/2011/04/hack215/">「Hack #215: Vundleでプラグインをモダンに管理する」</a>やVimテクニックバイブルでも紹介されています。
				私も最初はpathogenを使っていましたが、アップデートが簡単なVundleに乗り換えた経緯があります。
				ただしVundleにもいくつか不満があったため、自分でforkしたVundleをしばらく使用していました。
				しかし、最終的にVundleの仕様変更に追随できなくなったため、forkしたVundleを元にneobundle.vimを開発することにしました。
				変更点をVundleにマージするには、変更点が多すぎたということもあります。
				今回はneobundle.vimについて紹介します。</p>
				
				<h2>neobundle.vimとVundleの違い</h2>
				
				<p>Vundleをベースにしたため、基本的な機能は同じです。
				Vundleを知っているなら、すぐに乗り換えることも可能でしょう。
				変更点は幾つかありますが、主なものは以下の通りです。</p>
				
				<h3>コマンド名が改善されている</h3>
				
				<p>VundleはBundleを意識して付けられたコマンド名になっているため、コマンド名とプラグイン名が対応していません。
				例えば、プラグインをインストールするコマンド名は<code>:VundleInstall</code>ではなく、<code>:BundleInstall</code>です。
				この辺りは、議論がされているようですが、まだ結論は出ていません。
				neobundle.vimはプラグイン名をプレフィクスとした、<code>:NeoBundleInstall</code>となっています。
				BundleをNeoBundleに改名するだけで、基本的に使用することができます。</p>
				
				<h3>vital化されている</h3>
				
				<p>ルーチンを他のプラグインと共通化するために、vital.vimを使用しています。
				プラグインの開発が楽になります。</p>
				
				<h3>shellslashがオンでも動作する</h3>
				
				<p><code>shellescape()</code>を使用していますが、shellslashオプションがオンの場合、クオートが&#8221;になってしまうという問題があります。
				つまりWindows環境で、cmd.exeをshellとして使用している場合、shellslashを有効にしていると動きません。
				neobundle.vimでは<code>shellescape()</code>を使用していません。</p>
				
				<h3>vimprocに対応している</h3>
				
				<p>vimprocが利用できる環境では、アップデートにvimprocを使用します。
				Windows環境では、DOS窓が出ないという利点につながります。</p>
				
				<h3>unite.vimインタフェースの実装</h3>
				
				<p>実は、これがneobundle.vimで一番やりたかった機能です。
				neobundle.vimはunite.vimのインタフェースを実装しているため、unite.vimからVimプラグインをアップデートすることができます。
				非同期でアップデートを行うため、使用にはvimprocが必要です。
				neobundle.vimはunite.vimやvimprocがない環境でも動作しなくてはならないため、従来のインタフェースも残っています。
				ただし、従来のインタフェースは緊急用のため重視していません。</p>
				
				<h3>Subversion, Mercurialへの対応</h3>
				
				<p>tsukkeeさんがVundleに追加していた機能をマージし、Subversion, Mercurialに試験的な対応をしました。
				まだ実験段階ですが、試していただければと思います。</p>
				
				<h3>リビジョン指定</h3>
				
				<p><code>:NeoBundle {repository} {revision}</code>という構文でリビジョン指定ができます。まだ実験段階の機能です。
				不具合のあるプラグインのバージョンを固定する時に便利だと思います。</p>
				
				<h2>neobundle.vimの導入</h2>
				
				<p>neobundle.vimの開発は、github上で行われています。<a href="https://github.com/Shougo/neobundle.vim">https://github.com/Shougo/neobundle.vim</a>
				導入する場合、~/.vimにリポジトリをcloneすると楽でしょう。</p>
				
				<pre><code>$ git clone https://github.com/Shougo/neobundle.vim ~/.vim/neobundle.vim.git
</code></pre>
				
				<h2>plugin の管理</h2>
				
				<p>plugin の管理は以下の様に .vimrc に <code>NeoBundle 'plugin name'</code> と記述することで行います。
				極端な話、<code>Bundle</code>を<code>NeoBundle</code>に変更するだけです。</p>
				
				<pre><code>set nocompatible
filetype off

if has('vim_starting')
  set runtimepath+='path to neobundle directory'

  call neobundle#rc(expand('~/.bundle'))
endif

NeoBundle 'git://github.com/Shougo/clang_complete.git'
NeoBundle 'git://github.com/Shougo/echodoc.git'
NeoBundle 'git://github.com/Shougo/neocomplcache.git'
NeoBundle 'git://github.com/Shougo/neobundle.vim.git'
NeoBundle 'git://github.com/Shougo/unite.vim.git'
NeoBundle 'git://github.com/Shougo/vim-vcs.git'
NeoBundle 'git://github.com/Shougo/vimfiler.git'
NeoBundle 'git://github.com/Shougo/vimshell.git'
NeoBundle 'git://github.com/Shougo/vinarise.git'

filetype plugin on
filetype indent on
</code></pre>
				
				<p>Vundleと同様、先にfiletypeをoffにしてから、neobundle.vimの設定を行います。
				最初、neobudle.vimの関数を呼べるよう、neobundle.vimのパスを<code>&amp;runtimepath</code>に追加します。
				そして<code>neobundle#rc(expand('~/.bundle'))</code>で初期化します。
				<code>neobudle#rc()</code>の引数はプラグインをインストールする基準となるパスです。
				<code>NeoBundle</code>コマンドで設定をしたあと、最後にfiletype pluginをオンにします。</p>
				
				<h2>NeoBundle コマンドの使い方</h2>
				
				<p>Vundleと全く同じです。基本的にBundleコマンドがNeoBundleコマンドに変わっただけです。</p>
				
				<h4>Github 上のリポジトリから取得する</h4>
				
				<pre><code>NeoBundle 'user_name/repository_name'
</code></pre>
				
				<h4>vim-scripts 上のリポジトリから取得する</h4>
				
				<pre><code>NeoBundle 'script_name'
</code></pre>
				
				<h4>それ以外のリポジトリから取得する</h4>
				
				<pre><code>NeoBundle 'git://repository_url'
NeoBundle 'http://svn.macports.org/repository/macports/contrib/mpvim/'
NeoBundle 'https://bitbucket.org/ns9tks/vim-fuzzyfinder'
</code></pre>
				
				<p>Gitリポジトリのフルパスを指定します。
				MercurialやSubversionにも試験的に対応しています。</p>
				
				<h2>pluginの管理</h2>
				
				<p>plugin のインストールには、<code>:NeoBundleInstall</code> コマンドを使用します。
				.vimrcで設定したplugin が自動的に取得され、インストールまで行われます。
				ただし、アップデートしたプラグインを使用するには、Vimを再起動したほうが良いです。</p>
				
				<pre><code>:NeoBundleInstall
</code></pre>
				
				<p>既にインストールされている plugin をアップデートするには、 <code>:NeoBundleInstall!</code> コマンドを利用します。
				通常の<code>NeoBundleInstall</code>では、アップデートが行われないからです。</p>
				
				<pre><code>:NeoBundleInstall!
</code></pre>
				
				<p>不要になったプラグインを削除するには、<code>:NeoBundle</code>の設定を.vimrcから削除した後、
				<code>:NeoBundleClean</code>コマンドを実行します。</p>
				
				<p>neobundle.vimはplugin検索には対応していません。</p>
				
				<p>neobudle.vimはneobundle/install sourceを使用することで、
				unite.vimインタフェースによりアップデートを行うことができます。
				アップデートは非同期に行われます。
				neobundle/install sourceの引数に!を与えると、<code>:NeoBundleInstall!</code>相当になります。
				プラグイン名を引数に与えることで、個別にアップデートをすることも可能です。</p>
				
				<pre><code>:Unite neobundle/install:!
:Unite neobundle/install:neocomplcache
:Unite neobundle/install:neocomplcache:unite.vim
</code></pre>
				
				<h2>ドキュメントの更新</h2>
				
				<p>プラグインのインストール時に、自動的に<code>:helptags</code>コマンドが実行されるため、
				ユーザーは何もする必要がありません。</p>
				
				<h2>参考</h2>
				
				<ul>
				<li>:help neobundle</li>
				</ul>
				
				<address class="hack-author">Shougo</address>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2011/10/hack238/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hack #237: 古い quickfix を参照する</title>
		<link>http://vim-users.jp/2011/10/hack237/</link>
		<comments>http://vim-users.jp/2011/10/hack237/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 15:00:44 +0000</pubDate>
		<dc:creator>thinca</dc:creator>
				<category><![CDATA[Vim Hacks]]></category>
		<category><![CDATA[lv2]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=2664</guid>
		<description><![CDATA[quickfix は :grep や :make の結果として使われたり、時にはプラグインが何かの結果を表示するのに使ったりと、様々な状況で使用されます。 それだけ便利なものですが、時には、以前の内容をまだ見たいのにうっ [...]]]></description>
			<content:encoded><![CDATA[				<p>quickfix は <code>:grep</code> や <code>:make</code> の結果として使われたり、時にはプラグインが何かの結果を表示するのに使ったりと、様々な状況で使用されます。</p>
				
				<p>それだけ便利なものですが、時には、以前の内容をまだ見たいのにうっかり新しい内容を quickfix へ出力してしまうことがあります。</p>
				
				<h3><code>:colder</code> <code>:cnewer</code> コマンド</h3>
				
				<p>実は、quickfix は過去のリストを10個まで保持しています。これは <code>:colder</code> <code>:cnewer</code> コマンドで切り替えられます。</p>
				
				<pre><code>:colder [count]
:cnewer [count]
</code></pre>
				
				<p><code>:colder</code> で <code>[count]</code> 個分古い quickfix へ移動します。<code>:cnewer</code> で <code>[count]</code> 個分新しい quickfix へ移動します。</p>
				
				<p>もし誤って quickfix を上書きしてしまった場合でも、慌てず騒がず <code>:colder</code> すれば安心です。</p>
				
				<address class="hack-author">thinca</address>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2011/10/hack237/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hack #236: 短期間でVim script力を向上する</title>
		<link>http://vim-users.jp/2011/10/hack236/</link>
		<comments>http://vim-users.jp/2011/10/hack236/#comments</comments>
		<pubDate>Fri, 14 Oct 2011 15:00:38 +0000</pubDate>
		<dc:creator>ujihisa</dc:creator>
				<category><![CDATA[Vim Hacks]]></category>
		<category><![CDATA[lv3]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=2661</guid>
		<description><![CDATA[こんにちは、ujihisaです。この記事はGentoo上で執筆しています。ちなみに来日することが決まりました。こんなカンファレンスや、勉強会を企画してみました。いずれも来月です。 問題 Vim scriptというプログラ [...]]]></description>
			<content:encoded><![CDATA[				<p>こんにちは、ujihisaです。この記事はGentoo上で執筆しています。ちなみに来日することが決まりました。<a href="http://atnd.org/events/20567">こんな</a>カンファレンスや、<a href="http://cotocoto.jp/event/46351">勉強会</a>を企画してみました。いずれも来月です。</p>
				
				<h2>問題</h2>
				
				<p>Vim scriptというプログラミング言語の能力を高める効率的な方法はあるのでしょうか?</p>
				
				<p><a href="http://www.amazon.co.jp/Vim%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF%E3%83%90%E3%82%A4%E3%83%96%E3%83%AB-%EF%BD%9E%E4%BD%9C%E6%A5%AD%E5%8A%B9%E7%8E%87%E3%82%92%E3%82%AB%E3%82%A4%E3%82%BC%E3%83%B3%E3%81%99%E3%82%8B150%E3%81%AE%E6%8A%80-Vim%E3%82%B5%E3%83%9D%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%BA/dp/4774147958">Vimテクニックバイブル</a>も既に完読してしまい、次にやるべきことを見失っている読者も多いかもしれません。</p>
				
				<h2>解決</h2>
				
				<p>Project Eulerというオンラインの問題集があります。オンラインで答え合わせもできます。</p>
				
				<ul>
				  <li><a href="http://projecteuler.net/">http://projecteuler.net/</a></li>
				</ul>
				
				<p>ぜひこれにVim scriptで挑戦してみましょう。以下に問1の回答例を示します。</p>
				
				<p>(もっと良い回答を思いついた、という方はぜひコメントやトラックバックで示してください。楽しみにしています!)</p>
				
				<h2>問1</h2>
				
				<p><a href="http://projecteuler.net/problem=1">http://projecteuler.net/problem=1</a></p>
				
				<blockquote>
				  <p>If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.</p>
				
				  <p>Find the sum of all the multiples of 3 or 5 below 1000.</p>
				</blockquote>
				
				<p>回答例1</p>
				
				<p><code>range()</code>で1から1000までの数値の配列を作り、それをもとに<code>for</code>で加算していきます。</p>
				
				<pre><code>function! s:p1()
  let memo = 0
  for i in range(1, 999)
    if i % 3 == 0 || i % 5 == 0
      let memo += i
    endif
  endfor
  return memo
endfunction

echo s:p1()
</code></pre>
				
				<p>これを<code>filetype=vim</code>なバッファで作成し、最後にquickrunしましょう。そこには答えがでているはずです。</p>
				
				<p>回答例1</p>
				
				<p><code>filter()</code>を使います。</p>
				
				<pre><code>function! s:p1()
  let memo = 0
  let list = filter(range(1, 999), 'v:val % 3 == 0 || v:val % 5 == 0')
  for i in list
    let memo += i
  endfor
  return memo
endfunction

echo s:p1()
</code></pre>
				
				<p>さっきよりも見通しのよいコードになったでしょう。lambdaがなくて文字列になってしまうのがちょっと困りものですが…。</p>
				
				<p>さて、この調子で<code>for</code>を消せると考えた人も多くいるかもしれません。そうです、つい5日前に読んだ<a href="http://vim-users.jp/2011/10/hack235/">Hack #235</a>を思い出しましょう。vitalを使います。</p>
				
				<pre><code>function! s:p1()
  let L = vital#of('vital').import('Data.List')
  let list = filter(range(1, 999), 'v:val % 3 == 0 || v:val % 5 == 0')
  return L.foldl1('v:memo + v:val', list)
endfunction

echo s:p1()
</code></pre>
				
				<p>もうここまできたら一行にしたくなるのが人情ですよね。</p>
				
				<pre><code>echo vital#of('vital').import('Data.List').foldl1('v:memo + v:val', filter(range(1, 999), 'v:val % 3 == 0 || v:val % 5 == 0'))
</code></pre>
				
				<p>ほかにも多くの解法があると思います。読みやすくかつ短いコードを高速で書くことができるよう、日々鍛錬あるのみです。</p>
				
				<address class="hack-author">ujihisa</address>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2011/10/hack236/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hack #235: リストの要素の総和や総乗を簡単に求める</title>
		<link>http://vim-users.jp/2011/10/hack235/</link>
		<comments>http://vim-users.jp/2011/10/hack235/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 15:00:56 +0000</pubDate>
		<dc:creator>ujihisa</dc:creator>
				<category><![CDATA[Vim Hacks]]></category>
		<category><![CDATA[lv2]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=2659</guid>
		<description><![CDATA[こんにちは、ujihisaです。無事引っ越しが完了しましたが、インターネット回線の確保にはもうしばらく時間がかかるらしく、しばらく家でオフラインな状態です。ちなみに来日することが決まりました。こんなカンファレンスや、勉強 [...]]]></description>
			<content:encoded><![CDATA[				<p>こんにちは、ujihisaです。無事引っ越しが完了しましたが、インターネット回線の確保にはもうしばらく時間がかかるらしく、しばらく家でオフラインな状態です。ちなみに来日することが決まりました。<a href="http://atnd.org/events/20567">こんな</a>カンファレンスや、<a href="http://cotocoto.jp/event/46351">勉強会</a>を企画してみました。いずれも来月です。ふるってプレゼンに応募ください。</p>
				
				<h2>問題</h2>
				
				<p>リスト<code>list</code>の和は、他の言語ならば以下のようにして求めることが一般的です。</p>
				
				<ul>
				  <li>Ruby
				    <ul>
				      <li><code>list.inject(:+)</code></li>
				      <li>これは <code>list.inject {|i, j| i + j }</code>の意。<code>Enumerable#inject</code>の特殊用法</li>
				      <li><code>list.inject(0, :+)</code></li>
				      <li>同じくこれは <code>list.inject(0) {|i, j| i + j }</code>の意。</li>
				    </ul>
				  </li>
				  <li>Haskell
				    <ul>
				      <li><code>foldl1 (+) list</code></li>
				      <li>これは<code>foldl1 (\i j -&gt; i + j) list</code>の意。言語仕様として演算子は括弧でくくるだけで2引数関数のような振る舞いになる(*1)。</li>
				      <li><code>sum list</code></li>
				    </ul>
				  </li>
				  <li>Python
				    <ul>
				      <li><code>reduce(lambda a, b: a + b, list)</code></li>
				      <li><code>sum(list)</code>
				と、<code>sum</code>といった直接的な方法がサポートされているかは別にして、なんらかの「リストと関数を受け取り、(リストに限らない)なんらかの値を返す」関数が提供されるのが一般的であることがわかります。</li>
				    </ul>
				  </li>
				</ul>
				
				<p>Vim scriptには残念ながらそういった関数が標準では提供されていないようです。どうすればよいでしょうか。</p>
				
				<h2>解決</h2>
				
				<p>vital.vimという、プラギン埋め込み型の汎用ライブラリを使います。</p>
				
				<ul>
				  <li><a href="https://github.com/ujihisa/vital.vim">https://github.com/ujihisa/vital.vim</a></li>
				  <li><a href="http://d.hatena.ne.jp/thinca/20110310/1299768323">http://d.hatena.ne.jp/thinca/20110310/1299768323</a></li>
				</ul>
				
				<p>前述の問題を解決するには、vitalのData.Listモジュールを用いるのがよいでしょう。Data.Listの上記要件を満たす関数は以下の4つで、意味はそれぞれHaskellのPreludeに定義されているものと同じです。</p>
				
				<ul>
				  <li>foldl</li>
				  <li>foldl1</li>
				  <li>foldr</li>
				  <li>foldr1</li>
				</ul>
				
				<p>たとえば<code>foldl1</code>を用いると、以下のようにしてリストlistの要素の値の総和を求めることができます。</p>
				
				<pre><code>let L = vital#of('プラギン名').import('Data.List')
echo L.foldl1('v:memo + v:val', list)
</code></pre>
				
				<p>非常に書きやすく読みやすく、理想的です。なお、実験的にvitalを用いる場合は、vitalを<code>&amp;rtp</code>に入れた上で<code>vital#of('vital')</code>とするとそのvitalを読み込むことができます。</p>
				
				<address class="hack-author">ujihisa</address>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2011/10/hack235/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

