読者です 読者をやめる 読者になる 読者になる

table.el の使い方と org-mode 連携

emacs org

Emacs には自由に表を書くための機能が標準で付いています。それが table.el です。

org-mode にも表を作成する機能が付いていますが、これはあくまでも単純な表作成を行うためのものなので、表計算が行えても、セルが結合した表などは記述することはできません。 (ちなみに org-mode の表作成機能はマイナーモードとして org ファイル以外でも使えたりします。興味がある人は orgtbl-mode で調べてみてください)

ここでは、多機能ゆえに少々とっつきにくい table.el の使い方について詳しく説明していきます。また、 org-mode には table.el の表を出力する機能もあるので、 org-mode と連携した使い方についても説明します。前回 org-mode による論文作成入門 という記事を書きましたが、 table.el を使えば卒論で書きたい複雑な表も LaTeX で書かなくてすみます。

table.el の使い方

表の作成

表の作成方法は (org-mode との連携も含めて) 以下の 3 つ。

  1. 大きさを決めて表を新規作成 (table-insert)
  2. 表の形をしたテキストを table.el の形式に変換 (table-capture)
  3. org-mode の表形式を table.el の表形式に変換 (org-table-convert)

1 の新規作成は Emacs の適当なテキストファイルで M-x table-insert を実行してみてもらえばわかると思います。 3 は後ろの org-mode との連携のところでまた説明します。

2 については例を示した方がわかりやすいと思うので EmacsWiki の例を挙げてみましょう。 Emacs の適当なテキストファイルに以下を入力してみてください。

Name  cmd calls  Percentage
rgb  93 534       46%
Xah  82 090          40%
   total    203 118   100%

スペースの数がそろってなくて雑ですが表っぽい形のテキストができました。このテキストの表を選択 (表の先頭で C-SPC を入力後、表の末尾までカーソル移動) した状態で M-x table-capture を実行します。すると、どういう基準で表の行・列を分割するかたずねられます。

それでは、"Column delimiter regexp" では SPC SPC を、"Row delimiter regexp" では C-o (改行コードの意味です) を入力して決定、 Justify では何も入力せずに決定、最後に "Minimum cell width" では 10 を入力して決定してください。すると以下のような表ができます。

+----------+----------+----------+
|Name      |cmd calls |Percentage|
+----------+----------+----------+
|rgb       |93 534    |46%       |
+----------+----------+----------+
|Xah       |82 090    |40%       |
+----------+----------+----------+
|total     |203 118   |100%      |
+----------+----------+----------+

はじめのテキストから、 2 つ以上のスペースを列の区切りに、改行を行の区切りにした、セルの幅が 10 の表に変換されました。このように、形式的に書かれた表のテキストは M-x table-capture で table.el の形式に変換できます。

本来、この表の筆者はおそらく cmd と cells も別の列にしたかったのでしょう。その表を作るには "Column delimiter regexp" で SPC を 1 つだけ入力すれば OK です。

表の編集

table.el 形式の表では、それぞれのセルが 1 つの Emacs バッファのように動作すると考えてください。セルの中で C-a/C-e を入力するとそのセルの行頭/行末に、 C-< /C-> を入力するとセルの先頭/末尾に移動します。

また、行末で文字入力や改行を行うと、その状況に合わせてセルの行や列が広がるため、 table.el の形式を崩さずにセルを記入することができます。 C-w/C-y でコピペしても表は崩れません。

最後に、表編集中に使用できるコマンド一覧をのせておきます。

