javascriptemacsjs2-mode

Emacs: is it possible to automatically insert semicolons in js2-mode?


I'm using this superb js2-mode fork, along with autopairs to make Javascript editing awesome in Emacs. However it occurs to me that since js2-mode is a full parser, it should be possible to automatically insert semi-colons whenever I'm in a function calling context.

I thought I'd ask if anyone's looked into this before I dig too much deeper.


Solution

  • Here is my code that solves this:

    le-js2-mode-setup-partial.el
    (defvar js2-semicolon-contexts (list js2-NAME js2-LP js2-SCRIPT js2-CALL js2-BLOCK))
    (defun autopair-js2-maybe-insert-semi-colon (action pair pos-before)
      "handler for automatically inserting semi-colon at the end of function call.
    "
      ;; (message "node before is %s" (js2-node-type (js2-node-at-point (- (point) 1))))
      ;; (message "action is %s" action)
      ;; (message "pair is %c" pair)
      ;; (message "context is %s" (buffer-substring-no-properties (point-at-bol) (point-at-eol)))
      ;; (message "point is %s" (point))
      (cond ((and (eq action 'opening)
                  (eq pair ?\))
                 (save-excursion
                   (goto-char pos-before)
                   (skip-chars-backward " \t")
                   ;; (message "node is %s." (js2-node-type (js2-node-at-point (point))))
                   (memq (js2-node-type (js2-node-at-point (point))) js2-semicolon-contexts)
                   ))
             (save-excursion
               (let ((forward-sexp-function nil))
                 (goto-char pos-before)
                 (forward-sexp))
               (if (looking-at-p "[^[:graph:]]*$")
                 (insert ";"))))))
    
    ;;;###autoload
    (defun le::js2-mode-setup ()
      (setq autopair-handle-action-fns
            (list #'autopair-default-handle-action
                  #'autopair-js2-maybe-insert-semi-colon))
      (rebox-mode 1)
      (le::prog-modes-setup))
    ;;;###autoload(add-hook 'js2-mode-hook 'le::js2-mode-setup)
    

    You can also get this code from this GitHub Gist.