diff options
| author | mattkae <mattkae@protonmail.com> | 2022-05-11 09:23:58 -0400 | 
|---|---|---|
| committer | mattkae <mattkae@protonmail.com> | 2022-05-11 09:23:58 -0400 | 
| commit | 3f4a0d5370ae6c34afe180df96add3b8522f4af1 (patch) | |
| tree | ae901409e02bde8ee278475f8cf6818f8f680a60 /elpa/js2-refactor-20210306.2003/js2r-paredit.el | |
initial commit
Diffstat (limited to 'elpa/js2-refactor-20210306.2003/js2r-paredit.el')
| -rw-r--r-- | elpa/js2-refactor-20210306.2003/js2r-paredit.el | 227 | 
1 files changed, 227 insertions, 0 deletions
| diff --git a/elpa/js2-refactor-20210306.2003/js2r-paredit.el b/elpa/js2-refactor-20210306.2003/js2r-paredit.el new file mode 100644 index 0000000..3907558 --- /dev/null +++ b/elpa/js2-refactor-20210306.2003/js2r-paredit.el @@ -0,0 +1,227 @@ +;;; js2r-paredit.el --- Paredit-like extensions for js2-refactor    -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2014 Magnar Sveen +;; Copyright (C) 2015-2016 Magnar Sveen and Nicolas Petton + +;; Author: Magnar Sveen <magnars@gmail.com>, +;;         Nicolas Petton <nicolas@petton.fr> +;; Keywords: conveniences + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program.  If not, see <http://www.gnu.org/licenses/>. + +;;; Code: + +(require 'dash) + +(require 'js2r-helpers) + +(defun js2r--nesting-node-p (node) +  (or (js2-function-node-p node) +      (js2-if-node-p node) +      (js2-for-node-p node) +      (js2-while-node-p node))) + +(defun js2r--standalone-node-p (node) +  (or (js2-stmt-node-p node) +      (and (js2-function-node-p node) +           (eq 'FUNCTION_STATEMENT (js2-function-node-form node))))) + +(defun js2r-kill () +  "Kill a line like `kill-line' but tries to respect node boundaries. +Falls back to `kill-line' if the buffer has parse errors. + +if(|foo) {bar();}       -> if() {bar();} + +function foo() {|2 + 3} -> function foo() {} + +// some |comment        -> // some + +'this is a| string'     -> 'this is a' +" +  (interactive) +  (if js2-parsed-errors +      (progn +        (message "Buffer has parse errors.  Killing the line") +        (kill-line)) +    (condition-case error +	(js2r--kill-line) +      (progn +	(message "Error occured while trying to kill AST node.  Killing the line.") +	(kill-line))))) + +(defun js2r--kill-line () +  "Kill a line, but respecting node boundaries." +  (let ((node (js2r--next-node))) +    (cond +     ((js2-comment-node-p node) (kill-line)) +     ((js2-string-node-p node) (js2r--kill-line-in-string)) +     (t (js2r--kill-line-in-sexp))))) + +(defun js2r--next-node () +  "Return the node at point, or the node after the point if the +  point is at the exact end of a node." +  (save-excursion +    (when (= (js2-node-abs-end (js2-node-at-point)) +             (point)) +      (forward-char 1)) +    (js2-node-at-point))) + +(defun js2r--kill-line-in-sexp () +  "Kill a line, but only kills until the closest outer sexp on +  the current line, delimited with \")}]\". If no sexp is found +  on the current line, falls back to +  `js2r--kill-line-with-inner-sexp'." +  (condition-case error +      (let* ((beg (point)) +             (end (save-excursion +                    (up-list) +                    (forward-char -1) +                    (point)))) +        (if (js2-same-line end) +            (kill-region beg end) +          (js2r--kill-line-with-inner-sexp))) +    (scan-error +     (js2r--kill-line-with-inner-sexp)))) + +(defun js2r--kill-line-with-inner-sexp () +  "Kill a line, but respecting inner killed sexps, ensuring that +we kill up to the end to the next inner sexp if it starts in +the current line. + +If the parentheses are unbalanced, fallback to `kill-line' and +warn the user." +  (condition-case error +      (let* ((beg (point)) +             (end (save-excursion +                    (forward-visible-line 1) +                    (point))) +             (beg-of-sexp (save-excursion +                            (js2r--goto-last-sexp-on-line) +                            (point))) +             (end-of-sexp (save-excursion +                            (goto-char beg-of-sexp) +                            (forward-list) +                            ;; Kill all remaining semi-colons as well +                            (while (looking-at ";") +                              (forward-char)) +                            (point)))) +        (if (js2-same-line beg-of-sexp) +            (kill-region beg (max end end-of-sexp)) +          (kill-line))) +    (scan-error +     (message "Unbalanced parentheses. Killing the line.") +     (kill-line)))) + +(defun js2r--goto-last-sexp-on-line () +  "Move the cursor to the opening of the last sexp on the current +line, or to the end of the line if no sexp is found." +  (let ((pos (point))) +    (down-list) +    (backward-char 1) +    (forward-list) +    (if (js2-same-line pos) +        (js2r--goto-last-sexp-on-line) +      (backward-list)))) + +(defun js2r--kill-line-in-string () +  "Kill a line in a string node, respecting the node boundaries. +When at the beginning of the node, kill from outside of it." +  (let* ((node (js2-node-at-point)) +         (beg (point)) +         (node-start (js2-node-abs-pos node)) +         (node-end (js2-node-abs-end node))) +    (if (= beg node-start) +        (js2r--kill-line-in-sexp) +      (kill-region beg (1- node-end))))) + +(defun js2r-forward-slurp (&optional arg) +  "Add the expression following the current function into it. + +The addition is performed by moving the closing brace of the +function down. + +When called with a prefix argument ARG, slurp ARG expressions +following the current function." +  (interactive "p") +  (js2r--guard) +  (js2r--wait-for-parse +   (let* ((nesting (js2r--closest 'js2r--nesting-node-p)) +	  (standalone (if (js2r--standalone-node-p nesting) +			  nesting +			(js2-node-parent-stmt nesting))) +	  (next-sibling (js2-node-next-sibling standalone)) +	  (beg (js2-node-abs-pos next-sibling)) +	  (last-sibling (if (wholenump arg) +			    (let ((num arg) +				  (iter-sibling next-sibling)) +			      (while (> num 1) ;; Do next-sibling arg nbr of times +				(setq iter-sibling (js2-node-next-sibling iter-sibling)) +				(setq num (1- num))) +			      iter-sibling) +			  next-sibling)) ;; No optional arg. Just use next-sibling +	  (end (js2-node-abs-end last-sibling)) +	  (text (buffer-substring beg end))) +     (save-excursion +       (delete-region beg end) +       ;; Delete newline character if the deleted AST node was at the end of the line +       (goto-char beg) +       (when (and (eolp) +		  (not (eobp))) +	 (delete-char 1)) +       (goto-char (js2-node-abs-end nesting)) +       (forward-char -1) +       (when (looking-back "{ *") +	 (newline)) +       (setq beg (point)) +       (insert text) +       (when (looking-at " *}") +	 (newline)) +       (setq end (point)) +       (indent-region beg end))))) + +(defun js2r-forward-barf (&optional arg) +  (interactive "p") +  (js2r--guard) +  (js2r--wait-for-parse +   (let* ((nesting (js2r--closest 'js2r--nesting-node-p)) +	  (standalone (if (js2r--standalone-node-p nesting) +			  nesting +			(js2-node-parent-stmt nesting))) +	  (standalone-end (js2-node-abs-end standalone)) +	  (last-child (car (last (if (js2-if-node-p nesting) +				     (js2-scope-kids (js2r--closest 'js2-scope-p)) +				   (js2r--node-kids nesting))))) +	  (first-barf-child (if (wholenump arg) +				(let ((num arg) +				      (iter-child last-child)) +				  (while (> num 1) ;; Do prev-sibling arg nbr of times +				    (setq iter-child (js2-node-prev-sibling iter-child)) +				    (setq num (1- num))) +				  iter-child) +			      last-child)) ; No optional arg. Just use last-child +	  (last-child-beg (save-excursion +			    (goto-char (js2-node-abs-pos first-barf-child)) +			    (skip-syntax-backward " ") +			    (while (looking-back "\n") (backward-char)) +			    (point))) +	  (last-child-end (js2-node-abs-end last-child)) +	  (text (buffer-substring last-child-beg last-child-end))) +     (save-excursion +       (js2r--execute-changes +	(list +	 (list :beg last-child-beg :end last-child-end :contents "") +	 (list :beg standalone-end :end standalone-end :contents text))))))) + +(provide 'js2r-paredit) +;;; js2r-paredit.el ends here | 
