40
40
41
41
(require 'comint )
42
42
(require 'clojure-mode )
43
+ (require 'eldoc )
44
+ (require 'thingatpt )
43
45
44
46
45
47
(defgroup inf-clojure nil
@@ -131,6 +133,7 @@ The following commands are available:
131
133
132
134
\\ {inf-clojure-minor-mode-map}"
133
135
:lighter " " :keymap inf-clojure-minor-mode-map
136
+ (inf-clojure-eldoc-setup)
134
137
(make-local-variable 'completion-at-point-functions )
135
138
(add-to-list 'completion-at-point-functions
136
139
#'inf-clojure-completion-at-point ))
@@ -247,6 +250,7 @@ to continue it."
247
250
(setq comint-prompt-regexp inf-clojure-prompt)
248
251
(setq mode-line-process '(" :%s" ))
249
252
(clojure-mode-variables)
253
+ (inf-clojure-eldoc-setup)
250
254
(setq comint-get-old-input #'inf-clojure-get-old-input )
251
255
(setq comint-input-filter #'inf-clojure-input-filter )
252
256
(set (make-local-variable 'comint-prompt-read-only ) inf-clojure-prompt-read-only)
@@ -429,11 +433,15 @@ Used by this command to determine defaults."
429
433
; doesn't need an exact name
430
434
(comint-check-source file-name) ; Check to see if buffer needs saved.
431
435
(setq inf-clojure-prev-l/c-dir/file (cons (file-name-directory file-name)
432
- (file-name-nondirectory file-name)))
436
+ (file-name-nondirectory file-name)))
433
437
(comint-send-string (inf-clojure-proc)
434
438
(format inf-clojure-load-command file-name))
435
439
(inf-clojure-switch-to-repl t ))
436
440
441
+ (defun inf-clojure-connected-p ()
442
+ " Return t if inferior Clojure is currently connected, nil otherwise."
443
+ (not (null inf-clojure-buffer)))
444
+
437
445
438
446
; ;; Documentation functions: function doc, var doc, arglist, and
439
447
; ;; describe symbol.
@@ -519,6 +527,9 @@ The value is nil if it can't find one."
519
527
(and (symbolp obj) obj)))
520
528
(error nil )))
521
529
530
+ (defun inf-clojure-symbol-at-point ()
531
+ " Return the name of the symbol at point, otherwise nil."
532
+ (or (thing-at-point 'symbol ) " " ))
522
533
523
534
; ;; Documentation functions: var doc and arglist.
524
535
; ;; ======================================================================
@@ -535,7 +546,7 @@ See variable `inf-clojure-var-source-command'."
535
546
(interactive (inf-clojure-symprompt " Var source" (inf-clojure-var-at-pt)))
536
547
(comint-proc-query (inf-clojure-proc) (format inf-clojure-var-source-command var)))
537
548
538
- (defun inf-clojure-show- arglist (fn )
549
+ (defun inf-clojure-arglist (fn )
539
550
" Send a query to the inferior Clojure for the arglist for function FN.
540
551
See variable `inf-clojure-arglist-command' ."
541
552
(interactive (inf-clojure-symprompt " Arglist" (inf-clojure-fn-called-at-pt)))
@@ -549,12 +560,16 @@ See variable `inf-clojure-arglist-command'."
549
560
(process-send-string proc eldoc-snippet)
550
561
(while (and (not (string-match inf-clojure-prompt kept))
551
562
(accept-process-output proc 2 )))
552
- ; some nasty #_=> garbage appears in the output
553
563
(setq eldoc (and (string-match " (.+)" kept) (match-string 0 kept)))
554
564
)
555
565
(set-process-filter proc comint-filt))
556
- (when eldoc
557
- (message " %s : %s " fn eldoc))))
566
+ eldoc))
567
+
568
+ (defun inf-clojure-show-arglist (fn )
569
+ " Show the arglist for function FN in the mini-buffer."
570
+ (interactive (inf-clojure-symprompt " Arglist" (inf-clojure-fn-called-at-pt)))
571
+ (if-let ((eldoc (inf-clojure-arglist fn)))
572
+ (message " %s : %s " fn eldoc)))
558
573
559
574
(defun inf-clojure-show-ns-vars (ns )
560
575
" Send a query to the inferior Clojure for the public vars in NS.
@@ -644,6 +659,88 @@ Returns the selected completion or nil."
644
659
(completion-table-with-cache #'inf-clojure-completions )
645
660
(completion-table-dynamic #'inf-clojure-completions ))))))
646
661
662
+ ; ;;; ElDoc
663
+ ; ;;; =====
664
+
665
+ (defvar inf-clojure-extra-eldoc-commands '(" yas-expand" )
666
+ " Extra commands to be added to eldoc's safe commands list." )
667
+
668
+ (defvar-local inf-clojure-eldoc-last-symbol nil
669
+ " The eldoc information for the last symbol we checked." )
670
+
671
+ (defun inf-clojure-eldoc-format-thing (thing )
672
+ " Format the eldoc THING."
673
+ (propertize thing 'face 'font-lock-function-name-face ))
674
+
675
+ (defun inf-clojure-eldoc-beginning-of-sexp ()
676
+ " Move to the beginning of current sexp.
677
+
678
+ Return the number of nested sexp the point was over or after. "
679
+ (let ((parse-sexp-ignore-comments t )
680
+ (num-skipped-sexps 0 ))
681
+ (condition-case _
682
+ (progn
683
+ ; ; First account for the case the point is directly over a
684
+ ; ; beginning of a nested sexp.
685
+ (condition-case _
686
+ (let ((p (point )))
687
+ (forward-sexp -1 )
688
+ (forward-sexp 1 )
689
+ (when (< (point ) p)
690
+ (setq num-skipped-sexps 1 )))
691
+ (error ))
692
+ (while
693
+ (let ((p (point )))
694
+ (forward-sexp -1 )
695
+ (when (< (point ) p)
696
+ (setq num-skipped-sexps (1+ num-skipped-sexps))))))
697
+ (error ))
698
+ num-skipped-sexps))
699
+
700
+ (defun inf-clojure-eldoc-info-in-current-sexp ()
701
+ " Return a list of the current sexp and the current argument index."
702
+ (save-excursion
703
+ (let ((argument-index (1- (inf-clojure-eldoc-beginning-of-sexp))))
704
+ ; ; If we are at the beginning of function name, this will be -1.
705
+ (when (< argument-index 0 )
706
+ (setq argument-index 0 ))
707
+ ; ; Don't do anything if current word is inside a string, vector,
708
+ ; ; hash or set literal.
709
+ (if (member (or (char-after (1- (point ))) 0 ) '(?\" ?\{ ?\[ ))
710
+ nil
711
+ (list (inf-clojure-symbol-at-point) argument-index)))))
712
+
713
+ (defun inf-clojure-eldoc-arglist (thing )
714
+ " Return the arglist for THING."
715
+ (when (and thing
716
+ (not (string= thing " " ))
717
+ (not (string-prefix-p " :" thing)))
718
+ ; ; check if we can used the cached eldoc info
719
+ (if (string= thing (car inf-clojure-eldoc-last-symbol))
720
+ (cdr inf-clojure-eldoc-last-symbol)
721
+ (let ((arglist (inf-clojure-arglist (substring-no-properties thing))))
722
+ (when arglist
723
+ (setq inf-clojure-eldoc-last-symbol (cons thing arglist))
724
+ arglist)))))
725
+
726
+ (defun inf-clojure-eldoc ()
727
+ " Backend function for eldoc to show argument list in the echo area."
728
+ (when (and (inf-clojure-connected-p)
729
+ ; ; don't clobber an error message in the minibuffer
730
+ (not (member last-command '(next-error previous-error))))
731
+ (let* ((info (inf-clojure-eldoc-info-in-current-sexp))
732
+ (thing (car info))
733
+ (value (inf-clojure-eldoc-arglist thing)))
734
+ (when value
735
+ (format " %s : %s "
736
+ (inf-clojure-eldoc-format-thing thing)
737
+ value)))))
738
+
739
+ (defun inf-clojure-eldoc-setup ()
740
+ " Turn on eldoc mode in the current buffer."
741
+ (setq-local eldoc-documentation-function #'inf-clojure-eldoc )
742
+ (apply #'eldoc-add-command inf-clojure-extra-eldoc-commands))
743
+
647
744
(provide 'inf-clojure )
648
745
649
746
; ;; inf-clojure.el ends here
0 commit comments