typeof Diary

VimとかJSとか。やったことのメモ。自分のため。

listcharsでドキッとした話

Vim Advent Calendar 2013の174日目の記事となります。

さて今回は、listcharsでドキッとした話です。
体験したのは去年の秋ぐらいの話ですが、掘り返します!

set listcharts

例えば、vimrcに

set list
set listchars=tab:>-,trail:-,eol:$

こんな感じで書いておけば、

f:id:lisia:20140523003234p:plain

不可視文字を視覚化することができます。

字下げがタブなのか、スペースなのか、目で見て分かるのはとても便利です。
改行もどこで行われているのか、目で見て分かるのは便利です。

では次に、eol:$を、eol:↲と、いかにも改行っぽくしてみましょう。

set list
set listchars=tab:>-,trail:-,eol:

やじるしで変換して出るような環境依存文字です。

f:id:lisia:20140523005256p:plain

一応表示はされました。
ですが、半分しか表示されてません。そうです、この子、2倍幅ですね。
例えば、eol:終などとしても普通は反映されず$が表示されますが、
この子は設定できてしまいます。

設定できるなら、ちょっと見栄え悪いけど使ってしまおう。と考える人もいるかもしれません。
実際、Vim 不可視文字 視覚化 なんてキーワードでGoogle先生に聞いてみたら、
この設定をしているブログなどがちらほら見当たるはずです。

何が起こる?

少し文章を打ってみます。

f:id:lisia:20140523010348p:plain

そうですね。

明日は土曜日です。
休日ですので、出社しないでください。

ん!? 何か変ですね。

f:id:lisia:20140523010559p:plain

旧字体でしょうか。少し表示がおかしくなってます。
社以外にも何文字か見つけていたのですが、忘れました….

例えば、Viewを書いていて、会社と間違いなく打っていたはずなのに、
エディタ上で見ると表記がおかしい。
この変化に気づかずコミットしていたことがあるので、見つけた時はそれはもうドキッとしました。(実体験)
実際は何も変わってないので問題はないのですが...。

Osakaフォントでの発生です。他は見てませんが、
今はRicty使っていて再現せずです。

何が言いたいかというと

使えるからって安易に使わない方が良いと思います。
変なものには何かしらの副作用がある可能性があります。
この問題はhttps://github.com/vim-jp/issues/issues/491なんかを見ていただければと思います。
リンク見たら、つぶやき自分のですね。

Osakaといえば!

6/28(土)
Osaka.vimが開催されます。
私も初心者ながら参加させていただきます。
待ちに待った、関西でのVim勉強会です。
是非是非、参加をご検討ください! まだ空きあります。

そして、終了後には懇親会も予定しております。
こちらもご参加いただければと思います。

6/28は大阪で、V☆i☆m☆活!

余談ですが、カラオケ部良いですね。

Raspberry PiでMinecraft

昨日の夜中、TwitterのTLでMinecraftの話題が上がっていたので、ひとこと。
箱○しか持ってません。

もっと言うと、箱○も実家に放置してきたので、今は手元にないのです...
oh...

いろいろありまして、少し調べておりました。
すると!

なんとなんと、Raspberry pi版があるとのことでした。
Raspberry pi無駄に所持している身としては、これは入れてみるしかない!
ということで、入れてみました。

Minecraft Pi Edition

Minecraft Pi Edition
公式からダウンロードします。

普通にraspberry pi側でダウンロードしても問題ないですが、
ちょっとネットワーク設定でトラブってまして...raspberry piで外に出られない状態でした。

%scp -r minecraft-pi-0.1.1.tar.gz pi@xxx.xxx.xxx.xxx:送り先
scpで送りつけました。

あとは、sshで接続、送りつけたtar.gzを
%tar -zxvf minecraft-pi-0.1.1.tar.gzで解凍。
すると、mcpiディレクトリが出来ているので、%cd mcpiとします。
中にminecraft-piがあるので、%./minecraft-piとでもしてあげれば起動できます...
が、しかし。

