Emacs Lisp: How to Write Comment/Uncomment Command in Major Mode

By Xah Lee. Date: . Last updated: .

This page shows you how to write a command to comment/uncomment a region of text in a major mode.

See also: Emacs Lisp: How to Color Comment in Major Mode.

There are 2 ways to write a command to comment/uncomment code:

This page will discuss using the newcomment.el package.

Writing a Comment Command Using newcomment.el


Emacs has a standard command to insert or delete comment, named comment-dwimAlt+;】.

When there is a text selection, comment-dwim will comment or uncomment the region in a smart way.

If there is no text selection, comment-dwim will insert a comment syntax at the end of line.

The comment-dwim is the standard command to comment/uncomment code. Your major mode should support it. When a user types the keyboard shortcut for comment-dwim while in your language mode, he should expect it to work for that language.

comment-region & uncomment-region

comment-regionuncomment-region are lower level commands that do the actual work.

comment-dwim simply determine whether to comment or uncomment, and on what region boundary, then call comment-region or uncomment-region.

Making comment-dwim Work for Your Major Mode

All you have to do, is to set 2 buffer-local variables.

For example, here's code for emacs lisp:

(setq-local comment-start "; ")
(setq-local comment-end "")

Here's another example.

In CSS, comment has this syntax:

/* css comment syntax */

Here's full code from emacs's bundled css-mode:

(define-derived-mode css-mode fundamental-mode "CSS"
  "Major mode to edit Cascading Style Sheets."
  (setq-local font-lock-defaults css-font-lock-defaults)
  (setq-local comment-start "/*")
  (setq-local comment-start-skip "/\\*+[ \t]*")
  (setq-local comment-end "*/")
  (setq-local comment-end-skip "[ \t]*\\*+/")
  (setq-local parse-sexp-ignore-comments t)
  (setq-local indent-line-function 'css-indent-line)
  (setq-local fill-paragraph-function 'css-fill-paragraph)
  (setq-local add-log-current-defun-function #'css-current-defun-name)
  (smie-setup css-smie-grammar #'css-smie-rules
              :forward-token #'css-smie--forward-token
              :backward-token #'css-smie--backward-token)
  (setq-local electric-indent-chars
              (append css-electric-keys electric-indent-chars)))

〔➤see Emacs Lisp: Regex Tutorial

Complex Comment Syntax

If your language's comment syntax is more complex, different from any of the form in C, Java, python, ruby, php, etc. You'll need to write your own comment/uncomment command.

See: Emacs Lisp: How to Write a Command for Comment Handling.

thanks to Daniel for correction.

Like it? Buy Xah Emacs Tutorial. Thanks.

or, buy something from my keyboard store.