よんちゅBlog

― このブログは自分用のメモや日々の問題などを共有するためのものです ―

20121005185841 お知らせ:  2013/07/17 ブログデザインをリニューアルしました。

Macでmarkdownを書くときの環境

markdownを書く環境がほぼ固定されたので記録しておく。

基本は以下のページを踏襲
ぼくのかんがえたさいきょうの Markdown かんきょう - モトクロスとプログラムと粉砕骨折と

使用するアプリはMarked

Marked 1.4(¥350)App
カテゴリ: 仕事効率化, ユーティリティ
販売元: Brett Terpstra - Brett Terpstra(サイズ: 7.1 MB)

このアプリにはエディタの機能はついていませんが、そこがこのアプリの良い所。
どんなエディタとも簡単に連携することができます。
エディタはやっぱり使い慣れたものを使用したいですからね。

f:id:yonchu:20121112210131p:plain

使い方はいたって簡単
markdownのファイルをMarkedで開いて(ドラッグ&ドロップでもOK)、好きなエディタでファイルを編集するだけ
編集したファイルを保存すると自動的にMarked側でも更新が反映されるのですぐに結果が分かります。
変更箇所にはマークも表示されます。

また、最前面表示の機能もあり、更新時にページ先頭に戻されるようなこともなく表示位置も保持されます。
とても便利です。

以下のような設定がおすすです。

f:id:yonchu:20121112210830p:plain

また、デフォルトでGithubの書式にも対応しています。
特に Github Flavored Markdown に対応しているのが非常にうれしいところ。
(ただしちょっと重いです)
Github用の設定にするには以下のようにします。

f:id:yonchu:20121112210839p:plain
f:id:yonchu:20121112210850p:plain

続いてエディタの紹介
使用するエディタは基本的になんでも良いですが、特に親和性の高いエディタを紹介

CotEditor

ちょっと設定を追加しなければなりませんが、非常にシンプルで使い勝手が良いのでお勧めです。
追加する設定は2つ

1.markdown用シンタックス定義の追加
デフォルトではシンタックス・カラーリングに対応していないので定義を追加します。

定義ファイルは以下から入手できます。
CotEditor用シンタックス定義 -Goodies -Works //ヴォルフロッシュ

使用方法はCotEditorメニューから読み込むだけ。詳しい方法は同ページの一番上に書かれてます。

2.Markedの起動スクリプトを登録
手動でMarkedを起動してもいいですが、起動スクリプトをCotEditorに登録することでショートカットキー(Command + R)一発で起動できるようになります。

スクリプトは以下のページから拝借。
Marked 1.3.3 -Blog //ヴォルフロッシュ

Command + R でMarkedを起動するスクリプトとメニューに "Preview Markdown" という項目を追加するスクリプトがあります。
せっかくなので両方追加すると良いでしょう。

使用方法はスクリプトメニューからスクリプトフォルダを開くとができるので、そのフォルダにスクリプトファイルを置くだけ

f:id:yonchu:20121112211046p:plain
f:id:yonchu:20121112211104p:plain

vim

エディタといえばやっぱりvim
でもvimなんて知らないよって方は読み飛ばして下さい。
vimユーザに今更私などが細かい説明をしても仕方ないので設定を抜粋

キーマッピングの設定
vimで開いていファイルをMarkedで開く (om)
(redrawを入れているのは、Markedで開くとvimの描画が崩れることがあるためです)

if has("mac")
  " markdownをMarked.appで開く
  :nnoremap <leader>om :silent !open -a Marked.app '%:p'<cr>:redraw!<cr>
endif

いつもこんな感じで作業してます。

f:id:yonchu:20121112212256p:plain

Gihub

先の通り、MarkedはGithubの書式にも対応していて、表示もGithubと同じようにして見ることができます。

しかし、コミット前に最終確認として一度はちゃんと本家のGithubで確認した方が安心です。
この点に関しては以下のページがすごく参考になります。

