The special file format of my software uses angle brackets as a delimiter and #
/ #
as comment markers (note the whitespace after the first #
and before the last #
). I try to make a major mode to handle those files. I notice that the definition of the whitespace as a following character of the #
enters in conflict with the indentation and font lock. I used the same syntax of my comment syntax table than the C/C++ style with /*
and */
.
The MWE mode is
(defvar my-very-basic-mode-syntax-table nil
"Syntax table for `my-very-basic-mode'.")
;; My syntax table
(setq my-very-basic-mode-syntax-table
(let ((my-very-basic-table (make-syntax-table)))
; Delimiters
(modify-syntax-entry ?\{ "(}" my-very-basic-table)
(modify-syntax-entry ?\} "){" my-very-basic-table)
; Comments
(modify-syntax-entry ?# ". 14" my-very-basic-table)
;(modify-syntax-entry ? ". 23" my-very-basic-table) ; THE PROBLEM
my-very-basic-table))
;; My indentation function
(defvar my-very-basic-mode-indent-offset 2
"Indentation offset for `MY-VERY-BASIC-mode'.")
(defun my-very-basic-mode-indent-line ()
"Indent current line for `MY-VERY-BASIC-mode'."
(interactive)
(let ((indent-col 0))
(save-excursion
(beginning-of-line)
(condition-case nil
(while t
(backward-up-list 1)
(when (looking-at "[[{]")
(setq indent-col (+ indent-col my-very-basic-mode-indent-offset))))
(error nil)))
(save-excursion
(back-to-indentation)
(when (and (looking-at "[]}]") (>= indent-col my-very-basic-mode-indent-offset))
(setq indent-col (- indent-col my-very-basic-mode-indent-offset))))
(indent-line-to indent-col)))
;; = My basic font-lock
(setq my-very-basic-font-lock
(let* ((x-comments '("# " " #"))
(x-comments-regexp (regexp-opt x-comments 'words)))
`((,x-comments-regexp . 'font-lock-comment-face))))
;; My simple mode
(define-derived-mode my-very-basic-mode text-mode "my-very-basic-mode"
"Mode for editing some kind of config files."
(setq-local comment-start "# ")
(setq-local comment-end " #")
(make-local-variable 'my-very-basic-mode-indent-offset)
(set (make-local-variable 'indent-line-function) 'my-very-basic-mode-indent-line)
(set-syntax-table my-very-basic-mode-syntax-table)
(setq-local font-lock-defaults '((my-very-basic-font-lock))))
;; Myformat
(add-to-list 'auto-mode-alist '("\\.myformat\\'" . my-very-basic-mode))
;; = End of mode
(provide 'my-very-basic-mode)
;;; my-very-basic-mode.el ends here
When I comment this line (modify-syntax-entry ? ". 23" my-very-basic-table) ; THE PROBLEM
, I have a proper indentation but not the gray comment font (in file.myformat
) :
# a block # <- NOT GRAY
{
an internal block {
some text {
temperature 300
} <- GOOD INDENTATION
}
}
But if I uncomment the problematic line, it mixes with the indent calculation :
# a block # <- GRAY
{
an internal block {
some text {
temperature 300
} <- BAD INDENTATION
}
}
Indent function is not my own, but I cannot find the source any more, unfortunately. My knowledge of Elisp is not that strong, and I cannot figure out what is missing. Any clue how to mix the two? I tried escaping with ?\
but that did not change. Any clue on how to make everything work together?