To Home
Last modified: Sat Jul 25 21:38:22 JST 2009

XEmacs


前半は XEmacs (Emacs?) の設定。
後半はプログラミング言語としての Emacs Lisp の話と、Emacs Lisp のライブラリ関数の話

もくじ

分からないことの調べかた

カスタマイズグループ (customize-group)

簡単に設定を済ませたい時は、 メニューバーの[オプション] (Helpかも)のカスタマイズでできます。が、バージョンについてなーんも考えない Emacs-lispコードを .emacsファイルに書き込むのでちょっと注意が必要です。
  M-x customize-browse  でも起動できます。
あるキーワードに対する設定を見るには customize-aproposを使えばぞろぞろでてきて設定 できます。b これと、キーバインドの変更ができれば十分だと思います。(Emacs-20.**以降の話ですが)

ヘルプコマンド

[help-command]はdefaultでC-hかF1に割り当てていることが多いようです。
apropos
  関数や、変数を調べる
command-apropos ([help-command]-a)
  関数を調べる
describe-variable ([help-command]-v)
  変数を調べる
describe-key ([help-command]-k)
  キーバインドを調べる
describe-mode ([help-command]-m)
  現在のバッファが属するモードを調べる。キーバインドも分かる。
describe-bindings ([help-command]-b)
  キーバインドのリストを表示する
list-colors-display
  使える色と色の名前を調べる
view-lossage ([help-command]-l)
  最近のキーストロークと、ミニバッファのメッセージ列を見る。

  注)便利な customize-browseですが、 ときどき(versionによって挙動が違うかも知れませんが)変更していない変数についても default値を.emacsに書き込もうとします。(sourceを見たわけではないので正確ではない かも知れませんが、customize-aproposで設定する 時に起こる)で、 customize-browseでの変更をsaveしたときに、 膨大な時間がかかることがあります(.emacsを変更している)。なので、できるだけ、 できるものは手で設定するか、customize-apropos で十分に設定項目を絞っておいた方が良いでしょう。(おそらくこれから改善されていく でしょう)

aproposで項目説明に移る(apropos-follow)

  aproposで出てきた項目の詳細を見たい時、項目にカーソルを持っていってリターンキーで 詳細が見られるのが普通だと思っていたのですが、うちでは普通ではなかったようです。 aproposの結果はHelpモードで表示されます。そして、項目説明に移るコマンドは (apropos-follow)です。よって次のように設定します。

