core of emacs
たまたま、ソファーの下から、足の裏ぐりぐり君を見つけた。突起のあるローラーを足裏で回して、つぼの刺激をしましょってやつ。
昔々、女房がバイトしてた時に、立ち仕事がずっと続いて足がむくんでしまったので、その解消の為に買ったと言ってた。30年ぶりぐらいの発掘品。今では、100均で売ってるとか。
使っていないので、オイラーが貰って、パソコンやる時に利用し始めた。 癖になりそう。違う刺激も欲しくなったので、100均を覗いてみるかな。
FreeBSD 12.0 Release
が、出たので記念に、32BitのDebian機に入れてみた。勿論仮想化のvbox(Ver. 5.2.22)上だけど。
もっさりしてる。portsnap autoして、世界のOSSのメニューを取り寄せた時、終了まで3時間もかかったぞ。通常の make updateも極めて遅い。前はそんな事無かったんだけどな。 VerUpと共に遅くなる運命にあるのか。
感覚で言っていてもしょうが無いので、超簡単なベンチをする。最初にFreeBSD 12.0の方
$ time tar zxf /usr/ports/distfiles/emacs-26.1.tar.xz 37.81 real 6.88 user 28.36 sys
今度は、同じ環境にある、FreeBSD 11.2で試してみる。
$ time tar zxf /usr/ports/distfiles/emacs-26.1.tar.xz 14.03 real 4.98 user 5.06 sys
こういうのを、統計的に有意な差と言うのでしょうか(って、それぞれ一回づつの試行じゃん)。sysに非常に時間がかかってるって事は、糞石対策をきっちりとやってますって事ですかね?
64Bitなvbox上では、5秒で展開してくれるから、3倍遅いのか。これじゃリナ系がi386を棄てるのも頷けるな。遅いと評判がたつのは、営業戦略上不利になりますから。いや違うな。ウブはトロイので、64bit機で動かさざるを得ないのよ。
ひょっとして、最近出た、vbox 6.0 にすれば、改善するのかな? ああ駄目だな。i386版はサポートしていない。5.2系は、2020年7月までは面倒 見てくれるそうだ。こうして、i386は徐々に見棄てられる運命にあるのね。
追跡
前回やった、(progn (prin1 "HOGE") "lv") の評価。HOGEが勝手に *Messages* に書き込まれてしまう問題。どういう風になってるの?
こういうのを調べるには、騒ぎを起こして犯人を炙り出すに限る。CERNの実験装置しかり、警視庁の捜査支援室しかり。マッチポンプ式だな。
でも、火付けは死罪ですぜ、って江戸時代かよ。暮はむしゃくしゃで、放火が増えるぞ。江戸に在住の方は、戸締り用心火の用心してくださいな。
メッセージバッファーを消してしまって置いて、どうなるか見る方法を思い付いた。バッファーを消すには、C-x k *Messages* しとけば良い。
実験してみた。emacsが怒って、バックトレース画面が出て来ると期待してたんだけど、何事も無かったように、勝手に *Messages* が作られて、そこに出力されてたよ。つまんねぇ奴だな。
ならば、バッファーが作成される瞬間を捉えてしまおう。サツ用語で言うと、現行犯逮捕。 新たなバッファーを作成するプリミティブ関数(Infoで調べたら2個有った)にBPを置く。それから、eshell上で評価。
(gdb) b Fget_buffer_create Breakpoint 6 at 0x4aeae0: file buffer.c, line 512. (gdb) b Fgenerate_new_buffer_name Breakpoint 7 at 0x4ad490: file buffer.c, line 1076. (gdb) c Continuing. Breakpoint 6, Fget_buffer_create (buffer_or_name=8241948) at buffer.c:512 512 { (gdb) p buffer_or_name $34 = 8241948 (gdb) xpr Lisp_String $35 = (struct Lisp_String *) 0x7dc318 <pure+81240> "*Messages*"
トラップと言うか、罠に落ちてくれた。
Lisp Backtrace: "prin1" (0xabcc5710) "progn" (0xabcc57d8) "eval" (0xabcc58e8) "eshell-exec-lisp" (0xabcc5ab0) "eshell-lisp-command" (0xabcc5c50) "eval" (0xabcc5e28) "eshell-do-eval" (0xabcc61c0) :
その時の、バックトレース。どうやらprin1に先立って、*Messages*を用意してるように見える。バッファーを作っている所は、buffer.c 内だ。一般のelispユーザーには見えない所で、コソコソやってる。
(gdb) bt #0 Fget_buffer_create (buffer_or_name=8241948) at buffer.c:512 #1 0x00000000004221d9 in message_dolog (m=m@entry=0x7fffabcc5420 "\";\370\002", nbytes=nbytes@entry=1, nlflag=nlflag@entry=false, multibyte=multibyte@entry=true) at xdisp.c:10266 #2 0x000000000051a741 in printchar (ch=ch@entry=34, fun=fun@entry=43296) at print.c:311 #3 0x000000000051cd7a in print_object (obj=<optimized out>, obj@entry=49822740, printcharfun=43296, escapeflag=<optimized out>) at print.c:1835 #4 0x000000000051e5d6 in print (obj=obj@entry=49822740, printcharfun=<optimized out>, escapeflag=<optimized out>) at print.c:1131 #5 0x000000000051e71f in Fprin1 (object=49822740, printcharfun=<optimized out>) at print.c:629 #6 0x0000000000503093 in eval_sub (form=<optimized out>) at eval.c:2237 #7 0x0000000000503490 in Fprogn (body=<optimized out>) at eval.c:455 : ;; depth is 92 too deep!
でも、C語のbtを見れば、これはもう、ストリートカメラにばっちりと証拠が撮影されてますなあ。動かぬ証拠で有罪確定。まてまて、カメラに写っているからって、無条件で信用していいのか? 頑張ればねつ造出来るぞ。裁判になったら、それが真正な物が証明しろと、難癖付けてみような。
ああ、どうも雑音が多すぎるな。反省々。
つたない考察では、 *Messages* を、特別扱いしてるな。そう、Unixあたりで言うsyslogみたいにね。
ob6$ fgrep *Messages* *.c buffer.c: " prin1", "*scratch*", " *Minibuf-0*", "*Messages*", and editfns.c:The message also goes into the `*Messages*' buffer, if `message-log-max' gnutls.c:Set this larger than 0 to get debug output in the *Messages* buffer. lread.c: *Messages*. */ print.c: *Messages*. */ xdisp.c:/* The name of the *Messages* buffer, a string. */ xdisp.c: to *Messages*. */ xdisp.c:/* Output a newline in the *Messages* buffer if "needs" one. */ xdisp.c: in the *Messages* buffer now, delete the oldest ones. xdisp.c: incrementing windows_or_buffers_changed even if *Messages* is xdisp.c: shorter. This can be caused by log truncation in *Messages*. */ xdisp.c:They are still logged to the *Messages* buffer. */); xdisp.c: Vmessages_buffer_name = build_pure_c_string ("*Messages*"); xfaces.c: load color" messages in the *Messages* buffer. */
C語のemacsエリアでも、決め打ちしてる節がある。
ob6$ fgrep *Messages* *.el : simple.el: "Return the \"*Messages*\" buffer. simple.el: (or (get-buffer "*Messages*") simple.el: (with-current-buffer (get-buffer-create "*Messages*") startup.el: (with-current-buffer "*Messages*" startup.el: ;; Give *Messages* the same default-directory as *scratch*, startup.el: ;; buffers (probably *scratch*, *Messages*, *Minibuf-0*).
勿論、elispユーザーエリアも同様だ。
play/morse.el.gz
プリミティブもいいんだけど、底無し沼っぽいんで、軽めに行くぞ。そうemacsを動かしているelispの集積地の探訪。幾つかのdirが或るけど、面白そうな所をば。
モールスに反応。コードを見るも、音はしないっぽい。つまらないじゃないかと言う輩用に、NATO軍御用達の冗長コードが乗ってた。聞き間違い防止用。
朝日のあ、いろはのい、上野のう、、、ってのの英語版。言葉が訛っていてもただしく伝わるように、、文字通り死活問題ですからね。明治維新を経て、徴兵制度が引かれた時、方言が軍隊内で大問題になった。薩摩弁と津軽弁じゃ意思疎通は無理。それで標準語ですよ。 更に大事な所は、朝日のあ とかやったのね。
(defvar nato-alphabet '(("a" . "Alfa") ("b" . "Bravo") : ("(" . "Open") (")" . "Close") ("@" . "At")) "NATO phonetic alphabet. See "International Code of Signals" (INTERCO), United States Edition, 1969 Edition (Revised 2003) available from National Geospatial-Intelligence Agency at URL `http://www.nga.mil/'")
括弧は、カッコ、コッカ とは、言わないのね。このテーブルを参照して、文字をフォネティクスコードに変換する関数と、逆変換する関数が定義されてる。
使いかたは、関数付属のdocを参照。
(defun nato-region (beg end) "Convert all text in a given region to NATO phonetic alphabet."
helloを変換してみた。
hello ;; select hello then M-x nato-region Hotel-Echo-Lima-Lima-Oscar
で、どんな動きをするかと思って最初からedebugにかけてみると、
(cond ((looking-at "\\s-+") (goto-char (match-end 0)) (setq sep "")) => ((setq nato (assoc str★nato-alphabet)) (delete-char 1)
カーソルが★の所で、下記の様なエラー。
Symbol's value as variable is void: nato-alphabet
テーブルの名前がわからんとな。そうか、関数が一度も使われないと、テーブ ルがロードされない訳ね。edebugするなら、一度走らせてからにしろ、って事 なのね。了解しました。
leim
emacsで日本語ってのを以前やったけど、デフォで日本語出来るのね。C-\ すると、ステータス行が、Aあ に変化して日本語が入力できる様になる。入力中に大文字のKをたたくと、カナになる。
文節を縮めるには、C-i 延すには、C-o。次の文節へは、C-f 。次の候補グループへは、l 前のグループへは、L。キャンセルは、C-c。
ローマ字入力がちょっと特殊だけど、何も準備してない時に使うには、うってつけかな。
(define-key global-map (kbd "C-x j") 'toggle-input-method)
C-\ での切替で、手が釣りそうなので、上記の設定をしたよ。
こんな素敵な入力メソッドは、muleの遺産である。インターナショナルなDirに収納されてるぞ。後で謹んで拝んでおけ。
SKK
入力メソッドと言えば、もう一つ有名なものがあったぞ。
C-xj すると、SKKモードになって、モードラインに かな って出て来る。
C-x j runs the command skk-auto-fill-mode (found in global-map), which is an interactive autoloaded compiled Lisp function in ‘skk.el’. It is bound to C-x j. (skk-auto-fill-mode &optional ARG) 日本語入力モード。自動折り返し機能付き。 マイナーモードの一種で、オリジナルのモードには影響を与えない。 正の引数を与えると、強制的に ‘auto-fill-mode’ 及び SKK モードに入る。 負の引数を与えると ‘auto-fill-mode’ 及び SKK モードから抜ける。
おお、初めて日本語のdocを見たぞ。
SKKはshift keyを多用する。その負担を軽くする為、 windows 10 での SandS と言うのが有るそうな。
etc
来年にやりたい事が列挙されてるかなあ?