Sublime Textの導入、Markdown、日本語入力時の不具合対策

マルチプラットフォーム対応のテキストエディタSublime Text 2の初期設定について、自分が行ったことをメモ。Markdown形式でメモを取ってPlain textファイルで保存しているため、その辺で使いやすくなるように設定した。

これまではCotEditorを使っていたが、1ウィンドウに1ファイルが基本でタブ付きのウィンドウが使えないこととサイドバーなどでのファイル管理ができないことが不満だった。Kodというアプリケーションはこの2点を満たしていてChromeライクなタブが気に入っていたが、ベータ版のためか動作が不安定なうえ開発も終了したようなので代替品を探したところSublime Textに行き着いた。

0. 概要

設定項目の概要は以下。3.と4.が一番情報として需要がありそう。

  1. デフォルトで用意されている設定の変更
  2. Packageのインストール
  3. Markdownのシンタックスハイライト
  4. 日本語入力に関する不具合への対策

1. デフォルトで用意されている設定の変更

アプリケーション標準で用意される設定項目を記載したファイルはメニューバーのSublime Text 2 > Preferences > Settings - Defaultをクリックするとこで開ける。この設定を直接編集してもよいが、不具合が出た際にデフォルトへ戻すのが面倒なので基本的にはSettings - Userの方のファイルを編集する。このファイルは他のOS Xアプリケーション同様「Command + ,」のショートカットキーでも開ける。

自分の上記ファイルの中身は以下の通り。最後の行の行末にカンマがあると保存時にエラーを出すので注意。

{
    "draw_white_space": "all", //不可視文字の表示
    "fade_fold_buttons": false, //折りたたみボタンを常に表示。オススメ
    "find_selected_text": true, //検索開始時に選択範囲を検索フィールドに入力済みにする
    "font_size": 12, //フォントサイズの変更
    "highlight_line": true, //選択行のハイライト
    "highlight_modified_tabs": true, //編集されたファイルのタブの色を変える。オススメ
    "line_padding_top": 5, //行間のサイズの変更
    "tab_size": 4, //tabキーのサイズの変更
    "translate_tabs_to_spaces": true, //tabキーでスペースを入力する
    "trim_trailing_white_space_on_save": true, //行末の空白文字を保存時に削除
    "ensure_newline_at_eof_on_save": false //ファイルの最終行の行末を保存時に改行にする
}

2. Packageのインストール

