回答:
ここに1つの方法があります。コマンドをマウスイベントにバインドする必要があります。ただし、マウスボタンのクリックを使用する場合は、クリックの他の部分(ダウンなど)のイベントをにバインドする必要がありますignore
。これは単なる例です- C-mouse1
そのようなコマンドを無駄にしたくない場合があります。
主な機能(実際にはコマンド)はdescribe-char
です。これは、指定されたバッファー位置のポイントを示します。説明の一部には、テキストプロパティとその位置のオーバーレイが含まれています。プロパティface
がこれらの1つである場合は、その値が表示されます。
(defun foo (event)
(interactive "e")
(let* ((mouse-pos (event-start event))
(pos-pt (posn-point mouse-pos)))
(describe-char pos-pt)))
(global-set-key [(control down-mouse-1)] 'ignore)
(global-set-key [(control mouse-1)] 'foo)
これは少し良いかもしれません-上記はいくつかのコンテキストでは機能しないかもしれません:
(defun foo (event)
(interactive "e")
(let* ((mouse-pos (event-start event))
(mouse-buf (window-buffer (posn-window mouse-pos)))
(pos-pt (posn-point mouse-pos)))
(with-current-buffer mouse-buf (describe-char pos-pt))))
(これもを使用C-x =
するwhat-cursor-position
にバインドされていることに注意してくださいdescribe-char
。したがって、で正しい軌道に乗っていましたC-u C-x =
。)
Idoに関する懸念事項:オーバーレイを使用するIcompleteとは異なり、Idoモードはテキストをミニバッファーに挿入します。ただし、上記のコードがそのテキストに対して機能しないのは、イドモードが各コマンドの先頭にあるを使用してテキストを削除するためですpre-command-hook
。したがって、上記のコマンドを実行すると、補完を示すテキストはすでに削除されています。
次のコードは、イドモードの場合のみ、この問題を解決します。最初に補完を示すテキストを再挿入し、最後に補完を削除します。
(defun foo (event)
(interactive "e")
(when (and (boundp 'ido-mode) ido-mode) (ido-exhibit))
(let* ((mouse-pos (event-start event))
(mouse-buf (window-buffer (posn-window mouse-pos)))
(pos-pt (posn-point mouse-pos)))
(with-current-buffer mouse-buf (describe-char pos-pt)))
(when (and (boundp 'ido-mode) ido-mode) (ido-tidy)))
describe-char: No character follows specified position
describe-charによってメッセージが返されます。イベント後のある時点でミニバッファーがクリアされたことが原因だと思います。私は'ignore
これで止めると思いましたが、それは起こりません。何か案は?
M-x some-text
、C-mouse-1
ミニバッファーのそのテキスト上で。)もちろん、テキストがある位置でマウスをクリックしなければなりません。テキストの終わりの後にクリックすると、あなたが言及したエラーが発生します。
ポイントを正しい場所に配置してを使用できない場合C-u C-x =
、関連する要素がオーバーレイの前後の文字列を介して表示されているか、その要素がポイントを挿入しようとすると表示されなくなるか変更されることが原因である可能性がありますそれまたはあなたC-u C-x =
。
次のようにして、これらの問題を回避することができます。
posn-at-x-y
そのx / y座標にあるものの説明を返すuse を使用します。たとえば、後/前の文字列から取得されたテキストの一部である場合、その文字列はそこに(その文字列内の位置とともに)言及されるため、その位置でその文字列に適用されているfaceプロパティを参照できます。run-with-timer
、コードを毎秒実行して、選択したデバッグバッファに結果を出力できます。packate faceupを使用すると、人間が読める形式のテキストを、顔情報とともに作成できます。例えば:
(defun foo (arg)
(if arg 1 2))
を実行M-x faceup-vire-buffer RET
すると、次のように表示されます。
(«k:defun» «f:foo» («v:arg»)
(«k:if» arg 1 2))
標準のフォントロック面はk
forのように短い名前を使用して表されますが、font-lock-keyword-face
非標準の面はフルネームを使用して表示されます。
(Faceupは、フォントロックキーワードなどのパッケージを強調表示するための回帰テストシステムです。テキスト表現は参照ファイルとして保存されます。)
編集:
コメントの質問に答えるには、「ミニバッファディスプレイで使用されている面をデバッグしようとしている場合でも、これで情報が得られますか?」
はい、そうです。ただし、M-x
ミニバッファーが使用されている場合は、関数をキーにバインドする必要があります。例えば:
(global-set-key (kbd "<f6>") 'faceup-view-buffer)
「ミニバッファ」が本当にエコー領域を意味する場合、それは現在のメッセージを調べたいので、もう少し必要になります。次の関数はこれを行います:
(defun my-faceup-view-current-message ()
(interactive)
(let ((msg (current-message)))
(unless msg
(error "Echo area is empty"))
(with-temp-buffer
(insert msg)
(faceup-view-buffer))))
たとえば、次のとおりです。
(let ((s "My Message"))
(add-text-properties 3 (length s) '(face font-lock-warning-face) s)
(message s)
(my-faceup-view-current-message))
表示されます:
My «w:Message»
別の解決策は、カラーピッカーを使用して、list-faces-for-color
以下で定義するカラー値を提供することです(カラーピッカーが少しずれている場合は、distance引数を使用します)。
(defun list-faces-for-color (color &optional distance)
"List faces which use COLOR as fg or bg color.
Accept colors within DISTANCE which defaults to 0."
(interactive (list (read-color "Color: ")
(and current-prefix-arg
(prefix-numeric-value current-prefix-arg))))
(with-help-window (get-buffer-create (format " *%s*" this-command))
(dolist (face (sort
(list-faces--for-color color distance)
(lambda (f1 f2)
(string< (symbol-name f1)
(symbol-name f2)))))
(list-faces--print-face face)
(terpri))))
(defun list-faces--print-face (face)
"Print face and its parents if any."
(with-current-buffer standard-output
(let ((fchain (cdr (list-faces--inheritance-chain face :foreground)))
(bchain (cdr (list-faces--inheritance-chain face :background))))
(insert (propertize (format "%s" face) 'face face))
(cond (fchain
(dolist (face fchain)
(insert " > " (propertize (format "%s" face) 'face face))))
(bchain
(dolist (face bchain)
(insert " > " (propertize (format "%s" face) 'face face))))))))
(defun list-faces--inheritance-chain (face attr)
"Return inheritence change for face and attr."
(let ((g (face-attribute face attr)))
(if (and (stringp g)
(not (string= "unspecified" g)))
(list face)
(let ((inherit (face-attribute face :inherit)))
(when inherit
(if (facep inherit)
(cons face
(list-faces--inheritance-chain inherit attr))
(if (consp inherit)
(cl-dolist (face inherit)
(let ((res nil))
(when (and (facep face)
(setq res (list-faces--inheritance-chain face attr)))
(cl-return res)))))))))))
(defun list-faces--attribute (face attr)
"Get face attribute of face as defined or inherited."
(let* ((chain (list-faces--inheritance-chain face attr)))
(cl-dolist (f (nreverse chain))
(let ((g (face-attribute f attr)))
(when (and (stringp g)
(not (string= "unspecified" g)))
(cl-return g))))))
(defun list-faces--for-color (color &optional distance)
"Return all faces with COLOR as fg or bg withing DISTANCE."
(let ((faces ())
(distance (or distance 0)))
(mapatoms (lambda (atom)
(when (facep atom)
(let ((fg (list-faces--attribute atom :foreground))
(bg (list-faces--attribute atom :background)))
(when (or (and fg
(<= (color-distance
fg
color)
distance))
(and bg
(<= (color-distance
bg
color)
distance)))
(push atom faces))))))
(delete-dups faces)))