5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

これは、Emacs Lispの入門チュートリアルです。

主な参考文献は、以下の記事になります。

参考文献というか、ほぼこの記事を日本語翻訳したに近いです...

はじめに

ここでは、まだEmacsを入れたことがない人向けにEmacsのインストール方法を紹介します。

インストール

以下のサイトからインストールすることができます。

以下もおすすめ

また、macOSの場合、以下のサイトでインストールをすることをお勧めします。

このままでも良いのですが、以下の記事を参考に、簡単な設定をすると良いかもしれません。

Emacsの操作方法

Emacsでは基本操作をEmacsの中で学ぶことができます。

Control(以下、C)を押しながら、hを押し、次にtを押す、つまりCtrl-h + tと入力すると、チュートリアルに移動します。
最初はここから、基本的な操作を学ぶと良いでしょう。

画面収録 2026-02-28 10.09.46.gif

また、英語が苦手な方には、Esc + xを押して、help-with-tutorial-spec-language Japanese を実行すると、日本語のチュートリアル記事を読むことができます。

また、それでも不安という方は、Webサイトがあるので、こちらを参考にすると良いでしょう。

scratch バッファ

Emacsを起動したら、ウェルカムメッセージが開くと思ういます。こちらを q key を押して閉じてください。

ウィンド下部のグレーの行を見てください。"scratch"とあれば、成功です。

スクリーンショット 2026-02-28 9.50.52.png

"scratch" は現在あなたがいる編集スペースの名前です。
この編集スペースを「バッファ」と呼びます。

scratchバッファは、Emacs起動時のデフォルトバッファです。
ここでは、Emacs Lisp(以下、Elisp)を手で書き、コマンドを使って評価することができます。

多くのEmacsユーザーは、この画面で簡単な計算やコードの確認を行う(らしい)。(参考:podcast Vim-jp radio)

本題

ここからは実際に ELisp を触っていきます。

コメントアウト

セミコロンで、行のどこからでもコメントを開始できます。

;; コメントアウト

S式(sexp)

Elisp プログラムは、S式(sexp / S-expression) で構成されます。
S式はシンボリック式(symbolic expression)とも呼ばれます。

以下のS式は「2 + 2」を意味します。

(+ 2 2)

S式はカッコで囲まれ、ネストすることもできます。

(+ 2 (+ 1 1))

S式は、アトム(原子) か、他のS式を含みます。
上の例では 12 がアトム、(+ 2 (+ 1 1))(+ 1 1) がS式です。

評価

lisp-interaction-mode からS式を評価できます。
閉じカッコのすぐ後ろにカーソルを置き、C-j(Control + j)を押します。

  • C-j は評価結果をバッファに挿入します。
  • C-x C-e は、Emacs 下部のミニバッファに結果を表示します。

setq

setq は変数に値を格納します。

(setq my-name "Alice")
;; my-name に "Alice" が格納される

insert

insert はカーソル位置にテキストを挿入します。

(insert "Hello!")

insert は複数の引数を取れます。

(insert "Hello" " " "world!")

変数を扱うこともできます。

(setq my-name "Alice")
(insert "Hello I am " my-name)
;; Hello I am Alice

関数

関数は defun で定義します。

(defun hello (name)
  (insert "Hello " name "!"))

(hello "Bob")
;; Hello Bob!

別のウィンドウに切り替えることもできます。

(switch-to-buffer-other-window "*test*")

C-x C-e を実行すると、新しいウィンドウが開き *test* バッファに移動します。
元のウィンドウには、マウスまたは C-x C-o で戻れます。

複数のS式を progn でまとめる

ここまでのコードを1つにまとめてみましょう。

(defun hello (name)
  (insert "Hello " name " !"))

(progn
  (switch-to-buffer-other-window "*test*")
  (hello "you"))

C-x C-e を実行すると、*test* バッファに「Hello you !」が挿入されます。

次に、バッファの内容を事前に削除する処理を追加しましょう。

(defun hello (name)
  (insert "Hello " name " !"))