起動しても何もできない! そりゃそうです。コマンドから叩いているだけですから。

startx

startxとすると、Raspbian のデスクトップ画面が表示されるので、
そこからターミナル立ち上げて、minecraft-piを起動してあげましょう。

すると、こんな感じで起動されます。
あとは楽しむだけです。

f:id:lisia:20140518235352j:plain

この後

apt-get updateがエラーになり、いろいろと戸惑っておりましたが、
なんとか設定できたようで、無事updateできました。
ついでなので、LAMP入れてWebサーバ化してみました。

せっかく購入したものですから、何か活用しないと勿体無いですね。
ミニ四駆動かすとかしかやってない...

Vimでカラーコードをインクリメントする

Vim Advent Calendar2013 164日目の記事となります。
再開ということで、書きます。何気に3回目。

ゴールデンウィークも終わりましたが、いかがお過ごしでしょうか。
さて、社会人になって早くも1年が経過し、2年目に突入しました。
まとまった休みのありがたみを嫌というほど実感しますね。

さて今回は、初めてVim scriptを書いたというお話です。
同じタイトルの記事を数日前に書いていたのですが、中途半端だったので、
書き直し + VACの記事にしちゃいました。

Vim scriptと正面から向き合う

Vimの使い始めた経緯などは、私とVimを読んでいただければと思います。
あれから月日が経ちましたが、Vim scriptを「やらなきゃ」とは思っていたものの、一歩が踏み出せずにいました。

そこで出会った記事がこちらです。
Vim - プラグインまたはVim scriptを書く楽しさについて語りたい - ぼっち勉強会
一度は目を通していたものの、改めて真剣に読んでみて、かなり背中を押されました。

ネタが浮かばない。がまさに自分で、「やりたい」けど「やれない」の理由は大半がこれです。
そして、世の中には思いついても、ない物の方が少なくて、ほぼ絶対あるんですよね。
ですが、あるからやらないだと、一生身に付きません。

Vim scriptに関しては、下記記事が非常に参考になりました。
Vimスクリプト基礎文法最速マスター - 永遠に未完成
Big Sky :: モテる男のVim Script短期集中講座
Vim Advent Calendar 2013 136日目:Vim script で関数のデフォルト引数を設定したい - C++でゲームプログラミング

大体一度は目を通していたのですが、モチベーションが高い時に読むのと、
普段の状態で読むのとでは、頭への内容の入り方も全然違います。

それと、よく言われますがあとは「ヘルプを読みましょう」ということです。
今回、一番感じたことは、ヘルプを読むことの重要さです。
全てがここにあります。本当に。。。

本題

Vimには<C-a>でインクリメント、<C-x>でデクリメントという、
ちょっとした数値変更にとても便利な機能があります。
8、16進数、アルファベットにも対応ができ、なかなか面白いです。

8進数、アルファベットは置いておいて、16進数に目をつけましょう。
0xを前につけると、16進数と解釈します。
ですが、普段16進数を使う時はどのような時が多いでしょうか。
#RRGGBBの形ではないでしょうか。
最近、仕事の関係で、グラフやマップなど、データの視覚化を扱っており、
style系のプロパティでcolor設定は大体これです。

そこで思いました。
カラーコードのインクリメント、デクリメント。出来たらどうだろう。
(探せば絶対あると思う)

処理を考える
  1. カーソル下のカラーコードを取得
  2. #RRGGBB形式かをチェック
  3. インクリメント or デクリメント
  4. 更新する

ささっと思ったのがこの4つで、初めて書くのには丁度良さそうでした。

無理矢理実装

初めて書いたVim scriptになります。
なかなかひどいコードですが最初ですので…!!

