Windows 版 vim を使っています。
といってもちょっと便利な vi 程度にしか使っておらず、カスタマイズは最小限で
済ませています。コマンドシェルから gvim を起動してファイル毎に別のエディタを
開くスタイルです。
shell + gvim の組み合わせは X68000 の Ko-Window 上で vi (stevie) を使う
場合とよく似ています。shell と別ウィンドウでいくつでも開けるからです。
ほとんど同じ感覚で使用しています。

vim は vi 系のテキストエディタです。
コマンドシェルからヒストリを使ってエディタを呼び出していると、すでに開いている
ファイルなのに、つい多重で開いてしまうことがあります。
同じファイルを複数のエディタで同時に開くのはまずいです。
最後に保存した方の更新しか残らないからです。
stevie の時はよくミスしがちでした。

幸い vim の場合はあまり困ったことにはなりません。
ファイルを開くと .swp ファイルが作られるので、そのファイルがすでに編集中なのか
わかります。すでに .swp ファイルがあるなら、このまま開くか ReadOnly
で続けるか、起動を中止するか確認してくれます。

便利な反面、衝突するたびに動作を選択して中止し、起動中のウィンドウから
目的のものを探し出すのはだんだん面倒になってきます。
そこで、下記のようなプログラムを作って使っていました。

・指定したファイルがすでに gvim で開いているかどうか調べる
  ・もしすでに存在していたら、そのウィンドウをアクティブにする
  ・無ければ新たに gvim でそのファイルを開く

もしかしたら vim 自体に何らかの設定があったり、最初から似たような機能が付いて
いたり、または同等のものが存在しているのかもしれません。
必要あるかどうかわかりませんが置いておきます。

runvim100.zip

使い方
runvim [option] [<ファイル名>]

 -e<起動するgvimのパス>

たとえば alias や shell の関数定義で下記のように定義しておきます。
(gvim のパスは任意)

alias vi='runvim.exe -eC:/app/Vim71/gvim.exe'

上記定義した後「vi ファイル名」で起動すると、すでに開いていれば対応する
gvim を最前面に持ってきて入力フォーカスします。
無ければ gvim を通常起動します。


以下 vim (7.1) の個人的な設定です。
Vim 自体は本家 vim.org からダウンロードしたパッケージをそのままインストール
しています。

" $HOME/_vimrc
se ai columns=80 lines=46 hls nobackup ruler
se guifont=MS_ゴシック:h8:cSHIFTJIS
se linespace=0
se guioptions=grLt
se mouse=a
se iminsert=0 imsearch=0
se enc=cp932
se guioptions-=a
se statusline=%<%f\ %m%r%h%w%{'['.(&fenc!=''?&fenc:&enc).']['.&ff.']'}%=%b\ %B\ %l,%c%V%8P
lan en
lan cty en
lan mes en
lan tim ja
syntax enable
hi Constant	guifg=#a03800
hi PreProc	guifg=#008010
hi Folded	guifg=#808000 guibg=#fffffe
hi FoldColumn	guifg=#808000 guibg=#fffffe
so $HOME/format.vim
let format_join_spaces=2
se foldmethod=syntax

実はフォントは難ありで、この設定だと小文字のエル=l と大文字のアイ=I の区別が
付かないけど慣れました。このままプログラム書いてます。

format.vim は日本語で join したときに空白が入らないようにするため使用しています。

doxygen syntax を追加しています。
Vim を install したフォルダ内の filetype.vim を書き換えます。
"setf cpp" や "setf c" と定義されているところを全部 "setf cpp.doxygen"
のように変更します。".doxygen" を追加するわけです。
これで syntax として cpp が選択されると同時に doxygen のキーワードハイライト
が有効になります。

折りたたみ機能も利用しています。
そのまま folding を有効にすると C ソースコードのブロックも折りたたまれて
しまうので、その設定は削除。その代わり doxygen のコメントを部を折りたためる
ようにしています。

(1) syntax/c.vim の中の syntax ~ fold ~ と書かれた行の "fold" を全部削除
  たとえば下記のように (syn ~ で始まる場合もあり)
syntax region	cBlock		start="{" end="}" transparent fold
 ↓
syntax region	cBlock		start="{" end="}" transparent

(2) syntax/doxygen.vim に下記の 2行を追加
syn region myDoxFold start="/\*!" end="\*/" transparent fold keepend
syn sync fromstart

折りたたみ操作は vim 上で zr または zm です。


.hlsl や .fx 等、自分が使うファイルの syntax も追加しています。
専用の syntax ファイルが無くても、C言語系なら c や cpp を割り当てるだけで
見やすくなります。
たとえば filetype.vim を書き換えてこんな風に。(fsc は自前の C言語スクリプト)
" filetype.vim
au BufNewFile,BufRead *.fsc			setf cpp.doxygen


