shells
Table of Contents
WSL2
前回やった mingw64だけど、Disk上では、2.1Gも消費している。コンパイル等 のDiskアクセスはパフォーマンスが悪い(遅い)。 それに細かい事だけど、pacman -Syu した時にDiskの空き容量を調べる工程で、 CPUパワーを全部使い果している。どこかに無理がある設計だろうな。 実質、余り使い道は無い。
パフォーマンスが悪いと言えば、リリースされて直に入れたwsl1も悪かった。 最近のwsl2はどうなのだろう?
Linuxを手軽に動かしたい! Windows標準機能の「WSL2」がお薦め こんな記事で出会って、プチ試してみたい気がするぞ。
install ruby on FreeBSD
matzさんからの恒例のクリスマス・プレゼントruby 3.3.0を入れてみた。
まずはdebianだ。あろう事か、libyamlが入いってないぞエラー。例のいやが らせ、libyaml-dev まで入れて入った事になる、あれである。
次はFreeBSDだ。やはり同じ所で引っ掛る。今度は、/usr/localなんて、責任 範囲外だから、知らないよと言う、コンパイラーの根性に起因するエラーだ。
下記の様に環境変数を明示してあげたら、通った。
[sakae@fb /tmp/ruby-3.3.0]$ export LDFLAGS=-L/usr/local/lib [sakae@fb /tmp/ruby-3.3.0]$ export CPPFLAGS=-I/usr/local/include [sakae@fb /tmp/ruby-3.3.0]$ ./configure [sakae@fb /tmp/ruby-3.3.0]$ time gmake real 12m48.784s user 11m56.259s sys 0m38.196s
でも、残念ながら、JITは32Bit環境では、発動しないと言う罠が仕掛けられて いた。32Bit環境って、gdbによるグレート・ジャーニーには、うってつけ(ポ インター表示がすっきりしてるので)なんだけどな。
shells
突然だけどemacs上で使える、幾つかの端末と言うかshellを試してみる。 前回は、WezTermなんてのを見付けたし、Windows上でも、透けて見える端末と か色々あるからね。
そして、本物のemacs使いは、一度emacsを起動したら、OSを落とすまで、その 中から外に出る事が無いらしい。いわゆるemacs引きこもり症候群に罹患する らしい。でも、lsとかの良く使いコマンドはどうするの? diredで事足りるか。 じゃ、コンパイルは? そんなのMakefileを作っておいて、それでコンパイラー を起動できるよ。どうしてもって場合だけ、shellコマンドか。単発なら、 emacsからでもOKだな。
でも、長い事shellとの対話が必要なら、やっとその為のアプリの登場だ。
端末自慢をするのも良いけど、所詮OSとの通信窓口だ。通常はそこにshellが 顔を出す事になる。
トップバッターは、term
M-x term
[sakae@fb ~]$ pstree -+= 00001 root /sbin/init : |-+= 01472 sakae emacs -nw --daemon (emacs-29.1) | |-+= 10515 sakae /bin/csh | | \--= 10519 sakae emacs test-hello.c (emacs-29.1)
emacs上のtermでcshを起動。そこからemacsを起動。
[sakae@deb ~]$ pstree systemd─┬─avahi-autoipd───avahi-autoipd : ├─tmux: server─┬─bash───emacs───bash───emacs │ └─bash───pstree
同じ事をdebianでやった図。こちらの方が直感的だな。
termなshell上からemacsが起動するのは、お洒落であります。 そして頑固なんです。窓を掴んだまま離さない。他のemacsの窓にも移動でき ません(できるんだろうけど)。間違って起動しちゃったら、exitでshellを終 了しましょう。
M-x shell
上のtermと同じ事をやってみると、、、
[sakae@deb tmp]$ emacs hogefuga.txt emacs: Terminal type "dumb" is not powerful enough to run Emacs. It lacks the ability to position the cursor. If that is not the actual type of terminal you have, use the Bourne shell command 'TERM=...; export TERM' (C-shell: 'setenv TERM ...') to specify the correct type. It may be necessary to do 'unset TERMINFO' (C-shell: 'unsetenv TERMINFO') as well.
どこかで見たな。
M-x eshell
上記の2者共、本物のshellを起動している。対して、eshellは、なるべくlisp で機能を実現しましょって方針。こうしておけば、どこでも同じ挙動が実現で きる。どうしてもって場合だけ、サブ・シェルを起動する。この方針って、普 段使いで許容できる事?
debianで叩いたコマンドが2000個記録に残っているんで、ベスト10を出してみ た。オイラー特有の使用履歴かも知れないけど、参考にはなるだろう。
[sakae@deb ~]$ cut -f1 -d' ' < .bash_history | sort | uniq -c | sort -nr | head 404 ls 275 cd 129 sudo 109 mg 68 sync 59 wd 53 cat 45 grep 40 pwd 37 cc [sakae@deb ~]$ cut -f1 -d' ' < .bash_history | sort | uniq -c | sort -nr | wc 115 230 1594
2000個中1219個がベスト10に入っている。コマンドの種類は115種だった。頻 度のグラフを書いてみるまでもなく、ロング・テールな様相だね。それにして も、100種ものコマンドを繰り出すオイラーは、偉いな(と、自画自賛)。
新ためでコマンドを見ると、mgなんてのが有る。mgってOpenBSDで動作する emacsのクローンさ。all C言語での提供。カスタマイズは出来ないけど、めっ ぽう小さくて高速起動する。それに肖ってemacsclientって長ったらしいコマ ンドのエイリアスにしてるんだ。また、wdは、cd /tmp のエイリアスさ。作業 場は、清掃不要なRAM-Diskなんだわ。
mgとペアになると言うか、emacsをダエモン・モードで起動するエイリアスも 用意してる。Linux用にsystemdでemacsをサーバー化しちゃう機能も用意され てるけど、それはチトやりすぎ。世の中Linuxだけじゃ無いんだよと叫びつつ、 エイリアスに、してるのさ。
こうしてベスト10を観察すると、外部コマンドは、コンパイラーだけだね。後 は曲がり形にeshellが面倒を見てくれそう。
どんなコマンドをサポートしてるかとかは、 Eshell manual を参照。
コンパイル作業とかをしてて、しまったログを取るのを忘れたなんて場合、窓 をセーブしてしまえばOK。ただ、困った事がある。
less hogeとかしてて、ファイルの最後に辿りついた時、q すると
Process /usr/bin/less finished
と言われて、eshellが終了しちゃうんだ。 カスタマブルな Emacs Lisp 製シェル「eshell」 まだ詳しく読んでいないけ ど、解決策が有るのかな?
die emacs
ネットをうろうろしてると、 Emacsは死んだ なんてのに出会った。そうだよねぇ。閉じてしまったら終わり ですよ。 そして、こんな喧喧諤諤な意見も出てきた。 Emacsって今だに使われていますか?というより、使う必要がありますか?
ダイナミックモジュール
上で危惧されてた事が実現されてしてしまった。まあ、そのおかげで、前回やった IMEが簡単に実現できるんだけどね。
#define DLL_EXPORT #include <emacs-module.h> #include <string.h> DLL_EXPORT int plugin_is_GPL_compatible; emacs_value my_hello (emacs_env *env, ptrdiff_t nargs, emacs_value *args, void *data) { emacs_value str; if (nargs == 0) { const char *phello = "Hello World"; str = env->make_string (env, phello, strlen (phello)); } else if (nargs > 0) { str = args[0]; } emacs_value func_symb = env->intern (env, "message"); emacs_value func_args[] = {str}; env->funcall (env, func_symb, 1, func_args); return env->intern (env, "t"); } DLL_EXPORT int emacs_module_init (struct emacs_runtime *ert) { if (ert->size < sizeof (*ert)) return 1; emacs_env *env = ert->get_environment (ert); if (env->size < sizeof (*env)) return 2; { emacs_value func = env->make_function (env, 0, 1, my_hello, "My Hello function.", NULL); emacs_value symbol = env->intern (env, "my-hello"); emacs_value args[] = {symbol, func}; env->funcall (env, env->intern (env, "defalias"), 2, args); } { emacs_value symbol = env->intern (env, "test-hello"); emacs_value args[] = {symbol}; env->funcall (env, env->intern (env, "provide"), 1, args); } return 0; }
コンパイルして、pathの通った所に配置。
[sakae@arch tmp]$ cc --shared -fPIC -o test-hello.so test-hello.c [sakae@arch tmp]$ mv test-hello.so ~/.emacs.d/lisp/
いざ、実行。結果は、メッセージ・バッファーに蓄積されてる。
(require 'test-hello) (my-hello) (my-hello "foo bar baz")
M-x gdb
前回やった、emacsからgdbを起動すると、端末がdumbになってしまう問題を追 求する。dumbをlisp/で、検索すると、色々な場所に出現してて、始末におえ ない。
そこで、論理思考を発動。曰く、前回のサブ・プロセスを起動してるソースに 注目。requireで取り込んでいる奴ね。怪しいファイルが発見された。 lisp/progmodes/gud.el.gz
(require 'comint)
詳細を確認する。 lisp/comint.el.gz
(defcustom comint-terminfo-terminal "dumb" "Value to use for TERM when the system uses terminfo." (defun comint-term-environment () "Return an environment variable list for terminal configuration." ;; If using termcap, we specify `emacs' as the terminal type ;; because that lets us specify a width. ;; If using terminfo, we default to `dumb' because that is ;; a defined terminal type. `emacs' is not a defined terminal type ;; and there is no way for us to define it here. ;; Some programs that use terminfo get very confused ;; if TERM is not a valid terminal type. (with-connection-local-variables (if system-uses-terminfo (list (format "TERM=%s" comint-terminfo-terminal) "TERMCAP=" (format "COLUMNS=%d" (window-width))) (list "TERM=emacs" (format "TERMCAP=emacs:co#%d:tc=unknown:" (window-width))))))
ピッタりな所に行きついた。dumbをscreenとかに変更して実行(comint.elcは 削除しておく)。
そしたら、教育的な指導もなく、ターゲットのemacsが起動してきた。但し、 画面制御が正常に行なわれないので、実際には使えないけど。。。 まあ、emacsOSが起動するまでの軌跡ぐらいは、十分に確認できる。
昔、同じような事を、qemu上に構築したOpenBSDでやった。それに比べると、 遥かに作業は楽だ。
inside emacs
中がどうなってるか、探検したい。周り道かも知れないけれど、、、
compile log
とりあえず、コンパイルログを採取してみた。何事も成り立ちからって事です。
make[3]: Leaving directory '/tmp/emacs-29.1/lisp' cp -f temacs bootstrap-emacs rm -f bootstrap-emacs.pdmp ./temacs --batch -l loadup --temacs=pbootstrap \ --bin-dest /opt/bin/ --eln-dest /opt/lib/emacs/29.1/ Loading loadup.el (source)... Dump mode: pbootstrap Dumping under the name bootstrap-emacs.pdmp Dumping fingerprint: b7c7e345e75bb28f3d5898825aad47729948a2d89f71048848bd5ab650a 01f4d Dump complete Byte counts: header=100 hot=4203180 discardable=72640 cold=3900468 Reloc counts: hot=461661 discardable=4837 : rm -f emacs && cp -f temacs emacs LC_ALL=C ./temacs -batch -l loadup --temacs=pdump \ --bin-dest /opt/bin/ --eln-dest /opt/lib/emacs/29.1/ Loading loadup.el (source)... Dump mode: pdump : Pure-hashed: 17370 strings, 5449 vectors, 48562 conses, 4937 bytecodes, 323 othe rs Dumping under the name emacs.pdmp Dumping fingerprint: b7c7e345e75bb28f3d5898825aad47729948a2d89f71048848bd5ab650a 01f4d Dump complete Byte counts: header=100 hot=3914300 discardable=72640 cold=3639080 Reloc counts: hot=438601 discardable=4837
make –dry-run
最近のツール・チェインはコンパイル過程をなるべく隠すみたいで、つまらな い。曰く、CC eval.c とか compiling compile.c みたいにね。 生々しいやつが欲しいのよ。
やり方は、3つ程あるみたい。
make VERBOSE=1 gcc -### -o output_file source_file.c ;; gcc only ? make --dry-run
このうちの、ドライランが、時間もかからず、お勧め。
気になる、temacsの作成手順を白昼の元に晒してみる。
CCLD temacs gcc -o temacs.tmp \ -Demacs -I. -I. -I../lib -I../lib -I/usr/include/libxml2 \ -MMD -MF deps/.d -MP -I/usr/include/p11-kit-1 -O0 -g3 \ dispnew.o frame.o scroll.o xdisp.o menu.o window.o charset.o coding.o cate\gory.o ccl.o character.o chartab.o bidi.o cm.o term.o terminal.o xfaces.o em\ acs.o keyboard.o macros.o keymap.o sysdep.o bignum.o buffer.o filelock.o insdel\ .o marker.o minibuf.o fileio.o dired.o cmds.o casetab.o casefiddle.o indent.o s\ earch.o regex-emacs.o undo.o alloc.o pdumper.o data.o doc.o editfns.o callint.o\ eval[…] ../lib-src/make-fingerprint temacs.tmp mv temacs.tmp temacs
詳しい事は、elisp manualのAppendix E GNU Emacsの内部にあるぞ。これを一 読してからかな。それとも、 lisp.h lispsym あたりを徘徊してからかな。自習材料一杯!!
それから、どうでもいい事だけど、make –dry-run の最後に、こんなのが出 てた。一応作成されたemacsで、lispらしいハロワを実行してるんですねぇ。 でも、関数型じゃないから、そこんとこ宜しくと断りをいれてる。
v=$(src/emacs --batch --eval '(progn (defun f (n) (if (= 0 n) 1 (* n (f (- n 1)\ )))) (princ (f 10)))' 2> /dev/null); \ [ "X$v" = "X3628800" ] && exit 0; \ echo >&2 '***'; \ echo >&2 '*** '"\"make all\" succeeded, but Emacs is not functional."; \ echo >&2 '***'; \ :
これを見ると、emacsもshell属の一員ですってのが、良くわかる。
speed down by ielm
前回スピードくらべをした時、ielm環境では、めっぽう遅かった。その原因が メモリー割付にあるかと思って比較してみた。 ielm
((conses 8 507007 56324) (symbols 24 29032 18) (strings 16 151494 5376) (string-bytes 1 4145785) (vectors 8 53032) (vector-slots 4 1020450 61978) (floats 8 369 382) (intervals 28 4858 813) (buffers 560 17))
normal
((conses 8 504313 55645) (symbols 24 28952 2) (strings 16 151170 5700) (string-bytes 1 4132879) (vectors 8 53068) (vector-slots 4 1024947 50880) (floats 8 370 381) (intervals 28 4765 906) (buffers 560 15))
目立つ差は無いな。でも、一度ielmを起動しちゃうと、普通の環境にも影響が 出てしまう事が判明した。
(4.357396313 2 0.293296019) (4.329022473 2 0.292284805) (4.32166502 2 0.29148105499999977)
ielmの起動履歴が無い場合のスピード。
(14.452575794 50 7.3472316650000025) (14.464804613 50 7.3487036399999965)
そして、こちらは、ielmの起動と実行経験が有る環境(もちろん、ielmは削除した状 態)。地球温暖化みたいに、一度スイッチが入いってしまうと、もう元の環境 には戻れないぞって言う闇からの警告です。クワバラ・クワバラは、雷様にし か御利益がありません。
ひょっとして、ielmを起動しちゃうと、gc-cons-threshold とか gc-cons-percentage が変更されてしまうかと調べてみたけど、そうでもない みたい。でも、面白いコマンド (memory-report) を発見。
Estimated Emacs Memory Usage 9.2 MiB Overall Object Memory Usage 5.6 MiB Memory Used By Global Variables 1.4 MiB Memory Used By Symbol Plists 235 KiB Reserved (But Unused) Object Memory 39 KiB Total Buffer Memory Usage 0 B Total Image Cache Size Object Storage 4.4 MiB Strings 2.4 MiB Conses 1.9 MiB Vectors 462 KiB Symbols 6.1 KiB Buffer-Objects 2.1 KiB Intervals 888 B Floats Largest Buffers 12 KiB test.el 8 KiB *scratch* : Largest Variables 3.7 MiB package-archive-contents 256 KiB load-history 160 KiB package--compatibility-table 118 KiB obarray :
これはCommonLispの(room)相当だな。
tips org-mode
org-modeでファイルを開いた時にすべてのヘッディングを畳んだ状態にするに は
(setq org-startup-folded 'content)
を、init.elに記述しておくとな。