脱GitHub初心者を目指す人のREADMEマークダウン使いこなし術 | ゆっくりと…

オススメはGihubのWikiを使った確認方法
適当なリポジトリを1つ作っておいて、そこでWikiを作り、編集画面のプレビュー表示で確認を行います。
プレビューを表示したいだけなので、保存する必要もなく、同じWikiを使いまわすことができます。

Github本家以外だと以下のページでも確認ができるのでオススメです。
Github Preview


以上、最近の私のMarkdown環境でした。

gitリポジトリの状態をざっくり表示する

gitリポジトリ下での作業はじめにいつも実行しているコマンド

実行イメージはこんな感じ

リモートリポジトリの更新状況もぱっと見て分かります。
(fetch済みのローカルoriginの更新状況ではなく、リモートの更新状況が分かります)

submoduleが古くなっていないかも確認できます。

スクリプトはこんな感じ

gitで変更のあったファイルを簡単に開ける git-edit について

とにかく目的のファイルにすぐにアクセスしたかった。
ただそれだけ。

コードはGithubにあります。
github - yonchu/git-edit

インストール方法:

  • git-edit をPATHの通った所に置くだけ
  • zshを使用している場合は _git-edit をfpathの通った所に置いて下さい。

 (※ fpath は echo "$fpath" などで確認して下さい)

どういうコマンドなのか

変更のあったファイルをエディタで開くための gitサブコマンドです。

コマンド形式は以下

$ git edit [commit] [file ...]

こんな感じで使います。

