Emacs Part 54
eggが使えるかぎりどんどんバージョンアップしてもらってかまわない IDEが便利で強力になっても システム標準でviが必修でも VSCodeが流行しても Emacsは常に生き残ってきたじゃないか emacsを長らく使ってます(テキスト書き、プログラミングなどメイン使いのエディタ)。 何か新しいもの触ってみたくて spacemacs と doomemacsを知ったのですが、どっちがおすすめですか? (どっちがメンテされてる、など) >>10 どちらもクレカの番号を抜けないのでおすすめできません。 WSL の emacs(GNU Emacs 25.2.2 (x86_64-pc-linux-gnu) of 2017-09-23, modified by Debian)に markdown-mode 入れようとしてるんだが、packagelist 上では markdown-mode 20221105.236 incompat melpa Major mode for Markdown-formatted text と表示されてインストールできない。 何か互換性の問題ってあったっけ? Version: 20221105.236 Summary: Major mode for Markdown-formatted text Requires: emacs-26.1 って出てるな。 いまだに Windows XP 使い続けてる老人と一緒でしょ 次のように引数の必要な関数を関数名のシンボルの代わりに指定するときに、 lambda式で書くとエラーになる場合はどうするのがいいんでしょうか? Wrong type argument: symbolp, #'(lambda nil (dabbrev-expand nil)) (setq smart-tab-completion-functions-alist '((emacs-lisp-mode . lisp-complete-symbol) (lisp-interaction-mode . lisp-complete-symbol) (text-mode . #'(lambda () (dabbrev-expand nil))))) # この例では実際にはこの設定は不要なんですが、 # いじっているうちに疑問が出てきたので一例として。 うーん多分それ先頭の#'全く場違いなんじゃね? それシンボルのfunctionPartにアクセスするfunctionというかaliasというかsyntax sugarというべきかのものだしquoteされてたらそもそもなんも意味をなさん quote内部のpartial evalみたいのは先頭をbackquoteにして`(sym1 sym2 ,evaled)みたいに先頭にcommaを付記する defmacroとかのときによく使う手法だな。まぁ、俺はlispyじゃないと思うからあんま好きじゃないけど 単純に(list (cons 'someone 'something) (cons 'anyone (lambda (x) (some-over x))))みたいに書くか `((someone . something) (anyone . ,(lambda (x) (some-over x))とかじゃね(´・ω・`) まだよく理解できていないので一部だけ補足しますが、 #'(lammda ...は(lambda ...でも一緒なのかと思ったんですが。 https://www.gnu.org/software/emacs/manual/html_node/elisp/Anonymous-Functions.html で、そもそもこんな風に書いたのは次のような書法を参考にしたんですが、 どうもここではまずいようです。 (add-hook 'text-mode-hook (lambda ... )) いまいち何が解決出来ないのか何が分からんのかが分からんな ただhookにlambdaぶち込みたいならfbody 先頭に (lambda () (interactive) (insert "hello hook fucker"))みたいにinteractive宣言が要るぞ lambdaのargumentが必要な場合はこのinteractiveのargumentに別途それらにアサインする関数というか糞stringというかlist返すexpression書くんだけどこまけえ事は説明めんどい(´・ω・`) (quote symbol)は評価されないとsymbolにならないように、(function (lambda () ...) も評価されないと関数にならない。 >>20 評価される文脈なら一緒だけどリストの中にある場合はそうも行かない。 lambdaはそのままで関数として機能する(funcallできる)からややこしいのかな。 symbolは評価すると変数の値になってしまうけどlambdaは、まあ、closureになったりはするものの関数のままだしクォートの必要性を感じづらいというか。 >>19 >>22 何となく引っかかっていたところがちょっとわかりかけました。 lambda式が評価せずそのまま飲み込んで関数として定義されていないことが、 関数名のシンボルを要求する文脈ではエラーになると。 ではつまり関数として定義してしまうしかないということですかね? >>23 文脈と書いたのは>>18 の#'(の部分が評価されない文脈だから。なぜなら'(で囲まれてる中だからね。 #'(lambda () ...)は(function (lambda () ...)の略記だから(ここが分かってない?) '(の中ではそのまま一つ目の要素がシンボルfunctionで二つ目の要素が(lambda~のリストになってしまう。そしてそれはfuncall出来ない。例:(funcall '(function (lambda () 123))) 解決策は'(を使わずリストを組み立てることで、>>19 や>>24 が言うように(listやバッククォートでリストを組み立てること。シンボルだけで無く、(functionで囲まれていない)lambda(やそれを評価すると出来るclosure)も問題なく使える。 まあdefunして良いならそれでもOK。 >>25 中途半端にあれこれ聞いてお手間を取らせました。 まだろくにわかってないんですが、 疑問は疑問としてとりあえずこうすると動きます。 consだといいの?何だか不思議だなあ。 (setq smart-tab-completion-functions-alist '((emacs-lisp-mode . lisp-complete-symbol) (lisp-interaction-mode . lisp-complete-symbol) (cons 'text-mode (lambda () (dabbrev-expand nil))))) そうみたいですね。評価したら結果が変でした。 デフォルトでdabbrev-expandが呼ばれる仕様なんだった。 多分、こういうことだろうと思うんですが、 (setq smart-tab-completion-functions-alist `((emacs-lisp-mode . lisp-complete-symbol) (lisp-interaction-mode . lisp-complete-symbol) (text-mode . ,(lambda () (dabbrev-expand nil))) )) 今回の場合は条件がfboundpでチェックされるので同じエラーになりますが、 cond: Wrong type argument: symbolp, (lambda nil (dabbrev-expand nil)) これがなければfuncall以下はちゃんと動きます。 (cond ((fboundp smart-tab-mode-specific-completion-function) (funcall smart-tab-mode-specific-completion-function)) むしろその場合はこうするだけでいいんですね。 (setq smart-tab-completion-functions-alist '((emacs-lisp-mode . lisp-complete-symbol) (lisp-interaction-mode . lisp-complete-symbol) (text-mode . (lambda () (dabbrev-expand nil))))) >>19 > うーん多分それ先頭の#'全く場違いなんじゃね? そもそも最初に指摘されていたこの点がまずかったと。 評価されたら (lambda 〜) も #'(lambda 〜) も完全に等価だよね 何かの拍子で特定のバッファ(やてふモード)を閉じれなくなりました * Message *を確認すると以下のメッセージが出ます bm-buffer-save: Wrong type argument: listp, \.\.\. 他のやてふモードのバッファは問題ありません とりあえず当該バッファを閉じたいと思い *scratch*で (remove-hook 'after-save-hook 'bm-buffer-save) したのですが何ともなりません 何か解決方法はないでしょうか? どこでどう評価するかでは clのlambdaは評価するとレキシカルクロージャに化けるマクロだけど、(coerce '(lambda ...) 'function)でキャストすればcoerceはfunctionのように特殊形式でないからローカル関数を補足できないはず el的にはどうだっけ? そもそもクォートされたラムダ式を単にフォームとして受け取り、自分で勝手に解釈するだって全然アリ >>32 kill-buffer-hook とかじゃなくていいの? >>34 ああ!そうですね! ボケボケでした (remove-hook 'kill-buffer-hook 'bm-buffer-save) で閉じれました ただ今度は当該ファイルをfind-fileすると 初回に以下のエラーメッセージが出ます bm-buffer-restore: Wrong type argument: number-or-marker-p, nil 連続で2回当該ファイルをfind-fileすると開くので問題はないのですが これはbmのキャッシュが不整合を起こしているということでしょうかね? 前スレでDebianのunstableでEmacsパッケージのnative compilationが有効化されたって話があったけど その後色々問題があったものの解決されて有効化されたバージョンがTestingにやってきた模様 というわけでこのまま行けば来年出るであろうDebianの次の安定版ではEmacsパッケージは デフォルトでnative compilationが有効化されたものになるわけだ キャッシュのsaveにprincを使っていて print-lengthより長いリストが...になっているかもしれない (let ((aaa (list '(a) '(a) '(a))) (print-length 2)) (princ aaa)) ; => ((a) (a) ...) native compilationを有効にすると、 確かにごく偶に何も言わずに落ちることがあるから、 まったく問題がないわけでもないのかな。 まあ、最後に落ちたのも一月以上前だったりするけど。 companyと*Completions*バッファについて教えてください。 (use-package company)としてcompanyを使うようにすると、補完がcompany経由で行われる?と聞いたのですが、 例えば、 M-x shell ls ./[TAB] とすると、*Completions*バッファ内にカレントディレクトリのファイルが表示されます。 これはcompanyモードが効いてないのでしょうか?それともcompanyが補完するのは、こういう類の補完ではそもそもないのでしょうか? バッファでcompany-modeが有効になってないかキーバインドが定義されてないとか。 M-x company-completeするとどうなりますか? >>41 返信ありがとうございます。 shellのバッファで「M-x company-complete」するとカーソル位置で補完候補が現れました。 同じバッファでM-x describe-modeをすると、一覧にCompanyとGlobal-Companyが出てきています。 これは、単にキーバインドが定義されてないってことでしょうか? M-x describe-key で[TAB]押すとどうなんだろうか (global-company-mode 1) とかやっとけばいいんでないの? >>42 use-packageを使ってませんが、 とりあえずglobal-company-modeは有効にされてるんだと思います。 M-x company-completeで手動では起動できるわけだから、 どのキーにバインドするかは設定が必要だろうし、 tabでデフォルトのshellの補完を奪っていいかどうかも自分次第かと。 返信ありがとうございます。 >>43 ls ./[ここでdescribe-key TAB]すると、(completion-at-point)にバウンドされてるようです。 >>44 >>45 describe-modeした際にglobal-companyが出てきてるので、global-company-modeは有効になっているように見えます。 >どのキーにバインドするかは設定が必要だろうし、 >tabでデフォルトのshellの補完を奪っていいかどうかも自分次第かと。 なるほど。tabに対してキーバインドは設定していませんでした。 このあたりの仕組みがよくわかってないもので、company-modeを有効にすると自動的に*Completions*バッファが ツールチップで補完表示されるものかと思ってましたが、そういうものではなく、 自分で設定する必要があるんですね。 >>46 普段company-idle-delayをnilに設定してキーで起動していたので勘違いしましたが、 デフォルトのままだと入力するそばから自動的に補完候補を表示しますね。 私はそれが煩わしいので手動で起動するようにしてたんですが、 何かの設定がうまくいってないんですかね? >>47 頂いた情報を参考に色々調整した結果、 (setq company-idle-delay 0) (setq company-minimum-prefix-length 0) 上記設定を追加してみると、shellバッファで文字を打つたびに補完候補が表示されるようになりました。 試しに、 (setq company-minimum-prefix-length 5) とした場合、 (5文字未満) ls ./[TAB] # *Completions*バッファが表示される。 (5文字以上) ls ./../[TAB] # companyで補完候補が表示される。 という挙動になりました。 私がcompanyの機能を勘違いしている気がしてきました。 companyはemacs従来の「*Completions*バッファが表示される」動きをまるまる置き換えるものと思ってましたが、 そんなことはなく*Completions*バッファが表示されてしまう場面を完全に無くせるわけではないのでしょうか? companyは既存の設定だけでなく、 最終的には自分で補完に使用するbackendsまで作成すればほとんどどんな動作にもできるはずですが、 お話のようにデフォルトの補完completion-at-pointをcompanyで置き換えたいだけなら、 パッケージに同梱されたcompany-capfをcompany-backendsに設定すればよさそうですけどね。 company-backendsは以下のように設定されていました。 (company-bbdb company-semantic company-capf company-files (company-dabbrev-code company-gtags company-etags company-keywords) company-oddmuse company-dabbrev) リストの中にリストが含まれてるのが怪しいのですが、一応company-capfは入っているようです。 一つ気になったのが、 (use-package company :config ((global-set-key (kbd "TAB") 'company-complete)) と設定しても、shellバッファでdescribe-key [TAB]をすると、設定されているのは (completion-at-point) となっていました。これはキーバインドの設定の方が間違っている可能性がありますか? 質問ばかりですいません。 >>51 infoというのが、companyの公式ページの話であれば読んではいるもののなかなか理解できず苦労してます。 「emacsの情報」という意味であれば、すいません、emacsを使い始めたばかりなので拾いきれてないですね >>51 じゃないけど M-x info のことを言ってると思われ セルフドキュメント方式、てのがググれない時代からあるEmacsの思想の一つなんだわ で、そういった思想とか調べ方もinfoの中に書いてあった気がする 日本語の方が良いなら Emacs 日本語マニュアル インストール あたりでググれ companyモード用のinfoがあるかは知らん 公式のマニュアルにサンプルもあるのでまずそれを試してみては。 https://company-mode.github.io/manual/ とりあえずキーバインドを定義しなくても、 以下のcompany-backendsのサンプルで概ね希望通りの動作になるのでは? https://company-mode.github.io/manual/Backends.html#Package-Backends (setq company-backends '((company-capf company-dabbrev-code))) 最近font-lock-modeの仕様が変わった? wanderlustのsummaryでfont lockが効かなくなった、 というか挙動が変なような。 >>55 古いバージョンを戻して切り分けてみたら? 少なくともEmacsかそれ以外か分かれば すぐに思い浮かばなかったけどwhitespace.el関連の変更が原因でした。 細かい原因はまだ調べてないけど、 とりあえずwhitespace-global-modesから除外すればよさそう。 多分、これが原因だから年末頃? whitespace: Use `define-globalized-minor-mode' for global mode * lisp/whitespace.el (global-whitespace-mode): Fix interoperability between `whitespace-mode' and `global-whitespace-mode' by using `define-globalized-minor-mode'. (Bug#60334) * test/lisp/whitespace-tests.el (whitespace-tests--global): Add a regression test. >>58 戻って留まれ。自分が新しいものについていく必要があるとかついていく能力があるとかいう心得違いをしないこと。世界は君を中心に回っていない(甚だ遺憾であろうとは察する 戻って留まるにしても、そのための能力が必要なんよな 新しいOSで古いものについていく能力がないと、古いものさえビルドできない みんなDocker使ってるの? Emacs使いはエディタが環境だろ >>63 凡人がdockerでやってることをEmacsで再現できてるなら画期的すぎるから、そのノウハウをシェアしたらめちゃくちゃPV取れると思うよ Software Design辺りで連載の依頼も来るかもしれない USB起動のLinuxみたいなモン 一旦インスコとか設定をしたら別PCで 全く同じように動かせる 建前上ではそうなってる docker = chrootの化け物(ファイルシステムだけじゃなくプロセス空間も分けるよ的な) >>60 新しいものが道具として洗練されているとは限らない グーグルのための野暮な改悪は新しいとは言わない つか28はちょっと酷いなあ ネイティブコンパイルってそんなに有り難いもんなのか? .elファイルをコンパイルして.elcにしたら 物凄く速くなったことある 28速いか? むしろ遅くなってるように感じられるが? elnを生成している間は当然前より遅いけど、終わってしまえば遅いってことはないだろう 体感的にはとても速いと思っている 無能なのでベンチ取る気はない つか、ネイティブコンパイルなら早いって発想も随分とまあ、経験浅いのねぇw Native compileかあれはデフォオプション来るなら28で更新止めるな 本当にあれはイラン おま環かもしれんがpackage list packageとかやるごとにフリーズするかlaptopファン大回転始めるわで全く話にならんかった(´・ω・`) >>80 ビルドするスレッド数を制限しろ 当然、native-comp-async-jobs-numberぐらいを試した上で、文句を言っているよな? わが家の貧弱な環境でもデフォルト値のままで一時的に重くなるくらいだから、 もっと根本的な問題があるんじゃない? mozc.elを入れたんだけど、(setq mozc-candidate-style 'overlay)としても変換候補がミニバッファに表示される。 おまかん? emacs -nwで起動してみたけど入力している所の一行下に表示されるな overlay遅いのでmozc-popupっての使うといい posframe一度使ってみたけどpopupに戻した (let* ((l '((:p 'a) (:p 'b)))) (dolist (i l) (print (symbolp (plist-get i :p))))) :pに対応する'aと'bを順番取りたいんですが、出力がnilと表示されます。 l=プロパティリストのリスト i=プロパティリスト になると思ったので、plist-getで:pのペアになっているシンボルが変えると思ったのですが、 何が間違ってるんでしょうか? (let* ((l '((:p a) (:p b)))) にしたら? key重複alistならmap-remove? prop重複plistならalistに変換するかmapcarで丁寧に処理する? >>95 あざます。できました。クォートよくわからん・・・ 質問があります。 regionを適切にインデントするには、M-x indent-region か C-M-\ を押しますが、整形したいregionを選択している状態でtabキーを押すと、同じような挙動をすることに気がつきました。 もしかして、regionを選択してtabキーを押すと、indent-region と同じ事が実行されるのでしょうか? であれば、C-M-\ の代わりにtabキーを押すようにしようと思うのですが... 環境: Emacs 28.1 Mac(monterey) indent-for-tab-command でヘルプ引け 質問があります org-modeでアーカイブ先を変更するにはどうすればよいでしょうか? hoge_archive から org-directory/archives/hoge_YYYY に変更したいです https://repl.info/archives/52/ を読んで (setq org-archive-location (concat org-directory "/archives/“%s_archive_” (format-time-string “%Y” (current-time)")) としてみましたがorg-archive--compute-location: Invalid archive location: "~/Dropbox/emacs/org/archives/“%s_archive_” (format-time-string “%Y” (current-time)" とのエラーが出ます GNU Emacs 27.1 org-mode 9.6です。よろしくお願いします read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる