Skip to content

Commit

Permalink
Add nodejs-repl and eval commands for it
Browse files Browse the repository at this point in the history
  • Loading branch information
Jakub Holy committed Mar 3, 2015
1 parent e783e29 commit 31ffad9
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 1 deletion.
12 changes: 11 additions & 1 deletion .live-packs/jholy-pack/init.el
Expand Up @@ -120,7 +120,13 @@
("C-e" . ergoemacs-end-of-line-or-what)
("M-n" . ergoemacs-beginning-or-end-of-buffer) ; re-bind, was bound to outline-next-visible-heading from outline.el
("M-/" . dabbrev-expand) ;; rebind from toggle case
))
))
(use-package ac-js2 // better autoc., navigate to symbol; support for Company mode on itsway
;; It binds M-. to jump to definition, M-, to go back
:ensure t
:init (add-hook 'js2-mode-hook 'ac-js2-mode))
(use-package nodejs-repl
:ensure t)

;; see https://github.com/ergoemacs/ergoemacs-mode/issues/333
;; FIXME DOES NOT WORK
Expand Down Expand Up @@ -181,6 +187,10 @@
(add-hook 'clojure-mode-hook 'my-add-pretty-lambda)
(add-hook 'js2-mode-hook 'my-add-pretty-lambda)

;;; NODEJS-REPL
(live-add-pack-lib "nodejs-repl-eval")
(require 'nodejs-repl-eval)

;;; CLOJURE


Expand Down
89 changes: 89 additions & 0 deletions .live-packs/jholy-pack/lib/nodejs-repl-eval.el
@@ -0,0 +1,89 @@
;;; nodejs-repl-eval.el --- Summary
;;; Commentary:
;;;
;;; Evaluation functions for the `nodejs-repl' package. Written on a stormy
;;; night between days of node hacking.
;;;
;;; See https://gist.github.com/emallson/0eae865bc99fc9639fac
;;;
;;; Code:
(require 'js2-mode)
(require 'nodejs-repl)

(defun nodejs-repl--sanitize-lodash (text)
"Replace _. with $_. because _ is a special variable in Node.js"
(replace-regexp-in-string "\\_<_\\." "$_." text))

(defun nodejs-repl-eval-region (start end)
"Evaluate the region specified by `START' and `END'."
(let ((proc (get-process nodejs-repl-process-name)))
(comint-simple-send proc
(nodejs-repl--sanitize-lodash
(buffer-substring-no-properties start end)))))

(defun nodejs-repl-eval-node (node)
"Evaluate `NODE', a `js2-mode' node."
(let ((beg (js2-node-abs-pos node))
(end (js2-node-abs-end node)))
(nodejs-repl-eval-region beg end)))

(defun nodejs-repl--find-current-or-prev-node (pos &optional include-comments)
"Locate the first node before `POS'. Return a node or nil.
If `INCLUDE-COMMENTS' is set to t, then comments are considered
valid nodes. This is stupid, don't do it."
(let ((node (js2-node-at-point pos (not include-comments))))
(if (or (null node)
(js2-ast-root-p node))
(unless (= 0 pos)
(nodejs-repl--find-current-or-prev-node (1- pos) include-comments))
node)))

(defun nodejs-repl-eval-function ()
"Evaluate the current or previous function."
(interactive)
(let* ((fn-above-node (lambda (node)
(js2-mode-function-at-point (js2-node-abs-pos node))))
(fn (funcall fn-above-node
(nodejs-repl--find-current-or-prev-node
(point) (lambda (node)
(not (null (funcall fn-above-node node))))))))
(unless (null fn)
(nodejs-repl-eval-node fn))))

(defun nodejs-repl-eval-first-stmt (pos)
"Evaluate the first statement found from `POS' by `js2-mode'.
If this statement is a block statement, its first parent
statement is found. This will be either a function declaration,
function call, or assignment statement."
(let ((node (js2-mode-find-first-stmt (nodejs-repl--find-current-or-prev-node pos))))
(cond
((js2-block-node-p node) (nodejs-repl-eval-node (js2-node-parent-stmt node)))
((not (null node)) (nodejs-repl-eval-node node)))))

(defun nodejs-repl-eval-dwim ()
"Heuristic evaluation of JS code in a NodeJS repl.
Evaluates the region, if active, or the first statement found at
or prior to the point.
If the point is at the end of a line, evaluation is done from one
character prior. In many cases, this will be a semicolon and will
change what is evaluated to the statement on the current line."
(interactive)
(cond
((use-region-p) (nodejs-repl-eval-region (region-beginning) (region-end)))
((= (line-end-position) (point)) (nodejs-repl-eval-first-stmt (1- (point))))
(t (nodejs-repl-eval-first-stmt (point)))))

(defun nodejs-repl-eval-buffer (&optional buffer)
"Evaluate the current buffer or the one given as `BUFFER'.
`BUFFER' should be a string or buffer."
(interactive)
(let ((buffer (or buffer (current-buffer))))
(with-current-buffer buffer
(nodejs-repl-eval-region (point-min) (point-max)))))

(provide 'nodejs-repl-eval)

0 comments on commit 31ffad9

Please sign in to comment.