diff --git a/README.md b/README.md index dd74cb2..fde47dc 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,12 @@ A JavaScript refactoring library for emacs. This is a collection of small refactoring functions to further the idea of a JavaScript IDE in Emacs that started with js2-mode. +## Change in 0.8.0 + +Add `expand-node-at-point` and `contract-node-at-point` function to Expand / Contract bracketed list according to node type at point (array, object, function, call args). + +Removed previous `ea` `ca` `eo` `co` `eu` `cu` `ec` `cc` key bindings. + ## Breaking change in 0.7.0 js2-refactor.el is now a minor mode that has to be enabled, with @@ -68,16 +74,12 @@ to pick and choose your own keybindings with a smattering of: ## Refactorings + * `ee` is `expand-node-at-point`: Expand bracketed list according to node type at point (array, object, function, call args). + * `cc` is `contract-node-at-point`: Contract bracketed list according to node type at point (array, object, function, call args). * `ef` is `extract-function`: Extracts the marked expressions out into a new named function. * `em` is `extract-method`: Extracts the marked expressions out into a new named method in an object literal. * `ip` is `introduce-parameter`: Changes the marked expression to a parameter in a local function. * `lp` is `localize-parameter`: Changes a parameter to a local var in a local function. - * `eo` is `expand-object`: Converts a one line object literal to multiline. - * `co` is `contract-object`: Converts a multiline object literal to one line. - * `eu` is `expand-function`: Converts a one line function to multiline (expecting semicolons as statement delimiters). - * `cu` is `contract-function`: Converts a multiline function to one line (expecting semicolons as statement delimiters). - * `ea` is `expand-array`: Converts a one line array to multiline. - * `ca` is `contract-array`: Converts a multiline array to one line. * `wi` is `wrap-buffer-in-iife`: Wraps the entire buffer in an immediately invoked function expression * `ig` is `inject-global-in-iife`: Creates a shortcut for a marked global by injecting it in the wrapping immediately invoked function expression * `ag` is `add-to-globals-annotation`: Creates a `/*global */` annotation if it is missing, and adds the var at point to it. @@ -106,8 +108,10 @@ There are also some minor conveniences bundled: A list of some wanted improvements for the current refactorings. - * expand- and contract-array: should work recursively with nested - object literals and nested arrays. + * ~~expand- and contract-array: should work recursively with nested + object literals and nested arrays.~~ + Now the `expand-node-at-point` and `contract-node-at-point` should work, + by moving point into right place. * expand- and contract-function: should deal better with nested object literals, array declarations, and statements terminated only by EOLs (without semicolons). @@ -120,6 +124,7 @@ A list of some wanted improvements for the current refactorings. * [Alex Chamberlain](https://github.com/apchamberlain) contributed contracting and expanding arrays and functions. * [Nicolas Petton](https://github.com/NicolasPetton) contributed lots of stuff and is now a co-maintainer of the project. * [Brian J Brennan](https://github.com/brianloveswords) added support for `const` and `let` to inline-var. +* [James Yang](https://github.com/futurist) added `expand-node-at-point` and `contract-node-at-point` functions. Thanks! diff --git a/features/js2r-expand-collapse.feature b/features/js2r-expand-collapse.feature index 6a1ee3a..d337f58 100644 --- a/features/js2r-expand-collapse.feature +++ b/features/js2r-expand-collapse.feature @@ -4,7 +4,7 @@ Feature: Expand and collapse things When I insert "var a = { b: 1, c: 'def' };" And I turn on js2-mode and js2-refactor-mode And I go to the front of the word "b" - And I press "C-c C-m eo" + And I press "C-c C-m ee" Then I should see: """ var a = { @@ -17,7 +17,7 @@ Feature: Expand and collapse things When I insert "var a = { b: 1, c: 'def, ghi' };" And I turn on js2-mode and js2-refactor-mode And I go to the front of the word "b" - And I press "C-c C-m eo" + And I press "C-c C-m ee" Then I should see: """ var a = { @@ -36,7 +36,7 @@ Feature: Expand and collapse things """ And I turn on js2-mode and js2-refactor-mode And I go to the front of the word "b" - And I press "C-c C-m co" + And I press "C-c C-m cc" Then I should see "var a = { b: 1, c: 'def' };" Scenario: Contracting objects with comma @@ -49,14 +49,14 @@ Feature: Expand and collapse things """ And I turn on js2-mode and js2-refactor-mode And I go to the front of the word "b" - And I press "C-c C-m co" + And I press "C-c C-m cc" Then I should see "var a = { b: 1, c: 'def, ghi' };" Scenario: Expanding functions When I insert "function f (a, b, c) { var t = a + b + c; return t; }" And I turn on js2-mode and js2-refactor-mode And I go to the front of the word "var" - And I press "C-c C-m eu" + And I press "C-c C-m ee" Then I should see: """ function f (a, b, c) { @@ -69,7 +69,7 @@ Feature: Expand and collapse things When I insert "function f (a, b, c) { var t = a + b + c; var arr = [1, 2, 3, a, b]; return [t, arr]; }" And I turn on js2-mode and js2-refactor-mode And I go to the front of the word "var" - And I press "C-c C-m eu" + And I press "C-c C-m ee" Then I should see: """ function f (a, b, c) { @@ -83,7 +83,7 @@ Feature: Expand and collapse things When I insert "function f (a, b, c) { var t = a + b + c; var o = {e1: a, e2: b + 1, e3: 'xyzzy'}; return o; }" And I turn on js2-mode and js2-refactor-mode And I go to the front of the word "var" - And I press "C-c C-m eu" + And I press "C-c C-m ee" Then I should see: """ function f (a, b, c) { @@ -92,18 +92,18 @@ Feature: Expand and collapse things return o; } """ - + Scenario: Expanding arrow functions When I insert "var arrowFunc = (a, b, c) => { return a + b + c; }" And I turn on js2-mode and js2-refactor-mode And I go to the front of the word "return" - And I press "C-c C-m eu" + And I press "C-c C-m ee" Then I should see: """ var arrowFunc = (a, b, c) => { return a + b + c; } - """ + """ Scenario: Contracting arrow functions When I insert: @@ -114,7 +114,7 @@ Feature: Expand and collapse things """ And I turn on js2-mode and js2-refactor-mode And I go to the front of the word "return" - And I press "C-c C-m cu" + And I press "C-c C-m cc" Then I should see: """ var arrowFunc = (a, b, c) => { return a + b + c; } @@ -130,7 +130,7 @@ Feature: Expand and collapse things """ And I turn on js2-mode and js2-refactor-mode And I go to the front of the word "var" - And I press "C-c C-m cu" + And I press "C-c C-m cc" Then I should see "function f (a, b, c) { var t = a + b + c; return t; }" Scenario: Contracting functions containing arrays @@ -144,7 +144,7 @@ Feature: Expand and collapse things """ And I turn on js2-mode and js2-refactor-mode And I go to the front of the word "var" - And I press "C-c C-m cu" + And I press "C-c C-m cc" Then I should see "function f (a, b, c) { var t = a + b + c; var arr = [1, 2, 3, a, b]; return [t, arr]; }" Scenario: Contracting functions containing object literals @@ -158,7 +158,7 @@ Feature: Expand and collapse things """ And I turn on js2-mode and js2-refactor-mode And I go to the front of the word "var" - And I press "C-c C-m cu" + And I press "C-c C-m cc" Then I should see "function f (a, b, c) { var t = a + b + c; var o = {e1: a, e2: b + 1, e3: 'xyzzy'}; return o; }" Scenario: Expanding function call arguments @@ -168,7 +168,7 @@ Feature: Expand and collapse things """ And I turn on js2-mode and js2-refactor-mode And I go to the front of the word "overlay" - And I press "C-c C-m ec" + And I press "C-c C-m ee" Then I should see: """ m( @@ -178,7 +178,7 @@ Feature: Expand and collapse things ); """ And I go to the front of the word "tr" - And I press "C-c C-m ec" + And I press "C-c C-m ee" Then I should see: """ m( @@ -248,7 +248,7 @@ Feature: Expand and collapse things When I insert "var a = [ b, 1, c, 3.1415927 ];" And I turn on js2-mode and js2-refactor-mode And I go to the front of the word "b" - And I press "C-c C-m ea" + And I press "C-c C-m ee" Then I should see: """ var a = [ @@ -271,7 +271,7 @@ Feature: Expand and collapse things """ And I turn on js2-mode and js2-refactor-mode And I go to the front of the word "b" - And I press "C-c C-m ca" + And I press "C-c C-m cc" Then I should see "var a = [ b, 1, c, 3.1415927 ];" Scenario: Expanding arrays with comment @@ -284,7 +284,7 @@ Feature: Expand and collapse things """ And I turn on js2-mode and js2-refactor-mode And I go to character "b" - And I press "C-c C-m ea" + And I press "C-c C-m ee" Then I should see: """ var a = [ @@ -293,3 +293,94 @@ Feature: Expand and collapse things 4 ]; """ + + Scenario: Expanding and contracting node at point + When I insert: + """ + var a = [1, 2, 3]; + var b = {c:4, d:5}; + function abc(x,y){x+=z; return x+y;} + func(6,7); + """ + And I turn on js2-mode and js2-refactor-mode + And I go to the front of the word "1" + And I press "C-c C-m ee" + Then I should see: + """ + var a = [ + 1, + 2, + 3 + ]; + var b = {c:4, d:5}; + function abc(x,y){x+=z; return x+y;} + func(6,7); + """ + When I press "C-c C-m cc" + Then I should see: + """ + var a = [ 1, 2, 3 ]; + var b = {c:4, d:5}; + function abc(x,y){x+=z; return x+y;} + func(6,7); + """ + When I go to the front of the word "4" + And I press "C-c C-m ee" + Then I should see: + """ + var a = [ 1, 2, 3 ]; + var b = { + c:4, + d:5 + }; + function abc(x,y){x+=z; return x+y;} + func(6,7); + """ + When I press "C-c C-m cc" + Then I should see: + """ + var a = [ 1, 2, 3 ]; + var b = { c:4, d:5 }; + function abc(x,y){x+=z; return x+y;} + func(6,7); + """ + When I go to the front of the word "z" + And I press "C-c C-m ee" + Then I should see: + """ + var a = [ 1, 2, 3 ]; + var b = { c:4, d:5 }; + function abc(x,y){ + x+=z; + return x+y; + } + func(6,7); + """ + When I press "C-c C-m cc" + Then I should see: + """ + var a = [ 1, 2, 3 ]; + var b = { c:4, d:5 }; + function abc(x,y){ x+=z; return x+y; } + func(6,7); + """ + When I go to the front of the word "6" + And I press "C-c C-m ee" + Then I should see: + """ + var a = [ 1, 2, 3 ]; + var b = { c:4, d:5 }; + function abc(x,y){ x+=z; return x+y; } + func( + 6, + 7 + ); + """ + When I press "C-c C-m cc" + Then I should see: + """ + var a = [ 1, 2, 3 ]; + var b = { c:4, d:5 }; + function abc(x,y){ x+=z; return x+y; } + func( 6, 7 ); + """ diff --git a/js2-refactor-pkg.el b/js2-refactor-pkg.el index dbc740e..15f0b35 100644 --- a/js2-refactor-pkg.el +++ b/js2-refactor-pkg.el @@ -1,3 +1,3 @@ -(define-package "js2-refactor" "0.7.1" +(define-package "js2-refactor" "0.8.0" "A JavaScript refactoring library for emacs." '((js2-mode "20101228") (s "1.9.0") (multiple-cursors "1.0.0") (dash "1.0.0") (s "1.0.0") (yasnippet "0.9.0.1"))) diff --git a/js2-refactor.el b/js2-refactor.el index 45a2b23..12a8754 100644 --- a/js2-refactor.el +++ b/js2-refactor.el @@ -51,18 +51,12 @@ ;; All refactorings start with `C-c C-m` and then a two-letter mnemonic shortcut. +;; * `ee` is `expand-node-at-point`: Expand bracketed list according to node type at point (array, object, function, call args). +;; * `cc` is `contract-node-at-point`: Contract bracketed list according to node type at point (array, object, function, call args). ;; * `ef` is `extract-function`: Extracts the marked expressions out into a new named function. ;; * `em` is `extract-method`: Extracts the marked expressions out into a new named method in an object literal. ;; * `ip` is `introduce-parameter`: Changes the marked expression to a parameter in a local function. ;; * `lp` is `localize-parameter`: Changes a parameter to a local var in a local function. -;; * `eo` is `expand-object`: Converts a one line object literal to multiline. -;; * `co` is `contract-object`: Converts a multiline object literal to one line. -;; * `eu` is `expand-function`: Converts a one line function to multiline (expecting semicolons as statement delimiters). -;; * `cu` is `contract-function`: Converts a multiline function to one line (expecting semicolons as statement delimiters). -;; * `ec` is `expand-call-args`: Converts a one line function call args to multiline. -;; * `cc` is `contract-call-args`: Converts a multiline function call args to one line. -;; * `ea` is `expand-array`: Converts a one line array to multiline. -;; * `ca` is `contract-array`: Converts a multiline array to one line. ;; * `wi` is `wrap-buffer-in-iife`: Wraps the entire buffer in an immediately invoked function expression ;; * `ig` is `inject-global-in-iife`: Creates a shortcut for a marked global by injecting it in the wrapping immediately invoked function expression ;; * `ag` is `add-to-globals-annotation`: Creates a `/*global */` annotation if it is missing, and adds the var at point to it. @@ -163,14 +157,8 @@ (defun js2r--add-keybindings (key-fn) "Add js2r refactoring keybindings to `js2-mode-map' using KEY-FN to create each keybinding." - (define-key js2-refactor-mode-map (funcall key-fn "eo") #'js2r-expand-object) - (define-key js2-refactor-mode-map (funcall key-fn "co") #'js2r-contract-object) - (define-key js2-refactor-mode-map (funcall key-fn "eu") #'js2r-expand-function) - (define-key js2-refactor-mode-map (funcall key-fn "cu") #'js2r-contract-function) - (define-key js2-refactor-mode-map (funcall key-fn "ec") #'js2r-expand-call-args) - (define-key js2-refactor-mode-map (funcall key-fn "cc") #'js2r-contract-call-args) - (define-key js2-refactor-mode-map (funcall key-fn "ea") #'js2r-expand-array) - (define-key js2-refactor-mode-map (funcall key-fn "ca") #'js2r-contract-array) + (define-key js2-refactor-mode-map (funcall key-fn "ee") #'js2r-expand-node-at-point) + (define-key js2-refactor-mode-map (funcall key-fn "cc") #'js2r-contract-node-at-point) (define-key js2-refactor-mode-map (funcall key-fn "wi") #'js2r-wrap-buffer-in-iife) (define-key js2-refactor-mode-map (funcall key-fn "ig") #'js2r-inject-global-in-iife) (define-key js2-refactor-mode-map (funcall key-fn "ev") #'js2r-extract-var) diff --git a/js2r-formatting.el b/js2r-formatting.el index 7fab8e8..c88ac26 100644 --- a/js2r-formatting.el +++ b/js2r-formatting.el @@ -186,5 +186,59 @@ (js2r--goto-closest-call-start) ",") +(defun js2r--expand-contract-node-at-point (&optional is-contract) + "Expand or contract bracketed list according to node type in point. +Currently working on array, object, function and call args node types. +With argument, contract closest expression, otherwise expand." + (let ((debug-on-error nil) + (pos (point)) + (array-start (point-max)) + (object-start (point-max)) + (function-start (point-max)) + (call-start (point-max))) + (save-excursion + (ignore-errors + (js2r--goto-closest-array-start) + (setq array-start (- pos (point))))) + (save-excursion + (ignore-errors + (js2r--goto-closest-object-start) + (setq object-start (- pos (point))))) + (save-excursion + (ignore-errors + (js2r--goto-closest-function-start) + (setq function-start (- pos (point))))) + (save-excursion + (ignore-errors + (js2r--goto-closest-call-start) + (setq call-start (- pos (point))))) + (setq pos (-min (list array-start object-start function-start call-start))) + (when (= pos array-start) + (if is-contract + (js2r-contract-array) + (js2r-expand-array))) + (when (= pos object-start) + (if is-contract + (js2r-contract-object) + (js2r-expand-object))) + (when (= pos function-start) + (if is-contract + (js2r-contract-function) + (js2r-expand-function))) + (when (= pos call-start) + (if is-contract + (js2r-contract-call-args) + (js2r-expand-call-args))))) + +(defun js2r-expand-node-at-point () + "Expand bracketed list according to node type at point." + (interactive) + (js2r--expand-contract-node-at-point)) + +(defun js2r-contract-node-at-point () + "Contract bracketed list according to node type at point." + (interactive) + (js2r--expand-contract-node-at-point t)) + (provide 'js2r-formatting) ;;; js2-formatting.el ends here