From 7fad7a69914a920774fd2ce766198ecbd25265bc Mon Sep 17 00:00:00 2001 From: Jose Antonio Ortega Ruiz Date: Tue, 16 Jun 2009 22:35:21 +0200 Subject: Better parsing of scheme retorts in the Emacs end. --- elisp/geiser-syntax.el | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) (limited to 'elisp/geiser-syntax.el') diff --git a/elisp/geiser-syntax.el b/elisp/geiser-syntax.el index 14d996c..c70aacb 100644 --- a/elisp/geiser-syntax.el +++ b/elisp/geiser-syntax.el @@ -89,23 +89,10 @@ (goto-char (point-max)) (and (re-search-backward "(output \\. \"" nil t) (point))))) - (goto-char (point-min)) - (while (re-search-forward "#\<\\([^>]*?\\)\>" end t) - (let ((from (match-beginning 1)) - (to (match-end 1))) - (goto-char from) - (while (re-search-forward "\\([ ;'`]\\)" to t) - (replace-match "\\\\\\1")) - (goto-char from) - (while (re-search-forward "[()]" to t) - (replace-match "")) - (goto-char to))) - (goto-char (point-min)) - (while (re-search-forward "#(" end t) (replace-match "(vector ")) - (goto-char (point-min)) - (while (re-search-forward "#" end t) (replace-match "\\\\#")) - (goto-char (point-min)) - (skip-syntax-forward "^("))) + (save-excursion + (while (re-search-forward "#(" end t) (replace-match "(vector ")) + (goto-char (point-min)) + (while (re-search-forward "#" end t) (replace-match "\\\\#"))))) (defsubst geiser-syntax--del-sexp (arg) (let ((p (point))) -- cgit v1.2.3 From bdd12279d05fd5451b186d2da9f1a864f1d1a0f9 Mon Sep 17 00:00:00 2001 From: Jose Antonio Ortega Ruiz Date: Thu, 2 Jul 2009 05:29:04 +0200 Subject: Simpler, nicer, more efficient handling of evaluation results. It comes with a pony too. --- elisp/geiser-connection.el | 1 - elisp/geiser-debug.el | 10 +++++++--- elisp/geiser-eval.el | 9 ++++++++- elisp/geiser-syntax.el | 10 ---------- 4 files changed, 15 insertions(+), 15 deletions(-) (limited to 'elisp/geiser-syntax.el') diff --git a/elisp/geiser-connection.el b/elisp/geiser-connection.el index 0ec6405..4f8592b 100644 --- a/elisp/geiser-connection.el +++ b/elisp/geiser-connection.el @@ -165,7 +165,6 @@ (goto-char (point-min)) (re-search-forward "((\\(result\\|error\\)\\>") (goto-char (match-beginning 0)) - (geiser-syntax--prepare-scheme-for-elisp-reader) (let ((form (read (current-buffer)))) (if (listp form) form (error)))) (error `((error (key . geiser-con-error)) diff --git a/elisp/geiser-debug.el b/elisp/geiser-debug.el index ec2e93e..6d795df 100644 --- a/elisp/geiser-debug.el +++ b/elisp/geiser-debug.el @@ -59,7 +59,7 @@ ;;; Displaying retorts -(defun geiser-debug--display-retort (what ret) +(defun geiser-debug--display-retort (what ret &optional res) (let* ((err (geiser-eval--retort-error ret)) (key (geiser-eval--error-key err)) (output (geiser-eval--retort-output ret)) @@ -69,6 +69,9 @@ (erase-buffer) (insert what) (newline 2) + (when res + (insert res) + (newline 2)) (unless (geiser-impl--display-error impl module key output) (when err (insert (geiser-eval--error-str err) "\n\n")) (when output (insert output "\n\n"))) @@ -88,10 +91,11 @@ (wrapped (if wrap (geiser-debug--wrap-region str) str)) (code `(,(if compile :comp :eval) (:scm ,wrapped))) (ret (geiser-eval--send/wait code)) + (res (geiser-eval--retort-result-str ret)) (err (geiser-eval--retort-error ret))) (when and-go (funcall and-go)) - (when (not err) (message (format "=> %S" (geiser-eval--retort-result ret)))) - (geiser-debug--display-retort str ret))) + (when (not err) (message "%s" res)) + (geiser-debug--display-retort str ret res))) (defun geiser-debug--expand-region (start end all wrap) (let* ((str (buffer-substring-no-properties start end)) diff --git a/elisp/geiser-eval.el b/elisp/geiser-eval.el index 90be67c..428d057 100644 --- a/elisp/geiser-eval.el +++ b/elisp/geiser-eval.el @@ -145,7 +145,14 @@ EVAL, COMPILE, LOAD-FILE and COMPILE-FILE should be supported.")) (defun geiser-eval--retort-result (ret) (let ((values (cdr (assoc 'result ret)))) - (if (> (length values) 1) (cons :values values) (car values)))) + (and (stringp (car values)) + (ignore-errors (car (read-from-string (car values))))))) + +(defun geiser-eval--retort-result-str (ret) + (let ((values (cdr (assoc 'result ret)))) + (if values + (concat "=> " (mapconcat 'identity values "\n=> ")) + "(No value)")))) (defsubst geiser-eval--retort-output (ret) (cdr (assoc 'output ret))) (defsubst geiser-eval--retort-error (ret) (cdr (assoc 'error ret))) diff --git a/elisp/geiser-syntax.el b/elisp/geiser-syntax.el index c70aacb..db1c842 100644 --- a/elisp/geiser-syntax.el +++ b/elisp/geiser-syntax.el @@ -84,16 +84,6 @@ (geiser-popup--define syntax " *geiser syntax analyst*" scheme-mode) -(defun geiser-syntax--prepare-scheme-for-elisp-reader () - (let ((end (save-excursion - (goto-char (point-max)) - (and (re-search-backward "(output \\. \"" nil t) - (point))))) - (save-excursion - (while (re-search-forward "#(" end t) (replace-match "(vector ")) - (goto-char (point-min)) - (while (re-search-forward "#" end t) (replace-match "\\\\#"))))) - (defsubst geiser-syntax--del-sexp (arg) (let ((p (point))) (forward-sexp arg) -- cgit v1.2.3 From f4b4ba80ce66f7ae21d436103b6bc8262d211305 Mon Sep 17 00:00:00 2001 From: Jose Antonio Ortega Ruiz Date: Mon, 17 Aug 2009 04:18:02 +0200 Subject: Simpler, more correct and efficient autodoc implementation. Not that it was difficult: it's replacing an ugly kludge. --- elisp/geiser-autodoc.el | 148 ++++++++++++++++++++++++------------------------ elisp/geiser-syntax.el | 27 +++++++++ 2 files changed, 102 insertions(+), 73 deletions(-) (limited to 'elisp/geiser-syntax.el') diff --git a/elisp/geiser-autodoc.el b/elisp/geiser-autodoc.el index 1225f87..16ca9ac 100644 --- a/elisp/geiser-autodoc.el +++ b/elisp/geiser-autodoc.el @@ -46,14 +46,6 @@ 'font-lock-function-name-face geiser-autodoc "highlighting procedure name in autodoc messages") -(geiser-custom--defface autodoc-optional-arg-marker - 'font-lock-keyword-face - geiser-autodoc "highlighting #:opt marker in autodoc messages") - -(geiser-custom--defface autodoc-key-arg-marker - 'font-lock-keyword-face - geiser-autodoc "highlighting #:key marker in autodoc messages") - (defcustom geiser-autodoc-delay 0.3 "Delay before autodoc messages are fetched and displayed, in seconds." :type 'number @@ -74,82 +66,92 @@ when `geiser-autodoc-display-module-p' is on." ;;; Procedure arguments: (make-variable-buffer-local - (defvar geiser-autodoc--last nil)) - -(make-variable-buffer-local - (defvar geiser-autodoc--last-result nil)) - -(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)))) - 500))) - (when (and res (listp res)) - (unless (equalp res geiser-autodoc--last-result) - (setq geiser-autodoc--last-result 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 ((p (point)) - (str (format "%s" (cond ((eq arg 'geiser-rest_marker) ".") - ((eq arg 'geiser-opt_marker) "#:opt") - ((eq arg 'geiser-key_marker) "#:key") - (t arg)))) - (face (cond ((eq 'geiser-opt_marker arg) - 'geiser-font-lock-autodoc-optional-arg-marker) - ((eq 'geiser-key_marker arg) - 'geiser-font-lock-autodoc-key-arg-marker) - ((= current pos) - 'geiser-font-lock-autodoc-current-arg) - (t nil)))) - (insert str) - (when (listp arg) - (save-excursion - (replace-regexp "(quote \\(.*\\))" "'\\1" nil p (point)) - (replace-string "nil" "()" t p (point)))) - (when face (put-text-property p (point) 'face face)))) + (defvar geiser-autodoc--cached-signatures nil)) + +(defun geiser-autodoc--get-signatures (funs) + (when funs + (let ((missing) (cached)) + (if (not geiser-autodoc--cached-signatures) + (setq missing funs) + (dolist (f funs) + (let ((cf (assq f geiser-autodoc--cached-signatures))) + (if cf (push cf cached) + (push f missing))))) + (unless cached + (setq geiser-autodoc--cached-signatures nil)) + (if (not missing) + geiser-autodoc--cached-signatures + (let ((res (geiser-eval--send/result `(:eval ((:ge autodoc) + (quote ,missing))) + 500))) + (when res + (setq geiser-autodoc--cached-signatures (append cached res)))))))) + +(defun geiser-autodoc--insert-args (args current &optional pos) + (dolist (a args) + (let ((p (point))) + (insert (format "%s" a)) + (when (or (and (numberp pos) + (numberp current) + (setq current (1+ current)) + (= (1+ pos) current)) + (and (symbolp current) + (listp a) + (eq current (car a)))) + (put-text-property p (point) 'face 'geiser-font-lock-autodoc-current-arg) + (setq pos nil current nil))) + (insert " ")) + (when args (backward-char)) + current) (defsubst geiser-autodoc--proc-name (proc module) (let ((str (if module (format geiser-autodoc-procedure-name-format module proc) proc))) - (put-text-property 0 (length str) - 'face 'geiser-font-lock-autodoc-procedure-name - str) - str)) - -(defun geiser-autodoc--str (signature pos module) - (when (consp signature) - (let* ((proc (car signature)) - (args (cdr signature)) - (len (if (listp args) (length args) 0)) - (current 1) - (pos (if (> pos len) len pos))) - (if (eq args 'variable) - (geiser-autodoc--proc-name proc module) - (save-current-buffer - (set-buffer (geiser-syntax--font-lock-buffer)) - (erase-buffer) - (insert (format "(%s" (geiser-autodoc--proc-name proc module))) - (dolist (a args) - (insert " ") - (geiser-autodoc--insert-arg a current pos) - (setq current (1+ current))) - (insert ")") - (buffer-string)))))) + (propertize str 'face 'geiser-font-lock-autodoc-procedure-name))) + +(defun geiser-autodoc--str (proc desc signature) + ;; (message "composing %s with desc %s and signature %s" proc desc signature) + (let ((cpos 1) + (pos (second desc)) + (prev (third desc)) + (module (cdr (assoc 'module signature))) + (reqs (cdr (assoc 'required signature))) + (opts (cdr (assoc 'optional signature))) + (keys (cdr (assoc 'key signature)))) + (save-current-buffer + (set-buffer (geiser-syntax--font-lock-buffer)) + (erase-buffer) + (insert (format "(%s " (geiser-autodoc--proc-name proc module))) + (setq cpos + (geiser-autodoc--insert-args reqs cpos (and (not (zerop pos)) pos))) + (when opts + (insert " [") + (setq cpos (geiser-autodoc--insert-args opts cpos pos)) + (when keys + (insert " [") + (geiser-autodoc--insert-args keys prev nil) + (insert "]")) + (insert "]")) + (insert ")") + (buffer-string)))) + +(defun geiser-autodoc--autodoc (path) + (let* ((funs (nreverse (mapcar 'car path))) + (signs (geiser-autodoc--get-signatures funs))) + (when signs + (catch 'signature + (dolist (f funs) + (let ((signature (cdr (assq f signs)))) + (when signature + (throw 'signature (geiser-autodoc--str f (assq f path) signature))))))))) ;;; Autodoc function: (defun geiser-autodoc--eldoc-function () (condition-case e - (geiser-autodoc--function-args (geiser-syntax--get-partial-sexp)) + (geiser-autodoc--autodoc (geiser-syntax--scan-sexps)) (error (format "Autodoc not available (%s)" (error-message-string e))))) diff --git a/elisp/geiser-syntax.el b/elisp/geiser-syntax.el index db1c842..475a556 100644 --- a/elisp/geiser-syntax.el +++ b/elisp/geiser-syntax.el @@ -94,6 +94,33 @@ (defsubst geiser-syntax--beginning-of-form () (memq (char-after (point)) '(?\" ?\())) +(defun geiser-syntax--scan-sexp () + (let ((p (point)) + (n -1) + prev + head) + (ignore-errors + (backward-up-list) + (save-excursion + (forward-char) + (skip-syntax-forward "^_w" p) + (when (setq head (symbol-at-point)) + (while (< (point) p) + (setq n (1+ n)) + (setq prev (symbol-at-point)) + (forward-sexp)))) + (if head (list head n prev) 'skip)))) + +(defun geiser-syntax--scan-sexps () + (save-excursion + (goto-char (or (nth 8 (syntax-ppss)) (point))) + (let* ((sap (symbol-at-point)) + (path (and sap `((,sap 0)))) + s) + (while (setq s (geiser-syntax--scan-sexp)) + (when (listp s) (push s path))) + path))) + (defun geiser-syntax--complete-partial-sexp (buffer begin end) (geiser-syntax--with-buffer (erase-buffer) -- cgit v1.2.3 From 0377f2e81a24640a7ab8aaef7d36fe31cb13ce71 Mon Sep 17 00:00:00 2001 From: Jose Antonio Ortega Ruiz Date: Mon, 17 Aug 2009 16:23:45 +0200 Subject: Well, i said that it was better, not that it was perfect. Autodoc buglets and support for displaying module variables too. --- elisp/geiser-autodoc.el | 54 ++++++++++++++++++++++++------------------------- elisp/geiser-doc.el | 5 ++++- elisp/geiser-syntax.el | 20 +++++++++--------- 3 files changed, 42 insertions(+), 37 deletions(-) (limited to 'elisp/geiser-syntax.el') diff --git a/elisp/geiser-autodoc.el b/elisp/geiser-autodoc.el index 16ca9ac..1d876dd 100644 --- a/elisp/geiser-autodoc.el +++ b/elisp/geiser-autodoc.el @@ -79,8 +79,7 @@ when `geiser-autodoc-display-module-p' is on." (push f missing))))) (unless cached (setq geiser-autodoc--cached-signatures nil)) - (if (not missing) - geiser-autodoc--cached-signatures + (if (not missing) geiser-autodoc--cached-signatures (let ((res (geiser-eval--send/result `(:eval ((:ge autodoc) (quote ,missing))) 500))) @@ -111,33 +110,34 @@ when `geiser-autodoc-display-module-p' is on." (propertize str 'face 'geiser-font-lock-autodoc-procedure-name))) (defun geiser-autodoc--str (proc desc signature) - ;; (message "composing %s with desc %s and signature %s" proc desc signature) - (let ((cpos 1) - (pos (second desc)) - (prev (third desc)) - (module (cdr (assoc 'module signature))) - (reqs (cdr (assoc 'required signature))) - (opts (cdr (assoc 'optional signature))) - (keys (cdr (assoc 'key signature)))) - (save-current-buffer - (set-buffer (geiser-syntax--font-lock-buffer)) - (erase-buffer) - (insert (format "(%s " (geiser-autodoc--proc-name proc module))) - (setq cpos - (geiser-autodoc--insert-args reqs cpos (and (not (zerop pos)) pos))) - (when opts - (insert " [") - (setq cpos (geiser-autodoc--insert-args opts cpos pos)) - (when keys - (insert " [") - (geiser-autodoc--insert-args keys prev nil) - (insert "]")) - (insert "]")) - (insert ")") - (buffer-string)))) + (let ((args (cdr (assoc 'args signature))) + (module (cdr (assoc 'module signature)))) + (if (not args) (geiser-autodoc--proc-name proc module) + (let ((cpos 1) + (pos (or (second desc) 0)) + (prev (third desc)) + (reqs (cdr (assoc 'required args))) + (opts (cdr (assoc 'optional args))) + (keys (cdr (assoc 'key args)))) + (save-current-buffer + (set-buffer (geiser-syntax--font-lock-buffer)) + (erase-buffer) + (insert (format "(%s " (geiser-autodoc--proc-name proc module))) + (setq cpos + (geiser-autodoc--insert-args reqs cpos (and (not (zerop pos)) pos))) + (when opts + (insert " [") + (setq cpos (geiser-autodoc--insert-args opts cpos pos)) + (when keys + (insert " [") + (geiser-autodoc--insert-args keys prev nil) + (insert "]")) + (insert "]")) + (insert ")") + (buffer-string)))))) (defun geiser-autodoc--autodoc (path) - (let* ((funs (nreverse (mapcar 'car path))) + (let* ((funs (mapcar 'car path)) (signs (geiser-autodoc--get-signatures funs))) (when signs (catch 'signature diff --git a/elisp/geiser-doc.el b/elisp/geiser-doc.el index adef4c6..61c50f5 100644 --- a/elisp/geiser-doc.el +++ b/elisp/geiser-doc.el @@ -26,6 +26,7 @@ (require 'geiser-impl) (require 'geiser-completion) +(require 'geiser-autodoc) (require 'geiser-eval) (require 'geiser-syntax) (require 'geiser-popup) @@ -174,7 +175,9 @@ (message "No documentation available for '%s'" symbol) (geiser-doc--with-buffer (erase-buffer) - (geiser-doc--insert-title (cdr (assoc 'signature ds))) + (geiser-doc--insert-title (geiser-autodoc--str (format "%s" symbol) + nil + (cdr (assoc 'signature ds)))) (newline) (insert (or (cdr (assoc 'docstring ds)) "")) (goto-line (point-min)) diff --git a/elisp/geiser-syntax.el b/elisp/geiser-syntax.el index 475a556..6cadf61 100644 --- a/elisp/geiser-syntax.el +++ b/elisp/geiser-syntax.el @@ -97,29 +97,31 @@ (defun geiser-syntax--scan-sexp () (let ((p (point)) (n -1) - prev - head) + prev head) (ignore-errors (backward-up-list) (save-excursion (forward-char) - (skip-syntax-forward "^_w" p) + (skip-syntax-forward "^_w(" p) (when (setq head (symbol-at-point)) (while (< (point) p) (setq n (1+ n)) (setq prev (symbol-at-point)) (forward-sexp)))) - (if head (list head n prev) 'skip)))) + (if head (list head n (and (> n 1) prev)) 'skip)))) (defun geiser-syntax--scan-sexps () (save-excursion (goto-char (or (nth 8 (syntax-ppss)) (point))) (let* ((sap (symbol-at-point)) - (path (and sap `((,sap 0)))) - s) - (while (setq s (geiser-syntax--scan-sexp)) - (when (listp s) (push s path))) - path))) + (fst (and sap (geiser-syntax--scan-sexp))) + (path (and fst + (cond ((not (listp fst)) `((,sap 0))) + ((eq sap (car fst)) (list fst)) + (t (list fst (list sap 0))))))) + (while (setq fst (geiser-syntax--scan-sexp)) + (when (listp fst) (push fst path))) + (nreverse path)))) (defun geiser-syntax--complete-partial-sexp (buffer begin end) (geiser-syntax--with-buffer -- cgit v1.2.3 From 5c7b3550e46cb6b29a65a77b656f89523ba3fc18 Mon Sep 17 00:00:00 2001 From: Jose Antonio Ortega Ruiz Date: Tue, 18 Aug 2009 06:16:57 +0200 Subject: Yet another deklugdification: locals scanning moved to elisp. ... and say goodbye to the ugly parse partial sexp, reducing not only sloppy code, but also duplication and data transfers. --- elisp/geiser-completion.el | 5 +-- elisp/geiser-syntax.el | 101 ++++++++++++++++++++++++--------------------- 2 files changed, 55 insertions(+), 51 deletions(-) (limited to 'elisp/geiser-syntax.el') diff --git a/elisp/geiser-completion.el b/elisp/geiser-completion.el index 799280e..28aef12 100644 --- a/elisp/geiser-completion.el +++ b/elisp/geiser-completion.el @@ -148,9 +148,8 @@ terminates a current completion." (defsubst geiser-completion--symbol-list (prefix) (delete-duplicates - (geiser-eval--send/result - `(:eval ((:ge completions) ,prefix - (quote (:scm ,(or (geiser-syntax--get-partial-sexp) "()")))))) + (append (mapcar (lambda (s) (format "%s" s)) (geiser-syntax--locals-around-point)) + (geiser-eval--send/result `(:eval ((:ge completions) ,prefix)))) :test 'string=)) (defsubst geiser-completion--module-list (prefix) diff --git a/elisp/geiser-syntax.el b/elisp/geiser-syntax.el index 6cadf61..6af04a1 100644 --- a/elisp/geiser-syntax.el +++ b/elisp/geiser-syntax.el @@ -84,15 +84,11 @@ (geiser-popup--define syntax " *geiser syntax analyst*" scheme-mode) -(defsubst geiser-syntax--del-sexp (arg) - (let ((p (point))) - (forward-sexp arg) - (delete-region p (point)))) +(defsubst geiser-syntax--skip-comment/string () + (goto-char (or (nth 8 (syntax-ppss)) (point)))) -(defconst geiser-syntax--placeholder (format "___%s___" (random 100))) - -(defsubst geiser-syntax--beginning-of-form () - (memq (char-after (point)) '(?\" ?\())) +(defsubst geiser-syntax--nesting-level () + (or (nth 0 (syntax-ppss)) 0)) (defun geiser-syntax--scan-sexp () (let ((p (point)) @@ -112,7 +108,7 @@ (defun geiser-syntax--scan-sexps () (save-excursion - (goto-char (or (nth 8 (syntax-ppss)) (point))) + (geiser-syntax--skip-comment/string) (let* ((sap (symbol-at-point)) (fst (and sap (geiser-syntax--scan-sexp))) (path (and fst @@ -123,46 +119,55 @@ (when (listp fst) (push fst path))) (nreverse path)))) -(defun geiser-syntax--complete-partial-sexp (buffer begin end) - (geiser-syntax--with-buffer - (erase-buffer) - (insert-buffer-substring-no-properties buffer begin end) - (when (not (geiser-syntax--beginning-of-form)) - (skip-syntax-backward "-<>") - (delete-region (point) (point-max))) - (let ((p (nth 8 (syntax-ppss)))) - (when p ;; inside a comment or string - (delete-region p (point-max)) - (insert geiser-syntax--placeholder))) - (when (cond ((eq (char-after (1- (point))) ?\)) - (geiser-syntax--del-sexp -1) t) - ((geiser-syntax--beginning-of-form) - (delete-region (point) (point-max)) t) - ((memq (char-after (1- (point))) (list ?. ?@ ?, ?\' ?\` ?\# ?\\)) - (skip-syntax-backward "^-(") - (delete-region (point) (point-max)) - t)) - (insert geiser-syntax--placeholder)) +(defun geiser-syntax--read-list (p) + (let ((list (ignore-errors (read (current-buffer))))) + (if (and list (< (point) p)) + list + (goto-char p) + nil))) + +(defconst geiser-syntax--delim-regexp "\\(?:[\s-\s<\s>$\n]+\\)") + +(defconst geiser-syntax--ident-regexp + (format "\\(?:%s\\([^ (]+?\\)\\)" geiser-syntax--delim-regexp)) + +(defconst geiser-syntax--let-regexp + (format "\\=(let\\(?:\\*\\|rec\\|%s\\|%s\\)%s*(" + geiser-syntax--ident-regexp + geiser-syntax--delim-regexp + geiser-syntax--delim-regexp)) + +(defconst geiser-syntax--ldefine-regexp + (format "\\=(define%s%s" geiser-syntax--ident-regexp geiser-syntax--delim-regexp)) + +(defconst geiser-syntax--define-regexp + (format "\\=(\\(?:define\\|lambda\\)%s(" geiser-syntax--delim-regexp)) + +(defun geiser-syntax--locals-around-point () + (when (eq major-mode 'scheme-mode) (save-excursion - (goto-char (point-min)) - (while (re-search-forward "[.@,'`#\\\\]" nil t) - (replace-match "" nil nil)) - (goto-char (point-min)) - (while (re-search-forward "\\[" nil t) - (replace-match "(" nil nil)) - (goto-char (point-min)) - (while (re-search-forward "\\]" nil t) - (replace-match ")" nil nil))) - (let ((depth (nth 0 (parse-partial-sexp (point-min) (point))))) - (unless (zerop depth) (insert (make-string depth ?\))))) - (when (< (point-min) (point)) (buffer-substring (point-min) (point))))) - -(defsubst geiser-syntax--get-partial-sexp () - (unless (zerop (nth 0 (syntax-ppss))) - (let* ((end (if (geiser-syntax--beginning-of-form) (1+ (point)) - (save-excursion (skip-syntax-forward "^-\"<>()") (point)))) - (begin (save-excursion (beginning-of-defun) (point)))) - (geiser-syntax--complete-partial-sexp (current-buffer) begin end)))) + (geiser-syntax--skip-comment/string) + (let ((ids)) + (while (not (zerop (geiser-syntax--nesting-level))) + (let ((p (point))) + (backward-up-list) + (save-excursion + (while (< (point) p) + (cond ((re-search-forward geiser-syntax--let-regexp p t) + (when (match-string 1) (push (intern (match-string 1)) ids)) + (backward-char 1) + (dolist (l (nreverse (geiser-syntax--read-list p))) + (when (and (listp l) (symbolp (car l))) + (push (car l) ids)))) + ((re-search-forward geiser-syntax--ldefine-regexp p t) + (when (match-string 1) (push (intern (match-string 1)) ids))) + ((re-search-forward geiser-syntax--define-regexp p t) + (backward-char 1) + (dolist (s (nreverse (geiser-syntax--read-list p))) + (let ((sn (if (listp s) (car s) s))) + (when (symbolp sn) (push sn ids))))) + (t (goto-char (1+ p)))))))) + (nreverse ids))))) ;;; Fontify strings as Scheme code: -- cgit v1.2.3 From 9187b776fdfbb73e0ea6ebe1d203ed2c838fbdbd Mon Sep 17 00:00:00 2001 From: Jose Antonio Ortega Ruiz Date: Thu, 20 Aug 2009 02:58:01 +0200 Subject: Bug fix: bogus regexp. --- elisp/geiser-syntax.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'elisp/geiser-syntax.el') diff --git a/elisp/geiser-syntax.el b/elisp/geiser-syntax.el index 6af04a1..38bb76c 100644 --- a/elisp/geiser-syntax.el +++ b/elisp/geiser-syntax.el @@ -126,7 +126,7 @@ (goto-char p) nil))) -(defconst geiser-syntax--delim-regexp "\\(?:[\s-\s<\s>$\n]+\\)") +(defconst geiser-syntax--delim-regexp "\\(?:[\\s-\\s<\\s>$\n]+\\)") (defconst geiser-syntax--ident-regexp (format "\\(?:%s\\([^ (]+?\\)\\)" geiser-syntax--delim-regexp)) -- cgit v1.2.3 From e0dd77a67b8e7c7d2d56aa353967249cc1e19f1e Mon Sep 17 00:00:00 2001 From: Jose Antonio Ortega Ruiz Date: Mon, 24 Aug 2009 03:22:12 +0200 Subject: Taking into account those ugly square brackets while scanning locals. --- elisp/geiser-syntax.el | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'elisp/geiser-syntax.el') diff --git a/elisp/geiser-syntax.el b/elisp/geiser-syntax.el index 38bb76c..789b6e9 100644 --- a/elisp/geiser-syntax.el +++ b/elisp/geiser-syntax.el @@ -119,29 +119,35 @@ (when (listp fst) (push fst path))) (nreverse path)))) +(defsubst geiser-syntax--listify (l &optional strict) + (cond ((vectorp l) (append l nil)) + ((listp l) l) + (strict nil) + (t l))) + (defun geiser-syntax--read-list (p) - (let ((list (ignore-errors (read (current-buffer))))) + (let ((list (geiser-syntax--listify (ignore-errors (read (current-buffer))) t))) (if (and list (< (point) p)) - list + (mapcar 'geiser-syntax--listify list) (goto-char p) nil))) -(defconst geiser-syntax--delim-regexp "\\(?:[\\s-\\s<\\s>$\n]+\\)") +(defconst geiser-syntax--delim-regexp "\\(?:\\s-\\|\\s<\\|\\s>\\|$\\|\n\\)+") (defconst geiser-syntax--ident-regexp - (format "\\(?:%s\\([^ (]+?\\)\\)" geiser-syntax--delim-regexp)) + (format "\\(?:%s\\([^[ (]+?\\)\\)" geiser-syntax--delim-regexp)) (defconst geiser-syntax--let-regexp - (format "\\=(let\\(?:\\*\\|rec\\|%s\\|%s\\)%s*(" + (format "\\=[[(]let\\(?:\\*\\|rec\\|%s\\|%s\\)%s*[[(]" geiser-syntax--ident-regexp geiser-syntax--delim-regexp geiser-syntax--delim-regexp)) (defconst geiser-syntax--ldefine-regexp - (format "\\=(define%s%s" geiser-syntax--ident-regexp geiser-syntax--delim-regexp)) + (format "\\=[[(]define%s%s" geiser-syntax--ident-regexp geiser-syntax--delim-regexp)) (defconst geiser-syntax--define-regexp - (format "\\=(\\(?:define\\|lambda\\)%s(" geiser-syntax--delim-regexp)) + (format "\\=[[(]\\(?:define\\|lambda\\)%s[[(]" geiser-syntax--delim-regexp)) (defun geiser-syntax--locals-around-point () (when (eq major-mode 'scheme-mode) -- cgit v1.2.3 From fb39ae2fcc37bd2f0b44b16627e99af7e7daecc6 Mon Sep 17 00:00:00 2001 From: Jose Antonio Ortega Ruiz Date: Thu, 27 Aug 2009 00:05:13 +0200 Subject: Better detection of locals (internal defines). - The implementation is still buggy, though, because it uses the elisp reader, which bails at some scheme syntaxes (e.g. chars) --- elisp/geiser-syntax.el | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'elisp/geiser-syntax.el') diff --git a/elisp/geiser-syntax.el b/elisp/geiser-syntax.el index 789b6e9..937107b 100644 --- a/elisp/geiser-syntax.el +++ b/elisp/geiser-syntax.el @@ -144,10 +144,13 @@ geiser-syntax--delim-regexp)) (defconst geiser-syntax--ldefine-regexp - (format "\\=[[(]define%s%s" geiser-syntax--ident-regexp geiser-syntax--delim-regexp)) + (format "[[(]define%s%s" geiser-syntax--ident-regexp geiser-syntax--delim-regexp)) (defconst geiser-syntax--define-regexp - (format "\\=[[(]\\(?:define\\|lambda\\)%s[[(]" geiser-syntax--delim-regexp)) + (format "[[(]\\(?:define\\)%s[[(]" geiser-syntax--delim-regexp)) + +(defconst geiser-syntax--lambda-regexp + (format "[[(]\\(?:lambda\\)%s[[(]" geiser-syntax--delim-regexp)) (defun geiser-syntax--locals-around-point () (when (eq major-mode 'scheme-mode) @@ -165,13 +168,21 @@ (dolist (l (nreverse (geiser-syntax--read-list p))) (when (and (listp l) (symbolp (car l))) (push (car l) ids)))) + ((looking-at geiser-syntax--ldefine-regexp) + (when (match-string 1) (push (intern (match-string 1)) ids)) + (goto-char (min p (match-end 0)))) + ((or (looking-at geiser-syntax--define-regexp) + (looking-at geiser-syntax--lambda-regexp)) + (goto-char (min p (1- (match-end 0)))) + (dolist (s (nreverse (geiser-syntax--read-list p))) + (let ((sn (if (listp s) (car s) s))) + (when (symbolp sn) (push sn ids))))) ((re-search-forward geiser-syntax--ldefine-regexp p t) (when (match-string 1) (push (intern (match-string 1)) ids))) ((re-search-forward geiser-syntax--define-regexp p t) (backward-char 1) - (dolist (s (nreverse (geiser-syntax--read-list p))) - (let ((sn (if (listp s) (car s) s))) - (when (symbolp sn) (push sn ids))))) + (let ((s (car (geiser-syntax--read-list p)))) + (when (symbolp s) (push s ids)))) (t (goto-char (1+ p)))))))) (nreverse ids))))) -- cgit v1.2.3 From abe824fdc168e3405426b2df47de4178eb3e4276 Mon Sep 17 00:00:00 2001 From: Jose Antonio Ortega Ruiz Date: Sun, 30 Aug 2009 11:19:09 +0200 Subject: Biting the bullet: a simple, permissive, scheme reader. Currently put to (let's hope, good) use for context parsing in autodoc and locals discovery (internal defines are recognised now). --- elisp/geiser-autodoc.el | 9 ++- elisp/geiser-syntax.el | 209 ++++++++++++++++++++++++++++-------------------- 2 files changed, 128 insertions(+), 90 deletions(-) (limited to 'elisp/geiser-syntax.el') diff --git a/elisp/geiser-autodoc.el b/elisp/geiser-autodoc.el index e00f6b6..75f2e7c 100644 --- a/elisp/geiser-autodoc.el +++ b/elisp/geiser-autodoc.el @@ -71,8 +71,7 @@ when `geiser-autodoc-display-module-p' is on." (defun geiser-autodoc--get-signatures (funs &optional keep-cached) (when funs (let ((fs (assq (car funs) geiser-autodoc--cached-signatures))) - (if fs - (list fs) + (unless fs (let ((missing) (cached)) (if (not geiser-autodoc--cached-signatures) (setq missing funs) @@ -88,8 +87,10 @@ when `geiser-autodoc-display-module-p' is on." 500))) (when res (setq geiser-autodoc--cached-signatures - (append res (if keep-cached geiser-autodoc--cached-signatures cached)))))) - geiser-autodoc--cached-signatures))))) + (append res (if keep-cached + geiser-autodoc--cached-signatures + cached)))))))) + geiser-autodoc--cached-signatures))) (defun geiser-autodoc--insert-args (args current &optional pos) (dolist (a args) diff --git a/elisp/geiser-syntax.el b/elisp/geiser-syntax.el index 937107b..5cfbc32 100644 --- a/elisp/geiser-syntax.el +++ b/elisp/geiser-syntax.el @@ -80,9 +80,89 @@ (with-syntax 1)) -;;; Code parsing: +;;; A simple scheme reader + +(defvar geiser-syntax--read/buffer-limit nil) + +(defsubst geiser-syntax--read/eos () + (or (eobp) + (and (numberp geiser-syntax--read/buffer-limit) + (<= geiser-syntax--read/buffer-limit (point))))) + +(defsubst geiser-syntax--read/next-char () + (unless (geiser-syntax--read/eos) + (forward-char) + (char-after))) + +(defsubst geiser-syntax--read/token (token) + (geiser-syntax--read/next-char) + (if (listp token) token (list token))) + +(defsubst geiser-syntax--read/elisp () + (ignore-errors (read (current-buffer)))) + +(defun geiser-syntax--read/next-token () + (skip-syntax-forward "->") + (if (geiser-syntax--read/eos) '(eob) + (let ((c (char-after))) + (cond ((not c) '(eob)) + ((eq c '\;) + (skip-syntax-forward "^>") + (geiser-syntax--read/next-token)) + ((memq c '(?\( ?\[)) (geiser-syntax--read/token 'lparen)) + ((memq c '(?\) ?\])) (geiser-syntax--read/token 'rparen)) + ((eq c ?.) + (if (memq (syntax-after (1+ (point))) '(0 11 12)) + (geiser-syntax--read/token 'dot) + (cons 'atom (geiser-syntax--read/elisp)))) + ((eq c ?\#) + (let ((c (geiser-syntax--read/next-char))) + (cond ((not c) '(eob)) + ((eq c ?\\) (cons 'char (geiser-syntax--read/elisp))) + ((eq c ?\() (geiser-syntax--read/token 'vectorb)) + (t (geiser-syntax--read/next-token))))) + ((eq c ?\') (geiser-syntax--read/token '(quote . quote))) + ((eq c ?\`) (geiser-syntax--read/token + `(backquote . ,backquote-backquote-symbol))) + ((eq c ?,) (if (eq (geiser-syntax--read/next-char) ?@) + (geiser-syntax--read/token + `(splice . ,backquote-splice-symbol)) + `(unquote . ,backquote-unquote-symbol))) + ((eq c ?\") (cons 'string (geiser-syntax--read/elisp))) + (t (cons 'atom (geiser-syntax--read/elisp))))))) + +(defsubst geiser-syntax--read/match (&rest tks) + (let ((token (geiser-syntax--read/next-token))) + (if (memq (car token) tks) token + (error "Unexpected token: %s" token)))) + +(defsubst geiser-syntax--read/try (&rest tks) + (let ((p (point)) + (tk (ignore-errors (apply 'geiser-syntax--read/match tks)))) + (unless tk (goto-char p)) + tk)) + +(defun geiser-syntax--read/list () + (cond ((geiser-syntax--read/try 'dot) + (let ((tail (geiser-syntax--read))) + (geiser-syntax--read/match 'eob 'rparen) + tail)) + ((geiser-syntax--read/try 'rparen 'eob) nil) + (t (cons (geiser-syntax--read) + (geiser-syntax--read/list))))) + +(defun geiser-syntax--read () + (let ((token (geiser-syntax--read/next-token))) + (case (car token) + (eob nil) + (lparen (geiser-syntax--read/list)) + (vectorb (apply 'vector (geiser-syntax--read/list))) + ((quote backquote unquote splice) (list (cdr token) (geiser-syntax--read))) + ((char string atom) (cdr token)) + (t (error "Reading scheme syntax: unexpected token: %s" token))))) -(geiser-popup--define syntax " *geiser syntax analyst*" scheme-mode) + +;;; Code parsing: (defsubst geiser-syntax--skip-comment/string () (goto-char (or (nth 8 (syntax-ppss)) (point)))) @@ -90,105 +170,62 @@ (defsubst geiser-syntax--nesting-level () (or (nth 0 (syntax-ppss)) 0)) -(defun geiser-syntax--scan-sexp () - (let ((p (point)) - (n -1) - prev head) - (ignore-errors - (backward-up-list) - (save-excursion - (forward-char) - (skip-syntax-forward "^_w(" p) - (when (setq head (symbol-at-point)) - (while (< (point) p) - (setq n (1+ n)) - (setq prev (symbol-at-point)) - (forward-sexp)))) - (if head (list head n (and (> n 1) prev)) 'skip)))) - (defun geiser-syntax--scan-sexps () (save-excursion - (geiser-syntax--skip-comment/string) - (let* ((sap (symbol-at-point)) - (fst (and sap (geiser-syntax--scan-sexp))) - (path (and fst - (cond ((not (listp fst)) `((,sap 0))) - ((eq sap (car fst)) (list fst)) - (t (list fst (list sap 0))))))) - (while (setq fst (geiser-syntax--scan-sexp)) - (when (listp fst) (push fst path))) + (let* ((fst (symbol-at-point)) + (path (and fst (list (list fst 0))))) + (while (not (zerop (geiser-syntax--nesting-level))) + (let ((geiser-syntax--read/buffer-limit (1+ (point)))) + (backward-up-list) + (let ((form (save-excursion (geiser-syntax--read)))) + (when (and (listp form) (car form) (symbolp (car form))) + (let* ((len-1 (1- (length form))) + (prev (and (> len-1 1) (nth (1- len-1) form)))) + (push `(,(car form) ,len-1 ,@(and prev (symbolp prev) (list prev))) + path)))))) (nreverse path)))) -(defsubst geiser-syntax--listify (l &optional strict) - (cond ((vectorp l) (append l nil)) - ((listp l) l) - (strict nil) - (t l))) - -(defun geiser-syntax--read-list (p) - (let ((list (geiser-syntax--listify (ignore-errors (read (current-buffer))) t))) - (if (and list (< (point) p)) - (mapcar 'geiser-syntax--listify list) - (goto-char p) - nil))) - -(defconst geiser-syntax--delim-regexp "\\(?:\\s-\\|\\s<\\|\\s>\\|$\\|\n\\)+") - -(defconst geiser-syntax--ident-regexp - (format "\\(?:%s\\([^[ (]+?\\)\\)" geiser-syntax--delim-regexp)) - -(defconst geiser-syntax--let-regexp - (format "\\=[[(]let\\(?:\\*\\|rec\\|%s\\|%s\\)%s*[[(]" - geiser-syntax--ident-regexp - geiser-syntax--delim-regexp - geiser-syntax--delim-regexp)) - -(defconst geiser-syntax--ldefine-regexp - (format "[[(]define%s%s" geiser-syntax--ident-regexp geiser-syntax--delim-regexp)) - -(defconst geiser-syntax--define-regexp - (format "[[(]\\(?:define\\)%s[[(]" geiser-syntax--delim-regexp)) - -(defconst geiser-syntax--lambda-regexp - (format "[[(]\\(?:lambda\\)%s[[(]" geiser-syntax--delim-regexp)) - (defun geiser-syntax--locals-around-point () (when (eq major-mode 'scheme-mode) (save-excursion (geiser-syntax--skip-comment/string) - (let ((ids)) + (let* ((ids) + (push-id (lambda (n) (when (symbolp n) (push n ids)))) + (get-arg (lambda (n) (if (listp n) (car n) n))) + (push-ids (lambda (is) (mapc push-id (nreverse (mapcar get-arg is)))))) (while (not (zerop (geiser-syntax--nesting-level))) - (let ((p (point))) + (let ((geiser-syntax--read/buffer-limit (point))) (backward-up-list) - (save-excursion - (while (< (point) p) - (cond ((re-search-forward geiser-syntax--let-regexp p t) - (when (match-string 1) (push (intern (match-string 1)) ids)) - (backward-char 1) - (dolist (l (nreverse (geiser-syntax--read-list p))) - (when (and (listp l) (symbolp (car l))) - (push (car l) ids)))) - ((looking-at geiser-syntax--ldefine-regexp) - (when (match-string 1) (push (intern (match-string 1)) ids)) - (goto-char (min p (match-end 0)))) - ((or (looking-at geiser-syntax--define-regexp) - (looking-at geiser-syntax--lambda-regexp)) - (goto-char (min p (1- (match-end 0)))) - (dolist (s (nreverse (geiser-syntax--read-list p))) - (let ((sn (if (listp s) (car s) s))) - (when (symbolp sn) (push sn ids))))) - ((re-search-forward geiser-syntax--ldefine-regexp p t) - (when (match-string 1) (push (intern (match-string 1)) ids))) - ((re-search-forward geiser-syntax--define-regexp p t) - (backward-char 1) - (let ((s (car (geiser-syntax--read-list p)))) - (when (symbolp s) (push s ids)))) - (t (goto-char (1+ p)))))))) + (let* ((form (save-excursion (geiser-syntax--read))) + (head (and (listp form) (car form))) + (snd (and head (cadr form))) + (third (and head (caddr form))) + (is (case head + ((define define*) (if (listp snd) snd (list snd))) + ((let* letrec lambda let) + (if (listp snd) snd + (cons snd (and (eq head 'let) + (listp third) + third)))))) + (body (and is (case head + ((define define*) (and (listp snd) (cddr form))) + ((let let* letrec lambda) + (if (listp snd) (cddr form) + (cdddr form))))))) + (when is + (funcall push-ids + (mapcar 'cdr + (remove-if (lambda (f) (or (not (listp f)) + (not (eq (car f) 'define)))) + body))) + (funcall push-ids is))))) (nreverse ids))))) ;;; Fontify strings as Scheme code: +(geiser-popup--define syntax " *geiser syntax analyst*" scheme-mode) + (defun geiser-syntax--font-lock-buffer () (let ((name " *geiser font lock*")) (or (get-buffer name) -- cgit v1.2.3 From b3aaa30d9a655028d6b39c477f1b1a92a872415a Mon Sep 17 00:00:00 2001 From: Jose Antonio Ortega Ruiz Date: Sun, 30 Aug 2009 11:52:15 +0200 Subject: Tagging keywords as such in the scheme reader, for later spotting of active argument in autodoc. --- elisp/geiser-syntax.el | 59 +++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 27 deletions(-) (limited to 'elisp/geiser-syntax.el') diff --git a/elisp/geiser-syntax.el b/elisp/geiser-syntax.el index 5cfbc32..91993be 100644 --- a/elisp/geiser-syntax.el +++ b/elisp/geiser-syntax.el @@ -104,32 +104,32 @@ (defun geiser-syntax--read/next-token () (skip-syntax-forward "->") (if (geiser-syntax--read/eos) '(eob) - (let ((c (char-after))) - (cond ((not c) '(eob)) - ((eq c '\;) - (skip-syntax-forward "^>") - (geiser-syntax--read/next-token)) - ((memq c '(?\( ?\[)) (geiser-syntax--read/token 'lparen)) - ((memq c '(?\) ?\])) (geiser-syntax--read/token 'rparen)) - ((eq c ?.) - (if (memq (syntax-after (1+ (point))) '(0 11 12)) - (geiser-syntax--read/token 'dot) - (cons 'atom (geiser-syntax--read/elisp)))) - ((eq c ?\#) - (let ((c (geiser-syntax--read/next-char))) - (cond ((not c) '(eob)) - ((eq c ?\\) (cons 'char (geiser-syntax--read/elisp))) - ((eq c ?\() (geiser-syntax--read/token 'vectorb)) - (t (geiser-syntax--read/next-token))))) - ((eq c ?\') (geiser-syntax--read/token '(quote . quote))) - ((eq c ?\`) (geiser-syntax--read/token - `(backquote . ,backquote-backquote-symbol))) - ((eq c ?,) (if (eq (geiser-syntax--read/next-char) ?@) - (geiser-syntax--read/token - `(splice . ,backquote-splice-symbol)) - `(unquote . ,backquote-unquote-symbol))) - ((eq c ?\") (cons 'string (geiser-syntax--read/elisp))) - (t (cons 'atom (geiser-syntax--read/elisp))))))) + (case (char-after) + (\; + (skip-syntax-forward "^>") + (geiser-syntax--read/next-token)) + ((?\( ?\[) (geiser-syntax--read/token 'lparen)) + ((?\) ?\]) (geiser-syntax--read/token 'rparen)) + (?. (if (memq (syntax-after (1+ (point))) '(0 11 12)) + (geiser-syntax--read/token 'dot) + (cons 'atom (geiser-syntax--read/elisp)))) + (?\# (let ((c (geiser-syntax--read/next-char))) + (cond ((not c) '(eob)) + ((eq c ?:) + (if (geiser-syntax--read/next-char) + (cons 'kwd (geiser-syntax--read/elisp)) + '(eob))) + ((eq c ?\\) (cons 'char (geiser-syntax--read/elisp))) + ((eq c ?\() (geiser-syntax--read/token 'vectorb)) + (t (geiser-syntax--read/next-token))))) + (?\' (geiser-syntax--read/token '(quote . quote))) + (?\` (geiser-syntax--read/token + `(backquote . ,backquote-backquote-symbol))) + (?, (if (eq (geiser-syntax--read/next-char) ?@) + (geiser-syntax--read/token `(splice . ,backquote-splice-symbol)) + `(unquote . ,backquote-unquote-symbol))) + (?\" (cons 'string (geiser-syntax--read/elisp))) + (t (cons 'atom (geiser-syntax--read/elisp)))))) (defsubst geiser-syntax--read/match (&rest tks) (let ((token (geiser-syntax--read/next-token))) @@ -158,9 +158,13 @@ (lparen (geiser-syntax--read/list)) (vectorb (apply 'vector (geiser-syntax--read/list))) ((quote backquote unquote splice) (list (cdr token) (geiser-syntax--read))) + (kwd `(:keyword . ,(cdr token))) ((char string atom) (cdr token)) (t (error "Reading scheme syntax: unexpected token: %s" token))))) +(defsubst geiser-syntax--read/keyword-value (s) + (and (consp s) (eq (car s) :keyword) (cdr s))) + ;;; Code parsing: @@ -180,7 +184,8 @@ (let ((form (save-excursion (geiser-syntax--read)))) (when (and (listp form) (car form) (symbolp (car form))) (let* ((len-1 (1- (length form))) - (prev (and (> len-1 1) (nth (1- len-1) form)))) + (prev (and (> len-1 1) (nth (1- len-1) form))) + (prev (and prev (geiser-syntax--read/keyword-value prev)))) (push `(,(car form) ,len-1 ,@(and prev (symbolp prev) (list prev))) path)))))) (nreverse path)))) -- cgit v1.2.3 From 04630a92cf4a6a48cac29b7b4569c65158e57d26 Mon Sep 17 00:00:00 2001 From: Jose Antonio Ortega Ruiz Date: Sun, 30 Aug 2009 23:53:19 +0200 Subject: Improved local names detection (both implementation- and functional-wise). --- elisp/geiser-syntax.el | 66 +++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'elisp/geiser-syntax.el') diff --git a/elisp/geiser-syntax.el b/elisp/geiser-syntax.el index 91993be..13cab62 100644 --- a/elisp/geiser-syntax.el +++ b/elisp/geiser-syntax.el @@ -86,7 +86,7 @@ (defsubst geiser-syntax--read/eos () (or (eobp) - (and (numberp geiser-syntax--read/buffer-limit) + (and geiser-syntax--read/buffer-limit (<= geiser-syntax--read/buffer-limit (point))))) (defsubst geiser-syntax--read/next-char () @@ -165,6 +165,10 @@ (defsubst geiser-syntax--read/keyword-value (s) (and (consp s) (eq (car s) :keyword) (cdr s))) +(defsubst geiser-syntax--form-after-point (&optional boundary) + (let ((geiser-syntax--read/buffer-limit (and (numberp boundary) boundary))) + (save-excursion (values (geiser-syntax--read) (point))))) + ;;; Code parsing: @@ -179,9 +183,9 @@ (let* ((fst (symbol-at-point)) (path (and fst (list (list fst 0))))) (while (not (zerop (geiser-syntax--nesting-level))) - (let ((geiser-syntax--read/buffer-limit (1+ (point)))) + (let ((boundary (1+ (point)))) (backward-up-list) - (let ((form (save-excursion (geiser-syntax--read)))) + (let ((form (nth-value 0 (geiser-syntax--form-after-point boundary)))) (when (and (listp form) (car form) (symbolp (car form))) (let* ((len-1 (1- (length form))) (prev (and (> len-1 1) (nth (1- len-1) form))) @@ -190,41 +194,37 @@ path)))))) (nreverse path)))) +(defun geiser-syntax--scan-locals (form partial locals) + (flet ((if-symbol (x) (and (symbolp x) x)) + (if-list (x) (and (listp x) x)) + (normalize (vars) (mapcar (lambda (i) (if (listp i) (car i) i)) vars))) + (cond ((or (null form) (not (listp form))) (normalize locals)) + ((not (memq (car form) '(define let let* letrec lambda))) + (geiser-syntax--scan-locals (car (last form)) partial locals)) + (t + (let* ((head (car form)) + (name (if-symbol (cadr form))) + (names (if name (if-list (caddr form)) (if-list (cadr form)))) + (rest (if name (cdddr form) (cddr form))) + (use-names (or (eq head 'let*) (not partial) rest))) + (when name (push name locals)) + (when use-names (dolist (n names) (push n locals))) + (dolist (f (butlast rest)) + (when (eq (car f) 'define) (push (cadr f) locals))) + (geiser-syntax--scan-locals (car (last (or rest names))) + partial + locals)))))) + (defun geiser-syntax--locals-around-point () (when (eq major-mode 'scheme-mode) (save-excursion (geiser-syntax--skip-comment/string) - (let* ((ids) - (push-id (lambda (n) (when (symbolp n) (push n ids)))) - (get-arg (lambda (n) (if (listp n) (car n) n))) - (push-ids (lambda (is) (mapc push-id (nreverse (mapcar get-arg is)))))) + (let ((boundary (point))) (while (not (zerop (geiser-syntax--nesting-level))) - (let ((geiser-syntax--read/buffer-limit (point))) - (backward-up-list) - (let* ((form (save-excursion (geiser-syntax--read))) - (head (and (listp form) (car form))) - (snd (and head (cadr form))) - (third (and head (caddr form))) - (is (case head - ((define define*) (if (listp snd) snd (list snd))) - ((let* letrec lambda let) - (if (listp snd) snd - (cons snd (and (eq head 'let) - (listp third) - third)))))) - (body (and is (case head - ((define define*) (and (listp snd) (cddr form))) - ((let let* letrec lambda) - (if (listp snd) (cddr form) - (cdddr form))))))) - (when is - (funcall push-ids - (mapcar 'cdr - (remove-if (lambda (f) (or (not (listp f)) - (not (eq (car f) 'define)))) - body))) - (funcall push-ids is))))) - (nreverse ids))))) + (backward-up-list)) + (multiple-value-bind (form end) + (geiser-syntax--form-after-point boundary) + (geiser-syntax--scan-locals form (> end boundary) '())))))) ;;; Fontify strings as Scheme code: -- cgit v1.2.3 From fff6b102f88479f470d3d02a905674c594edb154 Mon Sep 17 00:00:00 2001 From: Jose Antonio Ortega Ruiz Date: Mon, 7 Sep 2009 00:17:12 +0200 Subject: Scheme reader improvements: #<>, #||# and other bits. --- elisp/geiser-syntax.el | 62 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 18 deletions(-) (limited to 'elisp/geiser-syntax.el') diff --git a/elisp/geiser-syntax.el b/elisp/geiser-syntax.el index 13cab62..ca218c8 100644 --- a/elisp/geiser-syntax.el +++ b/elisp/geiser-syntax.el @@ -101,32 +101,52 @@ (defsubst geiser-syntax--read/elisp () (ignore-errors (read (current-buffer)))) +(defun geiser-syntax--read/matching (open close) + (let ((count 1) + (p (1+ (point)))) + (while (and (> count 0) + (geiser-syntax--read/next-char)) + (cond ((looking-at-p open) (setq count (1+ count))) + ((looking-at-p close) (setq count (1- count))))) + (buffer-substring-no-properties p (point)))) + +(defsubst geiser-syntax--read/unprintable () + (geiser-syntax--read/token + (cons 'unprintable (geiser-syntax--read/matching "<" ">")))) + +(defun geiser-syntax--read/skip-comment () + (while (and (geiser-syntax--read/next-char) + (nth 8 (syntax-ppss)))) + (geiser-syntax--read/next-token)) + (defun geiser-syntax--read/next-token () (skip-syntax-forward "->") (if (geiser-syntax--read/eos) '(eob) (case (char-after) - (\; - (skip-syntax-forward "^>") - (geiser-syntax--read/next-token)) + (?\; (geiser-syntax--read/skip-comment)) ((?\( ?\[) (geiser-syntax--read/token 'lparen)) ((?\) ?\]) (geiser-syntax--read/token 'rparen)) (?. (if (memq (syntax-after (1+ (point))) '(0 11 12)) (geiser-syntax--read/token 'dot) (cons 'atom (geiser-syntax--read/elisp)))) - (?\# (let ((c (geiser-syntax--read/next-char))) - (cond ((not c) '(eob)) - ((eq c ?:) - (if (geiser-syntax--read/next-char) - (cons 'kwd (geiser-syntax--read/elisp)) - '(eob))) - ((eq c ?\\) (cons 'char (geiser-syntax--read/elisp))) - ((eq c ?\() (geiser-syntax--read/token 'vectorb)) - (t (geiser-syntax--read/next-token))))) + (?\# (case (geiser-syntax--read/next-char) + ('nil '(eob)) + (?| (geiser-syntax--read/skip-comment)) + (?: (if (geiser-syntax--read/next-char) + (cons 'kwd (geiser-syntax--read/elisp)) + '(eob))) + (?\\ (cons 'char (geiser-syntax--read/elisp))) + (?\( (geiser-syntax--read/token 'vectorb)) + (?\< (geiser-syntax--read/unprintable)) + (t (let ((tok (geiser-syntax--read/elisp))) + (if tok (cons 'atom (intern (format "#%s" tok))) + (geiser-syntax--read/next-token)))))) (?\' (geiser-syntax--read/token '(quote . quote))) (?\` (geiser-syntax--read/token `(backquote . ,backquote-backquote-symbol))) (?, (if (eq (geiser-syntax--read/next-char) ?@) - (geiser-syntax--read/token `(splice . ,backquote-splice-symbol)) + (geiser-syntax--read/token + `(splice . ,backquote-splice-symbol)) `(unquote . ,backquote-unquote-symbol))) (?\" (cons 'string (geiser-syntax--read/elisp))) (t (cons 'atom (geiser-syntax--read/elisp)))))) @@ -157,8 +177,10 @@ (eob nil) (lparen (geiser-syntax--read/list)) (vectorb (apply 'vector (geiser-syntax--read/list))) - ((quote backquote unquote splice) (list (cdr token) (geiser-syntax--read))) + ((quote backquote unquote splice) (list (cdr token) + (geiser-syntax--read))) (kwd `(:keyword . ,(cdr token))) + (unprintable (format "#<%s>" (cdr token))) ((char string atom) (cdr token)) (t (error "Reading scheme syntax: unexpected token: %s" token))))) @@ -185,12 +207,15 @@ (while (not (zerop (geiser-syntax--nesting-level))) (let ((boundary (1+ (point)))) (backward-up-list) - (let ((form (nth-value 0 (geiser-syntax--form-after-point boundary)))) + (let ((form + (nth-value 0 (geiser-syntax--form-after-point boundary)))) (when (and (listp form) (car form) (symbolp (car form))) (let* ((len-1 (1- (length form))) (prev (and (> len-1 1) (nth (1- len-1) form))) - (prev (and prev (geiser-syntax--read/keyword-value prev)))) - (push `(,(car form) ,len-1 ,@(and prev (symbolp prev) (list prev))) + (prev (and prev + (geiser-syntax--read/keyword-value prev)))) + (push `(,(car form) + ,len-1 ,@(and prev (symbolp prev) (list prev))) path)))))) (nreverse path)))) @@ -204,7 +229,8 @@ (t (let* ((head (car form)) (name (if-symbol (cadr form))) - (names (if name (if-list (caddr form)) (if-list (cadr form)))) + (names (if name (if-list (caddr form)) + (if-list (cadr form)))) (rest (if name (cdddr form) (cddr form))) (use-names (or (eq head 'let*) (not partial) rest))) (when name (push name locals)) -- cgit v1.2.3