2015/08/20


こんにちわ。Vim 使ってますか?使ってない?使いましょう。

2015年になっても Vim 使ってる人いるの?なんて人もいますが、よく考えて下さい。Vim だけで出版物が何冊もあるんですよ?Vim script は GitHub 上だと Go や R と同じくらい人気のあるプログラミング言語なんですよ?(出展: The RedMonk Programming Language Rankings: June 2015 – tecosystems)

新しいテキストエディタがどんどん出てきて、イケてないテキストエディタはどんどん消えるのに、Vim は未だに人気があるエディタなんですよ?Vim がそんなに根強いのには理由があると思いませんか?使うの難しくて Vim やめてしまったけど、もういちどチャレンジしたいと思いませんか?普段使ってる Vim をもっと便利にしたいと思いませんか?

今も尚進化し続けるテキストエディタ Vim の最新事情をもっと知りたいと思いませんか?

そんな皆さんの声にお答えするべく、技術評論社様の Software Design にて Vim の連載を開始させて頂ける事になりました。

Software Design|gihyo.jp … 技術評論社
http://gihyo.jp/magazine/SD

連載タイトルは

Vimの細道

となります。10月号からの連載となります。いやー力強いですねー。力こそパワーですね。

第1回目は Vim の歴史から Vim の人気の秘密を紐解き、なぜ Vim がそこまで人気のあるテキストエディタなのかをご紹介します。以降は Vim の最新事情や上級者テクニックを惜しげもなく紹介し、新しいプラグインの紹介等も行っていきたいと思います。つたない文章になるかもしれませんが、どうぞよろしくお願い致します。

Posted at by



2015/06/05


Vim で CtrlP を使っている人もそこそこいるかと思いますが、ファイル検索が終わり文字をタイプした時に行を絞り込む部分(マッチャーと言います)がデフォルトの状態だと Vim script を使って処理される為、ファイル数が多くなるとモッサリして来ます。これを解消する為に幾らかの人が頑張っています。

FelikZ/ctrlp-py-matcher - GitHub

Fast vim CtrlP matcher based on python

https://github.com/FelikZ/ctrlp-py-matcher
JazzCore/ctrlp-cmatcher - GitHub

CtrlP C matching extension

https://github.com/JazzCore/ctrlp-cmatcher
junegunn/fzf - GitHub

A command-line fuzzy finder written in Go

https://github.com/junegunn/fzf

どれも決め手に掛けるなーと思っていたのですが、そんな中に突如現れたのが cpsm です。

nixprime/cpsm - GitHub

A CtrlP matcher, specialized for paths.

https://github.com/nixprime/cpsm

README.md に書いてありますが、cpsm は python 拡張で実装されしかもスレッドで起動します。他のマッチャーでもそうですが文字列のファジーマッチングは意外に処理時間が必要になります。cpsm では使用可能なスレッド数を自動取得した後、ファイル一覧に対して並列に先取りして処理を行います。全ての一覧に対してマッチ結果が得られたらソートして vim 側に返しています。

cpsm/python_extension_main.cc at 00315bdd583f5083a90a6d8c6e38eef2f2d72070 · nixprime/cpsm · GitHub

CtrlP ではファイル一覧の作成には初回だけ時間が掛かりますが、以後は有限時間付きのキャッシュが読み込まれます。マッチャーの速度次第では目にも留まらない速度でファイルを選択出来る様になります。

以下は ruby22 のディレクトリ直下(総ファイル 24685個)を CtrlP で表示し、fluentd.gemspec を開くまでの操作です。

※キャッシュは作成済みです。

cpsm

はえぇ...。しばらく常用しようと思います。

尚、CtrlP ではファイルの一覧についても外部の機能を使う事が出来ますが、僕は files というツールを使っています。

mattn/files - GitHub

Fast file find

https://github.com/mattn/files

files は golang で書かれており、-a を付ける事で goroutine を使ってディレクトリ階層を下ってファイル一覧を出力します。よろしければこちらもお使い下さい。

CtrlP についてのご意見などあれば、現在 ctrlpvim/ctrlp.vim のメンテナをやってますので twitter 等でお声掛け下さい。

Posted at by



2015/05/27


問題1

scriptencoding utf-8

"forループ、whileループ、および再帰を使用して、リスト内の数字の合計を計算する
"3つの関数を記述せよ。

functions:problem1_1()
  let l = [3,5,1,2,9]
  let s = 0
  for i in l
    let s += i
  endfor
  return s
endfunction

functions:problem1_2()
  let l = [3,5,1,2,9]
  let s = 0
  let i = 0
  while i < len(l)
    let s += l[i]
    let i += 1
  endwhile
  return s
endfunction

