diff --git a/emacs b/emacs index e849a2b..575b6c5 100644 --- a/emacs +++ b/emacs @@ -203,12 +203,71 @@ ;; javascript ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; js-mode (espresso) +;; Espresso mode has sane indenting so we use that. +(setq js-indent-level 4) + +;; Customize JS2 +(setq js2-basic-offset 4) +(setq js2-cleanup-whitespace t) + (autoload 'js2-mode "js2-mode" nil t) (add-to-list 'auto-mode-alist '("\\.js$" . js2-mode)) (add-to-list 'auto-mode-alist '("Jakefile$" . js2-mode)) -(add-hook 'js2-mode-hook '(lambda () - (local-set-key "\C-m" 'newline) - (setq indent-tabs-mode nil))) + + +;; Custom indentation function since JS2 indenting is terrible. +;; Uses js-mode's (espresso-mode) indentation semantics. +;; +;; Based on: http://mihai.bazon.net/projects/editing-javascript-with-emacs-js2-mode +;; (Thanks!) +(defun my-js2-indent-function () + (interactive) + (save-restriction + (widen) + (let* ((inhibit-point-motion-hooks t) + (parse-status (save-excursion (syntax-ppss (point-at-bol)))) + (offset (- (current-column) (current-indentation))) + (indentation (js--proper-indentation parse-status)) + node) + + (save-excursion + + ;; I like to indent case and labels to half of the tab width + (back-to-indentation) + (if (looking-at "case\\s-") + (setq indentation (+ indentation (/ js-indent-level 2)))) + + ;; consecutive declarations in a var statement are nice if + ;; properly aligned, i.e: + ;; + ;; var foo = "bar", + ;; bar = "foo"; + (setq node (js2-node-at-point)) + (when (and node + (= js2-NAME (js2-node-type node)) + (= js2-VAR (js2-node-type (js2-node-parent node)))) + (setq indentation (+ 4 indentation)))) + + (indent-line-to indentation) + (when (> offset 0) (forward-char offset))))) + +(defun my-js2-mode-hook () + (if (not (boundp 'js--proper-indentation)) + (progn (js-mode) + (remove-hook 'js2-mode-hook 'my-js2-mode-hook) + (js2-mode) + (add-hook 'js2-mode-hook 'my-js2-mode-hook))) + (set (make-local-variable 'indent-line-function) 'my-js2-indent-function) + (define-key js2-mode-map [(return)] 'newline-and-indent) + (define-key js2-mode-map [(backspace)] 'c-electric-backspace) + (define-key js2-mode-map [(control d)] 'c-electric-delete-forward) + (local-set-key "\C-m" 'newline) + (setq indent-tabs-mode nil) + (message "JS2 mode hook ran.")) + +;; Add the hook so this is all loaded when JS2-mode is loaded +(add-hook 'js2-mode-hook 'my-js2-mode-hook) (autoload #'espresso-mode "espresso" "Start espresso-mode" t) ;;(add-to-list 'auto-mode-alist '("\\.js$" . espresso-mode))