キー 機能
TAB セルの移動
C-> セルの幅を広げる
C-< セルの幅を縮める
C-} セルの高さを広げる
C-{ セルの高さを縮める
C-- 現在のセルを上下に分割する
C-| 現在のセルを左右に分割する
C-* 現在のセルを隣のセルと連結する
C-+ 行 (列) を挿入する
C-^ HTML や LaTeX の形式に出力
C-: セルの文字位置の調整

表の認識

table.el 形式の表を作成した直後はテーブル編集モードで編集が行われるため、上記のコマンドを使用したりセル編集中に自動でセルの大きさが拡張されます。代わりに、そのテキスト形式の表を自由に編集できません。

テーブル編集モードを解除するにはテーブル上で M-x table-unrecognize-table を実行します。これで他のテキストと同じように編集できます。

再びテーブル編集モードで編集を行うには M-x table-recognize-table を実行します。

table.el と org-mode の連携

org-mode で使用できる table.el 関連のコマンド

org-mode では以下のコマンドが使用できます。ここでの「表」は table.el 形式の表のことです。

キー 機能
(表がないところで) C-c ~ 表を新規作成 (table-insert)
(表の上で) C-c ~ 表を変換 (Org-mode <-> table.el)
(表の上で) C-c ' テーブル編集モードで編集

表の編集はソースコードの編集などと同じコマンドです。表がテーブル編集モードなのかどうかを考えなくていいのでわかりやすいですね。

別形式への変換

table.el 形式の表が記述された org ファイルを LaTeX などに変換するとき、 org-mode はそれを自動で認識し適切な表に変換してくれます。

例えば、 org ファイルに以下の表を記述します。

+-----+-----+-----+
|1          |2    |
+-----+-----+     |
|4    |5    |     |
|     +-----+-----+
|     |3          |
+-----+-----------+

このファイルを LaTeX に変換すると、以下のように出力されます。

\begin{center}
\begin{tabular}{|l|l|l|}
\hline
\multicolumn{2}{|l|}{1} & 2 \\
\cline{1-2}
4 & 5 & \\
\cline{2-3}
 & \multicolumn{2}{l|}{3} \\
\hline
\end{tabular}
\end{center}

まとめ

table.el は org-mode の表編集に慣れていると使いづらかったり、一行ごとに区切りを記述する必要があるため無駄に行数が増えるということで、セルを結合した表を org-mode の表形式で記述できないかという話題がネット上でいくつか上がっています。しかし現状では、 org-mode でセルを結合した表を書きたい場合 table.el を使うしかないようです。

まあ LaTeX の multicolumn と cline を多用した表よりは書きやすいと思うのでその辺は我慢しましょう。 table.el による長時間の編集を避けるために、先に org-mode で全セルを区切った表を作っておき、それを table.el 形式に変換して C-* で連結だけ行うというのもありかもしれませんね。

org-mode による論文作成入門

emacs org

理系の人はそろそろ卒論・修論を執筆する時期ですね。 LaTeX で記述する人も多いと思いますが、 LaTeX は人が書くのにあまり向いていないと思います。 Emacs を使っている人は org-mode で書いたテキストを LaTeX に変換して論文を完成させてみてはいかがでしょうか。

以下の文章は Org 8.0 以降向けです。 EmacsLaTeX の処理系などはインストールされているものとします。

インストール

org-mode は Emacs のパッケージ管理システムでインストールするのがおそらく一番簡単です。 Emacs24 以降であれば標準でパッケージ管理システムがついてると思います。.emacs に以下を記述してください。

(require 'package)
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t)

その後 Emacs を再起動して M-x list-packages で org と org-plus-contrib をインストールしてください。 org-plus-contrib は bibtex を使用する際に必要になります。

設定

まずは LaTeX に変換する基本設定から。 Org 7.0 系のバージョンとは変数名などが微妙に異なるので注意してください。

(require 'ox-latex)
(require 'ox-bibtex)

;;; LaTeX 形式のファイル PDF に変換するためのコマンド
(setq org-latex-pdf-process
      '("platex %f"
        "platex %f"
        "bibtex %b"
        "platex %f"
        "platex %f"
        "dvipdfmx %b.dvi"))

;;; \hypersetup{...} を出力しない
(setq org-latex-with-hyperref nil)

ちなみに org-latex-pdf-process では下記のように置換されます。

置換前 置換後
%f 完全なファイル名
%b 拡張子を除いた名前
%o 出力ディレクトリ

次に、 org-mode のファイル変換時の LaTeX 出力フォーマットの設定です。出力フォーマットは以下の形式で設定します。

(add-to-list 'org-latex-classes
             '("出力フォーマット名"
               "プリアンブル"
               ("レベル 1" . "レベル 1*")
               ("レベル 2" . "レベル 2*")
               ...
               ))

プリアンブルの内容は org-mode の文書を LaTeX に変換したときに、そのファイルの先頭に挿入されます。ただし、 org-mode ではデフォルトで命令が挿入されるようになっていて、それを抑制するにはプリアンブル部分に [NO-PACKAGES] と [NO-DEFAULT-PACKAGES] を記述する必要があります。

具体的にはこんな感じの記述になります。

(add-to-list 'org-latex-classes
             '("thesis"
               "\\documentclass{jarticle}
                [NO-PACKAGES]
                [NO-DEFAULT-PACKAGES]
                \\usepackage[dvipdfmx]{graphicx}"
               ("\\section{%s}" . "\\section*{%s}")
               ("\\subsection{%s}" . "\\subsection*{%s}")
               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
               ("\\paragraph{%s}" . "\\paragraph*{%s}")
               ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))

