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