標準で用意されている設定以外にもプラグインのようなもの(Packageと呼ばれる)で機能を拡張することが可能。この拡張機能の管理にはPackage Controlというものをインストールするのが定石らしい。インストール方法と使い方は検索するとすぐ出るので省く。以下では自分がインストールしたPackageについて記載する。

  • Bracket Highlighter
    • カッコのハイライト。
  • SideBarEnhancements
    • サイドバーの機能拡張。自分はあまり活用できていない。
  • Simple Clone
    • ファイルの分割表示を楽に。メニューバーのView > Simple Cloneやキーボードショートカットから利用。
  • Markdown Preview
    • Option + Mでブラウザが開かれMarkdownファイル(".md", ".markdown", ".mdown")をプレビュー。
    • Sublime Text 2 > Preferences > Key Bindings - Userに以下を追加する必要有り。
      • {"keys": ["alt+m"], "command": "markdown_preview", "args": {"target": "browser"}}
  • Browser Refresh
    • Command + shift + rでファイルを保存しブラウザリフレッシュ。
  • SmartMarkdown
    • Markdown形式のファイルを見出し(#で始まる行)で折りたたむために導入。見出しの行でtabキーを押すと折り畳むことができる。予測変換のtabキーと衝突してしまうため、見出し文の編集時には日本語予測変換を使わないなどの工夫が必要。
      • Packageを導入せずシンタックスハイライトを定義しているファイルで設定しようと試みたが、折りたたみに関する定義は現在のところ未実装らしい。
    • Smart list機能が日本語入力時のenterキー入力と干渉するのを防ぐため、Sublime Text 2 > Preferences > Package Settings > SmartMarkdown > Key Bindings - Defaultで開くファイルの12-23行目辺り(Smart list関係)をコメントアウトする必要有り。
    • 同様にSmart table関係の24-57行目もコメントアウトすると予測変換を選択する際のtabキーとの機能衝突を防げる。

3. Markdownのシンタックスハイライト

標準ではMarkdownファイルにほとんど色がつかないようなので手動で設定する。

.tmThemeという拡張子のファイルでシンタックスハイライトを管理している様なので、このファイルを編集する。標準では以下のファイル。(この編集するファイルは使用するテーマで変わると思われる。Sublime Text 2 > Preferences > Color Schemeからチェック可能。)

~/Library/Application Support/Sublime Text 2/Packages/Color Scheme - Default/Monokai.tmTheme

このファイルの382行目付近の</array>の前に以下を貼付け。

<!-- for Markdown start -->
        <dict>
            <key>name</key>
            <string>Markdown: Linebreak</string>
            <key>scope</key>
            <string>text.html.markdown meta.dummy.line-break</string>
            <key>settings</key>
            <dict>
                <key>background</key>
                <string>#A57706</string>
                <key>foreground</key>
                <string>#E0EDDD</string>
            </dict>
        </dict>
        <dict>
            <key>name</key>
            <string>Markup: Inline Raw</string>
            <key>scope</key>
            <string>text.html.markdown markup.raw.inline</string>
            <key>settings</key>
            <dict>
                <key>foreground</key>
                <string>#269186</string>
            </dict>
        </dict>
        <dict>
            <key>name</key>
            <string>Markup: Block Raw</string>
            <key>scope</key>
            <string>markup.raw.block.markdown</string>
            <key>settings</key>
            <dict>
                <key>foreground</key>
                <string>#269186</string>
            </dict>
        </dict>
        <dict>
            <key>name</key>
            <string>Markup: Punctuation for Inline Block</string>
            <key>scope</key>
            <string>punctuation.definition.raw.markdown</string>
            <key>settings</key>
            <dict>
                <key>foreground</key>
                <string>#269186</string>
            </dict>
        </dict>
        <dict>
            <key>name</key>
            <string>Markup: Heading1</string>
            <key>scope</key>
            <string>markup.heading.level1.markdown</string>
            <key>settings</key>
            <dict>
                <key>foreground</key>
                <string>#D04070</string>
            </dict>
        </dict>
        <dict>
            <key>name</key>
            <string>Markup: Heading2</string>
            <key>scope</key>
            <string>markup.heading.level2.markdown</string>
            <key>settings</key>
            <dict>
                <key>foreground</key>
                <string>#FF9900</string>
            </dict>
        </dict>
        <dict>
            <key>name</key>
            <string>Markup: Heading3</string>
            <key>scope</key>
            <string>markup.heading.level3.markdown</string>
            <key>settings</key>
            <dict>
                <key>foreground</key>
                <string>#E6DB74</string>
            </dict>
        </dict>
        <dict>
            <key>name</key>
            <string>Markup: Italic</string>
            <key>scope</key>
            <string>markup.italic</string>
            <key>settings</key>
            <dict>
                <key>fontStyle</key>
                <string>italic</string>
                <key>foreground</key>
                <string>#839496</string>
            </dict>
        </dict>
        <dict>
            <key>name</key>
            <string>Markup: Bold</string>
            <key>scope</key>
            <string>markup.bold</string>
            <key>settings</key>
            <dict>
                <key>fontStyle</key>
                <string>bold</string>
                <key>foreground</key>
                <string>#586e75</string>
            </dict>
        </dict>
        <dict>
            <key>name</key>
            <string>Markdown: Punctuation for Bold, Italic</string>
            <key>scope</key>
            <string>punctuation.definition.bold.markdown, punctuation.definition.italic.markdown</string>
            <key>settings</key>
            <dict>
                <key>foreground</key>
                <string>#586e75</string>
            </dict>
        </dict>
        <dict>
            <key>name</key>
            <string>Markup: Underline</string>
            <key>scope</key>
            <string>markup.underline</string>
            <key>settings</key>
            <dict>
                <key>fontStyle</key>
                <string>underline</string>
                <key>foreground</key>
                <string>#839496</string>
            </dict>
        </dict>
        <dict>
            <key>name</key>
            <string>Markup: Quote</string>
            <key>scope</key>
            <string>markup.quote</string>
            <key>settings</key>
            <dict>
                <key>fontStyle</key>
                <string>italic</string>
                <key>foreground</key>
                <string>#268bd2</string>
            </dict>
        </dict>
        <dict>
            <key>name</key>
            <string>Markup: Separator</string>
            <key>scope</key>
            <string>meta.separator</string>
            <key>settings</key>
            <dict>
                <key>background</key>
                <string>#333344</string>
                <key>foreground</key>
                <string>#777777</string>
            </dict>
        </dict>
<!-- for Markdown end -->

さらに見出しのレベルに応じて色を変えるために、Markdownの文法を定義しているMarkdown.tmLanguageというファイルを編集する(本記事のハイライト)。ファイルの場所は以下。

~/Library/Application Support/Sublime Text 2/Packages/Markdown/Markdown.tmLanguage

このファイルの543行目付近の<key>heading</key>から始まる26行くらい(<key>image-inline</key>の前の行まで)をコメントアウトして、以下で置き換える。

<!-- Edited header start -->
        <key>heading</key>
        <dict>
            <key>patterns</key>
            <array>
                <dict>
                    <key>begin</key>
                    <string>\G(#{1})(?!#)\s*(?=\S)</string>
                    <key>captures</key>
                    <dict>
                        <key>1</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.heading.markdown</string>
                        </dict>
                    </dict>
                    <key>contentName</key>
                    <string>entity.name.section.markdown</string>
                    <key>end</key>
                    <string>\s*(#*)$\n?</string>
                    <key>name</key>
                    <string>markup.heading.level1.markdown</string>
                    <key>patterns</key>
                    <array>
                        <dict>
                            <key>include</key>
                            <string>#inline</string>
                        </dict>
                    </array>
                </dict>
                <dict>
                    <key>begin</key>
                    <string>\G(#{2})(?!#)\s*(?=\S)</string>
                    <key>captures</key>
                    <dict>
                        <key>1</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.heading.markdown</string>
                        </dict>
                    </dict>
                    <key>contentName</key>
                    <string>entity.name.section.markdown</string>
                    <key>end</key>
                    <string>\s*(#*)$\n?</string>
                    <key>name</key>
                    <string>markup.heading.level2.markdown</string>
                    <key>patterns</key>
                    <array>
                        <dict>
                            <key>include</key>
                            <string>#inline</string>
                        </dict>
                    </array>
                </dict>
                <dict>
                    <key>begin</key>
                    <string>\G(#{3,6})(?!#)\s*(?=\S)</string>
                    <key>captures</key>
                    <dict>
                        <key>1</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.heading.markdown</string>
                        </dict>
                    </dict>
                    <key>contentName</key>
                    <string>entity.name.section.markdown</string>
                    <key>end</key>
                    <string>\s*(#*)$\n?</string>
                    <key>name</key>
                    <string>markup.heading.level3.markdown</string>
                    <key>patterns</key>
                    <array>
                        <dict>
                            <key>include</key>
                            <string>#inline</string>
                        </dict>
                    </array>
                </dict>
            </array>
        </dict>
<!-- Edited header end -->

Markdownのシンタックスハイライトに関する作業は以上。

仕組みとしては、デフォルトでは全て一括りだった見出しにレベル毎に異なるscopeがつくようMarkdown.tmLanguageファイルを編集して、Monokai.tmThemeで各々のscopeに色を付けるかたち。この記事の通りに行うとレベル3から6までの見出しは同じ色になるので、1から6まで全て色を変えたい場合は上に挙げた両ファイルを適宜変更する。

下の画像はシンタックスハイライトの結果。

f:id:kamosidhe:20140115065728j:plain

SmartMarkdownを導入している場合は、上記Markdown.tmLanguageの変更によって見出しの折りたたみができなくなってしまう。解決するにはSublime Text 2 > Preferences > Key Bindings - Userに以下を追加する。

{ "keys": ["tab"], "command": "smart_folding", "context":
    [
        { "key": "selector", "operator": "equal", "operand": "markup.heading" }
    ]
}

4. 日本語入力に関する不具合への対策

デフォルトの設定だと日本語入力に不具合があるのでその対処法について。日本語入力中の予測変換候補のtabキーでの選択に関する不具合と、検索・置換時に日本語を入力しようとすると確定のenterキーで改行や検索開始をされてしまう不具合を解決する。

メニューバーからSublime Text 2 > Preferences > Key Bindings - Defaultをクリック。開かれたファイルの93行目付近の以下の部分をコメントアウト(Command + /)する。

{ "keys": ["tab"], "command": "insert_best_completion", "args": {"default": "\t", "exact": true} },
{ "keys": ["tab"], "command": "insert_best_completion", "args": {"default": "\t", "exact": false},
    "context":
    [
        { "key": "setting.tab_completion", "operator": "equal", "operand": true }
    ]
},

また、572、583、597行目付近の3カ所にある["enter"]["ctrl+enter"]に変更する。

あくまで暫定的な対処であり、「Find next」とインクリメンタルサーチ時の「パネルを隠す」がctrl + enterに置き換えられてしまうため、慣れないと不便を感じる可能性もある。他の良い解決法募集。ちなみに「Find next」はCommand + Gでも可能なのでこちらをおぼえるのも手。

以上が日本語入力に関する不具合への対処法。キーバインドの衝突を避けることで解決可能なので、Packageを導入して日本語入力時に不具合があれば、そのPackageのKey bindingsのファイルをチェックするとよいと思う。


参考サイト

https://github.com/demon386/SmartMarkdown
http://www.bram.us/2013/02/08/sublime-text-markdown-syntax-highlighting/ http://docs.sublimetext.info/en/sublime-text-2/extensibility/syntaxdefs.html http://docs.sublimetext.info/en/sublime-text-2/reference/syntaxdefs.html http://www.ecoop.net/memo/archives/%E3%80%90sublime-text-2%E3%80%91mac-os-x%E3%81%A7%E6%97%A5%E6%9C%AC%E8%AA%9E%E5%85%A5%E5%8A%9B%E3%81%AE%E3%82%BF%E3%83%96%E5%A4%89%E6%8F%9B%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%8F%E3%81%AA.html

Web制作者のためのSublime Textの教科書 今すぐ最高のエディタを使いこなすプロのノウハウ

Web制作者のためのSublime Textの教科書 今すぐ最高のエディタを使いこなすプロのノウハウ