卒論や修論では独自のクラスファイルが与えられている場合も多いと思います。その際に特別なコマンドが必要であればこの設定のプリアンブル部分に書くといいでしょう。

org-mode ファイルの作成

具体的な org-mode ファイルの書き方は Org-mode による HTML 文書作成入門 などを参考にしてください。ここでは LaTeX に変換する際に必要な記述や例などを示します。

文書情報

org-mode ファイルの先頭に、タイトルや著者名、それと先ほど設定した出力フォーマットを記述します。

#+TITLE: 論文タイトル
#+AUTHOR: 名前
#+LATEX_CLASS: thesis
#+OPTIONS: toc:nil timestamp:nil

#+LATEX_CLASS が設定した出力フォーマットの名前です。また #+OPTIONS では様々なオプションを設定することができます。設定できるオプションは http://orgmode.org/manual/Export-settings.html を参考にしてください。

図・表

普通の org-mode の書式と同様、画像を埋め込むには 「 file: ファイルのパス」 の形式、表は | で始まる形式で記述します。また、キャプションやラベルを付けたり、図のサイズを指定するには、以下のように図・表の直前に記述します。

#+CAPTION: 図のキャプション
#+NAME: fig:label
#+ATTR_LaTeX: :width 10cm
file:hoge.eps

#+CAPTION: 表のキャプション
#+NAME: tb:label
#+ATTR_LaTeX: :align |l|l|
|---+---|
| A | B |
|---+---|
| 1 | 2 |
| 3 | 4 |
|---+---|

ATTR_LaTeX が図・表の出力設定です。詳しくは http://orgmode.org/org.html#LaTeX-specific-attributes を参考にしてください。

他の多くのサイトでは #+ATTR_LaTeX: width=10cm のように書かれていると思いますが、これは古いバージョンの org-mode の記述方法なので注意です。

引用

上の図・表を引用する場合は以下のように書きます。

   図 [[fig:label]] の結果を表にまとめたものが表 [[tb:label]] です。

また、章や節のタイトルも [[]] で囲って引用することが可能です。

[[背景]] 節では本研究の背景となった概念に関して述べる。

数式

LaTeX の数式は本文中にそのまま記述することができます。

文章中の数式は $a=+\sqrt{2}$ のように書け、数式ブロックは

\begin{equation}
x=\sqrt{b}
\end{equation}

のように書ける。

LaTeX コマンド

数式はそのまま直接記述できますが、 org-mode に対応していない LaTeX コマンドを本文中に記述する際、コマンド中の記号などが org-mode の文法と干渉して記述した通りに出力されないことがあります。そのような場合は以下のように記述することで、 org-mode による変換を行わずに出力することができます。特殊な表や、.emacs 側には記述したくないプリアンブルを書いたりするのに便利です。

#+BEGIN_LaTeX
ここに LaTeX のコマンドを記述します。
#+END_LaTeX

参考文献

LaTeX で論文を記述する人の多くは、参考文献を bibtex で管理すると思います。 reference.bib ファイルを plain スタイルで出力する際は、 org-mode では参考文献のページを挿入する場所に以下を記述してください。

#+BIBLIOGRAPHY: reference plain

