I am confused about how to use a variable in elisp - emacs

I try to set the font as below:
(let ((my:font "WenQuanYi Micro Hei Mono"))
(when (member my:font (font-family-list))
(set-face-attribute 'default nil :font my:font :width 'condensed)
(add-to-list 'default-frame-alist
'(font . my:font))))
The set-face-attribute works fine. I can see the font is set to WenQuanYi. But when I check the value of default-frame-alist, it shows as (font . my:font) and when try to create a new frame (emacsclient), I got this error:
*ERROR*: Invalid font: my:font
It looks like it try to use the value name as a font name. So I am not sure what's the right way to do it.

The quoted list '(font . my:font) produces a cons of those two symbols, rather than the value that you want. Instead of quote you can use either backquoting or a call to cons:
`(font ,my:font)
or
(cons 'font my:font)
You might be interested in the info pages (info "(elisp)Quoting") and (info "(elisp)Backquoting"), which explain those constructs in more detail.
On an unrelated note, the emacs lisp lexical conventions for local variables uses hyphens like-this, not colons like:this.

Related

Emacs. Spell check "on fly" for 2 languages

Windows 7, Emacs 25.1
I need to spell check "on fly" for my custom text (e.g. to emphasize the incorrect words). But I write text in two languages: English and Russian. And I want easy to switch between spell checking for 2 languages.
What is the best emacs package for this? Thanks.
You want this: guess_language.el
(use-package guess-language ; Automatically detect language for Flyspell
:ensure t
:defer t
:init (add-hook 'text-mode-hook #'guess-language-mode)
:config
(setq guess-language-langcodes '((en . ("en_GB" "English"))
(it . ("it_IT" "Italian")))
guess-language-languages '(en it)
guess-language-min-paragraph-length 45)
:diminish guess-language-mode)
Alternatively if you just want to cycle through them:
(defvar mu-languages-ring nil "Languages ring for Ispell")
(let ((languages '("en_GB" "it_IT")))
(validate-setq mu-languages-ring (make-ring (length languages)))
(dolist (elem languages) (ring-insert mu-languages-ring elem)))
(defun mu-cycle-ispell-languages ()
(interactive)
(let ((language (ring-ref mu-languages-ring -1)))
(ring-insert mu-languages-ring language)
(ispell-change-dictionary language)))
These should work with FlySpell
I had a similar problem, the solution I found manages two or more languages at the same time without using guess_language package. This solution is based on Hunspell spelling checker.
SYSTEM:
Windows 7 SP1, GNU Emacs 26.1
First, perform a Ispell/Hunspell configuration after Hunspell installation. Insert the next code in the .emacs file, usually located within C:/Users/Account.
;; START BLOCK1 <-- Ispell/Hunspell setting
;; e.g., "C:/Hunspell/bin/hunspell.exe"
(setq-default ispell-program-name "hunspell.exe FULL PATH")
(setq-default ispell-extra-args '("--sug-mode=ultra"))
;; Set "DICTDIR" variable, e.g., "C:/Hunspell/share/hunspell"
(setenv "DICTDIR" "hunspell DICTIONARY PATH")
;; Uncomment next line to set English or another dictionary
;; (setq ispell-dictionary "en_US")
;; Automatically enable flyspell-mode in text-mode
(setq text-mode-hook '(lambda() (flyspell-mode t) ))
(require 'ispell)
;; END BLOCK1 <-- Ispell/Hunspell setting
This code is based on the spelling configuration section of another discussion, see M Parashar - Load Theme. The block code 1 works for the default dictionary, which can be changed uncommenting the line with the ispell-dictionary variable. This code works perfectly for me.
The second code block enable us to use multiple dictionaries, is based on AM Lafon - Multi Spell Checking. For me, this code block works only next of code block 1.
;;START BLOCK2<-- Multiple dictionaries. Only works with BLOCK1
(with-eval-after-load "ispell"
;; Configure `LANG`, otherwise ispell.el cannot find a 'default
;; dictionary' even though multiple dictionaries will be configured
;; in next line.
(setenv "LANG" "es_ES")
;; English/spanish configuration.
(setq ispell-dictionary "en_US,es_ES")
;; ispell-set-spellchecker-params has to be called
;; before ispell-hunspell-add-multi-dic will work
(ispell-set-spellchecker-params)
(ispell-hunspell-add-multi-dic "en_US,es_ES")
;; For saving words to the personal dictionary, don't infer it from
;; the locale, otherwise it would save to ~/.hunspell_de_DE.
(setq ispell-personal-dictionary "~/.hunspell_personal"))
;; The personal dictionary file has to exist, otherwise hunspell will
;; silently not use it.
(unless (file-exists-p ispell-personal-dictionary)
(write-region "" nil ispell-personal-dictionary nil 0))
;;END BLOCK2<-- Multiple dictionaries. Only works with BLOCK1
These two code blocks enable the spell checking for the english/spanish languages at the same time. More languages can be added to the checking system expanding the "en_US,es_ES" strings with the appropriate dictionary names. I used that ones located in the Share/Hunspell directory. There is no keybinding to change between languages and no per file dictionary assignation at the beginning of files, like this:
# -\*- ispell-dictionary: "castellano8" -\*-.
A context menu is displayed when clicking the middle mouse button over the misspelled word, an option is the Save Word entry. These words will be saved using the variable ispell-personal-dictionary in the new file called .hunspell_personal, located on the usual path.
The inclusion of the two code blocks gave the expected results. Just including the second block of code threw the error 'wrong-type-argument stringp nil'.

Color tags based on regex emacs org-mode

I'm using org-mode and I want all my tags beginning with # to be colored in blue.
Is it possible and how to do it ?
Best regards
The following answer uses the built-in mechanisms of org-mode. The variable org-tag-faces accepts a regexp for the tag, which is the car of the cons cell. The function org-set-tag-faces sets a global variable org-tags-special-faces-re, which combines the tags of the aforementioned cons cell(s). The global variable org-tags-special-faces-re is used by org-font-lock-add-tag-faces to re-search-forward through the org-mode buffer -- locating the matching tags and applying the appropriate face based on the function org-get-tag-face. The original version of the function org-get-tag-face looked for an exact match of the tag found (i.e., the key argument to the function assoc). The revised version of org-get-tag-face adds an additional key search for #.* and returns the proper face if the key is found -- this is necessary because the tag itself will usually look something like #home or #office, whereas our context regexp is #.*.
(require 'org)
(add-to-list 'org-tag-faces '("#.*" . (:foreground "cyan")))
;; Reset the global variable to nil, just in case org-mode has already beeen used.
(when org-tags-special-faces-re
(setq org-tags-special-faces-re nil))
(defun org-get-tag-face (kwd)
"Get the right face for a TODO keyword KWD.
If KWD is a number, get the corresponding match group."
(if (numberp kwd) (setq kwd (match-string kwd)))
(let ((special-tag-face (or (cdr (assoc kwd org-tag-faces))
(and (string-match "^#.*" kwd)
(cdr (assoc "#.*" org-tag-faces))))))
(or (org-face-from-face-or-color 'tag 'org-tag special-tag-face)
'org-tag)))
You can use font-lock-add-keywords, for example, evaluating the following org source block should color the '#' tag blue.
#+TITLE: Tag face
#+BEGIN_SRC emacs-lisp
(defface org-tag-face
'((nil :foreground "blue" :background "#f7f7f7"))
"org tag face")
(font-lock-add-keywords
'org-mode
'((":\\(#[^\:]+\\):" (1 'org-tag-face))))
#+END_SRC
* test :#tst:
* test2 :tst:
After evaluating, revert the buffer or call font-lock-flush and font-lock-ensure to update font-locking.

My Emacs mode does not highlight keywords

I am trying to write an Emacs major mode but it is not working; specifically, my keywords are not being displayed in keyword font face. I have tried to follow the tutorials but I must be doing something wrong. I know a little Lisp but I do not know Emacs scripting.
My Emacs mode script:
;; emacs mode for OldRope
;; does no work for some reason
(setq oldrope-directive-keywords-regexp (regexp-opt '("page" "link" "goto" "act" "end" "div" "span" "include")))
(defvar oldrope-font-lock-defaults '((
(oldrope-directive-keywords-regexp . font-lock-keyword-face))))
(define-derived-mode oldrope-mode fundamental-mode
"oldrope mode"
"Major mode for editing OldRope games"
(setq comment-start "/*")
(setq comment-end "*/")
(setq font-lock-defaults oldrope-font-lock-defaults))
(provide 'oldrope-mode)
Test file:
$[page start]$ Hello $[link]$ Click me $[act]$ That is right. $[end]$
(For context, this is part of https://github.com/martinellison/oldrope but that is not really relevant to the question).
You need this - the rest is OK:
(defvar oldrope-font-lock-defaults
`(((,oldrope-directive-keywords-regexp . font-lock-keyword-face))))
By simply quoting the list you were not evaluating oldrope-directive-keywords-regexp - your quoted list just had that symbol as its car.
Using either backquote (`) plus comma (,) or (list (list (cons oldrope-directive-keywords-regexp 'font-lock-keyword-face))) you evaluate that variable and use its value in the resulting list.

Reuse *compilation* window in another frame

How is it possible to enforce display-buffer-reuse-frames-like behavior for certain frames with display-buffer-alist?
I have tried doing
(setq display-buffer-alist
'(("\\*compilation\\*" .
(display-buffer-reuse-window '((inhibit-same-window . t))))
))
, but to no avail. The documentation is long and cryptic even by Emacs standards, and has no examples.
This is not the same as question 3311577 because (setq-default display-buffer-reuse-frames t) is deprecated.
It sounds like you want to be using the reusable-frames entry in your ALIST argument to display-buffer-reuse-window, rather than inhabit-same-window? (or perhaps you wanted both?)
You also want to be using add-to-list rather than clobbering the entire list with setq.
Edit: My original answer messed up the list structure, as I was using the dotted-pair notation from the documentation, but had omitted one of the dots!
So the correct value is:
(add-to-list
'display-buffer-alist
'("\\*compilation\\*" . (display-buffer-reuse-window
. ((reusable-frames . t)))))
or equivalently:
(add-to-list
'display-buffer-alist
'("\\*compilation\\*" display-buffer-reuse-window
(reusable-frames . t)))
I also notice that there's a good customize interface for configuring this.

Fontifying variable references within string literals in Emacs font-lock-mode

When I type the following code in Emacs ruby-mode, the "#{foo}" is fontified in a different color than the enclosing string. How do I do this in my own Emacs mode? I tried to decipher the ruby-mode source code but couldn't understand it in a reasonable amount of time.
"a #{foo} a"
Finally figured it out. The answer is that the "override" parameter in a fontification rule should be set to t, which means that the given face will override the string face. See the documentation for the variable "font-lock-keywords" for details. Here's an example:
(define-derived-mode temp-mode fundamental-mode "Temp"
"Temporary major mode."
(set (make-local-variable 'font-lock-defaults)
'((temp-mode-font-lock-keywords) nil nil nil nil)))
(defconst temp-mode-font-lock-keywords
(list (list "$[A-Za-z0-9]+" 0 font-lock-variable-name-face t)))
Search for where ruby-mode.el sets font-lock-syntactic-keywords:
(setq ruby-font-lock-syntactic-keywords
'(
;; #{ }, #$hoge, ##foo are not comments
("\\(#\\)[{$#]" 1 (1 . nil))
Here's some documentation on the similar font-lock-keywords variable, which is what you should use to accomplish the same type of fontification.