]> gitweb.factorcode.org Git - factor.git/blob - misc/fuel/fuel-debug-uses.el
FUEL: Fix for autodoc in presence of <PRIVATE > sections.
[factor.git] / misc / fuel / fuel-debug-uses.el
1 ;;; fuel-debug-uses.el -- retrieving USING: stanzas
2
3 ;; Copyright (C) 2008 Jose Antonio Ortega Ruiz
4 ;; See http://factorcode.org/license.txt for BSD license.
5
6 ;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
7 ;; Keywords: languages, fuel, factor
8 ;; Start date: Tue Dec 23, 2008 04:23
9
10 ;;; Comentary:
11
12 ;; Support for getting and updating factor source vocabulary lists.
13
14 ;;; Code:
15
16 (require 'fuel-debug)
17 (require 'fuel-eval)
18 (require 'fuel-popup)
19 (require 'fuel-font-lock)
20 (require 'fuel-base)
21
22
23 \f
24 ;;; Customization:
25
26 (fuel-font-lock--defface fuel-font-lock-debug-missing-vocab
27   'font-lock-warning-face fuel-debug "missing vocabulary names")
28
29 (fuel-font-lock--defface fuel-font-lock-debug-unneeded-vocab
30   'font-lock-warning-face fuel-debug "unneeded vocabulary names")
31
32 (fuel-font-lock--defface fuel-font-lock-debug-uses-header
33   'bold fuel-debug "headers in Uses buffers")
34
35 (fuel-font-lock--defface fuel-font-lock-debug-uses-prompt
36   'italic fuel-debug "prompts in Uses buffers")
37
38 \f
39 ;;; Utility functions:
40
41 (defun fuel-debug--file-lines (file)
42   (when (file-readable-p file)
43     (with-current-buffer (find-file-noselect file)
44       (save-excursion
45         (goto-char (point-min))
46         (let ((lines) (in-usings))
47           (while (not (eobp))
48             (when (looking-at "^USING: ") (setq in-usings t))
49             (let ((line (substring-no-properties (thing-at-point 'line) 0 -1)))
50               (when in-usings (setq line (concat "! " line)))
51               (push line lines))
52             (when (and in-usings (looking-at ".*\\_<;\\_>")) (setq in-usings nil))
53             (forward-line))
54           (reverse lines))))))
55
56 (defun fuel-debug--highlight-names (names ref face)
57   (dolist (n names)
58     (when (not (member n ref))
59       (put-text-property 0 (length n) 'font-lock-face face n))))
60
61 (defun fuel-debug--uses-new-uses (file uses)
62   (pop-to-buffer (find-file-noselect file))
63   (goto-char (point-min))
64   (if (re-search-forward "^USING: " nil t)
65       (let ((begin (point))
66             (end (or (and (re-search-forward "\\_<;\\_>") (point)) (point))))
67         (kill-region begin end))
68     (re-search-forward "^IN: " nil t)
69     (beginning-of-line)
70     (open-line 2)
71     (insert "USING: "))
72   (let ((start (point)))
73     (insert (mapconcat 'substring-no-properties uses " ") " ;")
74     (fill-region start (point) nil)))
75
76 (defun fuel-debug--uses-filter (restarts)
77   (let ((result) (i 1) (rn 0))
78     (dolist (r restarts (reverse result))
79       (setq rn (1+ rn))
80       (when (string-match "Use the .+ vocabulary\\|Defer" r)
81         (push (list i rn r) result)
82         (setq i (1+ i))))))
83
84 \f
85 ;;; Retrieving USINGs:
86
87 (fuel-popup--define fuel-debug--uses-buffer
88   "*fuel uses*" 'fuel-debug-uses-mode)
89
90 (make-variable-buffer-local
91  (defvar fuel-debug--uses nil))
92
93 (make-variable-buffer-local
94  (defvar fuel-debug--uses-file nil))
95
96 (make-variable-buffer-local
97  (defvar fuel-debug--uses-restarts nil))
98
99 (defsubst fuel-debug--uses-insert-title ()
100   (insert "Infering USING: stanza for " fuel-debug--uses-file ".\n\n"))
101
102 (defun fuel-debug--uses-prepare (file)
103   (fuel--with-popup (fuel-debug--uses-buffer)
104     (setq fuel-debug--uses-file file
105           fuel-debug--uses nil
106           fuel-debug--uses-restarts nil)
107     (erase-buffer)
108     (fuel-debug--uses-insert-title)))
109
110 (defun fuel-debug--uses-clean ()
111   (setq fuel-debug--uses-file nil
112         fuel-debug--uses nil
113         fuel-debug--uses-restarts nil))
114
115 (defun fuel-debug--uses-for-file (file)
116   (let* ((lines (fuel-debug--file-lines file))
117          (cmd `(:fuel ((V{ ,@lines } fuel-get-uses)) t t)))
118     (fuel-debug--uses-prepare file)
119     (fuel--with-popup (fuel-debug--uses-buffer)
120       (insert "Asking Factor. Please, wait ...\n")
121       (fuel-eval--send cmd 'fuel-debug--uses-cont))
122     (fuel-popup--display (fuel-debug--uses-buffer))))
123
124 (defun fuel-debug--uses-cont (retort)
125   (let ((uses (fuel-eval--retort-result retort))
126         (err (fuel-eval--retort-error retort)))
127     (if uses (fuel-debug--uses-display uses)
128       (fuel-debug--uses-display-err retort))))
129
130 (defun fuel-debug--insert-vlist (title vlist)
131   (goto-char (point-max))
132   (insert title "\n\n  ")
133   (let ((i 0) (step 5))
134     (dolist (v vlist)
135       (setq i (1+ i))
136       (insert v)
137       (insert (if (zerop (mod i step)) "\n  " " ")))
138     (unless (zerop (mod i step)) (newline))
139     (newline)))
140
141 (defun fuel-debug--uses-display (uses)
142   (let* ((inhibit-read-only t)
143          (old (with-current-buffer (find-file-noselect fuel-debug--uses-file)
144                 (sort (fuel-syntax--find-usings t) 'string<)))
145          (new (sort uses 'string<)))
146     (erase-buffer)
147     (fuel-debug--uses-insert-title)
148     (if (equalp old new)
149         (progn
150           (insert "Current USING: is already fine!. Type 'q' to bury buffer.\n")
151           (fuel-debug--uses-clean))
152       (fuel-debug--highlight-names old new 'fuel-font-lock-debug-unneeded-vocab)
153       (fuel-debug--highlight-names new old 'fuel-font-lock-debug-missing-vocab)
154       (fuel-debug--insert-vlist "Current vocabulary list:" old)
155       (newline)
156       (fuel-debug--insert-vlist "Correct vocabulary list:" new)
157       (setq fuel-debug--uses new)
158       (insert "\nType 'y' to update your USING: to the new one.\n"))))
159
160 (defun fuel-debug--uses-display-err (retort)
161   (let* ((inhibit-read-only t)
162          (err (fuel-eval--retort-error retort))
163          (restarts (fuel-debug--uses-filter (fuel-eval--error-restarts err)))
164          (unique (= 1 (length restarts))))
165     (erase-buffer)
166     (fuel-debug--uses-insert-title)
167     (insert (fuel-eval--retort-output retort))
168     (newline)
169     (if (not restarts)
170         (insert "\nSorry, couldn't infer the vocabulary list.\n")
171       (setq fuel-debug--uses-restarts restarts)
172       (if unique (fuel-debug--uses-restart 1)
173         (insert "\nPlease, type the number of the desired vocabulary:\n\n")
174         (dolist (r restarts)
175           (insert (format " :%s %s\n" (first r) (third r))))))))
176
177 (defun fuel-debug--uses-update-usings ()
178   (interactive)
179   (let ((inhibit-read-only t))
180     (when (and fuel-debug--uses-file fuel-debug--uses)
181       (fuel-debug--uses-new-uses fuel-debug--uses-file fuel-debug--uses)
182       (message "USING: updated!")
183       (with-current-buffer (fuel-debug--uses-buffer)
184         (insert "\nDone!")
185         (fuel-debug--uses-clean)
186         (kill-buffer (current-buffer))))))
187
188 (defun fuel-debug--uses-restart (n)
189   (when (and (> n 0) (<= n (length fuel-debug--uses-restarts)))
190     (let* ((inhibit-read-only t)
191            (restart (format ":%s" (cadr (nth (1- n) fuel-debug--uses-restarts))))
192            (cmd `(:fuel ([ (:factor ,restart) ] fuel-with-autouse) t t)))
193       (setq fuel-debug--uses-restarts nil)
194       (insert "\nAsking Factor. Please, wait ...\n")
195       (fuel-eval--send cmd 'fuel-debug--uses-cont))))
196
197 \f
198 ;;; Fuel uses mode:
199
200 (defvar fuel-debug-uses-mode-map
201   (let ((map (make-keymap)))
202     (suppress-keymap map)
203     (dotimes (n 9)
204       (define-key map (vector (+ ?1 n))
205         `(lambda () (interactive) (fuel-debug--uses-restart ,(1+ n)))))
206     (define-key map "y" 'fuel-debug--uses-update-usings)
207     (define-key map "\C-c\C-c" 'fuel-debug--uses-update-usings)
208     map))
209
210 (defconst fuel-debug--uses-header-regex
211   (format "^%s.*$" (regexp-opt '("Infering USING: stanza for "
212                               "Current USING: is already fine!"
213                               "Current vocabulary list:"
214                               "Correct vocabulary list:"
215                               "Sorry, couldn't infer the vocabulary list."
216                               "Done!"))))
217
218 (defconst fuel-debug--uses-prompt-regex
219   (format "^%s" (regexp-opt '("Asking Factor. Please, wait ..."
220                               "Please, type the number of the desired vocabulary:"
221                               "Type 'y' to update your USING: to the new one."))))
222
223 (defconst fuel-debug--uses-font-lock-keywords
224   `((,fuel-debug--uses-header-regex . 'fuel-font-lock-debug-uses-header)
225     (,fuel-debug--uses-prompt-regex . 'fuel-font-lock-debug-uses-prompt)
226     (,fuel-debug--restart-regex (1 'fuel-font-lock-debug-restart-number)
227                                 (2 'fuel-font-lock-debug-restart-name))))
228
229 (defun fuel-debug-uses-mode ()
230   "A major mode for displaying Factor's USING: inference results."
231   (interactive)
232   (kill-all-local-variables)
233   (buffer-disable-undo)
234   (setq major-mode 'fuel-debug-uses-mode)
235   (setq mode-name "Fuel Uses:")
236   (set (make-local-variable 'font-lock-defaults)
237        '(fuel-debug--uses-font-lock-keywords t nil nil nil))
238   (use-local-map fuel-debug-uses-mode-map))
239
240 \f
241 (provide 'fuel-debug-uses)
242 ;;; fuel-debug-uses.el ends here