また、本文中で文献を引用する場所には 「 cite: 引用キー」 を記述します。

PDF の作成

C-c C-e l o を入力すると org-latex-pdf-process で設定したコマンドで PDF を作成できます。

もし作成できなければコンパイルに失敗している可能性が高いです。そんな場合は C-c C-e l l で org-mode ファイルに対して LaTeX ファイルへの変換のみを行うので、そのファイルを読んだり、コンパイルしてみてエラー原因を調査しましょう。

生成される LaTeX ファイルの例

具体例として以下のような簡単な org-mode ファイルを作成してみました。

#+TITLE: 論文タイトル
#+AUTHOR: 名前
#+LATEX_CLASS: thesis
#+OPTIONS: toc:nil timestamp:nil


* 序論
  近年、○○が注目を集めている cite:abramowitz+stegun 。

* 評価実験
** 実験結果
   実験結果を図 [[fig:result]] に示す。

   #+CAPTION: 実験結果
   #+NAME: fig:result
   #+ATTR_LaTeX: :width 5cm
   file:hoge.eps

** アンケート結果
   また、アンケート結果を表 [[tb:questionnaire]] にまとめた。

   #+CAPTION: アンケート結果
   #+NAME: tb:questionnaire
   #+ATTR_LaTeX: :align |l|l|
   |---+---|
   | A | B |
   |---+---|
   | 1 | 2 |
   | 3 | 4 |
   |---+---|

* 結論
  [[実験結果]] 節の実験結果から

  \begin{equation}
  x=\sqrt{b}
  \end{equation}

  であるため、

  - A
  - B
  - C

  ということがわかった。

* 今後の課題
  がんばります。


#+BIBLIOGRAPHY: reference plain
@Book{abramowitz+stegun,
  author = "Milton Abramowitz and Irene A. Stegun",
  title = "Handbook of Mathematical Functions with
  Formulas, Graphs, and Mathematical Tables",
  publisher = "Dover",
  year = 1964,
  address = "New York",
  edition = "ninth Dover printing, tenth GPO printing"
}

これらを LaTeX ファイルに変換すると以下の .tex ファイルが出力されます。

\documentclass{jarticle}
\usepackage[dvipdfmx]{graphicx}
\author{名前}
\date{\today}
\title{論文タイトル}
\begin{document}

\maketitle


\section{序論}
\label{sec-1}
近年、○○が注目を集めている \cite{abramowitz+stegun}\section{評価実験}
\label{sec-2}
\subsection{実験結果}
\label{sec-2-1}
実験結果を図 \ref{fig:result} に示す。

\begin{figure}[htb]
\centering
\includegraphics[width=5cm]{hoge.eps}
\caption{\label{fig:result}実験結果}
\end{figure}
\subsection{アンケート結果}
\label{sec-2-2}
また、アンケート結果を表 \ref{tb:questionnaire} にまとめた。

\begin{table}[htb]
\caption{\label{tb:questionnaire}アンケート結果}
\centering
\begin{tabular}{|l|l|}
\hline
A & B\\
\hline
1 & 2\\
3 & 4\\
\hline
\end{tabular}
\end{table}
\section{結論}
\label{sec-3}
\ref{sec-2-1} 節の実験結果から

\begin{equation}
x=\sqrt{b}
\end{equation}

であるため、

\begin{itemize}
\item A
\item B
\item C
\end{itemize}

ということがわかった。
\section{今後の課題}
\label{sec-4}
がんばります。


\bibliographystyle{plain}
\bibliography{reference}
% Emacs 24.3.1 (Org mode 8.2.4)
\end{document}

作成した PDF は こんな感じ です。

まとめ

変換前の org-mode ファイルと変換後の LaTeX ファイルを見るとわかりますが、 org-mode の書式の方が圧倒的に覚えやすく、書くのが簡単です。

他にも LaTeX に変換できる書式はたくさんありますが、 org-mode は書式が簡単であること、現在も積極的に開発が行われていること、自分の思い通りに拡張できること、そしてなにより Emacs に標準でついていることが魅力です (本記事では最新版のインストールから説明しましたが) 。普段から Emacs を利用している人であれば、 org-mode の書式を覚えることは損ではないと思います。

