- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2020-07-05T13:45:21+00:00","","")
#author("2024-05-08T21:53:28+09:00","","")
#topicpath
////////////////////////////////////////////////////////////////////////////////
* 目次 [#xdc7c37e]
#contents();
#ls2(Editor/emacs/);
////////////////////////////////////////////////////////////////////////////////
* 編集関連 [#d174f0d4]
//==============================================================================
** 矩形選択 [#h1d64252]
** 編集コマンド [#cmd-edit]
|~Key |~command name |~Operation |
|C-SPC |set-mark-command |選択の開始 |
|M-P |set-mark-command |選択の開始 |
|C-w |kill-region |選択した箇所をカット |
|C-k |kill-line |現在のカーソル位置から行末までをカット |
|C-y |yank |選択した箇所をヤンク(貼り付け) |
//==============================================================================
** 矩形編集コマンド [#cm-edit-rectangle]
- rectangle-mark-mode を使う。
|~Key |~Operation |
|C-x SPC |矩形選択の開始 |
|C-w/M-w/C-y |選択した箇所をカット/コピー/ヤンク |
|C-o |矩形選択した箇所に空行を挿入 |
|C-t CHAR |矩形選択した箇所を CHAR で置換 |
|C-SPC → (region選択) → C-x SPC |選択したリージョンを矩形選択に変更 |
|~Key |~command name |~Operation |
|C-x SPC |rectangle-mark-mode |矩形選択の開始 |
|C-w |kill-region |選択した箇所をカット |
|M-w |kill-ring-save |選択した箇所をコピー |
|C-y |yank |選択した箇所をヤンク(貼り付け) |
|C-o |open-line |矩形選択した箇所に空行を挿入 |
|C-t <CHAR> |transpose-chars |矩形選択した箇所を <CHAR> で置換 |
|C-x r t <CHAR> |transpose-chars |矩形選択した箇所を <CHAR> で置換 |
|C-SPC → (region選択) → C-x SPC | |選択したリージョンを矩形選択に変更 |
|C-x r k |kill-rectangle |矩形の切り取り |
|C-x r y |yank-rectngle |矩形の貼り付け |
|C-x r N |rectangle-number-lines |上から1で始まる連番を振る(数字は右詰めとなる) |
-- 矩形編集は emacs24 あたりから使うことが出来るが、使うなら emacs25 以降の方が良い。理由は、入力内容がバッファにリアルタイムで反映される為(emacs24では、確定前の矩形編集入力はミニバッファにしか表示されない為、他の行とカラムを揃えたい場合に分かり難い)
//------------------------------------------------------------------------------
*** 使い方 [#d2cde02a]
+ 矩形編集モードに入る
C-x SPC
+ 編集対象とする矩形をカーソルキーで選択する
+ 編集したいコマンドを実行する
-- 例:矩形選択した箇所を <CHAR> で置換
C-x r t <CHAR>
//------------------------------------------------------------------------------
*** 参考リンク [#k8b26146]
- [[GNU Emacs Manual(Japanese Translation): Rectangles>https://ayatakesi.github.io/emacs/25.1/Rectangles.html]]
- [[Emacs における矩形領域のコピペ系編集機能 | プログラマーズ雑記帳>http://yohshiy.blog.fc2.com/blog-entry-254.html]]
//==============================================================================
** 置換 [#edit-replace]
//------------------------------------------------------------------------------
*** 対話置換 [#f82d1655]
- 検索と置換の開始
|~binding |~command name |~Operation |
|M-% |query-replace |検索して置換を開始 |
- 検索で見つかった文字列の置換
|~binding |~Operation |
|y |ハイライト中の文字列を、指定した文字列で置換して次を検索 |
|n |ハイライト中の文字列を置換しないで次を検索 |
|! |全てのマッチした文字列を置換する |
|q |置換を終了する |
|? |ヘルプを表示する |
//------------------------------------------------------------------------------
*** 一括置換(対話なし) [#da3ba60e]
|~binding |~command |~description |
| |replace-string |一括置換 |
| |replace-regexp |一括置換(正規表現版) |
//==============================================================================
** 一括検索&一括置換 [#ff58ba80]
- moccur-edit を使う。
- 一括検索&一括置換の手順
++ 検索する
+++ 検索開始
M-x: moccur-grep-find
++ 検索対象ディレクトリを指定
Directory: <firectory>
++ 検索キーワードとファイル名キーワードの入力
Input Regexp and FileMask: <keyword-for-grep> <file-name-mask>
--- 正規表現が使用可
--- 但し、ファイル名キーワードに於いて拡張子指定する場合は ''*.<拡張子>'' ではなく &color(red){''.<拡張子>$''}; とすること。
--- 例
Input Regexp and FileMask: hoge .html$
++ 検索結果を元に一括置換する為、編集モードに入る
r
++ 置換する
M-%
++ 置換した結果を保存する
C-x C-s
- 編集のキャンセル
C-x k
//==============================================================================
** 一括インデント [#y159cc3a]
+ まず、バッファ全体を選択する
C-x h (mark-whole-buffer)
+ 選択領域に対してインデントを実行する
C-M-\ (indent-region)
//==============================================================================
** キーワードによる一括アライン(align-regex)[#align-regex]
- 代入式などが複数行にわたって並んでいるときに "=" などのキーワードで縦のアラインを揃える
+ 範囲を選択
C-@
+ コマンド実行する
M-x: align-regex
+ アラインするキーワードを指定する
- 例
-- 実行前
int aaa = 120;
double ad = 23.55;
std::string buff = format("test data = %d, ad = %f\n", aaa, ad);
-- 実行後(アラインキーワードに "=" を指定した)
int aaa = 120;
double ad = 23.55;
std::string buff = format("test data = %d, ad = %f\n", aaa, ad);
//==============================================================================
** コメントアウト/コメントアウト取り消し toggle [#c91abb1e]
- 下記にて、使用言語に合わせたコメントアウト/コメントアウト取り消しを行う。
++ コメントアウトする領域を選択
C-@
++ コメント/コメントアウト取り消し実行
M-;
- 各言語毎の挙動
|~言語 |~コメントアウト文字 |~備考 |
|C | /* */ で各行毎に括る・削除 | |
|C++ | // を行頭に追加・削除 | |
|Objective-C | // を行頭に追加・削除 | |
|Java | // を行頭に追加・削除 | |
|Pike | // を行頭に追加・削除 | |
|python | # を行頭に追加・削除 | |
|perl | # を行頭に追加・削除 | |
|Tcl | # を行頭に追加・削除 | |
|expect | # を行頭に追加・削除 | |
|bash | # を行頭に追加・削除 | |
|HTML | <!-- --> で各行毎に括る・削除 | |
|PHP | <!-- --> で各行毎に括る・削除 | |
|C# | 未対応 | |
|Pascal | { } で各行毎に括る・削除 | |
|elisp | ;; を行頭に追加・削除 | |
- この他、非言語の設定ファイルでも対応しているものがある:
|~項目 |~コメントアウト文字 |~備考 |
|.gitconfig | # を行頭に追加・削除 | |
////////////////////////////////////////////////////////////////////////////////
* 編集以外の機能 [#q1c8a63a]
//==============================================================================
** シェルコマンドの実行 [#s3e9c369]
- 下記にてシェルコマンドを実行出来る:
M-!
//==============================================================================
** 文字数を数える [#t87cae47]
- 対象領域を選択し、
M-x: count-lines-region
または
M-=
とする。
- 行数と文字数が表示される。文字数は、全角も半角もそれぞれ1文字として扱われる。
//==============================================================================
** 行をウインドウ幅で折り返す・折り返さない [#rde48c86]
- 下記のコマンドで toggle 出来る
M-x toggle-truncate-lines
C-x x t
//==============================================================================
** ファイルを read-only で開く [#sd5faa53]
C-x C-r
//==============================================================================
** HTML文書編集での自動補完 [#d02f9e86]
- yahtmlを使う(yahtmlは、YaTeXに付属しているもの)。
- [[参考リンク>http://www.namazu.org/~tsuchiya/elisp/yahtml-mode.html]]
//==============================================================================
** 現在の文字サイズの変更 [#na2363e5]
|~binding |~command |~description |
|C-x C-- |text-scale-adjust |文字サイズを小さくする |
|C-x C-+ |text-scale-adjust |文字サイズを大きくする |
|C-x C-0 |text-scale-adjust |文字サイズを初期値に戻す |
//==============================================================================
** 起動済みのemacs にファイルを渡す (emacsclient) [#ob79c7cd]
- emacs起動時に、emacs-serverが起動するようにしておく必要がある。
-- .emacs に以下の行がなければ追記する:
(server-start)
- 起動済みのemacsに、コマンドラインからファイルを渡す方法
$ emacsclient <file-name> &
-- ファイルを送っただけのようで、実際には送り先のemacsとは別プロセスとして稼働するらしい。 '&' を付けないと、コマンドを打った端末のフォアグラウンドジョブになってしまう。
-- 上記コマンドを打った端末を終了すると、送り先のemacsからも、送られたファイルのエントリが消えてしまうので注意すること。
-- どうしてもemacsclientを起動した端末が死んでも構わないようにしたいなら、nohupコマンドから起動すればよい。
$ nohup emacslient <file-name> &
→[[System/Process#never-kill]]
////////////////////////////////////////////////////////////////////////////////
* キーバインド [#b4420c29]
//==============================================================================
** prefix の指針 [#z4320821]
|~prefix-key |~description |
|C-x |システムコマンドが使用する |
|C-c |ユーザが定義する。(拡張機能の実装ではこれはなるべく使用しないようにする) |
|M-g |行移動に関するキーバインドが定義される |
////////////////////////////////////////////////////////////////////////////////
* モードライン [#q8d089ae]
- モードラインの表示例
---------------------------------------------------------------------------------------------------------------------------
-UU-:----F1 color-moccur.el 16% (665,0) Git-master (ELisp/d GitGutter ARev FlyC:0|119 Develock ElDoc) [dmoccur-list]
---------------------------------------------------------------------------------------------------------------------------
- 文字コード
|~表記 |~文字コード |~emacs での呼称 |
|U |Unicode |utf-8, utf-16, utf-7, etc., |
|S |Shift_JIS |sjis (shift_jis) |
|J |JIS |iso-2022-jp, etc., |
|E |EUC (JP) |euc-jp, euc-jis-2004, etc., |
|1 |Latin-1 |latin-1 (iso-8859-1) |
- 改行コード
|~表記 |~改行コード |~emacs での呼称 |
|: |LF |unix |
|(DOS) |CR+LF |dos |
|(MAC) |CR |mac |
//==============================================================================
** モードラインの書式設定 [#o351158a]
|~format |~description |~remark |
|%b |カレントバッファ名 |(buffer-name) の値 |
|%f |ファイルのフルパス |(buffer-file-name) の値 |
|%F |選択中のフレーム | |
|%* |バッファが readonly であれば "%", 変更されていれば "*", それ以外は "-" を表示する | |
|%+ |バッファが readonly であっても変更されていれば "*", 変更されていなければ "%", それ以外は "-" を表示する | |
|%& |バッファが readonly であっても変更されていれば "*", それ以外は "-" を表示する | |
|%s |サブプロセスのステータス |(process-status) の値 |
|%l |カーソルの行番号 | |
|%c |カーソル一のカラム番号 | |
|%i |バッファのファイルサイズ |1byte 単位 |
|%I |~|kB/MB/GB |
|%p |ウインドウの上端より上にあるバッファ量の割合 |先頭なら Top", 途中はパーセンテージ、終端なら "Bottom", 全て表示している場合は "All" と表示する |
|%P |ウインドウの下端より下にあるバッファ量の割合 |~|
|%n |ナローイング中であれば "Narrow" を表示する | |
|%t |ファイルがテキストであれば "T", バイナリであれば "B" を表示する |但し、OSによる |
|%z |キーボード、端末、ファイルの文字コードを表示 |キーボードと端末は、ターミナル環境のみ |
|%Z |文字コードと改行コードを表示する | |
|%e |エラーメッセージを表示する | |
|%@ |ファイルがローカルホストであれば "-", リモートであれば "@" を表示する | |
|%[ |再帰編集のレベルを "[" の数で表示する。 "%]" も同様 | |
|%% |"%" を表示 | |
|%- |無限に "-" を表示する | |
////////////////////////////////////////////////////////////////////////////////
* 設定関連 [#l0e4033f]
(setq frame-title-format (format "emacs@%s : %%f" (system-name))) ; タイトルバーの表示書式にファイル名を入れる
//==============================================================================
** OS による処理分岐 [#h759b01c]
(when (eq system-type 'gnu/linux)
; Linux の場合
)
(when (eq system-type 'darwin)
; Mac の場合
)
(when (eq system-type 'windows-nt)
; Windows の場合
)
(when (eq system-type 'cygwin)
; Cygwin の場合
)
//==============================================================================
** GUI / CUI による処理分岐 [#uc1c5e73]
- 変数 window-system を参照して分岐する。
-- 変数 window-system には、 X Window-System の場合は値に "x" が入り、CUI の場合は定義されない。
- 分岐処理の例
-- 例1
(when window-system (progn
;; GUI用設定
))
(when (not window-system) (progn
;; CUI用設定
))
-- 例2
(if window-system (progn
;; GUI用設定
)
(progn
;; CUI用設定
))
-- 実使用例
--- Menu を開くコマンドは、emacs-28.2 時点では GUI と CUI で異なる為、下記のように分岐する:
(if window-system
(global-set-key "\M-m" 'accelerate-menu); メニューバーのメニュー (X)
(global-set-key "\M-m" 'menu-bar-open); メニューバーのメニュー (CUI)
)
//==============================================================================
** フォント設定 [#ld049214]
+ Menu → "Options" → "Set Default Font..." でフォントを選択。
+ Menu → "Options" → "Save Options" で設定を保存する。(この操作により、上で行ったフォント設定が ${HOME}/.emacs.d/init.el に保存される)
- フォントを "Noto Sans Mono" に設定する(${HOME}/.emacs/init.el の記載):
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(default ((t (:family "Noto Sans Mono" :foundry "GOOG" :slant normal :weight normal :height 113 :width normal)))))
//==============================================================================
** which-function-mode [#which-function-mode]
- ソースコードを開いているとき、カーソル位置が何らかの関数内にある場合に、モードラインにその関数名を表示する機能。
- 設定するには、この機能を使いたいモード(C/C++/perl/java/etc.)の hook で以下のように呼び出す:
-- 設定例:C/C++ (一旦 hook 用関数を定義してその中で呼び出すようにし、これを hook にセットしている)
; c系言語共通設定
(defun c-c++-mode-common-conf ()
"common settings for C/C++"
(if (which-function-mode nil) (which-function-mode)) ; ; 現在の関数名をモードラインに表示
)
(add-hook 'c-mode-common-hook 'c-c++-mode-common-conf)
-- 設定例:Perl (hook 用関数の代わりにλ関数を使用し、それを hook にセットしている)
(setq perl-mode-hook
#'(lambda ()
(if (which-function-mode nil) (which-function-mode)) ; ; 現在の関数名をモードラインに表示
))
- 設定時の注意点
-- 各モードの hook 以外のところ(例えばそれより前の段階で読み込まれる設定箇所)で呼んでも上手く機能しない。
//==============================================================================
** lisp の場所を設定する [#sa55267e]
- load-path : 指定したディレクトリを lisp を走査する場所として設定する
-- 書式:
(load-path <path-to-lisp-dir>)
-- 書式例:
(load-path (expand-file-name "~/.emacs.d/lisp")) ; ${HOME}/.emacs.d/lisp 相当の絶対パスに変換される
- normal-top-level-add-subdirs-to-load-path : load-path に登録されたディレクトリの下位ディレクトリも lisp を走査の対象に含める
-- 書式:
(normal-top-level-add-subdirs-to-load-path)
-- 環境によってはアクセス権の問題等でエラーになる場合があるので注意すること。
//==============================================================================
** タイトルバーの表示書式にファイル名を入れる [#h8aae4c1]
(setq frame-title-format (format "emacs@%s : %%f" (system-name)))
//==============================================================================
** 文字色の変更 [#j1818f18]
- emacs 上で指定された文字色を変更する方法について。
- magit, xcscope などのパッケージで、文字色の制御を行っているものがある。これらは端末の background color などの関係で、場合によって却って見難くなることがある。
//------------------------------------------------------------------------------
*** terinal 上で動作させる場合 [#q0925a19]
*** terminal 上で動作させる場合 [#q0925a19]
- 方法1
$ cat ${HOME}/.bashrc
alias emacsd='env TERM=xterm emacs --daemon'
alias emacs='emacsclient -t'
- 方法2
$ TERM=xterm-256color emacs -nw
- 方法3 init.elに以下を追加する
(defun terminal-init-gnome ()
"Terminal initialization function for gnome-terminal."
;; This is a dirty hack that I accidentally stumbled across:
;; initializing "rxvt" first and _then_ "xterm" seems
;; to make the colors work... although I have no idea why.
(tty-run-terminal-initialization (selected-frame) "rxvt")
(tty-run-terminal-initialization (selected-frame) "xterm"))
- 方法4 init.elに以下を追加する
(add-hook 'tty-setup-hook
'(lambda ()
(set-terminal-parameter nil 'background-mode 'dark)))
//------------------------------------------------------------------------------
*** どの変数で色定義されているかを調べる [#eefe35f4]
+ 対象となる文字列にカーソルを合わせた上で、以下を実行する:
M-x: describe-face
すると、ミニバッファに以下のように表示される:
Describe face (default `cscope-file-face'):
+ ここで決定(return キーを押す)と、以下のように表示される:
Face: cscope-file-face (sample) (customize this face)
Documentation:
Face used to highlight file name in the *cscope* buffer.
Defined in `xcscope.el'.
Family: unspecified
Foundry: unspecified
Width: unspecified
Height: unspecified
Weight: unspecified
Slant: unspecified
Foreground: yellow
DistantForeground: unspecified
Background: unspecified
Underline: unspecified
Overline: unspecified
Strike-through: unspecified
Box: unspecified
Inverse: unspecified
Stipple: unspecified
Font: unspecified
Fontset: unspecified
Inherit: unspecified
//------------------------------------------------------------------------------
*** 色変更の定義 [#v3047709]
+ 上記を元に、以下のように設定してやれば、色を変えることが出来る
(set-face-foreground 'cscope-file-face "#d54e53") ; yellow → (RGB)=(0xd5,0x4e,0x53)
//==============================================================================
** 色設定 [#uf6d738d]
- ${HOME}/.bashrc での、emacs/XEmacs の色設定
alias emacsk='emacs -bg "#303030" -fg white'
alias emacsb='emacs -bg azure'
alias emacsy='emacs -bg lightyellow'
alias emacsg='emacs -bg "#e0ffe0"'
alias emacsr='emacs -bg "#fff5f5"'
alias xemacs='/usr/bin/xemacs21'
alias xemacsb='xemacs -bg azure'
alias xemacsy='xemacs -bg lightyellow'
alias xemacsg='xemacs -bg "#e0ffe0"'
alias xemacsr='xemacs -bg "#fff5f5"'
//==============================================================================
** wahel-theme [#wahel-theme]
- 暗色形テーマの一つ。
- 概ね良いのだが、以下の問題がある:
-- which-function-mode でモード行に表示する関数名が暗い灰色背景に紺色文字の組み合わせとなり、見難い。
--- 以下のようにすると見やすくなる:
(custom-set-faces
;; which-function-mode の関数名表示の色を変更する
'(which-func ((t (:foreground "yellow"))))
)
-- C/C++ ソースコードの ediff で、コメント行同士の比較が見難くなる(特にBペイン)。
//------------------------------------------------------------------------------
*** 参考リンク [#g0d03289]
- [[waher-theme.el : ダークなカラーテーマ>http://emacs.rubikitch.com/waher-theme/]]
- [[Waher Theme | Emacs Themes>https://emacsthemes.com/themes/waher-theme.html]]
- [[GitHub>https://github.com/emacsfodder/emacs-waher-theme]]
//==============================================================================
** {menu|tool}-barを消す [#y7f4f9fe]
(tool-bar-mode 0) ; tool bar を表示しない
(menu-bar-mode 0) ; menu bar を表示しない
(which-function-mode 1) ; 現在の関数名をモードラインに表示
//==============================================================================
** 行頭に行番号を表示する(モード行ではなく) [#hd23498b]
- linum-mode を使用する(Emacs23以降で有効)
M-x: linum-mode
- Toggle する関数
; 行番号表示をトグル
; http://qiita.com/yyamamot/items/df430d4e725ea38ffc9f
(defun toggle-linum-mode ()
"toggle display line number"
(interactive)
(setq linum-format "%4d ")
(linum-mode
(if linum-mode -1 1)))
(global-set-key [f5] 'toggle-linum-mode) ; linum-mode
- 参考:[[Emacsで行番号表示をトグルする>http://qiita.com/yyamamot/items/df430d4e725ea38ffc9f]]
//==============================================================================
** モードラインに現在カーソルが位置している関数の関数名を表示する [#h095036c]
- モードラインに、現在カーソルがある位置の関数名を動的に表示することが出来る。
M-x: which-function-mode
- .emacs に設定するには、
(setq which-function-mode t)
////////////////////////////////////////////////////////////////////////////////
* Time-stamp [#m59e6eee]
//==============================================================================
** モードラインの現在時刻の表示 [#l41ac910]
- 現在時刻を表示する
(display-time)
- 24時間表示にする
(setq display-time-24hr-format t)
- 24時間制・秒も表示する
(setq display-time-interval 1)
(setq display-time-string-forms
; '((format "%s:%s:%s" 24-hours minutes seconds))
'((format "%s.%s.%s(%s) %s:%s:%s" day month year dayname 24-hours minutes seconds)) ; ヨーロッパ式
; '((format "%s/%s/%s(%s) %s:%s:%s" year month day dayname 24-hours minutes seconds)) ; 日本式
)
-- 秒の表示は、フォーマットで秒まで指定しただけでは駄目で、表示を更新するインターバルの設定値 display-time-interval を1にする必要がある(この値は、デフォルト値が60、つまり1分となっている為)。
//==============================================================================
** use-package [#use-package]
- 設定を、統一的な分かり易い記述で書けるようにするライブラリ。
- use-package マクロを利用することで、ライブラリのロード、遅延ロード、設定を分かり易く記述出来る。
- 取得元: https://github.com/jwiegley/use-package.git
//------------------------------------------------------------------------------
*** use-package 参考リンク [#use-package-link]
- [[use-packageで可読性の高いinit.elを書く - Qiita>https://qiita.com/kai2nenobu/items/5dfae3767514584f5220]]
- [[use-packageの使い方 [QumaWiki]>https://www-he.scphys.kyoto-u.ac.jp/member/shotakaha/dokuwiki/doku.php?id=toolbox:emacs:use-package:start]]
//==============================================================================
** Time-stamp [#m59e6eee]
; Time-stamp
; http://homepage.mac.com/zenitani/elisp-j.html#time-stamp
(require 'time-stamp)
(setq time-stamp-start "Last updated: <") ; 開始文字列の設定。通常は "Time-stamp: <>"
;; 日本語で日付を入れたくないのでlocaleをCにする
(defun time-stamp-with-locale-c ()
(let ((system-time-locale "C"))
(time-stamp)
nil))
(if (not (memq 'time-stamp-with-locale-c write-file-hooks))
(add-hook 'write-file-hooks 'time-stamp-with-locale-c))
; (setq time-stamp-format "%3a %3b %02d %02H:%02M:%02S %Z %:y")
(setq time-stamp-format "%04y/%02m/%02d %02H:%02M:%02S %Z") ; YYYY/MM/DD HH:MM:SS JST
////////////////////////////////////////////////////////////////////////////////
* 文字数を数える [#t87cae47]
- 対象領域を選択し、
M-x: count-lines-region
または
M-=
とする。
- 行数と文字数が表示される。文字数は、全角も半角もそれぞれ1文字として扱われる。
////////////////////////////////////////////////////////////////////////////////
* isearch で、カーソルの位置にある単語を検索対象にする [#t5442189]
//==============================================================================
** isearch で、カーソルの位置にある単語を検索対象にする [#t5442189]
- isearch時に、 C-w と打てばOK
////////////////////////////////////////////////////////////////////////////////
* shell-mode で制御文字を処理する [#s805f2e5]
//==============================================================================
** shell-mode で制御文字を処理する [#s805f2e5]
; shell-mode で制御文字を処理する。
(autoload 'ansi-color-for-comint-mode-on "ansi-color"
"Set `ansi-color-for-comint-mode' to t." t)
(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)
////////////////////////////////////////////////////////////////////////////////
* ファイルを read-only で開く [#sd5faa53]
C-x C-r
////////////////////////////////////////////////////////////////////////////////
* バックアップファイルを作らないようにする [#d7ff8fd4]
//==============================================================================
** バックアップファイルを作らないようにする [#d7ff8fd4]
(setq make-backup-files nil) ; *.~ とかのバックアップファイルを作らない
(setq auto-save-default nil) ; .#* とかのバックアップファイルを作らない
////////////////////////////////////////////////////////////////////////////////
* 選択領域を [DEL] で一気に消せるようにする [#y95ca8b8]
//==============================================================================
** 選択領域を [DEL] で一気に消せるようにする [#y95ca8b8]
; (setq delete-selection-mode t)
(delete-selection-mode)
////////////////////////////////////////////////////////////////////////////////
* HTML文書編集での自動補完 [#d02f9e86]
- yahtmlを使う(yahtmlは、YaTeXに付属しているもの)。
- [[参考リンク>http://www.namazu.org/~tsuchiya/elisp/yahtml-mode.html]]
////////////////////////////////////////////////////////////////////////////////
* scroll を1行単位にする [#l150a348]
//==============================================================================
** scroll を1行単位にする [#l150a348]
(setq scroll-step 1)
////////////////////////////////////////////////////////////////////////////////
* 分割した window のサイズを変える [#y029a37e]
//==============================================================================
** 分割した window のサイズを変える [#y029a37e]
|~command |~description |~remark |
|M-x: enlarge-window |縦方向にサイズを大きくする | |
|M-x: shrink-window |縦方向にサイズを小さくする | |
|M-x: enlarge-window-horizontally |横方向にサイズを大きくする | |
|M-x: shrink-window-horizontally |横方向にサイズを小さくする | |
- 参考: emacs25.1.1 では以下のように設定することで、キー割り当てが出来た
(global-set-key (kbd "M-<up>") 'enlarge-window)
(global-set-key (kbd "M-<down>") 'shrink-window)
(global-set-key (kbd "M-<right>") 'enlarge-window-horizontally)
(global-set-key (kbd "M-<left>") 'shrink-window-horizontally)
- 参考: emacs23 では以下のように設定することで、キー割り当てが出来た
(global-set-key "M-<up>" 'enlarge-window)
(global-set-key "M-<down>" 'shrink-window)
(global-set-key "M-<right>" 'enlarge-window-horizontally)
(global-set-key "M-<left>" 'shrink-window-horizontally)
////////////////////////////////////////////////////////////////////////////////
* ウインドウ自動分割時の制御 [#k8d8ac5a]
//==============================================================================
** ウインドウ自動分割時の制御 [#k8d8ac5a]
- ウインドウが自動分割される際の、垂直分割・水平分割の制御
- 垂直分割を防ぐには、下記を設定する:
(setq split-width-threshold nil)
- 挙動としては、
++ split-height-threshold の値が選択したウィンドウより小さい場合、下側にウィンドウを分割する。
++ そうでない場合、 split-width-threshold がウィンドウの横幅より小さい場合は、右側に分割する。
++ どちらも満たさず、既にウィンドウが分割されてない場合は、下側にウィンドウを分割することを試みる。
////////////////////////////////////////////////////////////////////////////////
* beep 音を消す [#oe941343]
//==============================================================================
** beep 音を消す [#oe941343]
- 以下を設定することで、beep が一切無効になる
(setq ring-bell-function 'ignore) ; beep を一切無効にする
- 嘗ては、以下の設定でカスタマイズすることが出来たが、emacs 24.4.1 では効かないようである。
-- Visible bell にする
(setq visible-bell t);; Visual Bell有効(エラー時画面反転)
;(setq visible-bell nil);; Visual Bell無効(エラー時ブザー音)
-- beep を鳴らさないようにする
; (setq message-beep 'silent)
//==============================================================================
** 今日の日付を挿入する [#af85099b]
(defun today()
(interactive)
(insert (format-time-string "%Y/%m/%d" (current-time))))
////////////////////////////////////////////////////////////////////////////////
* 前のウインドウに戻る [#ia6f365e]
//==============================================================================
** 前のウインドウに戻る [#ia6f365e]
; XEmacsにはあるが、emacsにはない(!)
; http://matome.replore.com/index.php?title=Emacs_Lisp%E3%81%BE%E3%81%A8%E3%82%81
; xemacsに合わせて、関数名を backward-other-window に変更。
; (defun other-window-backward (&optional n)
(defun backward-other-window (&optional n)
"Select nth previous window."
(interactive "P")
(other-window (- (prefix-numeric-value n))))
////////////////////////////////////////////////////////////////////////////////
* 起動済みのemacs にファイルを渡す (emacsclient) [#ob79c7cd]
- emacs起動時に、emacs-serverが起動するようにしておく必要がある。
-- .emacs に以下の行がなければ追記する:
(server-start)
- 起動済みのemacsに、コマンドラインからファイルを渡す方法
$ emacsclient <file-name> &
-- ファイルを送っただけのようで、実際には送り先のemacsとは別プロセスとして稼働するらしい。 '&' を付けないと、コマンドを打った端末のフォアグラウンドジョブになってしまう。
-- 上記コマンドを打った端末を終了すると、送り先のemacsからも、送られたファイルのエントリが消えてしまうので注意すること。
-- どうしてもemacsclientを起動した端末が死んでも構わないようにしたいなら、nohupコマンドから起動すればよい。
$ nohup emacslient <file-name> &
→[[System/Process#never-kill]]
////////////////////////////////////////////////////////////////////////////////
* 検索時に大文字・小文字を区別するかしないかの設定 [#case-fold-search]
//==============================================================================
** 検索時に大文字・小文字を区別するかしないかの設定 [#case-fold-search]
(setq default-case-fold-search nil) ; 大文字・小文字を区別させる(〜emacs23.1)
(setq case-fold-search nil) ; 大文字・小文字を区別させる (emacs23.2〜)
- emacs23.2 以降では default-case-fold-search ではなく case-fold-search を使うように推奨されている&br;(see also M-x describe-variable case-fold-search)
////////////////////////////////////////////////////////////////////////////////
* ediff [#ediff]
//==============================================================================
** control window を別ウインドウにしないようにする [#s0475775]
** ediff の control window を別ウインドウにしないようにする [#ediff]
- X11 環境では、デフォルトではコントロールウインドウが別のウインドウとして表示される。これをコンソール内で ediff を起動したときと同様、同じウインドウ内に表示するには、以下の設定を行う:
- 方法1
++ M-x: customize-group
++ [Ediff Window Setup Function] 行頭の三角をクリックし、詳細を表示する
++ [Value Menu] をクリックし、プルダウンから [Single Frame] を選択
++ バッファ先頭付近の [Apply and Save] をクリックして設定・保存する
- 方法2:以下を設定する:
;; コントロール用のバッファを同一フレーム内に表示
(setq ediff-window-setup-function 'ediff-setup-windows-plain)
;; diffのバッファを上下ではなく左右に並べる
(setq ediff-split-window-function 'split-window-horizontally)
(provide 'ediff.conf)
//------------------------------------------------------------------------------
*** 参考リンク [#qd6e9c5e]
- [[同一フレーム内にediffのコントロールバッファを表示>https://yamadawindsurf.blogspot.com/2016/07/ediff.html]]
- [[Emacs Lisp TIPS>https://sci.nao.ac.jp/MEMBER/zenitani/elisp-j.html]]
////////////////////////////////////////////////////////////////////////////////
* カレンダーで日本の祝日を表示する [#u4db1263]
//==============================================================================
** カレンダーで日本の祝日を表示する [#u4db1263]
- M-x: calendar で表示するカレンダーで日本の祝日を表示する方法。
- japanese-holidays.el を入手する
-- 入手先: https://github.com/emacs-jp/japanese-holidays/blob/master/japanese-holidays.el
- 設定
-- 参考: http://blog.livedoor.jp/tek_nishi/archives/3027665.html
- enmacs 起動時に cl-lib が見つからないと怒られた場合
-- cl-lib.el を入手し、load-path の通っているところに配置する。ちなみに Debian7 では相当するファイルはリポジトリにない模様。自分で取ってきて仕込むこと。
-- 入手先: http://elpa.gnu.org/packages/cl-lib.html
////////////////////////////////////////////////////////////////////////////////
* gdb-mode [#gdb-mode]
- 設定(${HOME}/.emacs.d/site-lisp/gdb.conf.el)
;; http://d.hatena.ne.jp/kobapan/20090506/1241593531
;;; GDB 関連
;;; 有用なバッファを開くモード
(setq gdb-many-windows t)
;;; 変数の上にマウスカーソルを置くと値を表示
(add-hook 'gdb-mode-hook '(lambda () (gud-tooltip-mode t)))
;;; I/O バッファを表示
(setq gdb-use-separate-io-buffer t)
;;; t にすると mini buffer に値が表示される
(setq gud-tooltip-echo-area nil)
* 自動インデントにおけるインデント量のカスタマイズ [#r8a90f0f]
//==============================================================================
** C++ [#ja3a6f5a]
//------------------------------------------------------------------------------
*** namespace の後のインデント [#m5fa651a]
- namespace 内でのインデント量を 0 に設定したい場合
+ 下記のようにカーソルをおく
namespace hogehoge {
| ← ここにカーソルをおく
}
+ C-c C-s をタイプする。するとミニバッファにこのときのインデント量を司る変数名が表示される:
Syntactic analysis: ((innamespace 353) (topmost-intro 353))
-- ここでは、''innamespace'' がインデント量を司る変数
+ インデント量を変更する
-- 直接反映する場合
+++ C-c C-o をタイプする
+++ 変更対象を指定する
innamespace [Enter]
+++ インデント量を指定する
0 [Enter]
+++ 以上で namespace 内のインデント量が 0 に変更される
-- 設定ファイルに記述する場合
;; c++ 設定
(defun c++-mode-common-conf ()
"common settings for C/C++"
; (c-set-style "bsd")
; (c-set-style "cc-mode")
(c-set-style "stroustrup")
; (c-set-style "ellementel")
;; 注: c-set-offset は、 c-set-style よりも後に記述する必要がある
(c-set-offset 'innamespace 0) ;; namespace の後のインデント量指定
)
(add-hook 'c-mode-common-hook 'c++-mode-common-conf)
- gdb-mode のコマンド
|~bindings |~description |~remark |
|C-x C-a C-t |ソースコードの現在のカーソル位置に break point を設定する | |
|C-h m |EmacsのGDBモードの機能に関する説明を表示 | |
|M-s |Step実行。関数なら入って止まる | |
|C-x C-a C-s |~|~|
|M-n |GDBのnextコマンドのように、 関数呼び出しをすべてスキップして、 現在の関数内の次のソース行まで実行 | |
|C-x C-a C-s |~|~|
|M-i |GDBのstepiコマンドのように、 1命令を実行 | |
|C-x C-a C-i |~|~|
|M-x gdb-nexti |GDBのnextiコマンドを使って、 次の命令まで実行 | |
|C-c C-f |GDBのfinishコマンドのように、 選択されたスタック・フレームを終了するまで実行を継続 | |
|M-c |GDBのcontinueコマンドのように、 ユーザ・プログラムの実行を継続 | |
|M-u |GDBのupコマンドのように、 数値引数によって示される数だけ上位のフレームに移動 | |
|M-d |GDBのdownコマンドのように、 数値引数によって示される数だけ下位のフレームに移動 | |
|C-x & |カーソルの位置にある数値を読み取り、 GDBのI/Oバッファの末尾に挿入 | |
|C-x C-a C-r |次の break point まで実行 | |
|C-x C-a C-f |現在のカーソル位置まで実行 | |
////////////////////////////////////////////////////////////////////////////////
* helm [#helm]
** 入手先 [#s31bbdeb]
- [[GitHub: emacs-helm/helm>https://github.com/emacs-helm/helm]]
** 参考リンク [#g7fffd17]
- [[初心者〜初級者のためのEmacs-Helm事始め : 前編>https://qiita.com/jabberwocky0139/items/86df1d3108e147c69e2c]]
- [[【Emacs】helmを使う>https://www.yokoweb.net/2017/01/20/emacs-helm-mode/]]
////////////////////////////////////////////////////////////////////////////////
* clang-format [#o04f0607]
//==============================================================================
** 環境構築 [#qeac0163]
+ パッケージをインストールする
apt-get install clang-tools-7 clang-format
+ clang-tools のパスを通す
export PATH=/usr/lib/llvm-7/bin:${PATH}
+ emacs 向けパッケージの設定
-- package-install を使う場合
M-x package-install lsp-mode lsp-ui company-lsp dash-el elpa-f elpa-markdown-mode dash-el
--- これとは別途、パッケージが存在しない ht.el を、下記と同様に取得する。
-- 個別に lisp を取ってくる場合
+++ 以下のリポジトリを取得する:
|~package name |~package repository URI |~remark |
|lsp-mode |http://github.com/emacs-lsp/lsp-mode.git |各種LSPの言語モードを実装している。 C/C++ の設定もここに含まれる。 |
|lsp-ui |https://github.com/emacs-lsp/lsp-ui.git |補完を担うcompany-modeのLSP向け設定 |
|company-lsp |https://github.com/tigersoldier/company-lsp.git |ドキュメントの表示など各種アクションを実装している。 |
|elpa |https://git.savannah.gnu.org/git/emacs/elpa.git |elpa/packages/cl-generic 等を使用する為に取得する。サイズが大きいので注意。 |
|ht |https://github.com/Wilfred/ht.el.git |debian9のパッケージには存在しない。lsp-mode の動作に必要 |
|dash |https://github.com/magnars/dash.el | |
|f |https://github.com/rejeep/f.el | |
|markdown-mode |https://github.com/jrblevin/markdown-mode.git | |
|clang-format |https://github.com/sonatard/clang-format.git |clang-format-<version> package に含まれる |
* emacs のローカルビルド [#i3fe752c]
+ 最新のコードを取得する
-- この項の執筆時点の最新は 27.1
http://ftp.jaist.ac.jp/pub/GNU/emacs/emacs-27.1.tar.xz
-- 又は、開発リポジトリから取得する
git://git.savannah.gnu.org/emacs.git
// git clone git://git.sv.gnu.org/emacs.git
--- 開発リポジトリから取得した場合は、 tag で checkout してから使う
$ git checkout refs/tags/emacs-27.1
~
+++ 上記各リポジトリを tag で checkout する
|~package name |~tag |~remark |
|lsp-mode |refs/tags/7.0 | |
|lsp-ui |refs/tags/7.0 | |
|company-lsp |refs/tags/2.1.0 | |
|elpa |(HEAD) |tagは試行中。動かなかったら検討する。 |
~
+++ 上記各リポジトリのファイルが emacs から見える場所に配置する。~
${HOME}/.emacs.d/init.el への記述例
;;; ~/.emacs/init.el
;;; ~/.emacs.d/site-lisp 配下に各リポジトリを配置した場合の設定例
(setq load-path (cons (expand-file-name "~/.emacs.d/site-lisp/dash") load-path)) ; dash
(setq load-path (cons (expand-file-name "~/.emacs.d/site-lisp/elpa/packages/cl-generic") load-path)) ; cl-generic
(setq load-path (cons (expand-file-name "~/.emacs.d/site-lisp/ht") load-path)) ; ht.el
(setq load-path (cons (expand-file-name "~/.emacs.d/site-lisp/elpa/packages/hydra") load-path)) ; lv.el
(setq load-path (cons (expand-file-name "~/.emacs.d/site-lisp/elpa/packages/spinner") load-path)) ; spinner.el
(setq load-path (cons (expand-file-name "~/.emacs.d/site-lisp/elpa/packages/company") load-path)) ; company.el
(setq load-path (cons (expand-file-name "~/.emacs.d/site-lisp/markdown-mode") load-path)) ; markdown-mode
(setq load-path (cons (expand-file-name "~/.emacs.d/site-lisp/lsp-mode") load-path))
(require 'lsp-mode)
(setq load-path (cons (expand-file-name "~/.emacs.d/site-lisp/lsp-ui") load-path))
(require 'lsp-ui)
(setq load-path (cons (expand-file-name "~/.emacs.d/site-lisp/company-lsp") load-path))
(require 'company-lsp)
(setq load-path (cons (expand-file-name "~/.emacs.d/site-lisp/clang-format") load-path))
(require 'clang-format)
~
+ 設定を記載する
;;; ~/.emacs/init.el
;; (require 'clang-format) などの記述はこれより上に ...
(add-hook 'c++-mode-hook 'company-mode) ; 補完用
(add-hook 'c++-mode-hook 'flycheck-mode) ; チェック用
(add-hook 'c++-mode-hook #'lsp)
;;; key bindings
;;; 以下は clang-format の README.md の記載より転記した。
(require 'clang-format)
(global-set-key (kbd "C-c i") 'clang-format-region) ; カーソルがある場所のコードをフォーマットする
(global-set-key (kbd "C-c u") 'clang-format-buffer) ; 現在のバッファ全体をフォーマットする
//==============================================================================
** フォーマットルールを設定する [#fbad4231]
//------------------------------------------------------------------------------
*** 用意されたフォーマットルールを利用する [#t4ca6625]
;;; ~/.emacs/init.el
;;; format-style
(setq clang-format-style-option "llvm") ; llvm スタイルのフォーマットルールを利用する場合
+ ビルドに使うパッケージをインストールする
# apt-get install autoconf xaw3dg-dev xaw3dg libjpeg-dev libpng-dev libgif-dev libtiff-dev texinfo libx11-xcb-dev liblcms2-dev gtk+-3.0-dev ncurses-dev
-- gnutls がないと怒られる場合は、以下を入れる(これら全部が本当に必要なのかは未確認)
gnutls-bin gnutls-doc libgnutls-openssl27 libgnutls30 libgnutlsxx28 libgnutls28-dev
-- gtk3 ToolKit を使う場合は、以下もインストールする
libgtk-3-dev
+ ビルドする
$ ./configure
ここでエラーが出る場合、「こういうオプションをつけろ」というメッセージが出るので、それに従う。今回の環境では ''--with-gnutls=no'' が必要だった。
$ ./configure --with-gnutls=no
$ make
//------------------------------------------------------------------------------
*** 個別に設定を行う [#xe3b81ee]
- .clang-format にルールを記載すると、それが読み込まれて適用される。
-- .clang-format は再帰的に上位ディレクトリを探しに行くようになっているので、どんな場合でも適用したい書式が決まっている場合は、 ${HOME} 直下に .clang-format を配置すると良い。
- .clang-format は、規定の書式から dump して作成することが出来る。
-- google スタイルのフォーマットルールを .clang-format に出力する例:
$ clang-format -style=google -dump-config > .clang-format
-- 出力された .clang-format に手を加えて、独自のフォーマットルール設定を作ることが出来る。
//==============================================================================
** 参考 URI [#sb5f0ebe]
- [[EmacsでC/C++用にclangdとclang-formatを使う - Qiita>https://qiita.com/kari_tech/items/4754fac39504dccfd7be]]
- [[EmacsのC/C++開発環境を整える [lsp-mode, ccls] | | meda-log>https://blog.medalotte.net/archives/473]]
- [[clang-format を導入してカスタマイズした :: プログラマになりたい人生 — プログラマになりたいおじさんの日記>https://blog.takuchalle.dev/post/2018/04/26/setup_clang_format/]]
- [[ClangFormat — Clang 11 documentation>https://clang.llvm.org/docs/ClangFormat.html]]
- [[GNU Emacs Lisp Package Archive>https://elpa.gnu.org/]]
- f.el
-- [[モダンなファイル、ディレクトリを扱うAPIのf-elのインストールと設定>https://emacs.tsutomuonoda.com/f-el/]]
-- [[Emacsのモダンなライブラリ4+1選 (2013年版)>https://qiita.com/pogin503/items/01005402dc7cfd375b55]]
- ht.el
-- [[Emacsのハッシュテーブルライブラリht-elのインストールと設定>https://emacs.tsutomuonoda.com/ht-el/]]
-- [[Emacsのモダンなライブラリ4+1選 (2013年版)>https://qiita.com/pogin503/items/01005402dc7cfd375b55]]
-- [[ht.el : 【Rubyist歓喜】ハッシュテーブルを超絶使いやすくするライブラリ>http://emacs.rubikitch.com/ht/]]
- markdown-mode
-- [[markdown-modeで“GitHub Flavored Markdown”を実現する>https://qiita.com/ybiquitous/items/34a4c3cb33f26136f670]]
////////////////////////////////////////////////////////////////////////////////
* 多言語入力 [#we290545]
//------------------------------------------------------------------------------
** ドイツ語 [#g9ed5823]
+ M-x set-input-method german
+ ウムラウトは以下のキー入力にて。ちなみに z と y が入れ替わるので、慣れてない人は注意!
|~Character |~Key binding |
|ä |C-x 8 " a |
|ü |C-x 8 " u |
|ö |C-x 8 " o |
//------------------------------------------------------------------------------
** チェコ語 [#f2ed01e8]
- uim 環境下で ''setxkbmap cz'' として使用した場合
-- 数字キー(≠テンキー)でチャールカ付き・ハーチェク付き文字の幾つかが打てる。
-- "Ctrl(+Shift)+文字" では、チャールカ付き・ハーチェク付き文字を打つことが出来ない。
|~Character |~Key binding |
|ě |2 |
|š |3 |
|č |4 |
|ř |5 |
|ž |6 |
|ý |7 |
|á |8 |
|í |9 |
|é |0 |
|ů |+ |
-- それぞれ、CAPS LOCK した状態で打つと大文字の入力となる。
- 以下は "setxkbmap cz" を ''しない''状態での説明。
++ M-x set-input-method czech
++ type following keybind
|~Character |~Key binding |
|č |+ c |
|Č |+ C |
|ď |+ d |
|Ď |+ D |
|ě |+ e |
|Ě |+ E |
|ň |+ n |
|Ň |+ N |
|ř |+ r |
|Ř |+ R |
|š |+ s |
|Š |+ S |
|ť |+ t |
|Ť |+ T |
|á |= a |
|Á |= A |
|é |= e |
|É |= E |
|í |= i |
|Í |= I |
|ó |= o |
|Ó |= O |
|ů |+ |
|Ů | ~ U|
|ú |= u|
|Ú |= U|
|ý |= y|
|Ý |= y|
////////////////////////////////////////////////////////////////////////////////
* html-mode [#n74258af]
** キーバインド [#c69b3536]
|~key |~command |~description |~remark |
|C-c C-j |html-line |改行+ <br>挿入 | |
|C-c C-h |html-paragraph | <p> 挿入 | |
|C-c C-a |sgml-attributes | | |
|C-c C-b |sgml-skip-tag-backward |一つ前の開始タグまで戻る(?)| |
|C-c C-d |delete-tag |タグ単位で消す | |
|C-c C-f |sgml-skip-tag-foward |1つ先の終了タグまで飛ぶ(?) | |
|C-c / |sgml-close-tag |終了タグを挿入する | |
|C-c <1-6>|html-headline-<1-6> |h1-h6 の開始・終了タグを挿入する | |
|C-c C-c -|html-horizontal-rule |<hr> タグを挿入する | |
|C-c C-c c|html-checkboxes |'<input type="checkbox" name="' を挿入する | |
|C-c C-c h|html-href-ancor |'<a href="' を挿入する | |
|C-c C-c i|html-image |対話的に img タグを挿入する | |
|C-c C-c n|html-name-anchor |'<a name="' を挿入する | |
|C-c C-c o|html-ordered-list |番号リストの開始タグを挿入する | |
|C-c C-c r|html-radio-button |ラジオボタンを挿入する | |
|C-c C-c u|html-unordered-list |番号なしリストの開始タグを挿入する | |
|C-c DEL |sgml-delete-tag |カーソルの後ろのタグを消す | |
////////////////////////////////////////////////////////////////////////////////
* 参考リンク [#links]
- [[るびきち「日刊Emacs」>http://rubikitch.com/]]
- [[Programming in Emacs Lisp [ja]>http://www.math.s.chiba-u.ac.jp/~matsu/lisp/emacs-lisp-intro-jp.html]]
- [[Meadow/Emacs memo>http://www.bookshelf.jp/soft/meadow.html#SEC_Top]]
- [[Emacs 活用法>http://www.math.s.chiba-u.ac.jp/~matsu/emacs/emacs21/index.html]]
- [[navi.el(関数の一覧表示とジャンプ)>http://www.ne.jp/asahi/love/suna/pub/soft/navi.el/index.html]]
-- fume-mode.el は XEmacsでしか使えないが、これはemacsで使える。
- [[Emacs Lispまとめ>http://matome.replore.com/index.php?title=Emacs_Lisp%E3%81%BE%E3%81%A8%E3%82%81]]
- [[CEDET>http://sourceforge.jp/projects/sfnet_cedet/]]
-- [[Undo-tree.el>http://www.emacswiki.org/emacs/UndoTree]]
- [[Undo-tree.el>http://www.emacswiki.org/emacs/UndoTree]]