From 6100a2e3ff7469f745dfa20892d0180973dd609d Mon Sep 17 00:00:00 2001 From: Jose Antonio Ortega Ruiz Date: Fri, 27 Feb 2009 23:29:09 +0100 Subject: Autodoc system revamped. --- elisp/geiser-autodoc.el | 87 ++++++++++++++++++++++++----------------------- elisp/geiser-syntax.el | 90 ++++++++++++++++++------------------------------- 2 files changed, 76 insertions(+), 101 deletions(-) (limited to 'elisp') diff --git a/elisp/geiser-autodoc.el b/elisp/geiser-autodoc.el index 7460aa1..9f5954d 100644 --- a/elisp/geiser-autodoc.el +++ b/elisp/geiser-autodoc.el @@ -67,64 +67,65 @@ when `geiser-autodoc-display-module-p' is on." (make-variable-buffer-local (defvar geiser-autodoc--last-funs nil)) -(defun geiser-autodoc--function-args (funs) - (when funs - (let ((pr (and (eq (car geiser-autodoc--last) (caar funs)) (car funs)))) - (if pr (geiser-autodoc--fun-args-str (car pr) - (cdr geiser-autodoc--last) - (cdr pr)) - (setq geiser-autodoc--last-funs funs) - (geiser-eval--send - `(:eval ((:ge arguments) ,@(mapcar (lambda (f) (list 'quote (car f))) funs))) - 'geiser-autodoc--function-args-cont) - "")))) - -(defun geiser-autodoc--function-args-cont (ret) - (let ((result (geiser-eval--retort-result ret))) - (when (and result (listp result)) - (setq geiser-autodoc--last result) - (let* ((pos (or (cdr (assoc (car result) geiser-autodoc--last-funs)) 0)) - (msg (geiser-autodoc--fun-args-str (car result) (cdr result) pos))) - (when msg (eldoc-message msg)))))) - -(defun geiser-autodoc--insert (sym current pos) - (let ((str (format "%s" sym))) +(defun geiser-autodoc--function-args (form) + (if (equal (car geiser-autodoc--last) form) (cdr geiser-autodoc--last) + (when form + (let ((res (geiser-eval--send/result + `(:eval ((:ge autodoc) (quote (:scm ,form))))))) + (when (and res (listp res)) + (setq geiser-autodoc--last + (cons form + (geiser-autodoc--str (cdr (assoc 'signature res)) + (or (cdr (assoc 'position res)) 0) + (cdr (assoc 'module res))))) + (cdr geiser-autodoc--last)))))) + +(defun geiser-autodoc--insert-arg (arg current pos) + (let ((str (format "%s" arg))) (when (= current pos) (put-text-property 0 (length str) 'face 'geiser-font-lock-autodoc-current-arg str)) (insert str))) -(defun geiser-autodoc--fun-args-str (fun args pos) - (when fun +(defun geiser-autodoc--insert-args (arg args current pos) + (when arg + (geiser-autodoc--insert-arg arg current pos) + (cond ((null args) (insert ")")) + ((listp args) + (insert " ") + (geiser-autodoc--insert-args (car args) (cdr args) (1+ current) pos)) + (t (insert " . ") + (geiser-autodoc--insert-args args nil (1+ current) pos))))) + +(defun geiser-autodoc--str (signature pos module) + (when signature (save-current-buffer (set-buffer (geiser-syntax--font-lock-buffer)) (erase-buffer) - (let* ((current 0) - (module (and geiser-autodoc-display-module-p - (cdr (assoc 'module args)))) - (fun (if module - (format geiser-autodoc-procedure-name-format module fun) - fun))) - (insert "(") - (geiser-autodoc--insert fun current pos) - (dolist (arg (cdr (assoc 'required args))) - (setq current (1+ current)) - (insert " ") - (geiser-autodoc--insert arg current pos)) - (setq current (1+ current)) - (when (cdr (assoc 'optional args)) - (when (> pos current) (setq current pos)) - (insert " . ") - (geiser-autodoc--insert (cdr (assoc 'optional args)) current pos)) - (insert ")") + (let ((proc (car signature)) + (args (cdr signature))) + (insert (format "(%s " + (if module + (format geiser-autodoc-procedure-name-format module proc) + proc))) + (if args + (if (listp args) + (geiser-autodoc--insert-args (car args) (cdr args) 1 pos) + (insert ". ") + (geiser-autodoc--insert-arg args 1 1) + (insert ")")) + (delete-char -1) + (insert ")")) (buffer-string))))) ;;; Autodoc function: (defun geiser-autodoc--eldoc-function () - (or (geiser-autodoc--function-args (geiser-syntax--enclosing-form-data)) "")) + (condition-case e + (or (geiser-autodoc--function-args (geiser-syntax--get-partial-sexp t)) "") + (error (format "Autodoc not available (%s)" (error-message-string e))))) ;;; Autodoc mode: diff --git a/elisp/geiser-syntax.el b/elisp/geiser-syntax.el index 2025f3d..c8ad338 100644 --- a/elisp/geiser-syntax.el +++ b/elisp/geiser-syntax.el @@ -55,27 +55,47 @@ (geiser-popup--define syntax " *geiser syntax analyst*" scheme-mode) -(defun geiser-syntax--complete-partial-sexp (buffer begin end) +(defun geiser-syntax--prepare-scheme-for-elisp-reader () + (goto-char (point-min)) + (while (re-search-forward "#\<\\([^>]*?\\)\>" nil t) + (let ((from (match-beginning 1)) + (to (match-end 1))) + (goto-char from) + (while (re-search-forward "\\([() ;'`]\\)" to t) + (replace-match "\\\\\\1")) + (goto-char to))) + (goto-char (point-min)) + (while (re-search-forward "#(" nil t) (replace-match "(vector ")) + (goto-char (point-min)) + (while (re-search-forward "#" nil t) (replace-match "\\\\#")) + (goto-char (point-min)) + (skip-syntax-forward "^(")) + +(defun geiser-syntax--complete-partial-sexp (buffer begin end &optional str) (set-buffer buffer) (let ((inhibit-read-only t)) (copy-to-buffer (geiser-syntax--buffer) begin end)) (geiser-syntax--with-buffer (goto-char (point-max)) - (skip-syntax-backward "-") + (skip-syntax-backward "-<>") + (kill-region (point) (point-max)) (let ((pps (parse-partial-sexp (point-min) (point)))) - (cond ((nth 8 pps) ;; inside a comment or string - (delete-region (nth 8 pps) (point-max))) - ((nth 5 pps) (delete-char -1))) ;; after a quote - (let ((depth (nth 0 pps))) - (unless (zerop depth) (insert (make-string depth ?\))))) + (when (nth 8 pps) ;; inside a comment or string + (delete-region (nth 8 pps) (point-max)))) + (cond ((eq (char-after (1- (point))) ?\)) (kill-sexp -1) (insert "XXpointXX")) + ((eq (char-after (point)) ?\() (kill-sexp 1) (insert "XXpointXX"))) + (let ((depth (nth 0 (parse-partial-sexp (point-min) (point))))) + (unless (zerop depth) (insert (make-string depth ?\))))) + (if str + (buffer-string) (geiser-syntax--prepare-scheme-for-elisp-reader) (read (current-buffer))))) -(defsubst geiser-syntax--get-partial-sexp () - (save-excursion - (let* ((begin (point)) - (end (progn (beginning-of-defun) (point)))) - (geiser-syntax--complete-partial-sexp (current-buffer) begin end)))) +(defsubst geiser-syntax--get-partial-sexp (&optional str) + (unless (zerop (nth 0 (syntax-ppss))) + (let* ((end (save-excursion (skip-syntax-forward "^-()") (point))) + (begin (save-excursion (beginning-of-defun) (point)))) + (geiser-syntax--complete-partial-sexp (current-buffer) begin end str)))) (defun geiser-syntax--collect-local-symbols (sexp acc) (cond ((or (null sexp) (not (listp sexp))) acc) @@ -100,52 +120,6 @@ (mapcar 'symbol-name (geiser-syntax--collect-local-symbols (geiser-syntax--get-partial-sexp) '())))) -(defsubst geiser-syntax--end-of-thing () - (let ((sc (or (syntax-class (syntax-after (point))) 0))) - (when (= sc 7) (forward-char)) - (cond ((nth 3 (syntax-ppss)) - (skip-syntax-forward "^\"") - (forward-char)) - ((and (= sc 5) (eq ?\( (char-before))) (forward-char)) - ((not (or (= sc 0) (= sc 12))) ;; comment, whitespace - (ignore-errors (forward-sexp)))) - (point))) - -(defun geiser-syntax--enclosing-form-data () - (save-excursion - (let* ((p (geiser-syntax--end-of-thing)) - (current (cons (symbol-at-point) 0)) - (data)) - (ignore-errors - (while (not (bobp)) - (backward-up-list) - (save-excursion - (forward-char) - (let ((proc (symbol-at-point)) - (arg-no 0)) - (when proc - (while (< (point) p) - (forward-sexp) - (when (< (point) p) (setq arg-no (1+ arg-no)))) - (push (cons proc arg-no) data)))))) - (reverse (if (car current) (push current data) data))))) - -(defun geiser-syntax--prepare-scheme-for-elisp-reader () - (goto-char (point-min)) - (while (re-search-forward "#\<\\([^>]*?\\)\>" nil t) - (let ((from (match-beginning 1)) - (to (match-end 1))) - (goto-char from) - (while (re-search-forward "\\([() ;'`]\\)" to t) - (replace-match "\\\\\\1")) - (goto-char to))) - (goto-char (point-min)) - (while (re-search-forward "#(" nil t) (replace-match "(vector ")) - (goto-char (point-min)) - (while (re-search-forward "#" nil t) (replace-match "\\\\#")) - (goto-char (point-min)) - (skip-syntax-forward "^(")) - ;;; Fontify strings as Scheme code: -- cgit v1.2.3