dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

js-mode-expansions.el (6159B)


      1 ;;; js-mode-expansions.el --- JS-specific expansions for expand-region
      2 
      3 ;; Copyright (C) 2011-2020  Free Software Foundation, Inc
      4 
      5 ;; Author: Magnar Sveen <magnars@gmail.com>
      6 ;; Keywords: marking region
      7 
      8 ;; This program is free software; you can redistribute it and/or modify
      9 ;; it under the terms of the GNU General Public License as published by
     10 ;; the Free Software Foundation, either version 3 of the License, or
     11 ;; (at your option) any later version.
     12 
     13 ;; This program is distributed in the hope that it will be useful,
     14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 ;; GNU General Public License for more details.
     17 
     18 ;; You should have received a copy of the GNU General Public License
     19 ;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
     20 
     21 ;;; Commentary:
     22 
     23 ;; Extra expansions for JavaScript that I've found useful so far:
     24 ;;
     25 ;;    er/mark-js-function
     26 ;;    er/mark-js-object-property-value
     27 ;;    er/mark-js-object-property
     28 ;;    er/mark-js-if
     29 ;;    er/mark-js-inner-return
     30 ;;    er/mark-js-outer-return
     31 ;;
     32 ;; Feel free to contribute any other expansions for JavaScript at
     33 ;;
     34 ;;     https://github.com/magnars/expand-region.el
     35 
     36 ;;; Code:
     37 
     38 (require 'expand-region-core)
     39 
     40 (defun er/mark-js-function ()
     41   "Mark the current JavaScript function."
     42   (interactive)
     43   (condition-case nil
     44       (forward-char 8)
     45     (error nil))
     46   (word-search-backward "function")
     47   (while (or (er--point-inside-string-p)
     48              (er--point-is-in-comment-p))
     49     (word-search-backward "function"))
     50   (set-mark (point))
     51   (while (not (looking-at "{"))
     52     (forward-char))
     53   (forward-list)
     54   (exchange-point-and-mark))
     55 
     56 (defun er/mark-js-outer-return ()
     57   "Mark the current return statement, including return and ending semi-colon"
     58   (interactive)
     59   (condition-case nil
     60       (forward-char 6)
     61     (error nil))
     62   (word-search-backward "return")
     63   (while (or (er--point-inside-string-p)
     64              (er--point-is-in-comment-p))
     65     (word-search-backward "return"))
     66   (set-mark (point))
     67   (while (not (looking-at ";"))
     68     (if (looking-at "\\s(")
     69         (forward-list)
     70       (forward-char)))
     71   (forward-char)
     72   (exchange-point-and-mark))
     73 
     74 (defun er/mark-js-inner-return ()
     75   "Mark contents of the current return statement, not including return or semi-colon"
     76   (interactive)
     77   (condition-case nil
     78       (forward-char 6)
     79     (error nil))
     80   (word-search-backward "return")
     81   (while (or (er--point-inside-string-p)
     82              (er--point-is-in-comment-p))
     83     (word-search-backward "return"))
     84   (search-forward " ")
     85   (set-mark (point))
     86   (while (not (looking-at ";"))
     87     (if (looking-at "\\s(")
     88         (forward-list)
     89       (forward-char)))
     90   (exchange-point-and-mark))
     91 
     92 (defun er/mark-js-if ()
     93   "Mark the current if-statement."
     94   (interactive)
     95   (condition-case nil
     96       (forward-char 2)
     97     (error nil))
     98   (word-search-backward "if")
     99   (while (or (er--point-inside-string-p)
    100              (er--point-is-in-comment-p))
    101     (word-search-backward "if"))
    102   (set-mark (point))
    103   (while (not (looking-at "("))
    104     (forward-char))
    105   (forward-list)
    106   (while (not (looking-at "{"))
    107     (forward-char))
    108   (forward-list)
    109   (exchange-point-and-mark))
    110 
    111 (defun er/mark-js-object-property-value ()
    112   "Mark the current object property value, ie. from : to , or }"
    113   (interactive)
    114   (unless (er--point-inside-pairs-p)
    115     (error "Point is not inside an object"))
    116   (search-backward ":")
    117   (forward-char)
    118   (search-forward-regexp "[^\s]")
    119   (backward-char)
    120   (set-mark (point))
    121   (while (not (looking-at "[},]"))
    122     (if (looking-at "\\s(")
    123         (forward-list)
    124       (forward-char)))
    125   (when (er/looking-back-max "[\s\n]" 400)
    126     (search-backward-regexp "[^\s\n]")
    127     (forward-char))
    128   (exchange-point-and-mark))
    129 
    130 (defun er/mark-js-object-property ()
    131   "Mark js-object-property presumes that point is at the assignment part of key: value.
    132 If point is inside the value, that will be marked first anyway."
    133   (interactive)
    134   (when (or (looking-at "\"?\\(\\s_\\|\\sw\\| \\)*\":")
    135             (looking-at "\\(\\s_\\|\\sw\\)*:")
    136             (er/looking-back-max ": ?" 2))
    137     (search-backward-regexp "[{,]")
    138     (forward-char)
    139     (search-forward-regexp "[^\s\n]")
    140     (backward-char)
    141     (set-mark (point))
    142     (search-forward ":")
    143     (while (or (not (looking-at "[},]"))
    144                (er--point-inside-string-p))
    145       (if (looking-at "\\s(")
    146           (forward-list)
    147         (forward-char)))
    148     (when (er/looking-back-max "[\s\n]" 400)
    149       (search-backward-regexp "[^\s\n]")
    150       (forward-char))
    151     (exchange-point-and-mark)))
    152 
    153 (defun er/mark-js-call ()
    154   "Mark the current symbol (including dots) and then parens or squares."
    155   (interactive)
    156   (let ((symbol-regexp "\\(\\s_\\|\\sw\\|\\.\\)+"))
    157     (when (or (looking-at symbol-regexp)
    158               (er/looking-back-on-line symbol-regexp))
    159       (skip-syntax-backward "_w.")
    160       (when (looking-at "!")
    161         (forward-char 1))
    162       (set-mark (point))
    163       (when (looking-at symbol-regexp)
    164         (goto-char (match-end 0)))
    165       (if (looking-at "\\[\\|(")
    166           (forward-list))
    167       (exchange-point-and-mark))))
    168 
    169 (defun er/add-js-mode-expansions ()
    170   "Adds JS-specific expansions for buffers in js-mode"
    171   (set (make-local-variable 'er/try-expand-list) (append
    172                                                   er/try-expand-list
    173                                                   '(er/mark-js-function
    174                                                     er/mark-js-object-property-value
    175                                                     er/mark-js-object-property
    176                                                     er/mark-js-if
    177                                                     er/mark-js-inner-return
    178                                                     er/mark-js-outer-return
    179                                                     er/mark-js-call))))
    180 
    181 (er/enable-mode-expansions 'js-mode 'er/add-js-mode-expansions)
    182 (er/enable-mode-expansions 'js2-mode 'er/add-js-mode-expansions)
    183 (er/enable-mode-expansions 'js3-mode 'er/add-js-mode-expansions)
    184 
    185 (provide 'js-mode-expansions)
    186 
    187 ;; js-mode-expansions.el ends here