Hatena::ブログ(Diary)

かせいさんとこ

2013-09-17

Amazon Linux AMIってなあに?


そもそもAMIって何?


Amazon Machine Imageの略

Amazon EC2で動作する仮想マシンのインスタンスの元になるもの


Amazon Linux AMIって?


Amazonが独自に開発しているLinuxディストリビューション

Red Hat Enterprise をベースにしているらしい


Amazon Linux AMIの特徴って?


  • 最初からAWS連携する為のパッケージが組み込まれている
    • cloud-init(初回立ち上げ時に自動的に指定のコマンドを実行させて、初期設定を自動化するツール)
    • AWS API ツール
  • sshの鍵交換方式でのログインのみ許可
    • rootログインを許可しない設定に最初からなっている
  • 最低限の構成
    • いらないものをインストールして居るために発生するセキュリティリスク回避
    • 軽量
  • Amazonがサポートしてくれやすい

参考


Amazon Linux AMI (EC2用 Linuxパッケージ)| アマゾン ウェブ サービス(AWS 日本語)


EC2で動作することを前提に開発されているので、EC2上で扱いやすいと

なるほど


そんな感じで

2013-09-16

AWSでインスタンスを生成して、ローカルからログインできるようにしてみる


仕事必要になったのでクッキーを秒間170万枚焼きながらやってみる


インスタンス生成


  1. https://console.aws.amazon.com/ec2/v2/homeアクセス。ログインする
  2. デフォルトでは、アメリカにインスタンスが生成されるので、変更したければ、右上の「Oregon」をクリックして、好きなエリアを選択
  3. 左のメニューから「instances」を選択
  4. インスタンス管理画面に遷移するので、「Launch Instance」ボタンをクリック
  5. インスタンス生成画面に遷移するので「Classic Wizard」を選択
  6. Amazon Linux AMI」を選択

INSTANCE DETAILS

  1. インスタンス数は 1
  2. Instance Type は今のところデフォルトに。Availability Zone は今回は1台だし特に設定せず
  3. 更に色々聞かれるけど、今のところはデフォルトのままで進む

CREATE KEY PAIR

  1. キーペア名を設定する
  2. 「Create & Download your Key Pair」をクリックして、秘密鍵をダウンロードする(〜.pem)

CONFIGURE FIREWALL

  1. 今のところは、sshでアクセスしたいだけなのでデフォルトのまま

インスタンス起動

  1. 「Launch」をクリックしてインスタンス起動!!
  2. インスタンス管理画面に遷移して、一覧に今回生成したインスタンスが表示される
    • 暫く待つと、State が running になるのでそれまで待機

IPアドレスの払い出しと紐付け


このままだと、外部からアクセスする為のIPアドレスが無いので、Elastic IP にて、IPアドレスを払いだして、インスタンスに紐付けする必要がある


  1. 左のメニューから「Elastic IPs」を選択
  2. 「Allocate New Address」を選択
    • 一覧に生成されたIPアドレスが表示される
  3. IPアドレスを選択して、「Associatae Address」を選択
    • 関連付けるインスタンスの選択画面になるので、さっき生成したインスタンスを選択

ローカル環境からアクセスしてみる