function! s:Color_Fluctuation(type, ...)
  " 第2引数がなければ ''
  let color = get(a:, 1, '')

  " カラーコード
  let colorcode = expand('<cfile>')
  " カーソル位置
  let pos = getpos(".")

  " check
  if !s:Check_ColorCode(colorcode)
    echo colorcode. ' is not color code.'
    return 0
  endif

  " r,g,bで分離
  let red   = str2nr(colorcode[1:2], 16)
  let green = str2nr(colorcode[3:4], 16)
  let blue  = str2nr(colorcode[5:6], 16)
  let c_dict = {'red': red, 'green': green, 'blue': blue}

  if a:type
    " increment
    let new_dict = s:Color_Increment(color, c_dict)
  else
    " decrement
    let new_dict = s:Color_Decrement(color, c_dict)
  endif

  let new_color = s:Get_ColorCode(new_dict)

  " replace
  execute 's/'.colorcode.'/'.new_color.'/g'
  call setpos('.', pos)
endfunction
" ColorCord Increment
function! s:Color_Increment(color, c_dict)
  let max = 255
  let min = 0
  for key in keys(a:c_dict)
    if a:color != ''
      if a:color == key && s:Check_Range(a:c_dict[key], max, min)
        let a:c_dict[key] = a:c_dict[key] + 1
      endif
    else
      if s:Check_Range(a:c_dict[key], max, min)
        let a:c_dict[key] = a:c_dict[key] + 1
      endif
    endif
  endfor

  return a:c_dict
endfunction

" ColorCord Decrement
function! s:Color_Decrement(color, c_dict)
  let max = 256
  let min = 1
  for key in keys(a:c_dict)
    if a:color != ''
      if a:color == key && s:Check_Range(a:c_dict[key], max, min)
        let a:c_dict[key] = a:c_dict[key] - 1
      endif
    else
      if s:Check_Range(a:c_dict[key], max, min)
        let a:c_dict[key] = a:c_dict[key] - 1
      endif
    endif
  endfor

  return a:c_dict
endfunction
" #RRGGBBの形かチェック
function! s:Check_ColorCode(code)
  if a:code =~ '^\#\{1}\x\{6}$'
    return 1
  else
    return 0
  endif
endfunction

" 範囲内かチェック
function! s:Check_Range(color, max, min)
  if a:min <= a:color && a:color < a:max
    return 1
  else
    return 0
  endif
endfunction

function! s:Get_ColorCode(new_dict)
  let s:V = vital#of('vital')
  let s:M = s:V.import('Data.String')
  let code = '#'
  let show = 'Red:'. a:new_dict.red. ' Green:'. a:new_dict.green. ' Blue:'. a:new_dict.blue

  for key in keys(a:new_dict)
    " 10 -> 16
    let val = s:M.nr2hex(a:new_dict[key])

    if strlen(val) == 1
      let val = '0'.val
    elseif  strlen(val) == 0
      let val = '00'
    endif
    let a:new_dict[key] = val
  endfor

  " echo
  echo show

  " create new color code.
  let code = code. a:new_dict.red. a:new_dict.green. a:new_dict.blue
  return code
endfunction

コマンド定義とマッピング

そして、無理矢理には無理矢理なマッピング。。。
<C-A>+<C-X>-にしてあります。

command! -nargs=* ColorIncrement call s:Color_Fluctuation(<f-args>)
nnoremap <C-A> :ColorIncrement 1<CR>
nnoremap <Left> :ColorIncrement 1 red<CR>
nnoremap <Up> :ColorIncrement 1 green<CR>
nnoremap <Right> :ColorIncrement 1 blue<CR>

command! -nargs=* ColorDecrement call s:Color_Fluctuation(<f-args>)
nnoremap <C-X> :ColorDecrement 0<CR>
nnoremap <S-Left> :ColorDecrement 0 red<CR>
nnoremap <S-Down> :ColorDecrement 0 green<CR>
nnoremap <S-Right> :ColorDecrement 0 blue<CR>

