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.
Related
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.
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.
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.
I'm using EmacsForMacOsX, v23.3.1, and I wonder how I can change the color for floating point values celsiusFloat = (5.0/9.0); to be a different color than those I get from my current color-theme-billw theme for integers age = 23;.
I doubt that StackOverflow colours them differently.
EDIT:
My initial approach to add a regex for the floating point d*\.d* in cc-mode.el was apparently not the way Emacs work with syntax highlighting (also known as font locking) - further research has led me to the following website: http://www.gnu.org/software/emacs/elisp/html_node/Customizing-Keywords.html
Edit 2:
I seem to have found my answer at http://www.emacswiki.org/emacs/AddKeywords and http://www.gnu.org/software/emacs/manual/html_node/emacs/Font-Lock.html#Font-Lock
(add-hook 'c-mode-hook
(lambda ()
(font-lock-add-keywords nil
'(("[0-9]+\\.[0-9]+" 1 font-lock-warning-face t)))))
I found a solution at: http://hbfs.wordpress.com/2010/03/02/adding-keywords-in-emacs/
First:
(make-face 'font-lock-special-macro-face) ;; Create a new face
(set-face-foreground 'font-lock-special-macro-face "pink") ;; Set the colour
Then we proceed to add regular expressions to the list of keywords and associate each regexp with a face:
(defun add-custom-keyw()
"adds a few special keywords for c and c++ modes"
;
(font-lock-add-keywords nil
'(
("[0-9]+\\.[0-9]+" . 'font-lock-special-macro-face )
; more of those would go here
)
)
)
Last we hook it to our mode:
(add-hook 'c-mode-hook 'add-custom-keyw)
I have tried to search Google and look in the manual, but still cannot find how to get major mode of a buffer object. Can you help me with an example or a reference. Thanks
only solution I could find was to query major-mode after changing the buffer and then changing back to original buffer. Is there a better way to do it?
Is there a problem with that?
(defun buffer-mode (buffer-or-string)
"Returns the major mode associated with a buffer."
(with-current-buffer buffer-or-string
major-mode))
with-current-buffer will restore your buffer when it returns.
For current buffer:
(message "%s" major-mode)
A simple way to do this is to use the buffer-local-value function since major-mode is a buffer-local variable:
(buffer-local-value 'major-mode (get-buffer "*scratch*"))
Just extending from previous answers - call with no arguments to get the current buffer's mode:
(defun buffer-mode (&optional buffer-or-name)
"Returns the major mode associated with a buffer.
If buffer-or-name is nil return current buffer's mode."
(buffer-local-value 'major-mode
(if buffer-or-name (get-buffer buffer-or-name) (current-buffer))))
E.g. in *scratch* buffer:
(buffer-mode) => 'lisp-interaction-mode
(buffer-mode "tasks.org") => 'org-mode
Well, describe-mode takes an optional buffer argument, but that displays the help... and I'm not exactly sure what it returns...
But that's the best I could find in a brief search... sorry...
Simply evaluate this:
(print major-mode)
Another way, apart from directly readind the major-mode variable would be by directly readind the mode-name variable.