functions:_problem1_3(s, l)
  if len(a:l)
    return a:s + a:l[0+ s:_problem1_3(a:sa:l[1:])
  endif
  return a:s
endfunction

functions:problem1_3()
  let l = [3,5,1,2,9]
  return s:_problem1_3(0, l)
endfunction

if s:problem1_1() != 20
  throw "プログラマ失格: s:problem1_1"
endif

if s:problem1_2() != 20
  throw "プログラマ失格: s:problem1_2"
endif

if s:problem1_3() != 20
  throw "プログラマ失格: s:problem1_3"
endif

問題2

scriptencoding utf-8

" 交互に要素を取ることで、2つのリストを結合する関数を記述せよ。例えば
" [a, b, c]と[1, 2, 3]という2つのリストを与えると、関数は [a, 1, b, 2, c, 3]
" を返す。

functions:_problem2(lhs, rhs)
  let r = []
  for i in range(len(a:lhs))
    call add(r, a:lhs[i])
    call add(r, a:rhs[i])
  endfor
  return r
endfunction

functions:problem2()
  let lhs = ["a""b""c"]
  let rhs = [123]
  return s:_problem2(lhs, rhs)
endfunction

if s:problem2() !=# ["a"1"b"2"c"3]
  throw "プログラマ失格: s:problem2"
endif

問題3

scriptencoding utf-8

" 最初の100個のフィボナッチ数のリストを計算する関数を記述せよ。定義では、フィ
" ボナッチ数列の最初の2つの数字は0と1で、次の数は前の2つの合計となる。例えば最
" 初の10個のフィボナッチ数列は、0, 1, 1, 2, 3, 5, 8, 13, 21, 34となる。

functions:fib(n)
  let r = [01]
  let i = 2
  while i < a:n
    call add(r, r[i-1+ r[i-2])
    let i += 1
  endwhile
  return r
endfunction

functions:problem3()
  return s:fib(100)
endfunction

if s:problem3() !=# [0112358132134558914423337761098715972584418167651094617711286574636875025121393196418317811514229832040134626921783093524578570288792274651493035224157817390881696324598610233415516558014126791429643349443770140873311349031701836311903297121507348075269767778742049125862690252036501107432951280099533162911738626757127213958386244522585143371736543529616259128672987995672202604115480087559202504730781961405273953788165574703198421061020985772317167680177565277778900352884494557021285372723460248141117669030460994190392490709135308061521170129498454011879264806515533049393130496954492865721114850779780503416454622906707552793970088475789443943237914641447233402467622123416728348467685378890623731439066130579072161159199194853094755497160500643816367088259695496911122585420196140727489673679891637638612258110008777836610193117799794160047141892880067194370816120466004661037553030975401138047463464291220016041512187673819740274219868223167319404346349900999055168070885485832307283621143489848422977135301852344706746049218922995834555169026]
  throw "プログラマ失格: s:problem3"
endif

問題4

scriptencoding utf-8

" 正の整数のリストを与えられたとき、数を並び替えて可能な最大数を返す関数を記述
" せよ。例えば、[50, 2, 1, 9]が与えられた時、95021が答えとなる。

functions:compare(lhs, rhs)
  return a:rhs . a:lhs < a:lhs . a:rhs ? -1 : 1
endfunction

functions:problem4()
  let l = [50219]
  return join(sort(l, function('s:compare'))'')
endfunction

if s:problem4() !=# 95021
  throw "プログラマ失格: s:problem4"
endif

問題5

scriptencoding utf-8

" 1,2,…,9の数をこの順序で、"+"、"-"、またはななにもせず結果が100となるあらゆ
" る組合せを出力するプログラムを記述せよ。
" 例えば、1 + 2 + 34 - 5 + 67 - 8 + 9 = 100となる。

functions:make100(r, b, n) abort
  if a:n == 10
    if eval(a:b) == 100
      call add(a:ra:b)
    endif
  else
    for op in ['+''-''']
      call s:make100(a:ra:b . op . (a:n)a:n+1)
    endfor
  endif
  return ''
endfunction

functions:problem5()
  set maxfuncdepth=200
  let r = []
  call s:make100(r, 12)
  return r
endfunction

for s:l in s:problem5()
  if eval(s:l) != 100
    throw "プログラマ失格: s:problem5"
  endif
endfor
unlet s:l

で、問題3 なのですが Vim script では 32bit int しか扱えないので100個のフィボナッチ数列が数えられません。

プログラマ失格

よってわたくし、プログラマ失格となりました。みなさん今までお世話になりました。

えーっと、良く見たら結果が違ってただけでした。なのでエラーにはならなくなりました...。ですが Vim script が 32bit int 以上が扱えないのを知った上で bigint を1時間以内で実装出来なかった僕はプログラマ失格でしょうか。。。

Posted at by