Emacs: Adding custom code block delimiter? - emacs

I using emacs to write some ejs files. I have set
(show-paren-mode t)
in my .emacs for highlighting parentheses. The ejs code looks like:
<ul>
<% for(var i=0; i<supplies.length; i++) {%>
<li><%= supplies[i] %></li>
<% } %>
</ul>
It seems that this mode doesn't work fine when editing ejs using html-mode. For example, a left '<' in '<%' matches the '}' on the right instead of matching a '%>'.
So my question is can I add '<%' as a code block delimiter to make show-paren-mode work fine in ejs files?
Any help is appreciated.

Have you really fully thought out how this this bracket highlighting might work?
You have have a naked starting delimiter "{" starting delimiter in between
"<%" and "%>".
This is equivalent to:
( { )
Does show-paren-mode highlight such code properly?
Editing mixed major-mode files (JS in HTMl), (Ruby in HTML), is hard in Emacs.
You can use this snippet to remove "<" and ">" as matching delimiters, which
alleviates your problem a little.
(eval-after-load "sgml-mode" '(progn
(modify-syntax-entry ?< "'" sgml-mode-syntax-table)
(modify-syntax-entry ?> "'" sgml-mode-syntax-table)))
But you need a multi-major-mode library to really get it to work, but I doubt
anyone's put in the work to make "EJS" work.

Related

How to add a comment style to an emacs mode

I am looking to add an additional single line style of comments !* to the Fortran mode on emacs, I'd add this to my init.el file.
From what I can see this should be doable using the modify-syntax-entry command, but I am struggling to succeed and there doesn't seem to be a fortran-mode-syntax-table so I can't see how I'd hook it to the mode.
My current effort (which causes an error).
(modify-syntax-entry ?\!\* "< \n")
(modify-syntax-entry ?\n "< \!\*")
The error reads An error occurred while loading 'init.el':
Invalid read syntax: ?
I finally figured out how to do this, and it's worth mentioning that with a normal Fortran setup ! causes comments, but not in mine.
So what I add to my init.el is
(add-hook 'fortran-mode-hook
(lambda ()
(modify-syntax-entry ?\! ". 1")
(modify-syntax-entry ?\* ". 2")
(modify-syntax-entry ?\n ">") ))
The first two modify-syntax-entry use the numeric syntax flags for a two character comment start sequence !* and > is the syntax class for comment ended, for which I have used \n to end the comment with a newline.
See https://www.gnu.org/software/emacs/manual/html_node/elisp/Syntax-Flags.html and https://www.gnu.org/software/emacs/manual/html_node/elisp/Syntax-Class-Table.html#Syntax-Class-Table for more details

Avoid font-locking interfering inside of comments

