Reputation: 1761
When I type M-;
, this invokes comment-dwim
which, on a line containing text and with no active region, I believe ultimately invokes comment-indent
to add an in-line or end-of-line comment.
In this custom major-mode, comment-start
is set to "# "
(and comment-style
is 'plain
) but this should only apply at the very start of a line. How do I get an in-line comment to start with ";; "
?
Example of current behaviour:
# Whole line comment
SOME CODE HERE # in-line comment
Example of required behaviour:
# Whole line comment
SOME CODE HERE ;; in-line comment
Additionally, comment-region
works perfectly when region starts at the beginning of a line and comment-start
is always left-aligned for this. However, halfway through a line, it will begin the comment with comment-start
(#
).
Upvotes: 0
Views: 589
Reputation: 1761
I've managed to write a solution to this:
I noted that comment-indent-function
is a variable which holds (from emacs describe-variable
):
Function to compute desired indentation for a comment. This function is called with no args with point at the beginning of the comment's starting delimiter and should return either the desired column indentation or nil. If nil is returned, indentation is delegated to `indent-according-to-mode'.
This allows creation of a custom function which can replace comment-start
and return nil
to allow default indentation, noting that when this function is called, point
will be "at the beginning of the comment's starting delimiter" (i.e. at the beginning of comment-start
). The following is now included in my custom major mode comment-indent
(through comment-dwim
) now behaves as required:
;;
(defun my-major-mode ()
(interactive)
(kill-all-local-variables)
...
(make-local-variable 'comment-start)
(make-local-variable 'comment-indent-function)
(make-local-variable 'comment-indent-start)
...
(setq major-mode 'my-major-mode
...
comment-start "# "
comment-indent-function 'my-comment-indent
comment-indent-start ";; "
)
...
)
(defun my-comment-indent ()
"Replace indented '#' with ';;'"
(interactive)
(if (not (looking-back ".\\{1\\}")) ;; if comment is left aligned
0 ;; leave it left aligned (return 0)
(progn ;; else: don't return until we're ready
(looking-at comment-start) ;; find "#"
(replace-match comment-indent-start)) ;; replace with ";;"
nil))) ;; return `nil' for default indentation
Upvotes: 0
Reputation: 87269
You may need to make custom syntax table as described at Emacs Wiki and ErgoEmacs:
For example, for my cql-mode I use following to distinguish between /* .. */
for block comments, and --
or //
for single-line/end-of line comments.
(defvar cql-mode-syntax-table
(let ((st (make-syntax-table)))
(modify-syntax-entry ?/ ". 124b" st)
(modify-syntax-entry ?* ". 23" st)
;; double-dash starts comments
(modify-syntax-entry ?- ". 12b" st)
;; newline and formfeed end comments
(modify-syntax-entry ?\n "> b" st)
(modify-syntax-entry ?\f "> b" st)
st)
"Syntax table for CQL mode")
and in declaration of derived mode I specify:
(set-syntax-table cql-mode-syntax-table)
And meaning is described in documentation for function modify-syntax-entry
: for /
- 1
means that character can start comment, 2
means that it could be also 2nd character in sequence, 4
- that it finishes comment, b
is that it could be comment type b
. for *
it says that it could be second or second to last character of comment type a
(default type).
Similarly, for -
it declares that it could be first & second characters in comment type b
.
In your case it could look following way (not tested):
(defvar some-mode-syntax-table
(let ((st (make-syntax-table)))
(modify-syntax-entry ?# ". 1b" st)
;; double-; starts comments
(modify-syntax-entry ?; ". 12b" st)
;; newline and formfeed end comments
(modify-syntax-entry ?\n "> b" st)
(modify-syntax-entry ?\f "> b" st)
st)
"Syntax table for some mode")
Upvotes: 1