左からRGBなので、
インクリメントは、R=<Left> G=<Up> B=<Right> RGB全て=<C-A>
デクリメントは、R=<S-Left> G=<S-Down> B=<S-Right> RGB全て=<C-X>
としました。

動き

NeoBundle 'lilydjwg/colorizer'
colorizerを入れて、色の変化が分かりやすいようにしています。

まとめ

一行まるまる置換しているので、同じ行に同じコードがあれば、全部変わってしまうことと、 よくもまぁこんなに無理矢理書いたなぁと思うことなど、心残りはありますが、
Vim scriptにとりあえず触れてみて、何か作ってみるという点で見れば、得た物は大きかったです。

  • 代入の方法
  • 辞書の使い方
  • 関数定義
  • 呼び出し方
  • 引数へのデフォルト値設定
  • コマンド定義
  • Vital.vimの使い方

結構いろいろ学べています。

コードが綺麗やお行儀なんてものは後からでもどうにでもなりますし、
まずは触れてみて、何でも良いからやってみる。このハードルを超えてみることをオススメします。
写経でも、簡単なものでも、やはりできた作ったが一番のモチベーションです。

とりあえず、何が言いたいかというと!
やめられない 止まらない Vim script

6月にはmomonga.vim#4もありますので、それまでにモチベーションが上げられたことも、
今回良かったことですね。

にしても、最近コード書いてると_の使用率が。。。 以上です。
次回は、せっかくVim scriptに触れたので、まだ触れられずにいる人向けの物が書けたらと思います。

(こっそり修正2 2014/05/14 9:25)

最後に

VAC2013、ぜひ書きましょう!

初オライリー

オライリー

初、オライリーを購入。
動物園目指しましょう!

何買ったの

ツイッターでオススメしていただいた、D3.js関係のものになります。

オススメしていただいたのが昨日。
家に帰って、図書カード2枚を発見しました。
「買え」と言わんばかりのタイミングでした。早速、今日の仕事終わりに本屋へ行ってまいりました。

オライリー買うと、こんなの貰えるんですね。
付箋だそうです。

f:id:lisia:20140421235405j:plain

可愛い。

軽く読む

軽く最初の方を読んでみましたが、最初はHTML、CSSJavaScriptSVG、そこからの説明です。
確かに、エンジニア向けというよりはデザイナーだとか向けなのは分かります。

個人的に嬉しいのは、地図描画があることですね。
早くそこまで辿り着きたいものです。案外集中すればスラっといけそうな分量なのも魅力ですね。

ログインシェルをzshに変える

zshを触る機会が巡ってきたので、自宅マシンにもzshを入れてみました。
Mac標準のzshを今まで使っていたようなので、homebrewから入れてみます。

homebrewから入れる

% brew install zshコマンドをターミナルから叩く。
すると、zshが入ります。

次に% vim /etc/shellsで、/etc/shellsを開き、
一番下に/usr/local/bin/zshと追加します。

f:id:lisia:20140419193516p:plain

こんな感じで。

% chsh -s /usr/local/bin/zshで、デフォルトのシェルを変更しちゃいます。

% chpassとしてshellが先ほど設定したパスになっていれば完了です。

f:id:lisia:20140419194055p:plain

oh my zsh

% curl -L http://install.ohmyz.sh | sh叩いて、oh my zsh入れておけば、
幸せになれるとか、なれないとか…。

f:id:lisia:20140419194708p:plain

D3.jsのチュートリアルを少し

D3.jsとは

Data Driven Documentの頭文字をとって、D3のようです。

D3.js はデータに基づいてドキュメントを操作するための JavaScript ライブラリです。
D3 はHTML や SVGCSSを使ってデータに命を吹き込みます。D3は WEB 標準に重点を置いており、
強力な視覚化コンポーネントとデータドリブン (データ駆動型)DOM 操作手法の組み合わせにより、
特定のフレームワークに縛られることなく、モダンブラウザの性能をフルに 引き出すことができます。