org-mode にはもっと便利な機能がたくさんあります。普段のメモ書きにはもちろん、 TODO リストやスケジュール管理にも利用できます。是非この機会に org-mode で論文を書きながら使い方を覚えて、普段の生活に org-mode を取り込んでみてはいかがでしょうか。

org-mode の publishing で特定のディレクトリ上のサイトマップを作成する

emacs org

org-mode には publishing という機能があります。特定のディレクトリの org ファイル全てに対して変換を行ったり、変換後の HTML ファイルをアップロードするといったことができます。

この publishing では、 org-publish-project-alist の設定で :auto-sitemap を t にすると、対象ディレクトリの全ファイルへのリンクを張ったページを publish と同時に作成できます。

これを、特定のディレクトリの中のファイルに対して行いたいと考えました。例えば、毎日の日記を public_html/diary/20130905.html のような名前で diary ディレクトリにためていき、 public_html/index.html には public_html/diary/diary.html へのリンクを、 diary.html では今まで書きためた日記全てへのリンクを貼るという使い方です。

このようなサイトマップを作成するために org-publish-project-alist でどのような設定をすべきかよくわかりませんでしたし、設定できたとしても base-directory に対してのサイトマップが作成できないような気がしました。

それで色々試してみたところ、 org-publish-org-sitemap 関数に適当な project のリストを渡せば上手くいくようです。

例えば publishing で以下のような設定をしているとします。

(setq org-publish-project-alist
      '(("Homepage"
         :base-directory "~/homepage/src/"
         :recursive t
         :publishing-directory "~/homepage/html/"
         :publishing-function org-html-publish-to-html)))

ここで、~/homepage/src/diary/ というディレクトリのサイトマップを ~/homepage/src/diary/diary.org に出力したいとします。その場合、以下のような関数を実行すれば可能です。

(defun org-publish-my-sitemap ()
  (interactive)
  (org-publish-org-sitemap
   '("Diary Sitemap"
     :base-directory "~/homepage/src/diary/")
   "diary.org"))

つまり、 org-publish-org-sitemap を第一引数に diary 用のプロジェクト設定を渡して実行するのです。もちろん渡すプロジェクト設定では :Sitemap-filename などの設定も利用することが可能です。ちなみに第二引数はサイトマップとして出力するファイル名です。

この関数を publishing の際に毎回実行したければ、 preparation-function を設定すればいいでしょう。

(setq org-publish-project-alist
      '(("Homepage"
         :base-directory "~/homepage/src/"
         :recursive t
         :publishing-directory "~/homepage/html/"
         :publishing-function org-html-publish-to-html
         :preparation-function org-publish-my-sitemap)))

DDSKK の入力モード切り替えを変換/無変換キーで行う

emacs skk

一度体に馴染んだ操作方法というのは簡単に変えることができないものです。その一つに、 IME の on/off 切り替えを変換/無変換キーで行うというものがあります。

変換/無変換キーという何に使えばよいのかよくわからないキーが押しやすいところにあることはパソコンを使い始めた当初から感じていました。しかし、これに間違えて触れてしまうと日本語入力がおかしくなるので (別におかしくなるわけではないのですが当時はそう感じていました) 、パソコンを使うときはこのキーには触らないというのが自分ルールでした。

そのキーを IME の on/off の切り替えに使うと便利だという記事を見かけたのは 5 年ほど前になります。それを実際に試してみたところ、ローマ字混じりの日本語が信じられないほど楽に打てて感動したのを今でもよく覚えています。

それからというもの、自分にとってこのキー設定は Ctrl キーと CapsLock キーを入れ替えるのと同じぐらい重要なもので、新しいパソコンを使う際には必ずこの設定を行っています。

で、タイトルの内容に戻るのですが、 Emacs で DDSKK を使う際にネックになったのがこの設定です。そもそも C-j はインデント付きの改行として使っていたのでモード変更に C-j を使うのは気に入らなかったし、変換/無変換キーも余っているので是非ここにモード変更を割り当てたいと思いました。変換/無変換キーを Shift キーにするというアイデアもあるようですが、それには SandS で事足ります (SandS 便利だからもっと流行ればいいのに…) 。

