0

I'm using emacs package that does LLM prompt construction and appends current major mode name(You are %s programmer. Rewrite the following code kind of string)

Related code looks like this:

;; "Remove the -mode suffix from MODE-NAME. MODE-NAME is typically a major-mode symbol." (let ((mode-name (thread-last (symbol-name mode-sym) (string-remove-suffix "-mode") (string-remove-suffix "-ts")))) (if (provided-mode-derived-p mode-sym 'prog-mode 'text-mode 'tex-mode) mode-name "") 

Which works fine in most cases except those like popular enh-ruby(enhanced ruby) package which makes prompt look like "You are enh-ruby programmer".

Is there a common way or convention for Emacs package to have separate "technical" and "human-readable" major mode names? Or what might be a good way to fix this issue?


Update

I checked interpreter-mode-alist variable, which looks like what I was looking for but it probably doesn't have all major modes listed here(only interpreter modes?)

(("ruby" . enh-ruby-mode) ("r" . ess-r-mode) ("Rscript" . ess-r-mode) ("lua" . lua-mode) ("python[0-9.]*" lambda nil (configuration-layer//auto-mode 'python 'python-mode)) ("ruby1.8" . ruby-mode) ("ruby1.9" . ruby-mode) ("jruby" . ruby-mode) ("rbx" . ruby-mode) ("ruby" . ruby-mode) ("python[0-9.]*" . python-mode) ("rhino" . js-mode) ("gjs" . js-mode) ("nodejs" . js-mode) ("node" . js-mode) ;; truncated ) 
3
  • Why not use your own translation table? Give it the major-mode symbol as input and it spits out whatever name you want to use in your sentence (falling back to the symbol name if there is no entry in your table). An alist would do perfectly for that. Commented Jul 31, 2024 at 15:35
  • emacs.stackexchange.com/tags/elisp/info Commented Jul 31, 2024 at 15:58
  • Instead of "You are enh-ruby programmer", use "You code in Emacs with enh-ruby mode." Commented Jul 31, 2024 at 20:08

2 Answers 2

2

Is there a common way or convention for Emacs package to have separate "technical" and "human-readable" major mode names?

The short answer is: Not in the way you're hoping for, no.

The long answer is...

Major modes have a descriptive name and a symbol name, which are independent.

The symbol for the major mode is stored in the buffer-local major-mode variable.

The descriptive name of a buffer's major mode -- as seen in the mode line, or in the *Help* buffer when you use C-h m -- is stored in the buffer-local mode-name variable.

The value of mode-name is commonly a string, but it may contain other mode-line constructs, so you should probably assume that it does. However (and relatedly) the mode-name value is intended to be informative in the mode line, and is not necessarily an ideal substitute into a sentence. In particular, these values frequently combine the mode name with some kind of status information, and modes are free to do this however they wish. For example:

  • The mode-name of text-mode is "Text"
  • The mode-name of dired-mode is "Dired by name", but when I toggle the sort-order it becomes "Dired by date"
  • The mode-name of emacs-lisp-mode is ("ELisp" (lexical-binding (:propertize "/l" help-echo "Using lexical-binding mode") (:propertize "/d" help-echo "Using old dynamic scoping mode mouse-1: Enable lexical-binding mode" face warning mouse-face mode-line-highlight local-map (keymap (mode-line keymap (mouse-1 . elisp-enable-lexical-binding))))))

The latter is rendered in the mode line as either ELisp/l or ELisp/d, with various text properties in effect.

You could obtain the relevant string without the text properties like so:

(substring-no-properties (format-mode-line mode-name)) 

However "You are ELisp/l programmer" isn't necessarily an improvement upon "You are emacs-lisp programmer".

There's no convenient solution to this, as there is no descriptive mode name value which guaranteed to only be a human-friendly representation of the major mode symbol.

See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=68600#11 for a similar issue, where the conclusion was to use what you're currently using: the symbol name for the mode function.

If your requirement was for personal use only and you wanted to use delight as shown by Dunaevsky Maxim to manipulate the mode-name values to have only very plain names (and/or you wanted to allow for other users to be using delight.el for this purpose), then you could use the following to obtain the 'delighted' version of mode-name:

(substring-no-properties (let ((delight-mode-name-inhibit nil)) (format-mode-line mode-name))) 

If you're using this to eliminate information, however, then you also lose that information when the same thing is rendered in the mode line; so I don't think that's a sensible way to go.

You risk winding up with undesirable values whichever way you go, so I'd suggest just using the symbol name (which is simpler), and if necessary maintain your own custom mapping of friendly names for the specific modes where the symbol name looks unsuitable.

1

You can use delight.el package.

;; Hide `anzu-mode' from modeline: (delight 'anzu-mode nil :major) ;; Rename `markdown-mode' to `MD-MODE': (delight 'markdown-mode " MD-MODE" :major) 

See https://www.emacswiki.org/emacs/DelightedModes for full details.

Also delight.el package can be integrated with use-package.el:
https://www.gnu.org/software/emacs/manual/html_node/use-package/Hiding-minor-modes.html

3
  • I believe diminish.el only handles minor modes? Certainly that used to be the case. Commented Jul 31, 2024 at 8:43
  • Unfortunately I don't believe this answers the question. I've referenced this answer in my own, though, as there's a tangential usage of delight which might be of interest. Commented Jul 31, 2024 at 10:17
  • 1
    Hello! Me remove diminish.el from answer and add link to delight home page. Commented Aug 7, 2024 at 5:46

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.