<?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; Vim Hacks</title>
	<atom:link href="http://vim-users.jp/tag/vim-hacks/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>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>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>
		<item>
		<title>Hack #234: Vim外にいるときはVimを透けさせる</title>
		<link>http://vim-users.jp/2011/10/hack234/</link>
		<comments>http://vim-users.jp/2011/10/hack234/#comments</comments>
		<pubDate>Tue, 04 Oct 2011 15:00:49 +0000</pubDate>
		<dc:creator>ujihisa</dc:creator>
				<category><![CDATA[Vim Hacks]]></category>
		<category><![CDATA[lv1]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=2655</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>Vim使いの大半は、Vimをフルスクリーンで使っていることと思います。このとき、WindowのfocusがVimの窓にあるときは別に構わないのですが、focusがVimの外にあるときに、つねに背景がVimになってしまいます。せっかくファンシーなデスクトップの壁紙を設定しているのに、システム起動直後と終了直前にしか見れないのは、いささか寂しいものです。</p>
				
				<h2>解決</h2>
				
				<p>Vimには<code>FocusGained</code>と<code>FocusLost</code>というイベントがあります。これを用いてVimの透明度を変更すると、とてもいい感じになります。
				参考までに、著者のMacVimのための設定を以下に掲載します。<code>~/.vimrc</code>ではなく<code>~/.gvimrc</code>に記述してください。</p>
				
				<pre><code>augroup hack234
  autocmd!
  if has('mac')
    autocmd FocusGained * set transparency=10
    autocmd FocusLost * set transparency=50
  endif
augroup END
</code></pre>
				
				<p>普段は透明度10 (ほとんど不透明)にしており、focusがないときは透明度50 (かなり透明) にしています。筆者のGentoo上のGVimは<code>'transparency'</code>をサポートしていないため、<code>if has('mac')</code>で条件分岐しています。</p>
				
				<p><img src="http://cache.gyazo.com/1024f68ab4fee85b5399de675c11cd08.png" alt="ふだん" /></p>
				
				<p><img src="http://cache.gyazo.com/3481670a3bfc6dddfd139540001ef5ed.png" alt="ノーフォーカス" /></p>
				
				<h2>追記</h2>
				
				<p><a href="http://twitter.com/mattn_jp">mattn</a>さんがWindows版GVimでも動作するためのプロジェクトを発動させたようです。</p>
				
				<ul>
				  <li><a href="https://github.com/mattn/transparency-windows-vim">https://github.com/mattn/transparency-windows-vim</a></li>
				</ul>
				
				<address class="hack-author">ujihisa</address>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2011/10/hack234/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hack #233: 現在使用中のColorSchemeの名前を取得する</title>
		<link>http://vim-users.jp/2011/09/hack233/</link>
		<comments>http://vim-users.jp/2011/09/hack233/#comments</comments>
		<pubDate>Thu, 29 Sep 2011 15:00:32 +0000</pubDate>
		<dc:creator>ujihisa</dc:creator>
				<category><![CDATA[Vim Hacks]]></category>
		<category><![CDATA[lv1]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=2651</guid>
		<description><![CDATA[こんにちは、ujihisaです。今月末に引っ越しをする予定があり、毎日忙しく、Vimを使う暇すらない日々が続いています。 問題 美しいColorSchemeを使用しており、それを友達に自慢したいVim使いは多数いると思い [...]]]></description>
			<content:encoded><![CDATA[				<p>こんにちは、ujihisaです。今月末に引っ越しをする予定があり、毎日忙しく、Vimを使う暇すらない日々が続いています。</p>
				
				<h2>問題</h2>
				
				<p>美しいColorSchemeを使用しており、それを友達に自慢したいVim使いは多数いると思います。しかしながら、現在使用中のColorSchemeの名前を取得する方法が分からず、はがゆい思いをしたことがある人も少なくないのではないでしょうか。</p>
				
				<h2>解決</h2>
				
				<p>二つの方法があります。</p>
				
				<pre><code>:colorscheme
</code></pre>
				
				<p>あるいは</p>
				
				<pre><code>:echo g:colors_name
</code></pre>
				
				<p>前者は画面にColorScheme名を表示する専用のコマンド、後者はColorScheme名が入っている変数を得てそれを表示しているわけですので、対話的に使用するときは前者を、Vim scriptから値を使用するときは後者を使うと自然になります。</p>
				
				<h2>注意</h2>
				
				<p>必ずしも上記方法で現在使用中のColorSchemeが得られる<em>とは限りません</em>。ColorScheme開発者には、そのColorScheme名を<code>g:colors_name</code>というグローバル変数に格納することが<em>推奨</em>されていますが、自動的に行われるわけではありません。</p>
				
				<p>上記のような場合、<code>:colorscheme</code>は無条件に<code>default</code>と出力します。また、<code>g:colors_name</code>にアクセスするとエラーを吐き出します。</p>
				
				<p>悪評高いColorSchemeの例として<code>leo</code>があります。<code>:colorscheme leo</code>して<code>:echo g:colors_name</code>ないし<code>:colorscheme</code>して、絶望しましょう。</p>
				
				<p>そして、<a href="https://github.com/vim-jp/issues">パッチを投げましょう。</a></p>
				
				<address class="hack-author">ujihisa</address>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2011/09/hack233/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hack #232: Clojure開発環境を整える</title>
		<link>http://vim-users.jp/2011/09/hack232/</link>
		<comments>http://vim-users.jp/2011/09/hack232/#comments</comments>
		<pubDate>Sat, 24 Sep 2011 15:00:37 +0000</pubDate>
		<dc:creator>ujihisa</dc:creator>
				<category><![CDATA[Vim Hacks]]></category>
		<category><![CDATA[lv2]]></category>

		<guid isPermaLink="false">http://vim-users.jp/?p=2644</guid>
		<description><![CDATA[こんにちは、ujihisaです。Vancouverでは空前のClojureブームが発生しており、毎週のようにClojure勉強会があり、Vim使いやEmacs使いが集結しています。 問題1 Clojureでシンタックスハ [...]]]></description>
			<content:encoded><![CDATA[				<p>こんにちは、ujihisaです。Vancouverでは空前のClojureブームが発生しており、毎週のようにClojure勉強会があり、Vim使いやEmacs使いが集結しています。</p>
				
				<h2>問題1</h2>
				
				<p>Clojureでシンタックスハイライトや自動インデントを行いたい。</p>
				
				<h2>解決1</h2>
				
				<p>VimClojureというプラギンをインストールします。</p>
				
				<p><a href="https://github.com/jondistad/vimclojure">https://github.com/jondistad/vimclojure</a></p>
				
				<p>なお、<code>g:clj_highlight_builtins</code>を設定すると標準関数のハイライトが、また<code>g:clj_paren_rainbow</code>を設定すると括弧の対応が虹色に美しく輝き、便利です。筆者は以下のようにして両方とも利用可能にしています。</p>
				
				<p><code>~/.vimrc</code>:</p>
				
				<pre><code>let g:clj_highlight_builtins = 1
let g:clj_paren_rainbow = 1
</code></pre>
				
				<p><img src="http://cache.gyazo.com/b06a1ebce88f8e4185758a1439ba617c.png" alt="vimclojure highlighting" /></p>
				
				<h2>問題2</h2>
				
				<p>改行するたびにyankしている文字列が消える?</p>
				
				<h2>解決2</h2>
				
				<p>VimClojureをアンインストールするか、頑張ってパッチを書きます。</p>
				
				<p>VimClojureには深刻なバグがあり、インデントを調整するたびにyankしている文字列が完全に破壊されます。</p>
				
				<h2>問題3</h2>
				
				<p>Clojureのコードを即座に実行し、結果を別バッファに表示しつづけたい。</p>
				
				<h2>解決3</h2>
				
				<p>quickrunを用います。もし<code>clj</code>というコマンドを持っていれば、ファイルタイプがclojureであるバッファに対してquickrunは無設定で動作します。</p>
				
				<p><a href="https://github.com/thinca/vim-quickrun">https://github.com/thinca/vim-quickrun</a></p>
				
				<p><img src="http://cache.gyazo.com/c75140516995cd5ccfb6593584bc7af4.png" alt="quickrun clj" /></p>
				
				<h2>問題4</h2>
				
				<p>quickrunに時間がかかりすぎる。</p>
				
				<h2>解決4</h2>
				
				<p>JVMの立ち上げ時間とライブラリの読み込み時間がとても長いのが原因です。Clojure処理系を立ち上げたままにしておくことで、劇的な高速化が実現できます。そのための道具としてNailGunとJarkがあります。筆者のオススメはJarkです。</p>
				
				<p><a href="https://github.com/icylisper/jark">https://github.com/icylisper/jark</a></p>
				
				<p>Jarkをインストールしたら、まずはJarkサーバを立ち上げましょう。vimshellなどで</p>
				
				<pre><code>$ jark vm start
</code></pre>
				
				<p>として事前にJarkサーバを立ち上げ、そしてquickrunします。OSを終了するときまで、すなわちVimを終了するときまで、Jarkサーバを終了する必要はありません。</p>
				
				<p>quickrunは<a href="https://github.com/thinca/vim-quickrun/pull/18">既にjarkに対応していますので</a>、無設定でいきなり使えるはずです。</p>
				
				<p>以下に感動的なベンチマーク結果を載せます。</p>
				
				<pre><code>(println "hello")
</code></pre>
				
				<p>とだけ書いたコードを<code>clj</code>と<code>jark</code>のそれぞれで<code>time</code>コマンドで比較してみたところ、それぞれ</p>
				
				<ul>
				  <li>
				    <p>clj</p>
				
				    <pre><code>  1.40 real         2.09 user         0.15 sys
</code></pre>
				  </li>
				  <li>
				    <p>jark</p>
				
				    <pre><code>  0.19 real         0.11 user         0.06 sys
</code></pre>
				  </li>
				</ul>
				
				<p>となりました。実験はかなりパワフルなiMacを用いて行ったので、一般的な初代MacBook Airなどのマシンで行うと、さらに顕著な差が出るでしょう。</p>
				
				<address class="hack-author">ujihisa</address>
]]></content:encoded>
			<wfw:commentRss>http://vim-users.jp/2011/09/hack232/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