そこでその設定を行うために以下のコードを書きました。

SKK には 3 つ以上のモードがありますが、そのために様々なキーを用意するのも嫌ですし覚えるのもしんどいので、モードは全て変換/無変換キーに割り当てたいと考えました。そこでモードは以下のようなキー割り当てとなっています (唯一 SKK モードへの以降だけは全角/半角キーを使用していますが、ファイルを開くときに SKK モードを起動するように設定すればほとんど使用することはありません) 。

キー モード
全角/半角キー SKK モード
変換キー かな/カナモード (トグル)
無変換キー アスキーモード
SHift + 変換キー 半角カナモード
Shift + 無変換キー 全英モード

また、自分用の設定として、 AZIK の設定が加えてあります。 AZIK を使用しないのであれば skk-azik-load-hooks の関数定義とその add-hook は必要ないはずです。

あまりにも特殊な設定ですが、 SKK のモード変更のキーを変更をしたい人 (たとえそれが変換/無変換キーでなくても) の参考になれば幸いです。

org 文書をはてな記法に変換する ox-hatena.el (旧 org-export-hatena) を作った

emacs org

Org 8.0 で文書変換のコードが完全に書き換えられ,新しい export 関数を簡単に書けるようになったということなので,試しに org 文書をはてな記法に export する elisp を書いてみました.

akisute3/ox-hatena · GitHub

インストールしたら org-mode に C-x C-e b のコマンド群が追加されます.

以下のはてな記法に対応したつもりですが,しっかりは確認していません.

  • 見出し記法,カテゴリー記法
  • 小見出し記法,小々見出し記法
  • リスト記法
  • 表組み記法
  • 引用記法
  • スーパーpre記法,シンタックス・ハイライト
  • 脚注記法
  • http記法

ox-hatena/sample に変換前 org 文書 と変換後の はてな記法文書 を置いているので参考にしてください.変換後の はてな記法文書 をブログに貼りつけると以下のようになります.


/////////////////////////////////////////

[日記][読書] 赤毛のアン

小見出しです.

小見出しの文章です.

さらに小さい小々見出しです.

小々見出しの文章です.

リスト記法

リスト
  • ぶどう
    • 巨峰
    • マスカット
  • もも
数字付きリスト
  1. ぶどう
  2. もも
    1. すもも

表組み記法

項目名なしの表
りんご 1
みかん だいだい 2
ぶどう 3
項目名ありの表
名前 個数
りんご 1
みかん だいだい 2

引用記法

ここは引用文です。
ただのブロックとして使うこともできます。

スーパー pre 記法

整形済みテキストです。
ブロック
整形済みテキストです。

スーパーpre記法 (シンタックス・ハイライト)

class Foo
  def bar'baz' # return baz
  end
end

脚注記法

しなもん*1 はお散歩が好きなんです。

http 記法,mailto 記法

タイトル指定

はてなのトップページ

オブション指定

はてな
http://d.hatena.ne.jp/images/diary/s/sample/2004-08-20.jpg

*1:はてなのマスコット犬

Emacsを便利に使うための提案(語のkill・マーク編)

emacs

前回 に引き続き,今回は語の操作に関する提案である.

M-f や M-d などの語の操作は C-f や C-d の1字の操作に対応しているが, C-h が元々ヘルプであったためか,M-h に関しては,大半の人が C-h に設定しているであろう delete-backward-char との対応が取れていない.そこで,1つ目に M-h を「カーソルより前の語を削除」に変更することを提案する.

