Emacs Lisp: How to Write Your Own Comment Command from Scratch

By Xah Lee. Date: . Last updated: .

This page shows you how to write a command to insert/delete comment syntax chars of a programing language.

First, you should know about emacs's builtin comment package newcomment.el. See: Emacs Lisp: How to Write Comment Command in Major Mode.

Problem

You want to write a emacs command to comment or uncomment code for your own language. You want to write it from scratch. (maybe because you don't like the newcomment.el behavior, or, your language's comment syntax is different from popular languages supported by emacs syntax table.)

Solution

The following code handles C++-style comment // …. The code can be easily modified to handle any comment syntax that starts with a comment char and ends in a newline. (for example, Python's # ….)

It has 3 user-level functions:

“my-comment-dwim” is the general command. If there are no text selection, then it will comment or uncomment the current line, depending on whether the current line is a comment (If the comment start in the middle of the line, the line is not considered a comment). If there is a text selection, then it will comment or uncomment the whole region. Which action it does depends on whether the first line in selection is a comment line.

(defun my-comment-dwim ()
  "Comment or uncomment the current line or text selection."
  (interactive)

  ;; If there's no text selection, comment or uncomment the line
  ;; depending whether the WHOLE line is a comment. If there is a text
  ;; selection, using the first line to determine whether to
  ;; comment/uncomment.
  (let (p1 p2)
    (if (use-region-p)
        (save-excursion
          (setq p1 (region-beginning) p2 (region-end))
          (goto-char p1)
          (if (wholeLineIsCmt-p)
              (my-uncomment-region p1 p2)
            (my-comment-region p1 p2)
            ))
      (progn
        (if (wholeLineIsCmt-p)
            (my-uncomment-current-line)
          (my-comment-current-line)
          )) )))

(defun wholeLineIsCmt-p ()
  (save-excursion
    (beginning-of-line 1)
    (looking-at "[ \t]*//")
    ))

(defun my-comment-current-line ()
  (interactive)
  (beginning-of-line 1)
  (insert "//")
  )

(defun my-uncomment-current-line ()
  "Remove “//” (if any) in the beginning of current line."
  (interactive)
  (when (wholeLineIsCmt-p)
    (beginning-of-line 1)
    (search-forward "//")
    (delete-backward-char 2)
    ))

(defun my-comment-region (p1 p2)
  "Add “//” to the beginning of each line of selected text."
  (interactive "r")
  (let ((deactivate-mark nil))
    (save-excursion
      (goto-char p2)
      (while (>= (point) p1)
        (my-comment-current-line)
        (previous-line)
        ))))

(defun my-uncomment-region (p1 p2)
  "Remove “//” (if any) in the beginning of each line of selected text."
  (interactive "r")
  (let ((deactivate-mark nil))
    (save-excursion
      (goto-char p2)
      (while (>= (point) p1)
        (my-uncomment-current-line)
        (previous-line) )) ))

Writing Major Mode Topics

  1. How to Write a Emacs Major Mode for Syntax Coloring
  2. Emacs Lisp: html6-mode
  3. Emacs Lisp: Font Lock Mode Basics
  4. Emacs Lisp: How to Define Face
  5. Emacs Lisp: How to Color Comment in Major Mode
  6. Emacs Lisp: How to Write Comment Command in Major Mode
  7. Emacs Lisp: How to Write Your Own Comment Command from Scratch
  8. Emacs Lisp: How to Write Keyword Completion Command
  9. Emacs Lisp: How to Create Keymap for Major Mode
  10. Emacs Lisp: Create Abbrev and Templates for Major Mode
  11. Emacs Lisp: Text Properties
  12. Emacs Lisp: Overlay Highlighting
  13. Emacs: Lookup Google, Dictionary, Documentation

  1. Emacs Lisp: How to Name Your Major Mode
  2. Emacs Lisp: What's “feature”?
  3. Emacs Lisp: require, load, load-file, autoload, feature, Explained

Syntax Table

  1. Emacs Lisp: Syntax Table Tutorial
  2. Emacs Lisp: How to Find Syntax of a Character?
  3. Emacs Lisp: How to Modify Syntax Table Temporarily
  4. Emacs Lisp: How to Determine If Cursor is Inside String or Comment
  5. Emacs Lisp: Find Matching Bracket Character
Like it? Buy Xah Emacs Tutorial. Thanks.