how to highlight elisp macro argument? - emacs

when I use "use-package" macro in emacs lisp, I found that the argument is highlighted.
but argument of my own macro is not highlighted by emacs.
How to write a macro with highlighted arguments?

use-package uses font-lock-add-keywords to mark the argument with font-lock-constant-face. Replacing "use-package" with "test_macro" in the the code would colorize your argument similarly
(defconst my-font-lock-keywords
'(("(\\(test_macro\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?"
(1 font-lock-keyword-face)
(2 font-lock-constant-face nil t))))
(font-lock-add-keywords 'emacs-lisp-mode my-font-lock-keywords)

Related

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.

Syntax read error: )

I'm trying to set up an emacs environment like this guy, but I keep getting this darn error:
Syntax read error: )
Here's what my init.el file looks like, it's not long, but I have NO idea what any of it means. I'm brand spankin new to lisp.
(add-to-list 'load-path' "~/.emacs.d/auto-complete-1.3.1")
;Load the default configuration
(require 'auto-complete-config')
;Make sure we can find the dictionaries
(add-to-list 'ac-dictionary-directories' "~/.emacs.d/auto-complete-1.3.1/dict")
;Use dictionaries by default
(setq-default ac-sources (add-to-list 'ac-sources' 'ac-source-dictionary'))
(global-auto-complete-mode t)
;Start auto completion after two characters of a word
(setq ac-auto-start 2)
; case sensitivity is important when finding matches
(setq ac-ignore-case nil)
(add-hook 'js-mode-hook'
(lambda ()
;;Scan the file for nested code blocks
(imenu-add-menubar-index)
;;Activate folding mode
(hs-minor-mode t))
You have unbalanced parentheses in the call to add-hook at the end.
Basically, add an extra ) to the two at the end.
If you type M-x show-paren-mode RET and then position the cursor after a closing parenthesis, it'll highlight the matching opening parenthesis (and vice-versa if you position the cursor on an opening paren).
You have extra quotes at the end of some symbols. In lisp, you quote an expression by putting a single quote (') immediately before it and nowhere else: 'correct, 'incorrect'. String literals are like many other languages, with double quotes both before and after: "a string literal".
Also, the missing paren as pointed out by phils.
In general, you can start emacs with --debug-init to make it do a backtrace on any errors in your init file. In this case it's not very useful because the code isn't even evaluated.

How to know when to use parenthesis

I am reading through An Introduction to Programming in Emacs Lisp, and I see the following:
This code works:
(message "The name of this buffer is: %s." (buffer-name))
while this one fails:
(message "The name of this buffer is: %s." buffer-name)
However, this code works:
(message "The value of fill-column is %d." fill-column)
while this one fails:
(message "The value of fill-column is %d." (fill-column))
My question is why? What is the difference between buffer-name and fill-column? How do I know when to use parentheses?
Simply put - buffer-name is a function (that returns a string) and fill-column is a variable (that evaluates to an integer).
Functions calls in all Lisp dialects should be surrounded by parentheses.
To see details about a function in Emacs press C-h f function-name RET.
To see details about a variable in Emacs press C-h v variable-name RET.

Emacs Auctex custom syntax highlight

I'd like to highlight a new command I created in LaTeX:
\newcommand{\conceito}[3]{
\subsection{#1} (Original: \textit{#2} #3).
}
I use this code in this way:
\conceito{Foo}{Bar}{Bla}
I followed the manual and put this code in my ~/.emacs, but it didn't work:
(add-hook 'LaTeX-mode-hook
(lambda ()
(font-lock-add-keywords nil
'((""\\<\\(\\conceito)\\>"" 1 font-lock-warning-face t)))))
What's wrong?
EDIT: Deokhwan Kim originally pointed out that your regexp contains two consecutive double quotes, and that the closing parenthesis ) needs to be escaped with double quotes as well:
(add-hook 'LaTeX-mode-hook
(lambda ()
(font-lock-add-keywords nil
'(("\\<\\(\\conceito\\)\\>" 1 font-lock-warning-face t)))))
In addition to the points pointed out by Deokhwan Kim, there are also the following two issues:
You need four backslashs instead of two in front of 'conceito': \\\\conceito
The backslash sequence \\< matches the empty string only at the beginning of a word, however, the backslash at the beginning of your new LaTeX command is not considered part of a word, so \\< will not match.
Try this instead:
(add-hook 'LaTeX-mode-hook
(lambda ()
(font-lock-add-keywords nil
'(("\\(\\\\conceito\\)\\>" 1 font-lock-warning-face t)))
EDIT: Another good observation that Deokhwan Kim made is that in this particular case, you don't really need the parenthesis at all, because you're attempting to match the whole expression anyway. So an alternative to the last line could be:
'(("\\\\conceito\\>" 0 font-lock-warning-face t)))))
The point about the parenthesis is correct, but you could actually extend your regexp to only match when an opening curly brace { follows the word "conceito". But since you don't really want to highlight that brace, using sub-groups defined by parentheses is the way to go:
(add-hook 'LaTeX-mode-hook
(lambda ()
(font-lock-add-keywords nil
'(("\\(\\\\conceito\\)\\s-*{" 1 font-lock-warning-face t)))
Note that since we're testing for a { that follows directly after "conceito" (unless there's whitespace in between), we don't need the test for \\> any more at all.
In general, try M-x re-builder to craft regular expression interactively: you can edit a new regexp in a small buffer and instantly see what is highlighted in the buffer from which you invoked the re-builder.
GNU AUCTeX has a built-in way of defining custom highlighting to user-defined macros. Have a look at the variable font-latex-user-keyword-classes and the AUCTeX documentation.
Here's a simple example (my configuration):
(setq font-latex-user-keyword-classes
'(("shadow-hidden" (("hide" "{")) shadow command)
("shadow-mycomment" (("mycomment" "{")) shadow command)
("shadow-comment" (("comment" "{")) shadow command)))
This will show the contents of \hide{}, \mycomment{}, and \comment{} macros in the dim shadow face.

How to replace a word instead of a string in emacs like this?

For example, I have the codes below:
(defun toggle-light ()
"Toggle setting tab widths between 4 and 8"
(setq a
(if (boundp 'a) a nil))
(interactive)
(if a
(progn
(load-theme 'solarized-dark t)
(setq a nil))
(progn
(load-theme 'solarized-light t)
(setq a t) )))
And now I want to refactor this blocks by replacing the variable name a with is-lighted, but without changing other character a in other words (for example, in interactive or tab).
Is there a built-in function in emacs that can finsih that job?
C-uM-% a RET is-lighted RET
The prefix argument ("delimited") to the standard query-replace functions wraps the pattern with word-boundary markers.
While phils's answer is correct and idiomatic, you should also learn about \b word boundary regular expression. Thus, equivalent regexp replace would be M-%\ba\b. See Backslash in Regular Expressions # Emacs Manual and Regular Expression # EmacsWiki.