emacs prettify-symbols replacing characters at same point - emacs

I am using prettify-symbols to switch between the following words and shortcuts. The problem is that when the replacement is more than a single character, all letters are being inserted at the same point.
For instance when little is replaced I get a single l, rather than ll.
(defvar cluster
'(
("all" . "l") ("as" . "as") ("can" . "k")
("do" . "do") ("for" . "f") ("in" . "n")
("is" . "s") ("it" . "t") ("know" . "no")
("like" . "lk") ("little" . "ll") ("more" . "mo")
("some" . "so") ("than" . "n") ("that" . "ta")
("there" . "tr") ("this" . "th") ("time" . "ti")
("to" . "to") ("we" . "w") ("well" . "l")
("will" . "l") ("work" . "wk") ("you" . "u"))
"List of replacements for specific words.")
(defun prettify-cluster ()
"Set keywords and corresponding glyph."
(setq-local prettify-symbols-alist cluster))

The doc string of variable prettify-symbols-alist tells you that each alist entry is (SYMBOL . CHARACTER), where SYMBOL is a string.
In your alist, you have instead (STRING . STRING) entries.
prettify-symbols-alist is a variable defined in prog-mode.el.
Its value is nil
Automatically becomes buffer-local when set.
Documentation:
Alist of symbol prettifications.
Each element looks like (SYMBOL . CHARACTER), where the symbol
matching SYMBOL (a string, not a regexp) will be shown as
CHARACTER instead.
CHARACTER can be a character, or it can be a list or vector, in
which case it will be used to compose the new symbol as per the
third argument of compose-region.
Furthermore, if you use a list or vector of chars for CHARACTER then those chars are composed.
I think that what you want is maybe something like abbrev-mode?

Related

emacs automatically highlight *E *F etc and highlight to EOL