Vim の syntax や script ファイルは下記ページで検索できます。

vim.org Scripts Browse all


関連エントリ
vi の話


VisualC++ 2010 beta ではラムダ式が使えます。
無名の関数を inline で宣言することが可能で、関数オブジェクトのように
取り扱いできます。

Download Visual Studio 2010 Beta
Examples of Lambda Expressions

変数で受け取る場合は auto や template を使った汎用の入れ物が必要です。

auto f0= []( int x, int y ){ return x * y; };
std::tr1::function<int(int,int)> f1= f0;

lambda 式は無名の型宣言に相当するので、同等の型を明示的に宣言することが
できません。
名前をつけるだけなら下記の定義は出来ますが、これも f0 が有効な範囲のみです。

typedef decltype(f0) lambda_type2;
lambda_type2 f2= f0;

全く中身が同じ lambda 式を定義しても別の型と見なされるようです。

auto	f2= []( int a, int b ){ return	a * b; };
auto	f3= []( int a, int b ){ return	a * b; };
decltype(f2)*	fp2= &f3;  // error

上記の例はエラーです。
そのため定義内容を知らない外部から直接参照する手段がありません。

実際に使ってみると単純な関数ポインタでは無いことがわかります。

・lambda 式に応じて無名のクロージャー用クラスが定義される
・メンバとしてキャプチャした変数のコピーまたは参照が格納される
・クロージャークラスのメンバ関数として呼び出される。

確認してみます。

int v= 0;
auto  f4= []( int a, int b ){ return  a * b; };
auto  f5= [&]( int a, int b ){ return  a * b + v; };
auto  f6= [=]( int a, int b ){ return  a * b + v; };

sizeof(f4) == 1
sizeof(f5) == 8 // x64
sizeof(f6) == 4

sizeof(f4) が 1 なのは実質的にサイズが無いことを意味しています。
sizeof(f5) と sizeof(f6) はどちらも v を参照していますが、たまたま x64 で
コンパイルしていたので異なるサイズになりました。
ポインタ(参照)である証拠で x86 だと 4 になります。

auto	f4= []( int a, int b ){ return a * b; };
f4.operator()( 2, 10 );

operator() の呼び出しが出来ます。

int	v;
auto	f5= [&]( int a, int b ){ return a * b + v; };
int	r0= f5.v; // cannot access private member
int	r1= f5.w; // is not a member

直接アクセスはエラー。変数名はそのままメンバになってます。

lambda 式の定義が返す値はその場でキャプチャされたクロージャーそのものであるということ。
クロージャー未使用でも空の構造体が定義されること。
実行する関数はクロージャー型と静的に関連づけられており、そのために型は常にユニークとなること。
lambda 式の呼び出しは静的なものであってポインタでは無いということ
等がわかります。

実際に出力コードも追いかけて確認。

きちんとインライン展開されているし、これで定義を知らない外部からは直接アクセス
できない理由もわかりました。
外部関数呼び出しのようにインライン出来ない場合は std::tr1::function のような
関数オブジェクトが必要になるわけです。

struct func_base_2 {
    virtual int  operator()( int a, int b )= 0;
};

template<typename T>
struct func_impl_2 : public func_base_2 {
    T  exf;
    func_impl_2( T lambda_f ) : exf( lambda_f ) {}
    int	operator()( int a, int b )
    {
        return  exf( a, b );
    }
};

struct func_2 {
    func_base_2*   ptr;
    template<typename T>
    func_2( const T&& lambda_f )
    {
        ptr= new func_impl_2<T>( lambda_f );
    }
    template<typename T>
    func_2( T& lambda_f )
    {
        ptr= new func_impl_2<T&>( lambda_f );
    }
    int	operator()( int a, int b )
    {
        return	(*ptr)( a, b );
    }
    ~
};


    func_2    f7( []( int x, int y ){ return x*x + y*y; } );
    int   mm= f7( 3, 9 );

この場合の f7 は callback として持ち出せます。
使えるのはクロージャーが作られた関数スコープの中のみです。


関連エントリ
VisualStudio 2010 beta1


そろそろソースコードも UTF-8 で統一したいと常々思っていました。
VisualC++ の場合 BOM (ef bb bf) があれば UTF-8 とみなしてくれます。

コンパイラおよびリンカでの Unicode のサポート

バイナリには記述したコードのまま格納されるわけではなく、
必要に応じて ShiftJIS や UTF-16 に変換されます。

関連エントリ
_T() と TEXT() の違いやソースの文字コード

逆に UTF-8 のままデータを記述することが難しいのと、
BOM が付くと他のコンパイラでエラーになることがあるようです。

"表示" を utf-8 でコンパイルしてみる

  SJIS = 95 5c 8e a6
  UTF8 = e8 a1 a8 e7 a4 ba
  UTF16= 8868 793a

