86
86
(require 'cider-debug )
87
87
(require 'cider-util )
88
88
89
+ (require 'cl-lib )
89
90
(require 'tramp-sh )
90
91
(require 'subr-x )
91
92
(require 'seq )
@@ -346,6 +347,26 @@ Sub-match 1 must be the project path.")
346
347
(defvar cider-host-history nil
347
348
" Completion history for connection hosts." )
348
349
350
+ (defvar cider-jack-in-universal-options
351
+ '((clojure-cli (:prefix-arg 1 :cmd (:jack-in-type clj :project-type babashka :edit-project-dir t )))
352
+ (lein (:prefix-arg 2 :cmd (:jack-in-type clj :project-type clojure-cli :edit-project-dir t )))
353
+ (babashka (:prefix-arg 3 :cmd (:jack-in-type clj :project-type lein :edit-project-dir t )))
354
+ (nbb (:prefix-arg 4 :cmd (:jack-in-type cljs :project-type nbb :cljs-repl-type nbb :edit-project-dir t ))))
355
+ " The list of project tools that are supported by the universal jack in command.
356
+
357
+ Each item in the list consists of the tool name and its plist options.
358
+
359
+ The plist supports the following keys
360
+
361
+ - :prefix-arg the numerical prefix arg to use to jack in to the tool.
362
+
363
+ - :cmd a plist of instructions how to invoke the jack in command, with keys
364
+
365
+ - :jack-in-type 'clj to start a clj repl and 'cljs for a cljs repl.
366
+
367
+ - &rest the same set of params supported by the `cider-jack-in-clj' and
368
+ `cider-jack-in-cljs' commands." )
369
+
349
370
;;;### autoload
350
371
(defun cider-version ()
351
372
" Display CIDER's version."
@@ -1169,6 +1190,7 @@ nil."
1169
1190
(define-key map (kbd " j j" ) #'cider-jack-in-clj )
1170
1191
(define-key map (kbd " j s" ) #'cider-jack-in-cljs )
1171
1192
(define-key map (kbd " j m" ) #'cider-jack-in-clj&cljs )
1193
+ (define-key map (kbd " j u" ) #'cider-jack-in-universal )
1172
1194
(define-key map (kbd " C-j j" ) #'cider-jack-in-clj )
1173
1195
(define-key map (kbd " C-j s" ) #'cider-jack-in-cljs )
1174
1196
(define-key map (kbd " C-j m" ) #'cider-jack-in-clj&cljs )
@@ -1393,9 +1415,15 @@ non-nil, don't start if ClojureScript requirements are not met."
1393
1415
(t params)))
1394
1416
1395
1417
(defun cider--update-project-dir (params )
1396
- " Update :project-dir in PARAMS."
1418
+ " Update :project-dir in PARAMS.
1419
+
1420
+ Params is a plist with the following keys (non-exhaustive)
1421
+
1422
+ :edit-project-dir prompt (optional) ask user to confirm the project root
1423
+ directory."
1397
1424
(let* ((params (cider--update-do-prompt params))
1398
- (proj-dir (if (plist-get params :do-prompt )
1425
+ (proj-dir (if (or (plist-get params :do-prompt )
1426
+ (plist-get params :edit-project-dir ))
1399
1427
(read-directory-name " Project: "
1400
1428
(clojure-project-dir (cider-current-dir)))
1401
1429
(plist-get params :project-dir )))
@@ -1460,10 +1488,17 @@ non-nil, don't start if ClojureScript requirements are not met."
1460
1488
(format " -encodedCommand %s " (base64-encode-string utf-16le-command t ))))
1461
1489
1462
1490
(defun cider--update-jack-in-cmd (params )
1463
- " Update :jack-in-cmd key in PARAMS."
1491
+ " Update :jack-in-cmd key in PARAMS.
1492
+
1493
+ PARAMS is a plist with the following keys (non-exhaustive list)
1494
+
1495
+ :project-type optional, the project type to create the command for; see
1496
+ `cider-jack-in-command' for the list of valid types)."
1464
1497
(let* ((params (cider--update-do-prompt params))
1465
1498
(project-dir (plist-get params :project-dir ))
1466
- (project-type (cider-project-type project-dir))
1499
+ (params-project-type (plist-get params :project-type ))
1500
+ (project-type (or params-project-type
1501
+ (cider-project-type project-dir)))
1467
1502
(command (cider-jack-in-command project-type))
1468
1503
(command-resolved (cider-jack-in-resolve-command project-type))
1469
1504
(command-global-opts (cider-jack-in-global-options project-type))
@@ -1484,7 +1519,8 @@ non-nil, don't start if ClojureScript requirements are not met."
1484
1519
(eq cider-allow-jack-in-without-project t )
1485
1520
(and (null project-dir)
1486
1521
(eq cider-allow-jack-in-without-project 'warn )
1487
- (y-or-n-p " Are you sure you want to run `cider-jack-in' without a Clojure project? " )))
1522
+ (or params-project-type
1523
+ (y-or-n-p " Are you sure you want to run `cider-jack-in' without a Clojure project? " ))))
1488
1524
(let ((cmd (format " %s %s " command-resolved (if (or (string-equal command " powershell" )
1489
1525
(string-equal command " pwsh" ))
1490
1526
(cider--powershell-encode-command cmd-params)
@@ -1767,6 +1803,55 @@ PROJECT-DIR defaults to the current project."
1767
1803
; ; 0.18, therefore the need for `cider-maybe-intern'
1768
1804
(t (cider-maybe-intern cider-jack-in-default)))))
1769
1805
1806
+ ;;;### autoload
1807
+ (defun cider-jack-in-universal (arg )
1808
+ " Start and connect to an nREPL server for the current project or ARG project id.
1809
+
1810
+ If a project is found in current dir, call `cider-jack-in' passing ARG as
1811
+ first parameter, of which see. Otherwise, ask user which project type to
1812
+ start an nREPL server and connect to without a project.
1813
+
1814
+ But if invoked with a numeric prefix ARG, then start an nREPL server for
1815
+ the project type denoted by ARG number and connect to it, even if there is
1816
+ no project for it in the current dir.
1817
+
1818
+ The supported project tools and their assigned numeric prefix ids are
1819
+ sourced from `cider-jack-in-universal-options' , of which see.
1820
+
1821
+ You can pass a numeric prefix argument n with `M-n` or `C-u n`.
1822
+
1823
+ For example, to jack in to leiningen which is assigned to prefix arg 2 type
1824
+
1825
+ M-2 \\ [cider-jack-in-universal]."
1826
+ (interactive " P" )
1827
+ (let ((cpt (clojure-project-dir (cider-current-dir))))
1828
+ (if (or (integerp arg) (null cpt))
1829
+ (let* ((project-types-available (mapcar #'car cider-jack-in-universal-options))
1830
+ (project-type (if (null arg)
1831
+ (intern (completing-read
1832
+ " No project found in current dir, select project type to jack in: "
1833
+ project-types-available
1834
+ nil t ))
1835
+
1836
+ (or (seq-some (lambda (elt )
1837
+ (cl-destructuring-bind
1838
+ (project-type (&key prefix-arg &allow-other-keys)) elt
1839
+ (when (= arg prefix-arg)
1840
+ project-type)))
1841
+ cider-jack-in-universal-options)
1842
+ (error " :cider-jack-in-universal :unsupported-prefix-argument %S :no-such-project "
1843
+ arg))))
1844
+ (project-options (cadr (seq-find (lambda (elt ) (equal project-type (car elt)))
1845
+ cider-jack-in-universal-options)))
1846
+ (jack-in-opts (plist-get project-options :cmd ))
1847
+ (jack-in-type (plist-get jack-in-opts :jack-in-type )))
1848
+ (pcase jack-in-type
1849
+ ('clj (cider-jack-in-clj jack-in-opts))
1850
+ ('cljs (cider-jack-in-cljs jack-in-opts))
1851
+ (_ (error " :cider-jack-in-universal :jack-in-type-unsupported %S " jack-in-type))))
1852
+
1853
+ (cider-jack-in-clj arg))))
1854
+
1770
1855
1771
1856
; ; TODO: Implement a check for command presence over tramp
1772
1857
(defun cider--resolve-command (command )
0 commit comments