In my font-lock-defaults I have:
("\\(^\\| \\|\t\\)\\(![^\n]+\\)\n" 2 'factor-font-lock-comment)
The comment character is ! and this makes it so comments get the right face. This works mostly, except when there is a competing font-locked entity inside the comment, like a string (delimited by double quotes):
! this line is font-locked fine
! this one is "not" because "strings"
How do you get font-lock to understand that the comment is already font-locked fine and it doesn't need to try to font-lock any strings inside of it? The obvious way is to add ! to the comment starter class in the syntax table:
(modify-syntax-entry ?! "< 2b" table)
This solution is not possible because function names and other symbols containing ! are legal such as map! filter! and foo!bar. And adding ! would cause code containing such names to be highlighted incorrectly.
Generally, it's a bad idea to highlight comments using a font-lock keyword. It's better to use the syntactic phase for this.
Even though the syntax table isn't powerful enough to describe the syntax of your language, it's still possible to highlight comments using in the syntactic font-lock phase. The solution is to provide a custom function to assign syntactic properties to the ! characters that should start a comment. This is done using the variable syntax-propertize-function.
See the elisp manual for details. Also, this tutorial covers this in great detail.
Update: The following is a simple example that define ! to be comment start character, but not within identifiers. A real world example might need a more refined way to check if something is an identifier.
(defun exmark-syntax-propertize (start end)
(funcall (syntax-propertize-rules
("[[:alnum:]_]\\(!\\)"
(1 "_")))
start
end))
(defvar exmark-mode-syntax-table
(let ((table (make-syntax-table)))
(modify-syntax-entry ?\n "> " table)
(modify-syntax-entry ?! "< " table)
table))
(define-derived-mode exmark-mode prog-mode "!-Mark"
"Major mode for !-mark."
(set (make-local-variable 'syntax-propertize-function)
'exmark-syntax-propertize))

Emacs web-mode tabs not working

I am using emacs web-mode to edit my php files and have noticed that the tab key doesn't work the way I expect it to in a couple of different situations. For example if I have a string that spans multiple lines like this...
<?php
return "
<nav>
<a href='index.php?page=skills'>My skills and background</a>
<a href='index.php?page=projects'>Some projects</a>
</nav>
";
?>
and I go to the beginning of the lines with anchor tags and press tab nothing happens. I have to use the space bar to indent the lines the way I want.
The other situation is occurs inside of a php block for example
<?php
error_reporting( E_ALL );
ini_set( "display_errors", 1);
$pageData = new stdClass();
$pageData->title = "Jordan: Portfolio site";
$pageData->content = include_once "views/navigation.php";
$navigationIsClicked = isset($_GET['page']);
if($navigationIsClicked) {
$fileToLoad = $_GET['page'];
$pageData->content .= "<p>Will soon load $fileToLoad.php</p>";
}
$page = include_once "templates/page.php";
echo $page;
?>
if I go to one of the variable assignment lines and push tab nothing happens, again spaces work fine, then inside the if block only 1 tab is allowed. Is there any way to change how this mode uses tabs in my .emacs file. I currently have this in my .emacs
(defun my-setup-php ()
;; enable web mode
(web-mode)
;; make these variables local
(make-local-variable 'web-mode-code-indent-offset)
(make-local-variable 'web-mode-markup-indent-offset)
(make-local-variable 'web-mode-css-indent-offset)
;; set indentation, can set different indentation level for different code type
(setq web-mode-code-indent-offset 4)
(setq web-mode-css-indent-offset 2)
(setq web-mode-markup-indent-offset 2))
(add-to-list 'auto-mode-alist '("\\.php$" . my-setup-php))
As it turns out my question is completely unrelated to web-mode. The function that emacs binds to the tab key by default is called indent-for-tab-command the function I was looking for is called tab-to-tab-stop which by default is bound to M - i. This website has a very detailed explanation of how the tab key works in emacs and how to customize it.
You should try (setq-default indent-tabs-mode t)

Make Emacs prettify-symbols-mode work on non-whitespace separated words.

The new prettify-symbols-mode in Emacs works beautifully for translating:
lambda something -> λ something
I'd also like to make:
lambda.something -> λsomething
Sadly, prettify-symbols-mode only recognizes spaces as word/symbol separators by default.
Any ideas on how to use '.' as a token separator?
The code that does the actual substitution is prettify-symbols--compose-symbol in prog-mode.el. It excludes matches if the character before or after the word has the character type word or symbol. In many mode, for example emacs-lisp-mode the . character has symbol type.
You could either change the syntax code for . in the major mode, you could tell font-lock to use a different character code when highlighting (see the variable font-lock-defaults for details), or you could do ju-jutsu on the prettify-symbols--compose-symbol mode like modifying it using defadvice or simply replace it with your own.
Thanks to Lindydancer, I ended up doing this:
(add-hook 'python-mode-hook
(lambda ()
(push '("self" . ?◎) prettify-symbols-alist)
(modify-syntax-entry ?. ".")))
which results in a reasonable compromise output of:
◎.method

Single and multiline comments in emacs mode using syntax table

I am trying to create an emacs syntax highlighting for a language in which the comments are written as
; A single line comment
;; This comment has
multipline lines ;;
To do this I need to modify the entries in the syntax table. I have found that the following works perfectly for comments on multiple lines:
(modify-syntax-entry ?\; ". 1234" sbgl-mode-syntax-table)
And the following works perfectly for single line comments:
(modify-syntax-entry ?\; "< b" sbgl-mode-syntax-table)
(modify-syntax-entry ?\n "> b" sbgl-mode-syntax-table)
Does anybody know of a way to combine these?
If you can survive adding a space after each semicolon starting a single-line comment, you can treat it as an second character for one of the comment-start sequences and then here's a snippet that works for me:
(define-derived-mode sbgl-mode prog-mode "sbgl"
(set (make-local-variable 'font-lock-defaults)
'(nil ;; keywords
nil ;; keywords-only
nil ;; case-fold
((?\; . ". 1234b")
(?\n . ">")
(?\ . "- 2")))))
If not, then you always have an option to do the syntactic analysis prior to fontification via syntax-propertize-function variable (or font-lock-syntactic-keywords variable for pre-Emacs24).
You can try something like:
(modify-syntax-entry ?\; "< 1234b" sbgl-mode-syntax-table)
(modify-syntax-entry ?\n ">" sbgl-mode-syntax-table)