# **** は、ダウンロードした秘密鍵の名前
$ cp ~/Downloads/*****.pem ./.ssh/.
$ chmod 600 ~/.ssh/test1234.pem
# Amazon Linux AMI では、ec2-user なるアカウントが用意されている
$ ssh -i ~/.ssh/test1234.pem ec2-user@***.***.***.***


       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2013.03-release-notes/
There are 10 security update(s) out of 21 total update(s) available
Run "sudo yum update" to apply all updates.

$ ruby -v
ruby 1.8.7 (2012-10-12 patchlevel 371) [x86_64-linux]

# 特にパスワードを聞かれずにsudoできる(らしい)
$ sudo ls

まずはここまで


終了手順


インスタンスの終了
  1. 左のメニューから「instances」を選択
  2. インスタンス管理画面に遷移するので、起動中のインスタンスを選択
  3. 「Actions」から「stop」か「terminate」を選択

IPアドレスの関連外しと破棄

  1. 左のメニューから「Elastic IPs」を選択
  2. 一覧から破棄したいIPアドレスを選択
  3. 「Disassociatae Address」をクリック
  4. 「Release Address」でIPアドレスを破棄

$0.00 : 実行中のインスタンスと関連付けられている Elastic IP アドレス 
$0.005 : 実行中のインスタンスと関連付けられていない Elastic IP アドレス/時間あたり(比例計算


宿題

  • Amazon Linux AMI の利点。centOS とかとの違いを調査
  • sudo できない dev アカウントを作る
  • セキュリティアップデートしてみる
  • ruby1.9 を入れてみる
  • コンソールからインスタンスを生成してみる
  • cloud watcher で監視してみる

そんな感じで

2013-09-13

bundlerの疑問点とか色々メモ


bundlerのgemのインストール先ってどこ?


普通は、rvm等で標準で指定されている場所

bundle show ${gem}

path オプション で格納先を変更できる

bundle install --path vender/bundle

Gemfile.lockって何?


初回の bundle install で生成される

全ての開発環境運用環境で使用するgemを統一する為に使用される

bundle install した時の依存関係まで含めた、全てのgemのバージョン指定と取得先が格納されている

Gemfile.lockがあると、それ以降はそれを元に、gemがインストールされる


で、結局 Gemfile.lock はリポジトリに含めるべきなの?


中の人の談話

Clarifying the Roles of the .gemspec and Gemfile « Katz Got Your Tongue?


和訳

LangTurn: gemspecとGemfileの役割をはっきりさせておく

  • gemを開発するときは、バージョンを厳密に定義し過ぎると(様々な環境の)利用者が困ることがあるので、含めない
  • アプリを開発するときは、どの環境でも同じソースの同じGemが使えるようにするべきなので、含める

gemのインストールオプションが環境によって異なるので、その辺で困ることがあるよね。--with-mysql-dir とか

理想的にはその辺の環境も合わせるべきなのかな

環境依存のオプションがあるgemがない場合は、入れちゃって良さそう


デプロイの時の話


deploymentオプションを付けて、bundle install する

bundle install --deployment

Ruby - bundlerでの運用方法 - Qiita

bundle install --deploymentすると、vender/bundle以下にgemがインストールされる。
また、.bundle/configにBUNDLE_FROZEN="1"が追加される。
deploymentオプションをつけた場合は、Gemfile.lockを元にgemがインストールされる。
deployment付きで実行された環境で、Gemfileを書き換えて新たにgemをインストールすることはできない。


開発用のgemを本番に入れたくない

withoutオプションをつければ良いはず

bundle install --without development --deployment

Bundler: The best way to manage a Ruby application’s gems


そんな感じ

2013-09-12

Bundlerの公式のトップページを読んでみた


元記事


Bundler: The best way to manage a Ruby application’s gems


What is Bundler?


It tracks an application's code and the rubygems it needs to run, 

それは、アプリケーションコードと、rubygemsが動くのに必要もの監視するよ

  • track : たどる、監視・追跡する

so that an application will always have the exact gems (and versions) that it needs to run.

アプリケーションが、動くのに必要な的確なgem(とそのバージョン)を常備できるようにするよ

  • so that : 〜できるように
  • always have : 常備
  • exact : 的確な

Getting Started


Getting started with bundler is easy! Open a terminal window and run this command: 

bundler を始めるのは簡単だよ! ターミナルを開いて、以下のコマンド入力してね

$ gem install bundler

Specify your dependencies in a Gemfile in your project's root:

依存関係を、Gemfileに書いて、あなたのプロジェクトルートディレクトリに格納してね

  • Specify : 〜を含める
  • dependencies : 依存関係
source 'https://rubygems.org'
gem 'nokogiri'
gem 'rack', '~>1.1'
gem 'rspec', :require => 'spec'

Install all of the required gems from your specified sources: 

以下のコマンドで、あなたが書いた、望んだgemを全てインストールするよ

  • required : 望んだ
$ bundle install
$ git add Gemfile Gemfile.lock

The second command adds the Gemfile and Gemfile.lock to your repository. 

2つめのコマンドは、Gemfileと、Gemfile.lockをリポジトリに入れてるよ


This ensures that other developers on your app, as well as your deployment environment, will all use the same third-party code that you are using now. 

これは、あなたのアプリをいじる、他の開発者が、あなたの開発環境のみならず、あなたが使っている、全てのサードパーティコードを使えるようにしてくれることを確実にしてくれるよ

  • ensures : 確実にする、守る、保険を掛ける
  • as well as : 〜の前後。AだけでなくBも

Inside your app, load up the bundled environment

バンドルした環境をあなたのアプリに入れるよ

require 'rubygems'
require 'bundler/setup'

# require your gems as usual
require 'nokogiri'

訳注 : railsだとこの部分はよきにはからってくれる


Run an executable that comes with a gem in your bundle: 

あなたの bundle にある gem の実行ファイルを起動させる

$ bundle exec rspec spec/models
  • executable : 実行ファイル

In some cases, running executables without bundle exec may work, 

往々にして、bundle exec なしでも、コマンドが実行できるよ

  • In some cases : 往々にして

if the executable happens to be installed in your system and does not pull in any gems that conflict with your bundle.

あなたのシステムに入っている gem と、bundle に入っている gem がコンフリクトしていないのが理由だよ


However, this is unreliable and is the source of considerable pain. 

けど、それは信頼ならなくて、多くの面倒の種となるよ

  • source of : 原因
  • considerable : かなりの
  • pain : 痛み、苦労、深い
  • However : けれども、しかしながら
  • unreliable : 信頼ならない、頼りにならない

Even if it looks like it works, it may not work in the future or on another machine. 

たとえ今いい感じに動いているように見えても、将来や別のマシンで動くとは限らないよ

  • Even : たとえ〜でも

Finally, if you want a way to get a shortcut to gems in your bundle:

最後に、gemコマンドのショートカットが欲しい時

$ bundle install --binstubs
$ bin/rspec spec/models

The executables installed into bin are scoped to the bundle, and will always work.

binディレクトリに、bundleのgemコマンドがインストールされるよ。

それはいつでも動作するよ


そんな感じ

2013-07-14

VimScriptざっくりチュートリアル(バッファ編集編)


やっとこさ、エディタのスクリプトらしい話


行操作


行取得

echo getline('.')   |" カレントバッファのカレント行を取得
echo getline(4)     |" カレントバッファの4行目を取得
echo getline(4,8)   |" カレントバッファの4〜8行目をリストで取得
echo getline(0,'$') |" 先頭〜行末まで取得

更新

call setline('.', 'abc')          |" カレントバッファのカレント行を 'abc' に変更
call setline(4,   'abc')          |" カレントバッファの4行目を 'abc' に変更
call setline('.', ['abc', 'def']) |" カレントバッファの4〜5行目を配列の内容に変更

行追加
call append('.', 'abc')          |" カレントバッファの下行に、'abc' を追加
call append('.', ['abc', 'def']) |" カレントバッファの4〜5行目を配列の内容に変更

行削除

直接行を削除する関数は無いらしい

delete コマンドがあるのでそれを使う


:4,5delete " 4〜5行目を削除
:.delete   " 現在行を削除

" 変数を使って3行目を削除
:let len = 3
:execute len . "delete" |" execute は、文字列をExコマンドとして実行するExコマンド

行検索

echo search("text") |" 引数(正規表現)にヒットする行を返す

バッファ操作


バッファ検索
echo bufnr('bufname')     | " 対象のバッファ名のバッファ番号を検索。なければ -1
echo bufnr("%")           | " カレントバッファのバッファ番号を取得
echo bufname(bufnum)      | " 対象のバッファ番号のバッファ名を取得
echo bufexists(bufnum)    | " 対象のバッファ番号が存在するか確認

echo bufwinnr(buf_number) | " 対象のバッファ番号が存在するウィンドウ番号を取得(ウィンドウを分割している場合に使用する)

バッファ作成

:enew `=bufname` |" 空のバッファを作成(バッファ名は、変数 bufname)して、カレントウインドウをこのバッファに変更
:new `=bufname`  |" ウィンドウを分割した後に enew を実行
:10new           |" 新規バッファをウインドウを分割して作成(高さは10行)

ウインドウ、バッファ移動
:execute bufnr(bufname).'buffer'             | " カレントウインドウを、変数 bufname に格納しているバッファに変更
                                               " :Nbuffer で、カレントバッファを、N 番のバッファに変更する
:execute bufwinnr(bufnr(bufname)).'wincmd w' | " 変数 bufname を開いているウィンドウに移動
                                               " :Nwincmd w で、N 番のウィンドウに移動

バッファの属性を操作

:setlocal は、カレントバッファに対して、オプションを設定する

スクリプトの実行結果を表示する領域によく設定するオプションの例


:setlocal buftype=nowrite     |"バッファの内容を保存しない
:setlocal noswapfile          |"スワップファイルを作成しない
:setlocal bufhidden=wipe      |"バッファがウィンドウ内から表示されなくなったら削除
:setlocal nonumber            |"行番号を表示しない
:setlocal nowrap              |"ラップしない
:setlocal nocursorline        |"カーソル行をハイライトしない
:setlocal nocursorcolumn      |"カーソル列をハイライトしない
:setlocal readonly            |"読み込み専用

カレントウインドウ、カレントバッファについて


似て非なる概念


カレントウインドウ

  • 現在操作対象になっているウインドウ
  • ウインドウは通常1つなので、表示されているウインドウ = カレントウインドウ
    • sp コマンド等でウインドウが複数になる場合に、必要になる概念

カレントバッファ

  • 現在操作対象になっているバッファ。

2013-07-13

Redcarpet を使って ruby で Markdown テキストを書いてみる


Redcarpet


https://github.com/vmg/redcarpet/


インストール


rvmsudo gem install redcarpet

試してみる


require 'rubygems'
require 'redcarpet'

markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :fenced_code_blocks => true)
puts markdown.render(DATA.read)

__END__
# h1

## h2

### h3

普通の文章は、p タグ囲みになる
普通の文章は、p タグ囲みになる

一行離すと別の p タグ

- リスト1
- リスト2
- リスト3
- リスト4

> 引用

<!-- リンク -->
[google](http://google.com)

![かせいさんのプロフィール画像](https://si0.twimg.com/profile_images/21140552/1785175_1374585433.jpg)

```
var test = function(){
  alert("test");
}
```

結果出力


<h1>h1</h1>

<h2>h2</h2>

<h3>h3</h3>

<p>普通の文章は、p タグ囲みになる
普通の文章は、p タグ囲みになる</p>

<p>一行離すと別の p タグ</p>

<ul>
<li>リスト1</li>
<li>リスト2</li>
<li>リスト3</li>
<li>リスト4</li>
</ul>

<blockquote>
<p>引用</p>
</blockquote>

<!-- リンク -->

<p><a href="http://google.com">google</a></p>

<p><img src="https://si0.twimg.com/profile_images/21140552/1785175_1374585433.jpg" alt="かせいさんのプロフィール画像"></p>

<pre><code>var test = function(){
  alert(&quot;test&quot;);
}
</code></pre>

参考リンク





そんなかんじ

2013-07-11

VimScriptざっくりチュートリアル(関数編)


関数宣言


:function Func(flg) " グローバルスコープの場合、関数名はアルファベットの大文字で始まる
:  if a:flg         " 引数の参照は、a:引数名
:    echo "true"
:  else
:    return "false" |" 戻り値を返したい場合、return コマンドを使う
:  endif
:endfunction


関数の呼び出し


:call Func(0)       " call コマンドは、渡された関数を実行するコマンド。この場合、false が返る
:let test = Func(1) " 戻り値を変数に格納したい場合
:echo Func(1)       " 戻り値をそのまま echo したい場合

関数の再定義


.vimrc に関数を定義した後で、:source .vimrc とかして、一度定義した関数が再定義されるとエラーになる

function! で、関数の再定義ができるので、.vimrc に関数を書く場合は、何度も呼ばれることを想定して function! で関数を定義したほうが良い


:function! Func(flg)
  ...
:endfunction

ローカル関数


関数は、スクリプトローカルのみ指定できる


:function! s:Func(flg)
  ...
:endfunction

FuncRef


関数ポインタ的な感じに関数への参照を変数に格納できる


:let FuncRef = function('Func') " グローバルスコープの場合、FuncRef 変数も大文字で始まる必要がある
:call FuncRef(0)

例外処理


VimScriptは、エラーが発生しても処理を止めない

なので、エラーが発生した時、処理を飛ばしたい場合は、try, catch 構文を使うか、abort 識別が必要



:function! ExceptionTest()
:  call aaaa() " 未定義の関数
:  return "???"
:endfunction
:
:echo ExceptionTest() |" エラーメッセージの後に、"???" が表示される


try, catch 構文

:function! TryCatchTest()
:  try
:    call aaaa() " 未定義の関数
:    return "???"
:  catch
:    " 例外処理
:  finally
:    return "finally"
:  endtry
:endfunction
:
:echo TryCatchTest() |" "finally" が表示される

abort 識別

関数宣言に abort 識別を付けることで、エラーが発生した時に、即時に関数を抜けるようにできる


:function! AboutTest() abort
:  call aaaa() " 未定義の関数
:  return "???"
:endfunction
:
:echo AboutTest() |" エラーメッセージが表示されて、-1 が返る

関数の範囲指定呼び出しについて


VimScriptでは行を加工する関数、コマンドは、範囲指定をして呼び出すことが出来る

範囲指定をした場合は、範囲の行を1行ずつカレントとして関数が呼び出される


例えばこんなテキストがあった場合


1
2
3
4
5

こんな関数を用意する


:function! Increment() |" カレント行を数値と見なして、+1 する関数
:  let line = str2nr(getline('.'), 10)   |" カレント行の取得(後述)
:  let line += 1
:  call setline('.', printf("%d", line)) |" カレント行の更新(後述)
:endfunction

で、以下のコマンドを実行する


:%call Increment() " 1行目〜最後行に対して、Increment を実行


すると、各行に対して、Increment が実行されて、以下のようになる



2
3
4
5
6

行指定子

行や範囲を指定する場合、以下の文字が使える

  • 数値 : 1から始まる行番号(0の場合大抵のコマンドは行頭と解釈する)
  • . : カレント行
  • $ : 行末
  • % : 行頭〜行末

:" delete は指定した行 or 範囲を削除するコマンド
:3delete    " 3行目を削除
:4,10delete " 4〜10行目を削除
:.,$delete  " カレント行〜行末まで削除
:%delete    " 全部削除


関数の range 識別について


range 識別をつけることで、範囲指定されることを前提とした関数を用意することができる


:function! Increment2() range
:  for n in range(a:firstline, a:lastline) " a:firstline, a:lastline に範囲指定時の行番号が格納される
:    let line = str2nr(getline(n), 10)
:    let line += 1
:    call setline(n, printf("%d", line))
:  endfor
:endfunction

上の例の場合、挙動は Increment とおんなじだけど、関数呼び出しが1回になるので、速度面や、特定の行を保持して、他の行に何かしたい時とかに便利

2013-07-10

VimScriptざっくりチュートリアル(if文と真偽値編)


if 文


if test == 1
  echo 'true'
else
  ehco 'false'
endif

比較演算子
  • ==, !=, >, <, >=, <=, =~, !~
  • is: 同一のインスタンス
  • isnot: 異なるインスタンス
  • ==#, !=#, =~#, !~#
    • ignorecase に関わらず大文字/小文字考慮
  • ==?, !=?, =~?, !~?
    • ignorecase に関わらず大文字/小文字無視
  • 後、! で論理否定ができる


and, or

&& と ||


真偽値について

真偽値型は無くて、数値の 0 とそれ以外で真偽を判定する


  • 0 : 偽
  • 0以外 : 真

文字列を真偽値に使った場合、数値以外であった場合は、0 に変換される


  • "0" : 偽
  • "" : 偽
  • "9999" : 真
  • "true" : 偽

三項演算子


echo test==1 ? "true" : "false"

2013-07-09

VimScriptざっくりチュートリアル(データ型)


まずはここを読む


help eval

データ型の確認方法

let test = 1
echo type(test)

以下の6種類が数値で返ってくる



数値型


32bit or 64bit の符号付き整数

  • 32bit なら、−2147483648 〜 2147483647

" 16進
echo 0x10

" 10進
echo 16

" 8進
echo 020

" サイズ越えの場合 -1 を返す
echo 999999999999999999999999999999999999999999999999

数値演算

" 四則演算
echo (1+1)-1*10/10
" 余り
echo 100%3
" 整数型の割り算は整数型を返す
echo 10/3 "| -> 3
" 0 除算すると 0 を返す
echo 1/0
"複合演算子は、+= と、-= だけ
let test = 0
let test += 1
echo test-=1

数値⇔文字列

文字列 -> 数値

" それぞれ 16 を返す
echo str2nr("0x10", 16)
echo str2nr("16", 10)
echo str2nr("020", 8)

" 123 を返す
echo str2nr("123abc", 10)

" 0 を返す
echo str2nr("abc123", 10)

数値 -> 文字列

echo printf("0x%x",16) | " -> "0x10"
echo printf("%d",16)   | " -> "16"
echo printf("0%o",16)  | " -> "020"
echo printf("%02d",8)  | " ->" "08"

文字列型


宣言
let test = "123"
let test = '123'

" ダブルクォーテーション文字列の場合、特殊文字を入力できる
let test = "改行:\n タブ:\t バックスラッシュ:\\ 等..."


" ダブルクォーテーション文字列中にダブルクォーテーションを入れたい場合
let test = "\"123\""
let test = '"123"'

" シングルクォーテーション文字列中にシングルクォーテーションを入れたい場合
let test = 'test''test'

ヒアドキュメントは無い


文字列操作

" 結合
echo 'abc'. '123'
" バイト数取得
echo strlen('abc')                       |" -> 3
echo strlen('2バイト文字')               |" -> 16
" 正規表現検索
echo stridx('123abc', 'bc')              |" -> indexが返る(ない場合は-1)
" 正規表現置換
echo substitute('123abc', 'a', 'z', 'g') |" -> 123zbc

正規表現については、後述


Funcref型


関数の項で解説


リスト型


宣言
let test = [1,'abc',[1,2,3]]

参照
echo test[0]                 " 要素の参照
echo test[99]                " 範囲外を参照するとエラー
" get 関数を使用すると、範囲外の場合 0 を返す
echo get(test, 99)
" デフォルト値も定義可能
echo get(test, 99, 'NONE')
" 部分リスト
echo test[1:2]
echo test[1:]  " 1〜末尾まで
echo test[:1]  " 先頭〜1まで

リスト操作
" 要素を変更したい時は let を使う
let test[1] = "123"

" 要素数
echo len(test)

" 空であるか?
echo empty(test)
echo empty([])

echo add(test, 'add')    | " 末尾に追加
echo insert(test, 'add') | " 先頭に追加
echo remove(test, -1)    | " 末尾を削除(remove の戻り値は消した要素)
echo remove(test, 0)     | " 先頭を削除

" ソート
echo sort(test)

" split/join
" -> "1\t2\t3\t4"
echo join(split('1,2,3,4', ','), "\t")

配列の繰り返し(for,map)

for i in [1,2,3,4]
  echo i
  unlet i " i にいろんなデータ型が来るとエラーになるので毎回 unlet する必要がある
endfor

echo map([1,2,3,4], '1+v:val')

第1引数の各要素を、第2引数の文字列をevalした結果に置き換えた結果を返す

v:val は、要素の値を格納する組み込み変数


辞書型


hashみたいなの


宣言
" キーは数値も定義できるけど、文字列に置換される
let hash = {'key1': 'val1', 2: 'val2'}

参照
echo hash['key1']
" キーがアルファベット、数値、アンダースコアだけの場合、以下でも参照できる
echo hash.key1

要素の再定義、追加
let hash.key2 = 'val'
let hash.key3 = 'val3'
echo hash

辞書操作
echo keys(hash)  | " キーをリストに
echo keys(hash)  | " 値をリストに
echo items(hash) | " 辞書をリストのリストに変換
" items を使って、辞書のループ
for [key, value] in items(hash)
 echo key . ': ' . value
endfor
echo has_key(hash, 'key1') | " 存在確認
echo remove(hash, 'key1')  | " 削除

不動小数点数型


int と同じく、64 or 32bit


let test = 0.1
let test = 1.0e3 " 指数もOK

" 数値型で割り算すると戻り値は数値型
echo 1/10
" 浮動小数点数型で割り算すれば良い
echo 1.0/10

異なる型の変数への再代入


文字列型 ⇔ 数値型は交互に再代入ができる


let test = 1
let test = "abc"
let test = 1


それ以外は例外になる

  • 古いvimでは、文字列型と数値型しか無かったのが理由???

let test = 1
let test = ["abc", "def"] |" 変数の型が一致しません

" 一度変数を削除する必要がある
unlet test
let test = ["abc", "def"] |" OK


異なる型の配列を for する時に大事


for i in [1,'test',0.1,[1,2,3 # 毎回内部でletされている
  echo i
  unlet i
endfor

2013-07-08

VimScriptざっくりチュートリアル(初回編)


10年近く Vim 使ってきていまだに習得していないのでそろそろ


目的とゴール


Vimのプラグインを書けるようになりたい!


ターゲット


数年vim使ってて、プラグイン入れたり、.vimrc いじったりしてるけど、

VimScriptについては敬遠してる人


VimScriptって何?


Vimの設定を記述する為の独自言語

実態はExコマンドの羅列で、 if 等の制御構文も全てがExコマンド


何が出来るの?


Exコマンドでできること全部。引いては Vim でできること、設定できること全部


詳しくは以下

:help ex-cmd-index

ざっくり言えば、vimの機能拡張や、テキストの編集が出来るよ! で良いのかな?


Exコマンドって何?


Vimのコマンドラインモードで実行できるコマンド群のこと

Vim起動して、<Esc> 押して、以下のように入力すれば実行できる

:echo "hello!"

何でExコマンドって言うかというと、Vimの元ネタのラインエディタ ex で使えたコマンドが元になっているから


【vimの歴史】
ex(ラインエディタ) -> vi(exの機能を内包したテキストエディタ) -> Vim(viの改良版clone)

ちなみに、vi が入力モードとコマンドモードに分かれているのも、コマンドモードでは、ex の機能。入力モードでは、vi の機能という分け方をしたため


ラインエディタって?

モニターではなく1行づつコマンドの結果をプリントするテレタイプ端末というもので実行することを前提としたエディタ

なので、そういう命令を打たない限り全体を表示しないし、各種コマンドを入力することで、テキストの編集を行うエディタ



VimScriptのリファレンスとかあるの?


help usr_41


hello world


:echo "hello world"

echo は、引数の文字列を表示する Exコマンド


コメント


:echo " ダブルクォーテーションはコメント
:echo "test" " 引用符が前にあったり、いくつかのコマンドの後ろにはコメントは付けられない
:echo "test" |" こうすればどのコマンドの後ろにもコメント可(パイプは、コマンドを区切って次のコマンドに行く)

ファイルからVimScriptを実行


:source 01.vim " 拡張子は vim

変数宣言のやり方


:let test = 1   " グローバル変数(デフォルト)
:let g:test = 1 " グローバル変数(明示的)
:let s:test = 1 " スクリプトローカル変数(1スクリプトファイル内でのみ有効)
:let l:test = 1 " 関数内ローカル変数(関数内のデフォルト)
:let b:test = 1 " バッファローカル変数
:let w:test = 1 " ウインドウローカル変数
:let t:test = 1 " タブローカル変数

上にあるバッファ、ウインドウ、タブって?

  • バッファ : ファイルを編集する仮想的な領域。ファイルを開くとバッファに格納される
  • ウインドウ : バッファを編集する表示領域。:sp で分割すると2つになる
  • タブ : ウィンドウの配置の状態を保持する領域。

わかりにくいので実例

:enew    " 新規にバッファを開く
:sp      " ウインドウを分割
:tabedit " 新規にタブを生成
:tabNext " 次のタブに移動(上で分割したウィンドウが保持される)
:ls      " バッファの一覧
:tabs    " タブの一覧

変数の削除

:unlet test  " test が宣言されていないとエラー
:unlet! test " test が宣言されていなくても OK

変数の存在確認

" existsは、exコマンドではなく関数。
" echo 関数 で、関数の戻り値を echo する
" 関数については後述
:echo exists("test") |" 0:なし 1:あり

変数の再代入

:let test = 1
:let test = 2 " もう一度代入する場合は、毎回 let が必要

今日はここまで