$ git edit
$ git edit HEAD
$ git edit hoge
$ git edit *
$ git edit *.txt
$ git edit HEAD^ dir/*

コミットの指定はハッシュ値でも構いません。

zshの補完機能との連携

今回一番やりたかったこと。

git-edit単体でも、まあそれなりに使えますがzshと併用することで格段に使い勝手がよくなる…と思います。たぶん

こんな感じで変更のあったファイル名が補完できます。

$ git edit <TAB>
Editable Files
xxxx.txt    yyyy.sh    zzzz.c
Deleted Files
hoge.txt

$ git edit HEAD <TAB>
Commit Hash:62c91ef1f56d89b3328fa4aeae4bb52b579ad679
Editable Files
aaaa.txt    bbbb.sh    cccc.c
Deleted Files
fuga.txt
zshの設定について

zshの設定によっては上記とは違った表示になるかも。

補完候補の一覧表示はデフォルトでも有効になっているはずだけど、説明項目(ラベル)はデフォルトでは表示されないはず。

説明項目(ラベル)を表示させるには "~/.zshrc" 等に以下のように設定します。

zstyle ':completion:*' group-name ''
zstyle ':completion:*:descriptions' format '%B%d%b'

%B はボールド(太字)の有効、%b はボールドの無効 (不要なら消して下さい)
%F{color name} と %f で色を変更することもできます。
%d が説明項目(ラベル)の指定

注意事項

  • submodule の変更は無視されます。そこまではちょっと…
  • ファイル名をリネームした場合はリネーム前のファイル名が Deleted FIles に表示されます
  • HEADなどのコミットオブジェクトは補完されません。これはそのうち対応するかも

以上

ちょっと説明がざっくりし過ぎているが、そんな需要があるとも思えないのでよしとしよう。

bash/zshで16色(ANSI カラーコード)と256色のカラーパレットを表示

bashzshでカラーパレットを表示するスクリプト

なんだか定期的に色を変えたくなる…

プロンプトの色やtmux/screenのステータスバーの色変更時のお共に。

yonchu/shell-color-pallet · GitHub

256色カラーパレットを表示

こんな感じに表示されます。
f:id:yonchu:20121020045036p:plain

ANSI のカラーコード(16色)を表示

こんな感じに表示されます。
f:id:yonchu:20121019042417p:plain

スクリプトのコメントにエスケープシーケンスの説明を記載しているので、設定するときに参照すると良いかと思います。

【Mac】zshをサブシェルで起動するとPATHがおかしくなる

どういう状態かというと。

★サブシェル起動前
$ printpath    ← $PATHを表示
/Users/yonchu/.pythonbrew/bin
/Users/yonchu/.rvm/gems/ruby-1.9.3-p286/bin
/Users/yonchu/.rvm/gems/ruby-1.9.3-p286@global/bin
/Users/yonchu/.rvm/rubies/ruby-1.9.3-p286/bin
/Users/yonchu/.rvm/bin
/usr/local/share/python
/usr/local/mysql/bin
/Library/Java/Home/bin
/Users/yonchu/bin
/Users/yonchu/dotfiles/bin
/usr/local/bin
/usr/local/sbin
/usr/local/share
/usr/bin
/bin
/usr/sbin
/sbin
/usr/X11/bin
$
$ zsh    ← サブシェルとして zsh を起動
$
★サブシェル起動後
$ printpath    ← $PATHを表示
/Users/yonchu/.pythonbrew/bin
/Users/yonchu/.rvm/gems/ruby-1.9.3-p286/bin
/Users/yonchu/.rvm/gems/ruby-1.9.3-p286@global/bin
/Users/yonchu/.rvm/rubies/ruby-1.9.3-p286/bin
/Users/yonchu/.rvm/bin
/usr/bin
/bin
/usr/sbin
/sbin
/usr/local/bin
/usr/X11/bin
/usr/local/share/python
/usr/local/mysql/bin
/Library/Java/Home/bin
/Users/yonchu/bin
/Users/yonchu/dotfiles/bin
/usr/local/sbin
/usr/local/share

(※ printpathはPATHを整形して出力してるだけです)

という感じです。
意味分かりませんね。

原因

何が問題なのかというと、/etc/zshenv に致命的な誤りがありました。
普段ユーザが触れるようなファイルではないので、え?と思うかもしれません。

この問題の原因に対して、homebrewのzshで以下のような注意書きがありました。

$ brew info zsh
zsh: stable 5.0.0
http://www.zsh.org/
Depends on: gdbm, pcre
/usr/local/Cellar/zsh/5.0.0 (956 files, 9.1M) *
https://github.com/mxcl/homebrew/commits/master/Library/Formula/zsh.rb
==> Options
--disable-etcdir
        Disable the reading of Zsh rc files in /etc
==> Caveats
To use this build of Zsh as your login shell, add it to /etc/shells.

If you have administrator privileges, you must fix an Apple miss
configuration in Mac OS X 10.7 Lion by renaming /etc/zshenv to
/etc/zprofile, or Zsh will have the wrong PATH when executed
non-interactively by scripts.

Alternatively, install Zsh with /etc disabled:

  brew install --disable-etcdir zsh

homebrewでzshを入れている方はこの注意書きに気づいたでしょうか。
自分は全然気づきませんでした…

対処方法

説明に書かれている通り、対処方法は2種類

  • /etc/zshenv を /etc/zprofile にリネームする
  • brew install --disable-etcdir zsh で/etc 無効版をインストールする

今回私は1を採用しました。
(1の方が今後気にすることが少なそうなので)

$ ls -l /etc/zshenv
-r--r--r--   1 root wheel  126 2012-04-06 03:56 zshenv
$ sudo mv /etc/zshenv /etc/zprofile
$ ls -l /etc/zprofile
-r--r--r--   1 root wheel  126 2012-04-06 03:56 zprofile
以下、自分用のメモを兼ねて説明

まず、zsh起動時に読み込まれる設定ファイルの読み込み順序についてです。
zshの設定ファイルは種類が多いので非常に分かりづらいです。

zshを起動する方法によって以下のように分けられます。

ログインシェルとして起動した場合

 /etc/zshenv
 $ZDOTDIR/.zshenv
 /etc/zprofile
 $ZDOTDIR/.zprofile
 /etc/zshrc
 $ZDOTDIR/.zshrc
 /etc/zlogin
 $ZDOTDIRA/.zlogin

インタラクティブシェル(対話シェル)として起動した場合
(GUIターミナル/ssh/サブシェルなど)
(※ MacのGUIターミナルはログインシェル扱いみたいです)

 /etc/zshenv
 $ZDOTDIR/.zshenv
 /etc/zshrc
 $ZDOTDIR/.zshrc

ノンインタラクティブシェル(非対話シェル)として起動した場合
(シェルスクリプト/リモートシェルなど)

 /etc/zshenv
 $ZDOTDIR/.zshenv

※ $ZDOTDIRを設定していない場合は、$HOMEになります。

今回問題となったのはサブシェルなので2番目のケースですね。

続いて問題の /etc/zshenv の中身です。

$ cat /etc/zshenv
# system-wide environment settings for zsh(1)
if [ -x /usr/libexec/path_helper ]; then
        eval `/usr/libexec/path_helper -s`
fi

path_helper というコマンドを起動しているだけのようです。

path_helper というのは man によると、

DESCRIPTION
The path_helper utility reads the contents of the files in the directories /etc/paths.d and /etc/manpaths.d and appends their contents to the PATH and MANPATH
     environment variables respectively.  (The MANPATH environment variable will not be modified unless it is already set in the environment.)

     Files in these directories should contain one path element per line.

     Prior to reading these directories, default PATH and MANPATH values are obtained from the files /etc/paths and /etc/manpaths respectively.

     Options:

     -c      Generate C-shell commands on stdout.  This is the default if SHELL ends with "csh".

     -s      Generate Bourne shell commands on stdout.  This is the default if SHELL does not end with "csh".

ということだそうです。

要するにデフォルトのPATHを設定しますってことですね。
デフォルトで設定されるパスは、/etc/paths に書かれているパスと /etc/paths.d 配下にあるファイルの中に書かれているパスです。

私のMac(OS X 10.7)では以下のようなパスが書かれていました。

$ cat /etc/paths
/usr/bin
/bin
/usr/sbin
/sbin
/usr/local/bin

$ cat /etc/paths.d/*
/usr/X11/bin

ここで私のPATH設定環境について補足しておくと、
基本的に、PATHは ZDOTDIR/.zprofile で設定しています。
しかし、一部 pythonbrew や rvm などのPATH設定処理を含んでいるスクリプトを $ZDOTDIR/.zshrc で読み込んでいます。

サブシェル起動時のPATH設定の流れ

以上を踏まえて、サブシェル起動時にどのようにPATHが設定されているかを考えてみます。
おそらく以下のような流れになっていると思われます。

  1. /etc/zshenv がデフォルトパスを設定
  2. 親シェルで元々設定されていたPATHを設定(環境変数の引き継ぎ)
  3. ZDOTDIR/.zshrc に書かれているPATHを設定

ここで1つ注意すべき点があります。
PATHを設定する際、重複したパスが存在すると"左"に書かれているパスが優先して設定され、"右"にあるパスは削除されます。
この重複パスを削除する機能は、通常 "typeset -U path" を行なっていないと有効になりませんが、2番目の親シェルから引き継いだパスを設定する際は、"typeset -U" を行なっていなくても重複パスが削除されるようになっています。

この重複削除によって、一見なぜあんな並び方になったのかが分かりづらい状態になってしまったわけです。

また、.zprofile や .zlogin を使用せず、PATH設定を全て .zshrc で行なっている場合は、サブシェル起動時でも .zshrc でPATHを上書きできるため問題が表面化しづらくなっています。
しかし、/etc/zshenv はサブシェルなどのインタラクティブシェルだけでなく、通常のスクリプトをzshで起動した場合にも読み込まれてしまうため、問題になる可能性があります。
(シェバングでzshを指定している場合や、zshを指定してスクリプトを起動する場合など)

Macでzshを使用している方はお気をつけ下さい。