(progn
  (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
  (hello "you"))

さらに、実行後に元のウィンドウへ戻るようにしましょう。

(defun hello (name)
  (insert "Hello " name " !"))

(progn
  (switch-to-buffer-other-window "*test*")
  (erase-buffer)
  (hello "you")
+ (other-window 1))

let を使うと、ローカル変数に値を束縛できます。

(defun hello (name)
  (insert "Hello " name " !"))

(let ((local-name "World"))
  (switch-to-buffer-other-window "*test*")
  (erase-buffer)
  (hello local-name)
  (other-window 1))

format を使うと、文字列をフォーマットできます(C 言語の printf と同様の使い方です)。

(format "Hello %s!\n" "visitor")

format を使って hello 関数を改良しましょう。

(defun hello (name)
  (insert (format "Hello %s!\n" name)))

(hello "you")

C-x C-e を実行すると、「Hello you!」が挿入されます。

関数をリストの各要素に適用する

以下の関数を作成して呼び出します。

(defun greeting (name)
  (let ((your-name "Bob"))
    (insert (format "Hello %s!\n\nI am %s.\n" name your-name))))

(greeting "you")
;;; 出力結果:
;;
;; Hello you!
;;
;; I am Bob.

変数のリストを作成します。

(setq list-of-names '("Sarah" "Chloe" "Mathilde"))

car でリストの先頭要素を取得できます。

(car list-of-names)

C-x C-e で確認すると、"Sarah" が出力されます。

cdr は先頭以外の要素を返します。

(cdr list-of-names)

C-x C-e で確認すると、("Chloe" "Mathilde") が出力されます。

push でリストの先頭に要素を追加しましょう。

(push "Stephanie" list-of-names)

C-x C-e で確認すると、("Stephanie" "Sarah" "Chloe" "Mathilde") が出力されます。

注意: carcdr はリストを変更しませんが、push はリストを変更することに注意してください。

mapcar を使うと、hello 関数をリストの各要素に適用できます。

(mapcar 'hello list-of-names)

まとめて実行してみましょう。

(progn
  (switch-to-buffer-other-window "*test*")
  (erase-buffer)
  (mapcar 'hello list-of-names)
  (other-window 1))

*test* バッファに、list-of-names の各名前に対して hello 関数が実行された結果が表示されます。

色々アレンジしてみる

search-forwardreplace-match を使って、「Hello」を「こんにちは」に置き換えます。

(defun hello-to-konnichiwa ()
  (switch-to-buffer-other-window "*test*")
  (erase-buffer)
  ;; list-of-names の各名前に挨拶する
  (mapcar 'hello list-of-names)
  (goto-char (point-min))
  ;; "Hello" を "こんにちは" に置き換える
  (while (search-forward "Hello" nil t)
    (replace-match "こんにちは"))
  (other-window 1))

(hello-to-konnichiwa)

名前を太字にしてみましょう。

(defun boldify-names ()
  (switch-to-buffer-other-window "*test*")
  (goto-char (point-min))
  (while (re-search-forward "こんにちは \\(.+\\)!" nil t)
    (add-text-properties (match-beginning 1)
                         (match-end 1)
                         (list 'face 'bold)))
  (other-window 1))

(boldify-names)

この関数では re-search-forward を使っています。
search-forward が文字列をそのまま検索するのに対し、re-search-forward正規表現(regular expression / regex) を使ってパターンを検索します("re-" はその略称です)。

add-text-properties は、フォントフェイスなどのテキストプロパティを追加します。

最後に

今回の記事でカバーした主な概念をまとめます。

概念 説明
sexp S式(S-expression)。シンボリック式とも呼ばれる。Elispの基本的な単位
setq 変数への値の代入
defun 関数定義
let ローカル変数への値の束縛
progn 複数のS式をまとめて順番に実行
mapcar リストの各要素に関数を適用
car / cdr リストの先頭 / 先頭以外を取得
push リストの先頭に要素を追加
while ループ
search-forward 文字列検索
re-search-forward 正規表現検索
format 文字列フォーマット
5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?