Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements js2r-kill #25

Merged
merged 8 commits into from
Sep 3, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 212 additions & 0 deletions features/js2r-kill.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
Feature: Killing lines

Scenario: Killing a comment
When I insert:
"""
//function foo() {
// bar();
//}
"""
And I turn on js2-mode
And I go to the front of the word "function"
And I press "C-c C-m k"
Then I should see:
"""
//
// bar();
//}
"""

Scenario: Killing a line with parse errors
When I insert:
"""
function foo(
bar();
}
"""
And I turn on js2-mode
And I go to the front of the word "function"
And I press "C-c C-m k"
Then I should see:
"""

bar();
}
"""


Scenario: Killing in a string
When I insert:
"""
function foo() {
bar('hello world');
}
"""
And I turn on js2-mode
And I go to the front of the word "world"
And I press "C-c C-m k"
Then I should see:
"""
function foo() {
bar('hello ');
}
"""
Scenario: Killing in an array
When I insert:
"""
function foo() {
return [1, 2, bar, baz]
}
"""
And I turn on js2-mode
And I go to the end of the word "bar"
And I press "C-c C-m k"
Then I should see:
"""
function foo() {
return [1, 2, bar]
}
"""

Scenario: Killing in a multiline array
When I insert:
"""
function foo() {
return [1,
2,
bar,
baz]
}
"""
And I turn on js2-mode
And I go to the front of the word "bar"
And I press "C-c C-m k"
Then I should see:
"""
function foo() {
return [1,
2,

baz]
}
"""

Scenario: Killing in an object
When I insert:
"""
function foo() {
return {a: {foo: 4, bar: 5}, b: 1}
}
"""
And I turn on js2-mode
And I go to the front of the word "bar"
And I press "C-c C-m k"
Then I should see:
"""
function foo() {
return {a: {foo: 4, }, b: 1}
}
"""

Scenario: Killing in an if statement
When I insert:
"""
function foo() {
if (foo) {return 2;}
}
"""
And I turn on js2-mode
And I go to the front of the word "return"
And I press "C-c C-m k"
Then I should see:
"""
function foo() {
if (foo) {}
}
"""

Scenario: Killing in an if statement with else branch
When I insert:
"""
function foo() {
if (foo) {return 2;} else {return 1;}
}
"""
And I turn on js2-mode
And I go to the front of the word "return"
And I press "C-c C-m k"
Then I should see:
"""
function foo() {
if (foo) {} else {return 1;}
}
"""

Scenario: Killing in an else branch of an if statement
When I insert:
"""
function foo() {
if (foo) {return 2;} else {bar();}
}
"""
And I turn on js2-mode
And I go to the front of the word "bar"
And I press "C-c C-m k"
Then I should see:
"""
function foo() {
if (foo) {return 2;} else {}
}
"""

Scenario: Killing in a function
When I insert:
"""
var foo = function() { return hello;}; bar;
"""
And I turn on js2-mode
And I go to the front of the word "hello"
And I press "C-c C-m k"
Then I should see:
"""
var foo = function() { return }; bar;
"""

Scenario: Killing in the parameters of a function
When I insert:
"""
function a(foo, bar) { return bar;}
"""
And I turn on js2-mode
And I go to the end of the word "foo"
And I press "C-c C-m k"
Then I should see:
"""
function a(foo) { return bar;}
"""

Scenario: Killing in front of a function
When I insert:
"""
function a(foo, bar) { return bar;}
"""
And I turn on js2-mode
And I go to the front of the word "function"
And I press "C-c C-m k"
Then I should see:
"""

"""

Scenario: Killing in front of a variable declaration
When I insert:
"""
var foo = 3;
"""
And I turn on js2-mode
And I go to the front of the word "foo"
And I press "C-c C-m k"
Then I should see:
"""
var
"""
2 changes: 2 additions & 0 deletions js2-refactor.el
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
;; * `C-S-down` and `C-S-up` moves the current line up or down. If the line is an
;; element in an object or array literal, it makes sure that the commas are
;; still correctly placed.
;; * `C-c C-m k` `kill-line`: Like `kill-line` but respecting the AST.

;; ## Todo

Expand Down Expand Up @@ -153,6 +154,7 @@
(define-key js2-mode-map (funcall key-fn "lt") 'js2r-log-this)
(define-key js2-mode-map (funcall key-fn "sl") 'js2r-forward-slurp)
(define-key js2-mode-map (funcall key-fn "ba") 'js2r-forward-barf)
(define-key js2-mode-map (funcall key-fn "k") 'js2r-kill)
(define-key js2-mode-map (kbd "<C-S-down>") 'js2r-move-line-down)
(define-key js2-mode-map (kbd "<C-S-up>") 'js2r-move-line-up))

Expand Down
45 changes: 45 additions & 0 deletions js2r-paredit.el
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,56 @@
(js2-for-node-p node)
(js2-while-node-p node)))

(defun js2r--balanced-node-p (node)
(or (js2-array-node-p node)
(js2-object-node-p node)
(js2-string-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 the AST.
Falls back to `kill-line` if the buffer has parse errors."
(interactive)
(let ((node (js2-node-at-point)))
(cond
((js2-comment-node-p node) (kill-line))
((js2r--balanced-node-p node) (js2r--kill-line-in-balanced-exp))
(t (js2r--kill-line-in-sexp)))))

(defun js2r--kill-line-in-sexp ()
"Kill a line, but respecting the closest sexp, delimited with
\")}]\"."
(condition-case error
(let* ((beg (point))
(end (save-excursion
(up-list)
(forward-char -1)
(point))))
(if (js2-same-line end)
(kill-region beg end)
(kill-line)))
(scan-error
(message "Unbalanced parentheses. Killing the line.")
(kill-line))))

(defun js2r--kill-line-in-balanced-exp ()
"Kill a line, but respecting the closest balanced node (an
array, literal object or string node)."
(if js2-parsed-errors
(progn
(message "Buffer has parse errors. Killing the line.")
(kill-line))
(let* ((node (js2r--closest #'js2r--balanced-node-p))
(beg (point))
(end (and node (1- (js2-node-abs-end node)))))
(if (and node (js2-same-line end))
(kill-region beg end)
(kill-line)))))

(defun js2r-forward-slurp ()
(interactive)
(js2r--guard)
Expand Down