(global-set-key (kbd "M-h") 'backward-kill-word)

M-h はもともと mark-paragraph だ.私は使用していないので気にしないが,これをよく使用するのであれば, C-* と M-* の対応関係を考えると mark-paragraph の方を別のキーに移動させるのが適当だろう.

2つ目の提案は,語のマークである.語をマークするコマンドとして M-@ がある.これは何度も押すことで複数の単語をマークできて非常に便利だが, M-d と同様にカーソルより後ろの語しかマークしない.カーソル位置の語全体がリージョンする場合は, M-b で語の先頭にカーソルを移動してから M-@ を入力する必要がある.

カーソル位置の語全体を copy や cut したいこともよくあるので,そのためのキーを用意しよう.キーは C-@ を使用することにする. C-@ を使用しても C-SPC と同じなので問題ない.

さて,カーソル位置の語全体のマークをどのように実現するかであるが,残念なことに Emacs に標準では用意されていない(それっぽい名前の関数 mark-word は M-@ の機能だ).そこで, リージョン選択(松山智大) — ありえるえりあ で紹介されている thing-opt を使用する.

thing-opt.el をパスが通ったところにダウンロードし,.emacs

(require 'thing-opt)
(define-thing-commands)

と記述すると,カーソル位置の語全体のマークする mark-word* が提供される.これを C-@ に割り当てればよい.

(global-set-key (kbd "C-@") 'mark-word*)

この提案に賛同してもらえるかどうかはわからないが, M-h や C-@ のような押しやすいキーを活用しないのは非常にもったいない. mark-paragraph や M-@ によるマークを使用しないのであれば,少しでも自分が使用する可能性の高いコマンドに変更することをオススメする.

Emacsを便利に使うための提案(行のcopy・kill編)

emacs

Emacs を使用していると,行全体をコピーしたくなることがよくある.そういうときは

  • C-a C-k C-y
  • C-a C-k C-/
  • C-a C-SPC C-e M-w

のどれかで行っているのだが,利用する頻度の割に入力するキーが多くて面倒だ.そこで,行全体をコピーするキーを定義したいと思う.

都合よく M-k が空いているのでそれを使用することにする. M-k は kill-sentence だが私はまず使用しない.また,C-w が kill に対し M-w が copy の対応に似ていて覚えやすいという利点もある(完全に対応させるなら末尾までコピーが正しいのだが,行copyの方が頻繁に使うし必要なキー操作が多いのでこちらを M-k とする).

また,行 copy があるなら行 kill もほしい.そこで,そちらは M-K に割り当てることにする.それでは .emacs の設定に移ろう.

emacs23 には行 kill を行う kill-whole-line が標準で用意されているので使用する.一方,行 copy はないので以下を .emacs に記述する.

(defun copy-whole-line (&optional arg)
  "Copy current line."
  (interactive "p")
  (or arg (setq arg 1))
  (if (and (> arg 0) (eobp) (save-excursion (forward-visible-line 0) (eobp)))
      (signal 'end-of-buffer nil))
  (if (and (< arg 0) (bobp) (save-excursion (end-of-visible-line) (bobp)))
      (signal 'beginning-of-buffer nil))
  (unless (eq last-command 'copy-region-as-kill)
    (kill-new "")
    (setq last-command 'copy-region-as-kill))
  (cond ((zerop arg)
         (save-excursion
           (copy-region-as-kill (point) (progn (forward-visible-line 0) (point)))
           (copy-region-as-kill (point) (progn (end-of-visible-line) (point)))))
        ((< arg 0)
         (save-excursion
           (copy-region-as-kill (point) (progn (end-of-visible-line) (point)))
           (copy-region-as-kill (point)
                                (progn (forward-visible-line (1+ arg))
                                       (unless (bobp) (backward-char))
                                       (point)))))
        (t
         (save-excursion
           (copy-region-as-kill (point) (progn (forward-visible-line 0) (point)))
           (copy-region-as-kill (point)
                                (progn (forward-visible-line arg) (point))))))
  (message (substring (car kill-ring-yank-pointer) 0 -1)))

kill-whole-line の "kill-region" を "copy-region-as-kill" に置換したものである.コピーしたことが確認できるよう,関数末尾に kill-ring の先頭をミニバッファに表示するコードも付け足した.

そして,以下を .emacs に記述する.

(global-set-key (kbd "M-k") 'copy-whole-line)
(global-set-key (kbd "M-K") 'kill-whole-line)

ここまで設定すれば M-k で行 copy,M-K で行 kill ができるようになる.M-k を使用しないのであれば,ぜひ試してみてほしい.