データの視覚化を考える際、使いこなせると幸せになれそうなライブラリです。
公式のギャラリーを見るだけでも楽しいですので、一度見てみてください。 D3.js Gallery

チュートリアルの途中まで

以前、少しだけチュートリアルを進めていたのですが、記事にはしていなかったので、
今回記事としています。

チュートリアルを少し進めるだけで、比較的に簡単に、このようなグラフらしきものと円なんかが出力できたりします。

f:id:lisia:20140417031139p:plain

var dataset = [];
var h = 50;
var w = 500;
for(var i = 0; i < 25; i++){
  var newNumber = Math.random() * 25;
  dataset.push(newNumber);
}

d3.select("body").selectAll("div")
  .data(dataset).enter().append("div").attr("class", "bar")
  .style("height", function(d){
    var barHeight = d * 5;
    return barHeight + "px";
  });

var svg = d3.select("body").append("svg");
svg.attr("width", w).attr("height", h);

var circles = svg.selectAll("circle").data(dataset).enter().append("circle");
circles.attr("cx", function(d, i){
  return (i * 50) + 25;
}).attr("cy", h/2)
  .attr("r", function(d){
    return d;
  });

書いているjsのコードはこれだけです。 D3.jsのコードを綺麗に書けるようにもならないといけないです。これは汚すぎて読み辛い。
ちょっと各部分が何をしているのかは、記憶が曖昧なので、今回は省略しますが、
これから少しずつ覚えていきたいと思います。

データの視覚化

データを視覚化することは楽しいです。
単純にDBにデータ登録、編集、削除だけよりも、目に見えるというのはモチベーションも上がりますたぶん。

Vim

最近はVImでjazzが聴けるようになったので、作業が捗りそうです!
この話はまたそのうち。

OpenLayers3を触ってみる

お久しぶりの投稿です。
めちゃくちゃサボっておりました。
さて、今回のネタは地図です。

地図といえば

Google Maps APIなんかを使えば、比較的容易に地図を使ったアプリの作成が可能ですね。
あとは、好みに合わせてYahooやBingなんかもあります。

Google Mapsは便利ですが、ある一定ラインを超えると、課金対象となってしまいます。
怖いですね。
無料で使えるものはないのか…。

OpenLayers3

A high-performance, feature-packed library for all your mapping needs.

OpenLayers2を一から書き直した物だそうです。
OpenLayers3
OpenLayers3 example
exampleが豊富ですし、組み合わせで大体のことができそうですね!
exampleのanimationとか、ゲームとかでありそうな動きです。

Quick Start

Quick Startがサイトにあるので、そのコードでどうなるか試してみます。
script部分のみぬき出し。全部はサイト参照。

var map = new ol.Map({
  target: 'map',
  layers:[
    new ol.layer.Tile({
      source: new ol.source.MapQuest({layer: 'sat'})
    })
  ],
  view: new ol.View2D({
    center: ol.proj.transform([37.41, 8.82], 'EPSG:4326','EPSG:3857'),
    zoom: 4
  })
});

target:'map':地図を表示する場所の指定になります。
<div id='hoge'>なら、target:'hoge'といったような感じです。

layers:[new ol.layer.Tile({}):表示する地図のタイル指定ですね。
source:new ol.source.MapQuest({layer:'sat'}):タイルのソース指定でしょうか?

center:ol.proj.transform(....):表示した時の中心の指定ですね。
transformは座標の変換です。
zoomは言う必要もなく、ズームレベルの指定です。

表示してみる

f:id:lisia:20140310232233p:plain

このように衛生地図が簡単に表示できました。 地図の表示はすごく簡単!

終わりに

久しぶりの投稿でしたが、テスト投稿でもありました。
Markdown記法を覚えると良いと教えていただいたこともあり、Markdownを少し使いながら書いてみました。
覚えるまで時間がかかりそうだな。。。

またOpenLayers3について書けることがあれば、ちまちま書いてみようかと思います。
あ、Vimやらないと…。