VC2008: utf8+bom  = 95 5c 8e a6  (SJISに変換されている)
VC2008: utf8      = e8 a1 a8 e7 a4 ba
CW    : utf8+bom  = error
CW    : utf8      = e8 a1 a8 e7 a4 ba
gcc4.1: utf8+bom  = error
gcc4.1: utf8      = e8 a1 a8 e7 a4 ba

VC bom 無しはたまたまうまくいってますが、Shift JIS 判定ありなので
問題が出ます。(warning C4819 になる事も)

例えば "引\n" を UTF-8 記述すると、バイト列では

 引       \  n
 e5 bc 95 5c 6e

ShiftJIS でも意味のあるコードなので、'\' 'n' が変換されず
文字として残ります。

常に日本語 (cp932) とみなすこの動作は、Windows のシステムロケールを
見ているようです。VisualStudio は英語版を使っているし、option の
"International Settings" にある Language を
"Same as Microsoft Windows" でなく English にしても変化無し。

Vista で コントロールパネル→地域と言語のオプション→管理
「Unicode対応ではないプログラムの言語」を「英語」に切り替えると
コードが素通りし、"引\n" の \n が改行に変換されるようになりました。

でも他のアプリに影響が出るので、このまま使うのは問題ありです。

gcc では「 -finput-charset=cset 」「 -fexec-charset=cset 」の
オプションがあって、それぞれ個別に指定できるようです。
例えば utf8 と sjis にすると VC とほぼ同じ挙動となりました。
でも BOM はだめ。


Quad の PC が一瞬だけ空いたので比較してみました。
最初 10分かかっていたコンパイルが
わずか 1分に

・Pentium4 3.6GHz×2 RAM 2GB
10'25 (セキュリティソフトあり)
05'30 (/MP4 セキュリティソフトあり)
05'40 (セキュリティソフト無し)
02'30 (/MP4 セキュリティソフト無し)

・Core2 Duo 2.4GHz RAM 4GB
01'50 (/MP4 セキュリティソフト無し)

・Core2 Quad 2.4GHz RAM 8GB
01'04 (/MP6 セキュリティソフト無し)



関連エントリ
Visual Studio 2008 IDE で MP を使う
Visual Studio 2008 MP オプション実験
Visual Studio 2008
コンパイル速度の実験


メモリの価格が急激に下がっているそうです。
そんな話をしていたら、タイミングよく PC Watch に記事が掲載されて
いました。
元麻布春男の週刊PCホットライン 1GB=2,000円時代のメモリ増設を考える(上)

バルクであれば 2GB のメモリが 4980円程度!
この間買ったばかりの 1GB メモリは 2枚で7000円くらいでした。

つい先日まで 1GB ×4 で喜んでいたのに、今なら 2GB×4 の 8GB RAM
だって十分現実的です。


まだ Quad では試せていませんが、最近試していた Multi Core による
build 時間の短縮も効果がありました。PC の性能向上は速くていつも
驚かされます。
Multi Core CPU や 64bit OS に大容量メモリなど、プログラミング環境
としてより速い PC を求めることに説得力が出てきました。
使い方次第ではありますが速さは作業効率の向上につながります。


ところがプログラマ用 PC の性能向上を妨げるものは、会社の予算でも、
上司の許可でもなく、プログラマ自身であることがあります。


せっかく PC をもっと良いものに交換しようと持ちかけても、
環境構築が面倒だからいらない、という人は思ったよりたくさんいます。

もちろんプロジェクトの終盤とか大事な時期とか、変えてはいけない時も
あります。だけどそうでなくても、環境再構築や OS の入れ替え、
PC の引越しをかなり面倒だと考える人は多いようです。
よほど困っている場合を除いて、意外にも現状で満足してしまうようです。


私は仕事柄ビデオカードテスト用にマシンを用意したり、各種 OS を
入れたり、またはスタッフ用に PC を準備したりと、
何度も何度も PC のセットアップすることが多いです。
そのため自然に再セットアップの最小手段を準備しておくようになりました。

コピーすべきデータを常に分けておいたり、最低限必要なアプリケーション
や設定など、自分の PC にするための手順を把握しています。

エデイタやシェルなど基本的な設定ファイルや環境は Subversion に全部
入れてしまっています。新しい PC 上でも checkout すればすぐ使え、
設定を変えても複数の PC 間で同期を取ることも容易です。

最初に書き換えるレジストリなども reg ファイルにして、同じように
svn に入れてしまっています。


環境の再構築で時間をとられるのはほんの一時的ですが、build 時間など
作業効率はその後長く影響し続けます。
これはチーム全体の効率にかかわってきます。

より速い環境へと PC を自在に渡り歩くスキルも、これから
必要になってくるのかもしれません。



| 次のページ(日付が古い方向)>>