(add-hook 'help-mode-hook
 '(lambda () 
    (define-key help-mode-map [return] 'apropos-follow)))

aproposの結果のモードはapropos-modeになっているかもしれません。その場合はhelpをapropos に置き換えると機能します。

チュートリアル

  [help-command]-t で起動します。初心者のためのEmacsガイド。まだ チュートリアルは読む価値があり。(あぁ初心者)

info

  Emacsに限らずinfoは便利です。関連項目にジャンプできるし、結構詳しく かいてあるし、目次、索引がついてるし。

Info modeでの(default)キー操作

b文頭に移動(beginning-of-buffer)
Ctrl-mカーソルの指すノードに移動(Info-follow-nearest-node)
u上のレベルのnodeに移動
s正規表現で検索
n前のnodeに移動
p次のnodeに移動

infoは項目毎にノードとして分けてあるのですっきりとして読みやすいし、ノードを跨る検索を s キー でできて便利です。ただ、前回検索を繰り返すコマンド (次を検索) がないようなので作ってみました。

(defun my-Info-search-next ()
  (interactive)
  (Info-search Info-last-search))

; うにゅ。hookがない??
;(add-hook 'Info-mode-hook
(require 'info)
(define-key Info-mode-map "\C-n" 'my-Info-search-next)

肝は前回検索した正規表現が Info-last-search に入っているということです。

man

  起動時のコマンドラインオプションを調べる時はmanを見ます。C libraryを調べるときなんかにも 重宝します。man -kでaproposと同じ挙動をします。
Tips: 英語のマニュアルを読むように設定する
  1. aproposして ^man$ といれる
  2. AproposバッファにはいってGroup:の上にカーソルをおいてEnter押す
  3. Manual Switches: という項目があるので -L en といれる (manでlocaleを設定するコマンドラインオプション)
  4. Setボタン、Saveボタンを押す

FAQ(Frequently Asked Question)


  [help-command]-Fで起動します。詳しいです。使えます。

サンプル.emacsコードを得る

  FAQで見つけました。etcディレクトリにsample.emacsなるファイルがあるので 参照してみるのもいいかと。このetcディレクトリを調べるには [help-command]-v data-directory [return]とタイプするとわかります。さっと眺めたところわからないコードが多いな。

XEmacsがconfigureされたときのオプションを知る

  system-configuration-options 変数をみてみましょう。

キーバインドを調べる(where-is / describe-bindings)

  キーバインドをお手軽に調べるコマンドはwhere-is です。このコマンドは、ある関数がどこにバインドされているかを出力します。 今のモードのキーバインドを見るにはdescribe-bindings を使うと見られます。

Emacs Lispの関数名,変数名からそれを定義するソースファイルをひらく

(find-function FUNCTION-SYMBOL)
  関数名を指定してそれを定義しているファイルを開いて定義している位置に飛ぶ.

  (find-function 'find-function)
(find-function-on-key KEY)
  キーに束縛されている関数を定義している場所に飛ぶ (\C-xKに束縛されてるかも?)

Minibufferのログ

  Minibuffer に表示されたメッセージ (たとえば (message "hoge") により表示 ) のログは " *Message-Log*" という名のバッファに入っている.バッファ名の先頭に空白が入っているので バッファリストには現れない事に注意. (switch-to-buffer " *Message-Log*") で見られる.

キーバインドについて

キーバインドを変更

(global-set-key KEY FUNCTION)で、大域的なキーバインドを設定して います。
  (local-set-key KEY FUNCTION)で、 局所的(モード特有の)キーバインドを設定できます。
  (global-set-key "\C-o" 'dabbrev-expand) は、おすすめです。(他のHPで見ました)
  (global-set-key [(control button3)] 'popup-buffer-menu)のようにすると、マウスのボタンのキーバインドも変えら れます。
  注) はまり技 C-uから始まるキーバインドを作ったら、他のC-uから 始まるキーバインド(comment-regionのコメント外し。いわばuncomment-region)が使えなく なりました。
  キーストロークの表現方法は、 info を Lispref -> Keymaps -> Key Sequences とたどると見られます。

pcのキーバインド (pc-select-mode)

Shift-[cursor_key]で リージョンを指定できます。リージョン をコピーするには(copy-primary-selection) を呼び出します。(キーにバインドすると便利です)。コピー& ペーストがわかりやすく簡単にできます。(マークとかよく知らないです)これを使うと、 Home/Endは行頭・ 行末へカーソル移動。Ctrl-[Home/End] で文頭・文末移動になります。

シェルで \C-d で EOF を送る (comint-delchar-or-maybe-eof)

  違うバージョンのEmacsをいろんなところで使ってるとこういうことに詳しくなっていきます。バッファの 終わりならばEOFを送りそうでなければ次の一文字を削除します。これを\C-dに割り当てるだけでおしまい。

ファイル毎の設定

  ファイルの末尾にファイルごとの設定を書くことができる。 "Local Variables:" を含む行から "End:"を含む行までに設定を書けて、 "VARIABLE:VAR" のように変数とその値を書く。VARIABLE のところを evalとすると VAR のところの Emacs Lisp の式を評価する。
この設定はファイルを開くときに評価されて、エラーがあるとファイルが開けなくなるので 注意が必要。
enable-local-variables を設定することでこの機能を 無効にしたり、有効にしたり評価 前にユーザーに尋ねるようにしたりできる。


  デフォルトでは euc-jp を使うのだけれど、このファイル (ここでは perl でかかれたプログラムとする) は shift_jis で保存したいという場合、ファイルの 末尾にこのように書く。
# Local Variables: 
# buffer-file-coding-system: shift_jis 
# End: 

  ファイルに namazu の index ディレクトリを関連付ける。
  Local Variables:
    namazu-default-dir: "/home/tak/.labltk_namazu /home/tak/.ocaml_namazu"
  End:

参考
  XEmacs の info の File Variables ノード
  hack-local-variables で現在のバッファの内容の Local Variables: の表記を読み込んで local variable を更新する。

ファイルの中身を変えたくない場合は find-file-hooks でファイルを判別する ようなコードを書くぐらいしか思いつかないなぁ。

ホイールマウスの設定

  この設定はdefaultの.xemacs(defaultの.emacsからloadされている) に設定されていました。とりあえず、mwheelパッケージが必要です。

(autoload
  'mwheel-install "mwheel" "Enabal mouse wheel support.")
(mwheel-install)

と設定されています。ホイールをクリックすると2番目のボタンのクリックになります。普通 のマウスだと2番目ボタンはdefaultでボタンの同時押しだそうです。

ソースコードに色をつける (font-lock-mode)

  (font-lock-mode 1)とするとソース コードに色がつきます。色が気に入らないなら、カスタマイズグループにいくなり、Emacs-lisp を自分で書くなり....。ちなみに、色を見るには (list-colors-display)を実行します。

YaTeXでfont-lockを用いた色づけをする


  hilit19ってdefaultでおしゃれな色を使えるかもれないけれど、動的な色づけを してくれないような気がして(数回仕方なく使ってただけなので知らない)あまり好きじゃない。 でもYaTeXの色づけは何でhilit19なんだーーという方に朗報です。(つまり、作者がこれを 見つけ出して喜んでいるということです)font-lockでの色づけはほぼfont-lock.elで定義され ていて(もちろん追加することもできる)tex-modeも例外ではないのです。font-lock.elに 次のような一節があります。

;; the nine billion names of TeX mode...
 (put 'bibtex-mode	'font-lock-defaults 'tex-mode)
 (put 'plain-tex-mode	'font-lock-defaults 'tex-mode)
   ..... ;;nine billion nameが続く(嘘)
 (put 'lATEx-mODe	'font-lock-defaults 'tex-mode)
 ;; ok, this is getting a bit silly ...
 (put 'eDOm-xETAl	'font-lock-defaults 'tex-mode)
  きっとLatexをみて踊り狂った人たちがたくさんのtex-modeをつくってしまった のでしょう。(というかTeX自体いろいろある)それを、いちいちいちいちfont-lock-defaults に加えているfont-lock.elの作者も偉いですね。でもこの中にはyatex-modeが含まれていない わけです。(悩みの種が増えた? font-lock.elの作者の悩みの種にならぬようにhilit19を選んだ のかも???)というわけで、この作者の気分になって以下のコードを加えます。

(require 'tex-mode)
(put 'yatex-mode 'font-lock-defaults 'tex-mode)

  つまりはtex-modeでの色づけを適用するわけですね。あぁ、これで明日から レポートを書けるようになった。(笑)

  と平和になったかと思いきや、大学の環境ではうまく行かず、adhocな方法を再び 見つけたので書いておきます。(自分がこのコードを破壊又は紛失してしまうので)

(require 'tex-mode)
(require 'font-lock)
(setq font-lock-defaults-alist
  (cons (cons 'yatex-mode
    (tex-font-lock-keywords
     tex-font-lock-keywords-1
     tex-font-lock-keywords-2)
     nil nil 
    ((?$ ."\""))
       nil (font-lock-mark-block-function .
       mark-paragraph)))
 font-lock-defaults-alist)

番外編
1.69.1を使っています。素朴にyatexをインストールして、font-lockで色づけすると、 ファイルを開いた時に(この時に色づけを行なう) "No such face: defun"というよく分からない エラーが出ました。308行目からの3行をコメントアウトすることで、エラーは出なくなりました。

 ;; (re-)define new commands/environments/counters
;    (YaTeX-19-region-section-type
;     "\\\\\\(re\\)?new\\(environment\\|command\\|theorem\\|length\\|counter\\)\\>"
;     defun)

おっかけかた
(toggle-debug-on-signal t)
ファイルを開くとエラーが出る。トレースが表示される。呼び出される関数名を grepで検索して、defunが関係しそうなところを見つける。(defunはElispのキーワードで 多く使われているので素朴にgrepすると大変)

インデントの設定

tab-width
  タブの表示幅。スペースいくつ分の幅をとるかを設定。
c-basic-offset
  インデント幅。
tab-width と c-basic-offset を入れることによって、Emacs はできるだけタブ文字を入れて インデントをいれようとする(らしい)ので、タブ文字でインデントを入れることができる。
(add-hook 'c-mode-hook
	  '(lambda ()
	     (setq c-basic-offset 4)
	     (setq tab-width 4)))

対応する括弧を強調 (paren-mode)

  対応する括弧を強調したり、対応しない括弧が来ると警告したりします。 XEmacsでは、点滅する括弧を使うことができます。

等幅で改行を入れる (auto-fill-mode)

yatex-modeではauto-fill-modeがデフォルトでonになってます。パソコンのメーラー向けの メールは行あたりの文字数をそろえて改行すると、美しいのでauto-fill-modeをonにする ように自分の設定を変えてみました。↓
(add-hook 'mew-draft-mode-hook
          '(lambda ()
             (auto-fill-mode 1)))

動的略語展開 (dabbrev-expand)

  これは便利!!同じ単語を使うことってありますよね。何度も同じ単語を打た なくても、単語の先頭の数文字を打つだけで展開してくれる嬉しい機能です。動的略語展開は今 編集しているバッファ、そして(設定によりますが)編集していない他のバッファから文字を探し てきて展開します。英語以外の言語に対しても使えますが、単語がスペースで区切られている 必要があるので、日本語に対して使うのは難しいです。

静的略語展開 (abbrev-expand)

  メジャーモードに特有の表現をあらかじめ略語で登録しておいて展開する 機能です。たとえば、Cのif文、 "if(){}"を i  で展開したいという時に使います。 メジャーモードごとに別々に略語を登録できるのが特徴です。

テンプレートファイルを挿入する (auto-insert)

  ファイルタイプによって、定型の表現がありますよね。(たとえばCなどで "おまじない"であるかもしれない #include <stdio.h>) こんなおきまりなところで タイプミスしてコンパイルエラーするのもやるせないし、タイプするのもいらいらというわ けで、auto-insertをつかいます。実体がどこにあるのかいまだに良く分かっていませんが、 あるホームページで見つけました。

(require 'autoinsert)
(add-hook 'find-file-hooks 'auto-insert)
(setq auto-insert-alist
  (append
    (("\\.cc$" . 
       (lambda ()
         (insert-string
           (concat "// "
                  (file-name-nondirectory
                  (buffer-file-name))
                  "   Created in "
                  (current-time-string)
                  "\n"))
         (insert-file
            (concat auto-insert-directory "c++-template.cc"))))
      ("\\.c$" . "c-template.c"))) ;ファイル名
   auto-insert-alist)

変数
  auto-insert-query
    auto-insertするかどうかを尋ねるか?(nilで尋ねない)
  auto-insert-directory
    テンプレートファイルのパス

制御文字の入力 (quoted-insert)

quoted-insertを実行した直後の入力を「そのまま」挿入します。だからC-*で入力 できる制御文字を挿入するのに便利です。ちなみにhexl-modeでは16進数表示されたファイルを 編集することができます。プログラムに与えるバイナリファイルを作る時や、制御文字を必要と する時に使えます。Escape文字なんかも簡単に入れられます。

モードラインに時計を表示する (display-time)

  そのまんまで、時計が表示されます。特にXEmacsを使っていて、 mode-lineの色を変えちゃってる時は(灰色は冷たい感じがしていやなので僕はkhakiです) 時計の背景は灰色になっててちょっとやな感じっておもっちゃうんですけど、さすがXEmacs。 設定できます。display-time-display-time-background にmode-lineと同じ色を指定するといい感じです。(でも、起動直後は一分たつまで灰色です。 我慢しましょう。)

背景色を変更する

例: (set-face-background 'default "aliceblue" nil '(x color))
参考: .xemacs.elのカスタマイズ - [物理のかぎしっぽ]

モードラインに左端からのカーソル位置を表示する (column-number-mode)

  (column-number-mode 1)を実行するだけで出ます。

キーボードマクロ (kbd-macro)

キーボードの動きから実行したコマンドを覚えさせて、それを繰り返し実行させる。
\C-x(start-kbd-macroキーボードマクロスタート
\C-x)start-kbd-macroキーボードマクロ終了
\C-xecall-last-kbd-macro最後に記憶させたキーボードマクロを実行
call-last-kbd-macro は universal-argument つきで回数指定して繰り返し実行すると効果的

コード管理に (Speedbar)

  現在編集中のパスにあるファイル(とか、ホーム以下)をスピードバー が表示してくれます。マウスのクリックでファイルを素早く(?)開くことができます。プロ グラムのソースコードをクリックすると、そのソースで定義されている関数を表示してくれ ます。その関数をマウスで指定するだけで、その関数が定義されている場所にカーソルが移動 します。ソースコード管理に使える!
異なるframeで立ち上がるので、 other-frame で speedbar にスイッチできる

タグジャンプ (etags)

一つのframe(←Emacsでは frame > window 普通の感覚(!?)でwindowというものは Emacsではframeという)で飛べたらいいな。マウスでクリックは極力したくないというときにお勧め です。つまりは、Speedbarは操作は(多分)マウスでやんなきゃならないから(僕から見ると)面倒なのです。 etagsは正規表現で定義されたタグをファイルに保存し、ジャンプできるようにします。

タグ表の生成

etags FILENAME で引数で与えたファイルに対してタグ表を作ります。FILENAMEが"-"であるときは 標準入力を入力として読みます。
オプション
--language=XXX
auto ソースを自動認識する
none 特定の言語向けの動作をしない(引数からタグの正規表現を指定)
NAME ソースの言語を明示的に指定する。
デフォルトで自動認識
--regex=/TAGREGEXP[/NAMEREGEXP]/ タグの正規表現(と名前の正規表現)を指定
(後方参照は\1,\2...でできるようです。)

タグの検索

(find-tag TAGNAME &optional OTHER-WINDOW) [Meta-.]
  TAGNAMEを含むタグを見付ける。
(tags-loop-continue &optional FIRST-TIME)
  最後に実行した tags-search, tags-query-replace をそのときと同じ引数で実行する。次のタグの検索とか。
(list-tags FILE)
  ファイル中のタグを全て表示する。

定義されている主な言語とタグ

ocamltags

ocamlにはocamltagsというコマンドがあります。Elispで書かれているファイルですが 最初のrequireでcamlパッケージが見付からないと文句を言われました。そこで、ocamltags の先頭にcaml.elcファイルへのパスをload-pathに付け加えるコードを加えると 動作しました。
くわしくはEmacsのinfoのTagsを見てください。

簡単な英和/和英辞書 (edict)

  これはパッケージedictパッケージをインストールする必要があります。 辞書ファイルは、 vectorで見つけました。 (edict で検索する) オリジナル辞書を作ることもできます。(単語追加関数もあることだし) この辞書データ、何でこんな日本語入ってるの?っていうのが多くて面白いです(笑)他にも EmacsでCD-ROMの辞書データを見ることができます。百科辞典の写真データをXEmacsから見 ることもできるようです。が、辞書はどれも、高価ですねぇ。ネットワークの辞書 (eg. goo)とどっちがお得か!? ちなみに、edictはフリーです。
edict-<version>-pkg.tar.gzがバイトコンパイル済のもの。srcはElispソースのみ。

edict基本操作

edict-search-english
  英和辞書として使う。単語はminibufferからも指定できる。defaultでカーソル 位置にある単語が検索対象となる。
edict-search-kanji
  漢字に限らず日本語をregionで指定して検索。minibufferから単語を指定できない。
ちなみに、「おニャン子」という単語までも登録されてました。
  Emacs Lispをバックグラウンドで実行できればうれしいのですが、そうはいかず、 例えば"h"を検索すると4分ほど制御がきかないまま、待たされました。しかも出てくる単語"H" ,"Hな映画"って、おい(汗)作業効率を下げたくなかったら文字列(なるべく長い部分文字列)でひ きましょう。CPUパワーが十分あるなら別ですが。

辞書クライアント (lookup)

自分のマシーンでは使っていないので簡単なメモ。\M-p, \M-n は電子辞書みたいで うれしい。
lookup-history-previous (\M-p)前の検索結果へ
lookup-history-next (\M-n)次の検索結果へ

(lookup-word WORD &optional MODULE)
  カーソルの近くにある単語を検索する
(lookup-words WORD &optional MODULE)
  カーソルの近くにある単語を検索する。 * をワイルドカードとして使える。

設定メモ
  lookup を起動して、 ndtpd (辞書サーバー) に接続する設定をしているけれども、 ndtp なんて知りませんといわれたら、 /etc/services に以下の項目を指定する。 ndtp はデフォルトで 2010 ポートを listen するらしい。
ndtp            2010/tcp
ndtp            2010/udp ## 不要かも?

スペルチェッカ (flyspell)

on the fly でスペルをチェックしてくれるスペルチェッカ。 aspell が必要。
aspell を使うには ltdl ライブラリが必要。 SourceforgeにあるGNU Aspell
aspellから提供されている ispell プログラム (ラッパーかな) ispell に使わせる ようにispell-program-nameを適切に設定するか、シンボリックリンクをはるかする。
flyspell自身はaspellを使うElisp なのでインストールは簡単。
(flyspell-goto-next-error)
  次のスペルミスがある場所にカーソルを飛ばす

シェルモード (shell)

M-x shell でシェルを起動できます。コンパイルもコマンド実行もできるのでとっても便利です。 shell でパスワードを求められると時々パスワード文字列を伏せてくれます。これは、端末 をエミュレートしているわけではなくて (最近まで期待をふくめそう思っていた) 単に パスワードのプロンプトが正規表現 comint-password-prompt-regexp にマッチすると 伏せられます。
たとえば無難な設定
  "\\(.*[Pp]assword\\|pass ?phrase\\):\\s *\\'"
あまり緩くすると煩わしい。例えば password: という名前のディレクトリをつくって ls すると次の入力は伏せられる。
そこでちょっときつい設定をしておく。ssh と su に限ってみる
  ^\\(tak@.*'s password: \\|Password: \\)
ここがわかったら読む価値なしな文章 なんでsshのパスワードはXEmacsのshell上で伏せ字にならないのかな?

新しいシェルバッファの生成
shell.el のソースを読んだところ shell-multiple-shells という変数があって、その変数の値が新しい バッファを作るか否かを決めている。そこで、 Lisp の動的変数束縛との合わせ技でこんな設定をすると、 Shift F8 では新しくバッファを作って、 F8 では既存の shell の挙動にすることができる。
(global-set-key [f8] 'shell)
(global-set-key [(shift f8)] '(lambda () (interactive)
   (let ((shell-multiple-shells t)) (shell)))) ;; shell-multiple-shells を局所的にtにする。

注意すべきキー / コマンド

注)以下では、[digits]は数字キーのことをs示しています。

  defaultでuniversal-argumentコマンドが C-uにバインドされています。このキーはコマンドの プレフィックスとして用います。コマンドによってこのプレフィックスの使い方が違います。
  たとえばcomment-region はC-uを用いることでuncomment-regionとして働きます。
    (comment-outしてあるリージョンのコメント記号をはずす)
  他に、C-u [digits] [command]で[command]に数字の引数を渡せます。僕の知る 限りでは繰り返しが多いです。
   e.g.)C-u 2 1 a でaを21個連続して入力する。
  C-uを数字を入れることなく何度も押し続けると、4^[C-uを押した回数] だけの数字の引数を入れたのと同じ効果が得られます。言うまでもなく、繰り返しだと特に回数 が指数爆発するので、気をつけて使いましょう。

  この項目に関連するのがC-[digits]にバイン ドされているdigit-argumentです。これは、digitsで指 定した数字を次に続くコマンドに引数として渡すものです。上のuniversal-argumentを使うと、 Ctrlキーを押しながらでなくても数字を指定できるのに対し、これは、Ctrlを押しながら数字を 入力する点が違うだけで、機能はほとんど同じです。これも、とんでもなく大きな数を指定する とEmacsが重くなります。

  とんでもない使い方をしなければこれらは便利です。たとえばC-[-] (Ctrlをおしながら- key)の後はbackword-charと、forward-charが入れ替わります。backspace とdelete(前方)も入れ替わります。(ただし、C-[-]の直後に実行した1コマンドにのみ有効)ま とめて、文字を削除したいときなどは便利ですね。

HTMLファイルのブラウズ

現在編集中のファイルをNetscapeで見る

sgml-html-netscape-fileで、現在編集中のファイルをNetscapeで見ることが できます。html-modeでキーバインドするととっても楽です。
21.4.6 で browse-url を呼ぶとある関数が見つからないといって怒られました。 MozillaFirebirdむけのブラウズ関数を書いて、それを呼ぶように設定することで お茶を濁しました。でもこれで、 new-tab で開けるので便利!!
browse-url-browser-function にブラウズするための関数を設定すればよいです。
(defun browse-by-mozilla-firebird (url arg)
  (shell-command (format "/usr/local/MozillaFirebird/MozillaFirebird -remote 'openURL(%s, new-tab)'" url)))
(setq browse-url-browser-function 'browse-by-mozilla-firebird)

カーソル位置のURLをNetscapeに渡す

browse-url-at-pointでカーソル位置、カーソルの直前にあるURLをNetscapeに 渡してbrowseすることができます。ファンクションキーに割り当てるといい感じです。
User OptionのBrowse Url Netscape Programに起動するブラウザを指定します。

メール (mew)

マウスクリックでNetscapeにURLを渡す

browse-url-at-mouseというコマンドがあるので、それをSh-button2などに割り当て ます。
(add-hook mew-message-mode-hook
  '(lambda ()
     (define-key [(shift button2)]
        'browse-url-at-mouse)))

  クリックしたURLをNetscapeに渡してくれる。

mewでのキーバインド

Summaryモード
mew-summary-reply (a)
  返事を書く
mew-summary-resend (r)
  転送
mew-summary-goto-folder (g)
  指定したフォルダへ移動
mew-summary-refile (o)
  メールの整頓マークをつける
mew-summary-delete (d)
  メールの削除のマークをつける
mew-summary-clean-trash (D)
  ゴミ箱(trash)の中のファイルをすべて削除する。
mew-summary-exec (x)
  メールの削除、移動を実行
mew-summary-auto-refile (M-o)
  現在のフォルダにあるメールの仕分け先を決める。
mew-summary-search (/)
  メールをパターンによって検索する。パターンマッチを行なうフィールド (From,To など) を指定できる。
mew-summary-search-mark (?)
  パターンにマッチしたメールに "*" マークをつける
mew-summary-reedit [E]
  メッセージを再編集する。
mew-summary-pack [O]
  フォルダ内のメッセージに1からはじまる番号をふり直す
mew-summary-config-imget [C]
  現在有効になっている設定を変更する

Draft(草稿)モード
mew-draft-send-letter [C-cC-c]
  送信
mew-draft-prepare-attachments [C-cC-a]
  添付ファイルを張り付ける準備をする
mew-draft-prepare-attachments [C-cC-a]
  添付ファイルを張り付ける準備をする
mew-draft-cite [C-cC-y]
  引用
mew-attach-copy [c]
  ファイルをコピー

グローバル
compose-mail [C-xm]
  メール作成準備

バインドされていないコマンド
mew-summary-kill-subprocess
  imget, imls などのプロセスが走っている場合にそれを止める。たとえば、 パスワードを間違えたり、ネットワークに繋がらないのに mew-summary-get を走らせた ときに、 imget は長い間走ってしまう。それを止めるときに使う。

メールの整理

くわしくはMewのマニュアル「楽々整理整頓」に書いてあります。ここでは フォルダとフォルダ推測に絡むファイルについて書きます。

パスワードをキャッシュする

(setq mew-use-cached-passwd t)
とするとパスワードをキャッシュして再利用する。

返事をだすメールの To: フィールド宛には返事を出さない

  1.94.2 での設定。新しいのにすると変数が廃止されている。
  よくメーリングリストへの返事を a, A で出すと、対象のメールの To: フィールドにある宛名が返事メールの Cc: に コピーされて、余計なメールを出してしまうことがある。これを避けるには
(setq mew-replyto-cc-list nil)
(setq mew-noreplyto-cc-list nil)
と設定するとよい。ここに "To" が入っているために上述したような現象が起こる。これを設定せずに \C-u a, \C-u A で返事を出す癖をつけるといいらしいが.....。

MIME タイプの設定

  1.94.2 での設定。新しいのにすると変数が廃止されている。
  ファイルを添付すると拡張子から MIME タイプを推測してくれるけれど、 デフォルトだと Excel ファイル (.xls) をテキストであるとみなして、 Base64 エン コードしない。これを開くと文字化けしてしまう。(らしい) ので 拡張子が.xls であるファイルには application/vnd.ms-excel というMIME タイプを割り当てて base64エンコードする。
(setq mew-mime-content-type
      (cons
       (list "application/vnd.ms-excel"
             "\\.xls$" 'mew-b64 'mew-prog-octet-stream
             'mew-icon-application/octet-stream)
       mew-mime-content-type))
mew-mime-content-type の要素は以下のとおり。 mew-mime-content-type の 値をみて推測しているだけなので、間違ってたらごめんなさい。
1 "application/vnd.ms-excel"MIMEタイプを表す文字列。Content-Type: ヘッダ部分に 書かれる文字列
2 "\\.xls$"該当するファイル名の正規表現。ここでは拡張子 .xls
3 'mew-b64エンコーディング方法("base64")
4 'mew-prog-octet-streamエンコーディングする関数
5 'mew-icon-application/octet-streamアイコン
参考
  The MIME Information Page

mew 3.3への移行


複数アカウントの使用
mew-config-alist に複数の設定を書く。Summary mode で C を押すと切替えられる
(setq mew-config-alist
      '(("net"
	 ("inbox-folder" . "+inbox")
	 ("pop-user" . "hogemoge")
	 ("pop-server" . "mogemoge.ne.jp")
	 ("smtp-server" . "mogemoge.ne.jp")
	 ("pop-auth" . "pass")     ;; plaintext による認証。mewのデフォルトはAPOP
	 ("pop-delete" . "nil")))) ;; サーバーにメールを残す

スレッド表示
Summary modeでtt でスレッド表示モードとの切替え。 mt などでマークをつけた メールのスレッド表示をする。スレッド表示は Virtual mode で表示する。
変数設定
制限サイズを越えるメールは分割してダウンロードする機能がいつの日がついたらしく、 デフォルトで制限サイズが指定されている。これをデフォルトで設定するのは困る。画像ファイルが添付されてるメールが一瞬壊れているのかと思った
制限サイズを越えて分割してダウンロードする対象となっているメールには T が ついている。 I でそのメールを全部ダウンロードできる。でも、そんなことしません。 全部ダウンロードする設定はこう。
(setq mew-pop-size 0) ;; do not truncate!

感想
mew 2.* を試した時はメールのダウンロードが遅くてすぐにあきらめたが、3.3では ちょっと速くなったようなきがする。メールの取得までをElispで書いているので、メール 取得がバックグラウンドで実行してくれないのが困る。
日本語で名付けられたファイル名をちゃんとデコードするようになった。
Virtual mode があるのはセンスがいいと思った。異なる View を提供している。
T

おまけ
  複数アカウントのメールを読む設定
    imget / imput に依存していた1.94.2 での設定。

カレンダーで予定管理 (calendar)

  カレンダーは祝日の表示、日記、予定書き込みができます。日記や、予定は デフォルトで ~/diary というファイルに書かれます。

日記のフォーマット

最初に日付をいれて、内容を書く。内容が数行にわたる場合は内容の前に1個以上の空白を入れる。

日記の例

Sep 1, 2002 大阪、京都、名古屋のチケット発売
  メンバーリスト
  ...

mark-diary-entries (m)
  日記、予定が書き込まれた日を強調表示する
insert-diary-entry (i d)
  選択中の日の日記、予定を書き込む
view-diary-entries (d)
  選択中の日の日記、予定を表示する

日本の休日を設定する

ほんまたけるのココログ: emacs の M-x calendar で日本の祝祭日を。

XEmacsでCVSを利用する(pcl-cvs)

(cvs-update DIRECTORY &optional ARG)
  カレントディレクトリでcvs updateを実行する。カレントディレクトリの ソースをレポジトリの最新状態にする。
cvs-status
  M-s 全ファイルの状態を表示。
(cvs-examine DIRECTORY FLAGS &optional NOSHOW)
  cvs -n update を走らせて DIRECTORY の中のファイルの状態を表示する

変数
cvs-reuse-cvs-buffer
  pcl-cvs のバッファを再利用する戦略の設定。 'current, 'samedir, 'subdir, 'always のいずれか。

なまずで高速ファイル検索 (namazu)

grep + find でうんぬんとか一瞬考えましたが、いくらなんでもこれだけ遅いと悲しいかな とおもいNamazuをEmacsから使って みることにしました。用途はjava APIをキーワード検索すること。便利でしょ?
namazu.elから namazu.elをとってきてcompileなりevalなりします。<!-- 以下読み飛ばし可 そのままだとデフォルトのindexを見に行くので僕にとってはよろしくない。んだけど、 マニュアルを全然読みたがらない僕にはどこで設定すればいいかわからないので、
  1. "namazu"という文字列をgrep (プロセスとして立ち上げるはず)
  2. namazu-command にバインドされているので namazu-command をgrep
  3. call-process でプロセス起動しているので (trace 'call-process)
  4. /usr/... がindexとして指定されているようなのでそれをgrep
  5. 見つからず(汗
  6. うろうろして発見!! (コメント読めばよかったかな?)
ここまで --> namazu-default-dir を設定する。でも複数あるときは...。alistがあるが、必要に迫られたら みることにしよう。
検索はさすがに速い。出力もきれい。でもちらつきが気になる。。。

bbdbでアドレス帳作成

あまりよく分かっていません。だいたい、BBDBの出力フォーマットを真似てデータを作って みてもうまくいかない。なんでだろ? 多量のデータを自動でいれる場合、perl と Emacs lispの 連携で行うのが楽!?
(bbdb-create-internal NAME COMPANY NET ADDRS PHONES NOTES)
  自作 Emacs Lisp プログラムから bbdb を作成する場合はこの関数をよぶ。 NET はメール アドレスのリスト、PHONESはベクタのリスト。引数はちょっと特殊な構造をしている (PHONEは決まった長さを持つベクタのリスト、しかもそのベクタのパターンは2種類ある) ので、 マニュアルをよみましょう。
(bbdb-save-db &optional PROMPT-FIRST MENTION-IF-NOT-SAVED)
  データベースの内容をファイルに保存する。デフォルトで ~/.bbdb に保存される。
bbdb
  検索する。

プログラム例
mew で保存したメールのヘッダから (To, From フィールドのみ見る) メールアドレスと 名前と思われるものをbbdbに登録する。
  mymew-bbdb.el
  collect-mail-address.pl
   使いにくーいプログラム。しょっちゅう使うわけでないから(汗)
   せっかく電話番号も入るので、vCardから情報抽出するものもつくりたい。

mpg123でmp3再生 (mpg123)

まえにそういう物があるのは聞いていて知っていましたが、名前を忘れていました。mpg123ね。 プログラムはここでダウンロードします mpg123。 Emacs Lisp はこっち mpg123.el。 plaympegのフロントエンド書けば、mpg123をインストールしなくてもいけるんだけど。まぁ、 怠惰なので書きません。playlistないのファイル名ににアンダーバー(_)が2つ続くとうまく 読み込んでくれないようなのでmp3のファイル名をリネームしました。これまた怠惰。

バイトコンパイル

> xemacs -batch -q -e batch-byte-compile `ls *.el`
怠惰っぷり全開

操作

(mpg123-add-new FILE) [a]
  現在の演奏リストにファイルを追加

mpg123.elメモ

(mpg123)で再生中に (mpg123) を呼び出した場合にプロセスの出力を整形する フィルタ関数が異常な動きをしているのか山ほどのWarningがでます。
ん、mpg123の生存チェック....?

怠惰な対策

(global-set-key [(control f8)] 
  '(lambda () (interactive) 
     (require 'mpg123)
     (if (buffer-live-p mpg123*buffer)
         (switch-to-buffer mpg123*buffer)
         (mpg123 (expand-file-name "~/mp3/playlist")))))

すでにバッファがあるならばスイッチする。ないならばプレイリストを 読み込み起動。

アイコン(toolbar) / メニューバー(menu-bar)を消す

  ただでさえ狭いディスプレイ、アイコンなんて使わないのに表示されて 困るというわけで、XEmacsのアイコンを消します。customise-aproposでtoolbar-visible-pを 検索し、値をoffにして下さい。アイコンが消えます。起動時は一度アイコンがでて消えます。 これで2行分ディスプレイを有効活用できます。メニューバーの[オプション]→[ツールバーの外観] →[表示]でもアイコンを表示させるか、させないかを変更できます。
  Emacs Lispでの指定方法は以下の通りです。customize-groupでも指定可能です。

;;; menubar
  (set-specifier menubar-visible-p nil)
  ;;; toolbar
  (set-specifier top-toolbar-visible-p nil)

細々したものたち (Window操作)

  Emacsはひとつのウインドウで複数のファイルを開けるのがうれしいです。 切り替えが楽だし、ひとつのファイルの編集にも役立つし、dabbrev-expandは設定すれば 他のバッファからも単語を検索してくれるしといいことがいっぱいあります。(dabbrev-expand はバッファが多かったり、バッファサイズが大きいと遅くなって困ることがありますが) というわけで、ウインドウの操作を紹介します。
window はいわゆる view のこと。 表示する内容 (いわゆるdocument) は buffer である。
split-window-vertically [C-x 2]
  windowを上下に二分割する。
split-window-horizontally [C-x 3]
  windowを左右に二分割する
other-window
  他のwindowにカーソルを移動する。
delete-window [C-x 0]
  現在カーソルがあるwindowを削除する(bufferは残る)
delete-other-window [C-x 1]
  現在カーソルがあるwindow以外を削除する(bufferは残る)

基本的なコマンド

編集

delete-rectangle
  矩形削除
isearch-forward [C-s]/isearch-backward [C-r]
  前方/後方 検索
isearch-forward-regexp [M-C-s]/ isearch-backward-regexp [M-C-r]
  正規表現で前方/後方 検索
query-replace
  置換するかどうかを尋ねながら の置換。すべて置換する時はy(or n)の変わりに!を入力する。
replace-string
  現在のバッファの現在の位置以降の文字列をすべて(黙って)置換する。 の置換。すべて置換する時はy(or n)の変わりに!を入力する。
set-mark-command [C-@]
  マークをつける(regionの一端)
copy-region-to-clipboard (Windows versionにはあった)
copy-region-as-kill

  リージョンをクリップボードにコピー(要するにcopy)
kill-region [C-w]
  リージョンを削除するがkill ringに保存(いわゆるカット)
yank [C-y]
  貼り付け(ペースト)

ファイル操作

save-buffer [C-xC-s]
  上書き保存
write-file [C-xC-w]
  名前をつけて保存 find-file [C-xC-f]
  ファイルを開く
find-file-read-only [C-xC-r]
  上書き禁止でファイルを開く save-buffers-kill-emacs [C-xC-c]
  バッファを保存するか問い合わせてEmacsを終了

ローマ字で日本語検索 (migemo)

migemoを使うと日本語入力モードにしなくても、日本語を検索できます。漢字も検索できます。すごい!!

ダウンロード
  migemo

インストール
配列二分探索ライブラリとローマ字かなを扱うRubyのライブラリが必要
  Rubyのbsearch
  Rubyのromkan
多分 /usr/lib/ruby/site_ruby に .rb ファイルをコピーすればよい。(僕はそれで使えてるし)
で、 ./configure && make && make install
migemo.elc は /usr/local/lib/xemacs/site-lisp/lookup/ とかにはいるので load-path に加えて おいて、 .emacs に (require 'migemo) を書く。isearch-{forward,backward}でローマ字検索ができる ようになる。

レジスタ

1文字の名前をもつ変数。コピーした文字列、矩形、設定などを保存、読み込みできる。以下はコピー & 貼りつけをレジスタを介して行なうコマンド。
copy-to-register [C-xx]
  レジスタにリージョンをコピー
insert-register [C-xg]
  レジスタの内容を挿入
view-register
  指定したレジスタの内容を表示

使用例
  Emacsのregisterを使って矩形コピー・ペーストしてみた

narrowing と widen

編集可能領域を狭めたり、戻したりします。置換を行なう時など便利ですね。
narrow-to-region [C-xnn]
  指定したリージョンにnarrowingする。他の領域はみえなくなるが慌てふためかぬよう。
widen [C-xnw]
  narrowingの解除

おすすめの変数設定

minibufferがactiveであってもコマンド実行 (enable-recursive-minibuffers)
  この変数をtにしておくと、前のコマンドが終了してなくてminibufferがactiveに なっているときも次のコマンドを実行させることができます。コマンドは必ず終了させるか、 キャンセルするなんてめんどくさいという方にはおすすめです。

バッファリストを表示

なんでもかんでもEmacs上でやるようになると、バッファがたまって気づけば メモリをかなりくっているなんて状況が多いです。aproposなんかはちゃんとkillしないとバッファを 次々に作っていきます。(まぁ、共有したければ簡単なEmacs Lispを書けばよいのですが)上で すすめたenable-recursive-minibuffersの設定も本当はすすめられたものではありません。(コマンドを 実行するのにやはりメモリが割り当てられるが、それが蓄積していくから)というわけで、バッファを 気軽にチェックする方法を二つ書きます。
  (electric-buffer-list &optional FILES-ONLY)
  スペースをおすとその行のバッファを選択し消えてしまうお手軽コマンド。まぁ、 buffer-list自体がバッファをいつまでも確保するのはしゃくですからね。でも、選んだバッファ のkillを実行する仕方がいまいちわかりません。バッファを選ぶだけならこれが簡単です。
  (buffer-list &optional FILES-ONLY)
  こちらは、buffer-list自体がバッファを確保してして居座るバッファリストです。default でC-xC-bにバインドされているようです。バッファの削除はdで削除マークをつけてxで実行です。リ ターン、スペースキーでバッファを選択できます。mewのバインドもにてますね。ちなみにマークを 消すにはu、すべてのマークを消すにはUをタイプします。

遠隔からEmacsを操作する (gnuserv, gnuclient (gnudoit))

gnuserv, gnudoit という Emacs に外部から Emacs Lisp を流し込んで実行させるプログラムがある。 Mozilla にある -remote オプションに似たようなもの。
  1. Emacs で gnuserv-start を実行し、
  2. 適当な端末から gnuclient -q -batch -eval '(find-file "/home/tak/lib/emacs/lisp/mymode.el") (goto-line 30)' のように gnuclient を用いて実行させたい Lisp を指定する

Emacs (Lisp)に関するメモ

デバッグ

(display-message LABEL MESSAGE) / (message MESSAGE)
  フレームの底(minibuffer)にメッセージを表示します。labelはメッセージの型です。
    error,message,progress,prompt,command
(clear-message &optional LABEL FRAME STDOUT-P NO-RESTORE)
  メッセージを消します。(message nil)で代用することも可能でです。
(trace-function FUNCTION)
  関数のトレースを表示します。
max-lisp-eval-depth
  関数呼出の上限。無限ループを防止します。止まらないwhile式を評価するとEmacsが止まりましたが、なんとか止める方法はないのでしょうか??(Emacsをkillする以外に)
-debug-initオプションを付けて起動
  .emacsのエラーの原因が分かります。
toggle-debug-on-signal
  エラーメッセージがどこから出たか分かります。

コマンドを作る

(interactive ..)
  対話的に使う関数(コマンドという)の引数のパースの仕方を指定する。 とりあえずコマンドにしたいならば必要。コマンドが引数をとる時にはinteractiveの 引数にプロンプトとデータの型を指定する。引数が文字列の場合は
    (interactive "sPrompt: ")
のように頭にsをつける。

コマンドや関数についてのドキュメント

(defun NAME ARGLIST [DOCSTRING] BODY...)と、 引数リストの後にドキュメントの文字列をつける事ができる。aproposなどでこのドキュメント を読む事ができる。ここのソースにも適宜ドキュメントを入れていく予定。

ユーザーの入力を得る

(thing-at-point THING)
  THINGはデータタイプ。list,filename,url,word,...カーソル位置の単語、文、URLを 取り出すのに使う。にている関数にcurrent-wordがある。
(read-string PROMPT &optional INITIAL-CONTENTS HISTORY)
  minibufferを介して入力を受け付ける。PROMPTはminibufferに表示するプロンプト。 INITIAL-CONTENTSはdefaultの値。
(read-char)
  1文字キーボードからの入力を読み込む。

文字列

(concat STRING...) / (format FORMAT ELEMENTS..)
  concatは連結した文字列を返す。formatは指定した書式で整形した文字列を返す。 書式はCのものとほぼ同じ。
(replace-in-string STR REGEXP NEWTEXT &optional LITERAL)
  引数で渡した文字列を置換する関数。(バッファの文字列置換ではなくて)
(split-string STRING &optional PATTERN)
  PATTERNで文字列を分割したリストを返す。
(split-string "hoge.moge" "[.]")
("hoge" "moge")
(split-string "hoge\\age.moge" "[\\.]")
("hoge" "age" "moge")

joinはないかなぁ。
(defun my-fold (f s lst)
  (if (null lst)
      s
    (funcall f (car lst) (my-fold f s (cdr lst)))))
(my-fold '(lambda (x y) (concat x " " y)) 
        "" '("takash" "masuyama" "hoge"))
"takash masuyama hoge "

文字コードを変換する関数。
(encode-coding-string STR CODING-SYSTEM)
  STR を CODING-SYSTEM で表される文字コードで変換する
(decode-coding-string (encode-coding-string "増山たかしまや" 'sjis) 'sjis)
"増山たかしまや"

おまけ
(length "増山隆")
3

文字

(char-before &optional POS BUFFER)
  位置POSの一つ前の文字を返す
(char-before &optional POS BUFFER)
  位置POSの文字を返す
(insert-char CHR &optional COUNT IGNORED BUFFER)
  COUNTの数だけCHRを挿入

ビットベクタ

#*1100 のように #* を1,0の列の前につけて表す。list, string, vector, vit vector の関係に ついて info の lispref -> Sequences Arrays Vectors に分かりやすい図がある。
(aref #*1101 2)
0

ファイル名

(buffer-file-name)
  バッファのファイル名を絶対パスで返す。
(file-name-nondirectory PATH)
  PATHからディレクトリ名を取り除いたものを返す。

バッファ

バッファは一意な名前をもち、編集できるテキストを持っているオブジェクト。 局所変数も持つ。 スペースから始まるバッファはユーザーには直接みえないバッファで、バッファリストには 現れない。プログラムの出力を扱うバッファの名前はスペースから初めてユーザーから みえないようにするとよい。

バッファの操作
(get-buffer NAME)
  NAMEであらわされるバッファがあるならそのバッファを返す。なければnilを返す。
(switch-to-buffer NAME)
  現在アクティブなウインドウにNAMEであらわされるバッファの内容を表示する。
(switch-to-other-buffer NUM)
  バッファスタックというのがあって、最近訪れたバッファがトップの方に 入っているらしい。それの NUM 番目のバッファにスイッチしてそれをトップに入れる。 0 を指定すると現在のバッファをスタックのそこに埋める (bury)
(set-buffer BUFFER)
  一時的にcurrent Bufferを変更するのに使う。
(erase-buffer BUFFER)
  バッファの内容を全て削除する。

バッファの局所変数 (local-variable)の操作
(make-local-variable VARIABLE)
  グローバル変数を変数を局所化する。バッファで共有されるデフォルトの変数 を変更したくて、他のバッファにはその変更をみせたくないときは、まず局所化する。

  namazu のデフォルトの検索ディレクトリを局所化して、バッファ固有の値に変更する。
(make-local-variable 'namazu-default-dir)
mew の summary モードでは namazu のインデックスは ~/.Mail_namazu を参照させるように 設定する。他のバッファからは参照できないように変数を局所化する。
(add-hook 'mew-summary-mode-hook
  '(lambda ()
     (make-local-variable 'namazu-default-dir)
     (setq namazu-default-dir (expand-file-name "~/.Mail_namazu"))))
(save-excursion BODY...)
  カーソル位置、マーク、現在のバッファといった Emacs の状態を保存して BODY部分を逐次評価する。評価が終ったら保存した状態を復元する。

ウィンドウ操作

(get-buffer-window BUFFER &optional WHICH-FRAMES WHICH-DEVICES)
  指定したバッファが表示されていれば、表示されているウィンドウを返す。 そうでなければ nil を返す。

論理演算

or / and
  たとえばorでは先頭の要素がnilである時には残りの要素を評価せずにnilを返す。 andについても同様。つまり、先頭から逐次評価し、全体の値が決まるならば直ちに評価を 止める。ちなみに、Emacs Lispではnilであるものが「偽」にあたり、non-nilな値は「真」 にあたる。(tという値もあるが) (not t)の返り値はnil、(not nil)の返り値はtなので、 tが真の「真」というべきか。

評価関係

(eval-print-last-sexp)
  pointの直前のS式を評価して、返り値をそのバッファに書く。
(eval-buffer BUFNAME)
  BUFNAMEという名のバッファを(もちろんLisp code)評価する。
(eval-region BEGIN END)
  リージョン(くどいがLisp code)を評価する。

locate-libraryをつかって複数ディレクトリ内のファイル検索

よくEmacs Lispのソースを検索するのにlocate-libraryを使いますが、検索対象は.el, .elc などの ファイルに限りません。検索したいディレクトリを指定して、拡張子をつけないようにオプション引数 を渡すと普通のファイルも検索できます。
(locate-library LIBRARY &optional NOSUFFIX PATH INTERACTIVE-CALL)
(defun my-java-open-source-file (class path-list)
  (let* ((filename (concat class ".java"))
	 (path (locate-library filename nil path-list)))
    (if path
	(find-file-other-window path)
      (message (concat "Not found the file: " filename)))))
クラス名と検索対象のディレクトリのリストを指定して、javaのソースファイルを検索し、あったら開く。

その他

  char型は文字の前に?をつけて表す。 ?a、?\aなど。stringはcharの配列。配列 操作は、参照はaref、添字を用いた変更はasetを使う。

確認した定数

  pi = 3.141592653589793 いわずと知れた円周率
  e = 2.718281828459045 自然対数の底 (もちろん(exp 1)でも得られる) ちなみに数学の関数は、exp,sin,cos,tan,sinh,cosh,tanh,sqrt...があります。

末尾再帰

末尾再帰の最適化は行なわれていない。trace-functionを使って次の関数を トレースしてみた。

(defun fuc (index result)
  (if (= index 0)
    result
    (fuc (- index 1) (* index result))))

(fuc 5 1)のトレース結果は以下の通りになった。
  1 -> fuc: index=5 result=1
  | 2 -> fuc: index=4 result=5
  | | 3 -> fuc: index=3 result=20
  | | | 4 -> fuc: index=2 result=60
  | | | | 5 -> fuc: index=1 result=120
  | | | | | 6 -> fuc: index=0 result=120
  | | | | | 6 <- fuc: 120
  | | | | 5 <- fuc: 120
  | | | 4 <- fuc: 120
  | | 3 <- fuc: 120
  | 2 <- fuc: 120
  1 <- fuc: 120

  普通に再帰した場合のトレース結果と同じ。

正規表現

.改行以外の任意の一文字にマッチ
^文頭にマッチ
$文末にマッチ
[]文字集合
*直前のパターンの0回以上の繰り返し
+直前のパターンの1回以上の繰り返し
?直前のパターンの1回または0回のマッチ
\|(中置)選択
\(\)グループ化

正規表現によるパターンマッチ

(string-match REGEXP STRING &optional START BUFFER)
  正規表現でパターンマッチを行う。
(match-string NUM &optional STRING)
  最後のマッチングででNUM番目のグループにマッチした文字列を返す。 STRINGは最後にマッチを行った文字列と同じでなければならない。
(match-beginning NUM)
  最後のマッチングででNUM番目のグループにマッチした文字列の 開始位置。
(match-end NUM)
  最後のマッチングででNUM番目のグループにマッチした文字列の 終了位置。
set-match-data / save-match-data / store-match-data
  マッチ位置のセット、復元。

関数について

関数はschemeのように直接引数として渡せないので、symbolとして渡し、 渡された ほうは、その関数適用をevalを用いて呼び出す。以下に例を示す。(簡単な例と、連想リスト からキーに一致するものの値を取り出す関数の例)

(eval '(equal "takashi" "takashi")) (defun my-search-alist2 (key alist equality) (while (and (not (null alist)) (not (eval (list equality key (caar alist))))) (setq alist (cdr alist))) (if (null alist) nil (cdar alist)))

  ソートの時の比較関数、検索の時の比較関数などを引数から渡す時はシンボルで。

シェルコマンドの実行

(shell-command COMMAND &optional OUTPUT-BUFFER)
  コマンドを実行し、出力がない場合はminibufferに出力がないという表示がされる。 出力が1行の場合はminibufferにその出力が出る。複数行の出力の場合はOUTPUT-BUFFERで指定 された(bufferまたはbuffer名)に出力が書き出される。M-!にバインドされてたりする。 対話的に標準入力を渡すプログラムには不向き。
(start-process-shell-command NAME BUFFER &rest ARGS)
  もある。
(shell-command-to-string COMMAND)
  コマンドを実行し、コマンドの標準出力を文字列として返す。
(shell-command-to-string COMMAND)
  コマンドを実行し、コマンドの標準出力を文字列として返す。

プロセスオブジェクトの操作

(start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS)
  プロセスを起動し、プロセスオブジェクトを返す。NAME はプロセスにつける名前。 BUFFER はプロセスの出力を出すバッファ名。PROGRAM は起動するプログラムへのパス。
(process-name PROC)
  プロセスオブジェクトのプロセス名の取得
(get-process NAME)
  process-name の逆関数。プロセス名からプロセスオブジェクトを得る。
(process-send-string PROCESS STRING &optional FROM TO)
  プロセスオブジェクトに入力として文字列を送る
(process-exit-status PROCESS)
  プロセスの終了ステータスコード(整数)を得る
(process-status PROCESS)
  プロセスの状態をみる。実行中(run) 停止中(stop) 終了(exit)などなどのシンボルが 返る
(set-process-filter PROCESS FILTER)
  プロセスにフィルタをつける。プロセスの出力文字列がフィルタに引数として渡されて 評価される。フィルタは2引数をとる関数で、その第一引数にはプロセスオブジェクト、第二引数に 文字列が渡される。プロセスにフィルタがセットされるとプロセスは関連づけられたバッファに 出力をはかなくなる。

  embiff.el
    アンテナ。未完成
  search_ocaml_type.el
    filter をつけてみました。
  関連ページ Internal Ocaml, search_type.ml, type_server.ml, type_server_with_type_annotation.ml

起動しているプロセスの表示

(list-processes)
  起動しているプロセスリストを表示するコマンド。 "*Process List*" と いう名前のバッファに表示される。

文字コードの設定

シェルのエラーメッセージ(日本語)が文字化けするときの対処

  エラーメッセージはJIS(iso-2022-jp)で出力されているけれど、普段はEUCを 使っていて、設定しないとシェルのバッファもEUCの設定になっているので、文字化けが おきていました。shell-mode-hookに以下のように設定しました。

(add-hook 'shell-mode-hook
  '(lambda ()
     (set-buffer-file-coding-system 'iso-2022-jp-unix)))

ファイルを読み込むときに文字コードを自動判別する

  ファイル読み込みのときに使う文字コードを set-buffer-file-coding-system で指定できる。
  でも、ファイルを指定された文字コードで決めうちして開いてしまうので、指定されていない 文字コードで書かれたファイルを開くと文字化けすることがある。文字コードを自動判別して 読み込むには、これらを 'undecided と設定することで自動判別して開く。デフォルトでは 'undecided であるようだ。
(set-buffer-file-coding-system-for-read 'undecided)
;; 上で駄目ならこうやる↓
(setq coding-system-for-read 'undecided)

Unicodeを使う

以下のLispコードを評価して set-buffer-file-coding-system とかする。
(require 'un-define)
(set-coding-priority-list '(utf-8))
(set-coding-category-system 'utf-8 'utf-8)
参考 Frequently asked questions about XEmacs: Introduction - Does XEmacs support Unicode?

ディレクトリの操作

(insert-directory DIR SWITCH)
  荒っぽくいうと ls に SWITCH をオプションとして、 DIR を引数として渡して 表示される結果を現在のバッファに文字列として挿入してしまう荒々しい関数。 ls 決めうち というわけではなくて、 どこかの変数で設定できるはず。あまり使う気はしない。 dired で使われている。

参考
  completionの巻

(directory-files DIRNAME &optional FULL MATCH NOSORT FILES-ONLY)
  ディレクトリの中にあるファイル名をリストにして返す。

その他の関数

(getenv ENV)
  環境変数を取り出す
(count-windows &optional MINIBUF)
  現在見えているウインドー数を返す。minibufferがアクティブならばminibufferも含む。オプション変数 MINIBUFがnilでなければいつもminibufferを含める。
(device-baud-rate &optional DEVICE)
  デバイスのボーレートを返す。
(lookup-key KEYMAP KEYS &optional ACCEPT-DEFAULT)
  インターラクティブでない関数。あるキーにバインドされた関数名を 調べる。

  例(一般的ではないキーバインドですが↓)
(lookup-key caml-mode-map "\C-c\C-c")を評価するとcomment-regionが返る

(map CL-TYPE CL-FUNC CL-SEQ &rest CL-REST)
  シーケンスの各要素に関数を適用して(必要ならば)返り値を返す。引数に 渡す関数が値を返すならば、その値を返り値の型にして返す。


(map 'vector (lambda (x) x) '("takashi" "masuyama"))
["takashi" "masuyama"]
(map 'list (lambda (x) x) '("takashi" "masuyama"))
("takashi" "masuyama")
(map 'string (lambda (x) x) '(?t ?a ?k))
"tak"

(buffer-local-variables &optional BUFFER)
  バッファの局所変数の名前から値を連想する連想リストを返す

Emacs lispのバイトコンパイル

(byte-compile-file FILENAME)
ファイルをバイトコンパイルする。
EmacsをEmacs Lispのコンパイラとして使うときのコマンドラインオプション
-eval [form]Lispの式formを評価する
-f [function]関数を実行
-l [file]Lispのファイルをloadする
-q.emacsを読み込まない。
-batchバッチモードで起動。結果を標準出力に 出力しEmacsを終了する

> xemacs -batch -eval '(byte-compile-file "mycextend.el")'

おまけ
  -batch オプションというのはコンパイルをするためだけにあるのではない。 ocamltags も Emacs を -batch オプションつきで立ち上げて ocaml のソースを読み込んで TAGS ファイルを書き出す Emacs Lisp で書かれた単体のプログラムである!! というわけで、 ocamltags をみながら、 hello world を Emacs Lisp で書いてみた。実行可能にして、 実行してみよう!! (一行めは完全に ocamltags からとってきたもので意味を正確には理解 していないです。 汗)
  hello_by_emacs.el
  echo.el
    コマンドライン引数は command-line-args-left にリストとして入る

いたたた

適当なEmacs Lispソース

もちろん、動作の保証はしません。versionによってパッケージが違うし。コメントに更新 情報や注意をのせるかも知れないので読んでから使ったほうが良いです。最近タコなエラーをたくさん 見付けてます。
  設定ファイル .emacs
  キーバインド設定ファイル mykeymap.el
  thing-at-point乱用コマンド mylibrary.el
  autoinsertの設定 myinsert.el (最近.pl(perl)/.cgiを修正)
  modeごとの設定 mymode.el
  コンパイル mycompile.el
  HTMLモードを自分(作者only)好みに myhtmlmode.el <= ちょっとバグ発見
  リージョン中に現れる数字をインクリメントした文面を挿入する myincrement.el (大きなリージョンを指定するときは使用しないほうがよい)
  シェルバッファの切替え。一つ上の番号がついたシェルバッファ(名前で判定) に切替える。switch-shell.el
  Makefile for OcamlMakefile
  現在編集中のファイルをWEBにアップする myftp.el
  read-passwd, completing-readのサンプル
  決めうちしたローカルホスト上の位置にWEBの内容を取得する
  hput,hagetというプログラムをこのホームページの更新を簡単にするために つくっていて、(hput [filename]/hget[filename]で動く決めうちシェルスクリプト) それをEmacsから動かした例です。プロセスオブジェクトとのやりとりのサンプルでもあります。
  ステータスコードの取得は怪しいです。
エラージャンプ他
  エラージャンプのジャンプ部分 myerrorjump.el
  C/C++モードを自分(作者only)好みに mycextend.el (gdb の backtrace jump を追加)
  Perlのエラージャンプ
  Ocamlのエラージャンプ
  platex (に限らないかも?) のエラージャンプ (とってもad-hoc)
  Promelaのエラージャンプ mypromelaextend.el (参考: Spin - Formal Verification, Spin)
APIサーチ
  出ました!! javaのAPIサーチ
  javaのAPIサーチ(やる気なさげバージョン + 2002/ 9/ 3 にNamazuをつかってサーチする機能を追加)
  でもindexを頑張ってつくらなあかん(汗
  2002/ 9/ 4 ページが0 originであることに気づき修正
  OcamlのAPIサーチ(リージョンで指定、完全一致)
grep
  バッファ内の適切なファイルに対してgrep
WEBブラウザとの連携 (browse-url を使用)
  googleにキーワード(一語)を渡す , キーワードをエンコードするプログラム(単純すぎ)
  history機能を追加。
  URLを入れるとそこを直接みるようにした (ただbrowse-urlのurlをminibufferから 取得するのみ)

今後やる気があればぜひ作りたいもの。とか調べたいこと
  とにかく、C++プログラミングを楽にしたいわけです。
  正規表現を理解すればできそう
hilight_test.el / get_function.pl
  ↑開発中。多分

設定

こまごま設定たちです。
No file on this lineと文句を言われる場合 ls -l の結果から正規表現を用いてxemacsはファイル名の最初の一文字を探します。 localeによってlsの結果が異なる(日付が問題)のでファイル名の取得に失敗して ファイルがありませんと言われます。ls -l の結果がUSフォーマットになるように localeを設定するか、dired-move-to-filename-regexp変数を、ファイル名 を探す正規表現をlocaleに合わせるかで対処できるそうです。
一つ対処方法
env LC_ALL=C xemacs
ただしこれを設定してしまうと日本語のmanが一部(なぜ一部??)文字化けする
lsだけ LC_ALL=C になりゃぁええじゃん。というわけで簡単なプログラムを 書いた。(aliasとか設定したらうまくいくんかなぁ? なぞ)
  lsをハイジャック。( /bin よりもパスを優先させる ls.c)
  環境を変えてlsするのみ。 setenv と execv のサンプル?
"dired-subdir-alist mangled" とかでるのをなんとかしたい
ソースがあるので調べてみようか?
minibufferの右に日本語入力のモードが出るのって困りますよね というわけで、設定。
env XMODIFIERS=@im=none xemacs
非同期プロセス起動でfind & grepをつかった便利なツールを作る
アンテナ。べつに目新しいものではないですが。 プロセスの起動とフィルタ。
  embiff-2004-01-05.tar.gz
  メモ
   バッファ上の文字列に変数と値の組を連想させることができる。 put-text-property で設定し、 get-text-property で参照、remove-text-properties で削除する。

メモ

今後のターゲット
  Semantic Bovinator: Parser generation for Emacs
   Emacs上でlexer/yaccを定義する。speedbarでの表示をカスタマイズできる!?
  Imenu GNU Emacs Lispリファレンスマニュアル: Imenu

リンク

Emacs & Mule Page
  けっこう派手で大きいEmacs Lisp のプログラムを書いてる!? ホームページも派手
Programs (このサイトのプログラム一覧)
Session Management for Emacs Emacs Lispプログラミング入門
Wnnで全角スペースを入力する
  Z+space / Q+spaceを押下する。

作者: 増山隆 address
To Home
Valid HTML 4.01!