my-emacs-d/elpa/clojure-quick-repls-20150814.36/clojure-quick-repls.el
2016-09-22 18:37:03 +02:00

156 lines
6.7 KiB
EmacsLisp

;;; clojure-quick-repls.el --- Quickly create Clojure and ClojureScript repls for a project.
;; Copyright (C) 2014 symfrog
;; URL: https://github.com/symfrog/clojure-quick-repls
;; Package-Version: 20150814.36
;; Keywords: languages, clojure, cider, clojurescript
;; Version: 0.2.0-cvs
;; Package-Requires: ((cider "0.8.1") (dash "2.9.0"))
;; 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/>.
;;; Commentary:
;; Quickly create Clojure and ClojureScript repls for a project.
;; Once the repls are created the usual CIDER commands can be used in either a clj/cljs buffer and the forms will be routed automatically via the correct connection.
;; So no need to manually switch connections!
;;; Installation:
;; Available as a package in melpa.org.
;; M-x package-install clojure-quick-repls
;;; Usage:
;; (require 'clojure-quick-repls)
;;; Code:
(require 'cider)
(require 'dash)
(defcustom clojure-quick-repls-cljs-setup
"(require 'cljs.repl.browser)
(cemerick.piggieback/cljs-repl
:repl-env (cljs.repl.browser/repl-env :port 9000))"
"Default form to initialize ClojureScript REPL"
:type '(string)
:group 'clojure-quick-repls)
(defvar clojure-quick-repls-nrepl-connected-fn nil)
(defvar clojure-quick-repls-current-buffer nil)
(defvar clojure-quick-repls-nrepl-connect-done nil)
(defvar clojure-quick-repls-clj-con-buf nil)
(defvar clojure-quick-repls-cljs-con-buf nil)
(defun clojure-quick-repls-noop-nrepl-connected-fn ()
(fset 'clojure-quick-repls-nrepl-connected-fn (lambda (buf) nil)))
(clojure-quick-repls-noop-nrepl-connected-fn)
(defun clojure-quick-repls-clear-con-bufs ()
(setq clojure-quick-repls-clj-con-buf nil)
(setq clojure-quick-repls-cljs-con-buf nil))
(add-hook 'nrepl-connected-hook (lambda ()
(clojure-quick-repls-nrepl-connected-fn clojure-quick-repls-current-buffer)))
(add-hook 'nrepl-disconnected-hook #'clojure-quick-repls-clear-con-bufs)
;;;###autoload
(defun clojure-quick-repls-connect ()
"Launch Clojure and ClojureScript repls for the current project"
(interactive)
(setq clojure-quick-repls-current-buffer (current-buffer))
(clojure-quick-repls-noop-nrepl-connected-fn)
(cider-jack-in)
(clojure-quick-repls-clear-con-bufs)
(lexical-let* ((cljs-fn (lambda (buf)
(with-current-buffer buf
(clojure-quick-repls-noop-nrepl-connected-fn)
(if (string= "ex" (cadr (nrepl-sync-request:eval clojure-quick-repls-cljs-setup)))
(message "Failed to initialize cljs connection with form %s" clojure-quick-repls-cljs-setup)
(progn
(setq clojure-quick-repls-cljs-con-buf (nrepl-current-connection-buffer))
(message "Clj connection buffer: %s Cljs connection buffer %s" clojure-quick-repls-clj-con-buf clojure-quick-repls-cljs-con-buf)
(message "Cljs browser repl ready")
; Make the clj buf default after completion
(nrepl-make-connection-default clojure-quick-repls-clj-con-buf))))))
(clj-fn (lambda (buf)
(with-current-buffer buf
(clojure-quick-repls-noop-nrepl-connected-fn )
(fset 'clojure-quick-repls-nrepl-connected-fn cljs-fn)
(setq clojure-quick-repls-clj-con-buf (nrepl-current-connection-buffer))
(message "Creating nrepl connection for cljs")
(clojure-quick-repls-new-repl-connection)))))
(fset 'clojure-quick-repls-nrepl-connected-fn clj-fn)))
(defun clojure-quick-repls-new-repl-connection ()
(let* ((host (nrepl-current-host))
(port (nrepl-extract-port)))
(message "Creating repl connection to nrepl server on port %s, host %s" host port)
(cider-connect host port)))
(defun clojure-quick-repls-bound-truthy-p (s)
(and (boundp s) (symbol-value s)))
(defun clojure-quick-repls-buffer-extension (buffer)
(let ((name (buffer-name buffer)))
(-when-let (p-loc (string-match-p "\\." name))
(substring name (1+ p-loc) nil))) )
(defun clojure-quick-repls-set-connection (f h)
(let ((ext (clojure-quick-repls-buffer-extension (current-buffer))))
(if (and (clojure-quick-repls-bound-truthy-p 'clojure-quick-repls-clj-con-buf)
(clojure-quick-repls-bound-truthy-p 'clojure-quick-repls-cljs-con-buf)
ext
(or (string= ext "clj") (string= ext "boot") (string= ext "cljs")))
(progn
(if (string= ext "cljs")
(nrepl-make-connection-default clojure-quick-repls-cljs-con-buf)
(nrepl-make-connection-default clojure-quick-repls-clj-con-buf))
(when f
(funcall f)))
(when h
(funcall h)))))
(defun clojure-quick-repls-switch-to-relevant-repl (arg)
(interactive)
(lexical-let ((a arg))
(clojure-quick-repls-set-connection (lambda () (cider-switch-to-current-repl-buffer a))
(lambda () (cider-switch-to-relevant-repl-buffer a)))))
(if (version< emacs-version "24.4")
(progn
(defadvice cider-interactive-eval (before clojure-quick-repls-nrepl-current-session activate)
(clojure-quick-repls-set-connection nil nil))
(defadvice cider-tooling-eval (before clojure-quick-repls-nrepl-current-session activate)
(clojure-quick-repls-set-connection nil nil))
(defadvice cider-complete-at-point (before clojure-quick-repls-nrepl-current-session activate)
(clojure-quick-repls-set-connection nil nil)))
(defun clojure-quick-repls-nrepl-current-session (&optional arg1 arg2 arg3)
(clojure-quick-repls-set-connection nil nil))
(advice-add 'cider-interactive-eval :before #'clojure-quick-repls-nrepl-current-session)
(advice-add 'cider-tooling-eval :before #'clojure-quick-repls-nrepl-current-session)
(advice-add 'cider-complete-at-point :before #'clojure-quick-repls-nrepl-current-session))
(provide 'clojure-quick-repls)
;;; clojure-quick-repls.el ends here