19

I like using a combination of describe-face and customize-face to adjust the appearance of my working environment. Sometime this workflow fails when I want to change the face of a location I can not reach with the cursor; mode-line, header-line, magit-blame headers etc. Most of the time, I can trail and error my way to a solution but sometimes I get stuck (I didn't know the header-line existed until yesterday for instance).

Is there a convenient way to describe the face of a location in a frame which is not reachable by the cursor? By means of a mouse for instance.

remvee
  • 561
  • 6
  • 13

3 Answers3

13

I do not know about using the mouse, but I've often found it's easiest for me to run list-faces-display and then just i-search for what the face is likely called or visually scan for text that looks the same.

Jordon Biondo
  • 12,332
  • 2
  • 41
  • 62
  • 1
    **This is the answer, IMHO.** The display is WYSIWYG, and it gives you direct access to the Customize buffer for a given face and direct access to a complete description. – Drew Sep 26 '14 at 22:53
  • I agree and changed the status. The other solution is cool but not convenient. – remvee Sep 27 '14 at 09:12
10

There are 4 regions where text may be displayed in Emacs, here is what you can do to inspect each of them.

  • The mode-line: See the value of mode-line-format.
  • The header-line: See the value of header-line-format.
  • Buffer: If the face is in a region of the buffer you can't reach, see the value of (buffer-string).
  • Minibuffer: If point is currently in the minibuffer, you can do M-: (buffer-string), and that will describe the contents of the minibuffer. You may need to (setq enable-recursive-minibuffers to t) first.
  • Fringe or Margin: None that I know of.

These methods will give you the entire contents of these regions, so it may take some reading to actually find the face you're looking for, but it will certainly be there. Most importantly, it will describe even regions you cannot reach.
For instance, let's say I want to know which face is used in the find-file prompt.

  1. Invoke find-file with C-x C-f.
  2. Describe the minibuffer with M-: (buffer-string)

That will give something like the following output, and right there at the end is the face I was looking for.

#("Find file: ~/" 0 11 (front-sticky t rear-nonsticky t field t read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt))
Malabarba
  • 22,878
  • 6
  • 78
  • 163
  • Interesting! I did not know `(buffer-string)`. But how do I invoke it while I'm in the minibuffer without yielding "Command attempted to use minibuffer while in minibuffer"? – remvee Sep 26 '14 at 12:18
  • @remvee Ah, set the variable enable-recursive-minibuffers to t – Malabarba Sep 26 '14 at 13:30
  • What about the fringe? – Tikhon Jelvis Sep 26 '14 at 18:39
  • @TikhonJelvis oh, good point. That I don't know. – Malabarba Sep 26 '14 at 18:54
  • I think that also leaves the margins? – Sigma Sep 26 '14 at 19:05
  • @Sigma which margin? The fringe? – Malabarba Sep 26 '14 at 19:24
  • @Malabarba I meant the display margins http://www.gnu.org/software/emacs/manual/html_node/elisp/Display-Margins.html For example, the area that `M-x linum-mode` uses to display the numbers – Sigma Sep 26 '14 at 21:36
  • In addition to fringe and margins, there are tooltips. (And the menu-bar and tool-bar, but one doesn't usually think of those as places to display text.) – Drew Sep 26 '14 at 22:51
  • @Drew can one customize text properties in a tooltip or in the menubar? – Malabarba Sep 26 '14 at 22:55
  • You can put pretty much anything in a tooltip, including text with properties. Dunno what you mean by "customize in". If you are asking whether you can customize faces for text shown in tooltips, yes, but probably only for use with property `display`. And no for the menu-bar, AFAIK. You can in some contexts (some platforms) control what fonts etc. are used for the menu-bar (using, e.g., Xresources), but not faces. Anyway, I was responding not to the question about customizing faces but to the description of the "regions where text may be displayed in Emacs". Sorry for any confusion about that. – Drew Sep 26 '14 at 23:06
  • @Drew not at all, I'm the one who was lazy because I'm typing on a phone. what I meant to ask was whether tooltips are capable of displaying faces, like different colors or underlining. I've messed a lot with tooltips in the mode line, and I honestly never tried that so it made me curious (and I'm at the phone =). Sorry for any confusion. – Malabarba Sep 26 '14 at 23:13
  • I'm no expert on tooltips. I've used them to show images, and I know you can use the `display` text property to display practically anything in a tooltip. But I kind of doubt that you can simply put propertized text (i.e., text with faces) there. But try it! – Drew Sep 27 '14 at 04:17
4

Turns out you can indeed use the mouse (I think this may be exactly what you were looking for):

  ;; based on: https://emacs.stackexchange.com/a/19585/13444
  (defun brds/describe-char-at-mouse-click (click-event)
    "`describe-char' at CLICK-EVENT's position.
CLICK-EVENT should be a mouse-click event."
    (interactive "e")
    (run-hooks 'mouse-leave-buffer-hook)
    (let ((pos (cadr (event-start click-event))))
      (describe-char pos)))

  ;; <d>escribe
  (global-set-key (kbd "C-c d <down-mouse-1>")
                  #'brds/describe-char-at-mouse-click)
zck
  • 8,984
  • 2
  • 31
  • 65
Braham Snyder
  • 360
  • 3
  • 8
  • This doesn't seem to work for me in the modeline. Does it work for you in any places mentioned in the question? – zck Sep 12 '17 at 04:25
  • Works for me on `magit-blame` headers, as well as, at a minimum, minibuffer completion candidates, the minibuffer prompt, and company popups. That said, it's not working for me either when I call it on the mode- or header-line: those give me `(wrong-type-argument number-or-marker-p header-line)` (or `[...] mode-line`, respectively). I think those might be particularly special cases (along with the fringe and margin). – Braham Snyder Sep 12 '17 at 07:01