I am trying to build my major mode for syntax highlighting log files from a certain tool flow.
and I've been using this excellent guide to get started
http://ergoemacs.org/emacs/elisp_syntax_coloring.html
but I would like to highlight "*W", "*E" and "*F"
but I cannot get that to work
here are my font-lock keywords
(setq mylog-font-lock-keywords
(let* (
;; define several category of keywords
(x-warnings '("UVM_ERROR" "UVM_FATAL" "^.*E" "F"))
(x-keywords '("UVM_INFO" "NOTE" "Note"))
(x-types '("UVM_WARNING" "*W," "xmsim"))
(x-constants '("ACTIVE" "AGENT" "ALL_SIDES" "ATTACH_BACK"))
(x-events '("at_rot_target" "at_target" "attach"))
(x-functions '("llAbs" "llAcos" "llAddToLandBanList" "llAddToLandPassList"))
;; generate regex string for each category of keywords
(x-keywords-regexp (regexp-opt x-keywords 'words))
(x-types-regexp (regexp-opt x-types 'words))
(x-constants-regexp (regexp-opt x-constants 'words))
(x-events-regexp (regexp-opt x-events 'words))
(x-functions-regexp (regexp-opt x-functions 'words))
(x-warnings-regexp (regexp-opt x-warnings 'words))
)
`(
(,x-types-regexp . font-lock-type-face)
(,x-constants-regexp . font-lock-constant-face)
(,x-events-regexp . font-lock-builtin-face)
(,x-functions-regexp . font-lock-function-name-face)
(,x-keywords-regexp . font-lock-keyword-face)
(,x-warnings-regexp . font-lock-warning-face)
;; note: order above matters, because once colored, that part won't change.
;; in general, put longer words first
)))
;;;###autoload
(define-derived-mode mylog-mode verilog-mode "log mode"
"Major mode for editing LOG FILES…"
;; code for syntax highlighting
(setq font-lock-defaults '((mylog-font-lock-keywords))))
(set-face-foreground 'font-lock-type-face "yellow")
;; add the mode to the `features' list
(provide 'mylog-mode)
as you can see I've tried a few things with out success.. any other words are highlighted correctly?
as a final touch I would like to for all occurenses of WARNING or ERROR I would like to highlight the entire line until EOL.
I have found some examples but none that show how to highlight until EOL in a major mode lisp file
This is an example (taken from my init.el). Hope it help.
(font-lock-add-keywords nil
'( ; high-light full line ending with "E" or "FATAL"
("^.*\\(E\\|FATAL\\)$" . 'font-lock-function-name-face)
; high-light full line beginning with '*E' '*F' '*W'
("^\\*[EFW]\\b.*$" . 'font-lock-comment-face)
; high-light only ending part of the lines which contain "F"
("\\b\\w*F$" . 'font-lock-function-name-face)
; high-light from "UVM" to end of line
("\\bUVM.*$" . 'font-lock-function-name-face)
; high-light only words that end with "G"
("\\b\\w*G\\b" . 'font-lock-function-name-face)
; bold things between 2 **, like **bold**
("\\*\\*.+?\\*\\*" . 'bold)))

Checking user input in Racket

I am getting an input from a user for a tex-field% in racket which would look something like this:
open button a = fwd; button b = xxx; button s = xxx; close
I have verified that it does contain open and close at beginning and end respectively. But now i need to store each of the substrings based on the semicolons to check them for semicolons at the end, among other things. For example, in the example above it should store 3 substrings in a vector/list (whichever is easier). It would be stored as:
button a = fwd;
button b = xxx;
button s = xxx;
;input is the name of the string the user enters
(define vec (apply vector (string-split input)))
(define vecaslist(vector->list vec))
(define removedopen (cdr vecaslist))
(define withoutopenandclose (reverse(cdr(reverse removedopen))))
(define stringwithoutopen (string-replace input "open " ""))
(define stringtoderivate (string-replace stringwithoutopen " close" ""))
(define tempvec (apply vector (string-split stringtoderivate ";" #:trim? #f #:repeat? #t)))
Attempted to split it by semicolons and place in a vector, but it removes the semicolons. When i do print the length of the vector it correctly shows 3 though, but i would like to keep the semicolons for now.
You can use string-split with a regular expression separator, as follows:
(string-split input #rx"(open | close)|(?<=;).")
which will output the list:
'("button a = fwd;" "button b = xxx;" "button s = xxx;")
To break down the regular expression:
(exp) matches any sub-expression "exp". Hence, (open ) matches the sub-expression "open " in input. Similarly with ( close), matching " close".
(?<=exp) does a positive look-behind, matching if "exp" matches preceding.
. matches anything, such as whitespace, characters etc.
| matches either the expression that comes before it, or after it, trying left first.

Trying to define comments for SPSS in syntax table

I'm trying to modify spss.el to provide accurate fontification for SPSS comments. Below is a summary of how SPSS's syntax highlights and treats comments:
* = an asterisk starts commment at beginning of line
\n\n = two new lines end comments
.\n = period + newline also ends comment
/* = slash and star starts comment, and is ended with a single new line
*/ ends a comment only if on the same line as a /*
So far my syntax table reads:
(let ((spss-mode-syntax-table (make-syntax-table)))
(modify-syntax-entry ?* "<" spss-mode-syntax-table)
(modify-syntax-entry ?. ". 3" spss-mode-syntax-table)
(modify-syntax-entry ?\n "- 34" spss-mode-syntax-table)
(modify-syntax-entry ?' "\"" spss-mode-syntax-table)
(modify-syntax-entry ?\\ "# " spss-mode-syntax-table)
spss-mode-syntax-table)
This for the most part works, except that the asterisk only functions as a commment delimiter when it's at the beginning of a line. Is there a way to denote that the asterisk is a comment delimiter only at the line start?
Thank you for reading!
For the /* ... */ part, you can use
(modify-syntax-entry ?/ ". 14" st)
(modify-syntax-entry ?* ". 23" st)
(modify-syntax-entry ?\n ">" st)
But for the * ... \n\n, you need a different comment style and since it reuses the same chars * and \n as the other comment style, you can't use simple syntax-table settings to explain it to Emacs. Instead, you'll need to use a syntax-propertize-function which will place a "< b" syntax on a * at beginning of line and a "> b" syntax on the \n of \n\n. E.g.
(set (make-local-variable 'syntax-propertize-function)
(syntax-propertize-rules
("^\\(\\*\\)" (1 "< b"))
("\n\\(\n\\)" (1 "> b"))
("\\(\\.\\)\n" (1 "> b"))))

How to use case and read-event with down-mouse-1

I have a function that uses (case (read-event) . . .) -- I have been unable to get down-mouse-1 to equal an integer for the duration of the function. The following is an example where down-mouse-1 yields a result of Try again instead of Hello world. All of the following examples work, except for down-mouse-1: ('f12 516); (?\s-k 517); ('f3 518); ('C-tab 519); ('C-M-s-right 520); (?m 522).
(let* (
(test (case (read-event)
('down-mouse-1 9999))))
(cond
((eq test 9999)
(message "Hello world."))
(t (message "Try again."))))
read-event never returns down-mouse-1. For a mouse click, the first event it will return will look like (down-mouse-1 ...). So you could do:
(pcase (read-event)
(`(down-mouse-1 . ,_) 9999))
Note that in my experience, 99% of the uses of read-event would be better rewritten some other way.
Not clear to me what you are trying to do. But you should not quote the keys in a case clause. E.g, use down-mouse-1, not 'down-mouse-1.

Jinja templates syntax hilighting

I'd like to adapt jinja.el to work with one-line comments using ##. But my knowlege of elisp is bad. Who can help me? What do I want: i'd like to hilite
## some text
## {% include "_template.html" %}
as a commented out strings. But it works not fully correct. 1st line of snippet looks like comment out while 2nd - not. Here is what i've got:
And here is a part of jinja.el taken from Jinja's git repo plus my regexp for ##:
(defconst jinja-font-lock-keywords
(list
; (cons (rx "{% comment %}" (submatch (0+ anything))
; "{% endcomment %}") (list 1 font-lock-comment-face))
'("{%-?\\|-?%}\\|{{\\|}}" . font-lock-preprocessor-face)
'("{# ?\\(.*?\\) ?#}" . (1 font-lock-comment-face))
'("## ?\\(.*\\)" . (1 font-lock-comment-face))
'("{#\\|#}" . font-lock-comment-delimiter-face)
'("##" . font-lock-comment-delimiter-face)
;; first word in a block is a command
OK. I found solution. Change
'("## ?\\(.*\\)" . (1 font-lock-comment-face))
to
'("## ?\\(.*\\)" . (1 font-lock-comment-face t))
ie setting 'override' parameter to true solves me question.