2008-12-15 17:44:13 -05:00
|
|
|
|
;;; fuel-completion.el -- completion utilities
|
|
|
|
|
|
2009-01-22 15:13:38 -05:00
|
|
|
|
;; Copyright (C) 2008, 2009 Jose Antonio Ortega Ruiz
|
2008-12-15 17:44:13 -05:00
|
|
|
|
;; See http://factorcode.org/license.txt for BSD license.
|
|
|
|
|
|
|
|
|
|
;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
|
|
|
|
|
;; Keywords: languages, fuel, factor
|
|
|
|
|
;; Start date: Sun Dec 14, 2008 21:17
|
|
|
|
|
|
|
|
|
|
;;; Comentary:
|
|
|
|
|
|
|
|
|
|
;; Code completion utilities.
|
|
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
|
|
|
|
(require 'fuel-base)
|
|
|
|
|
(require 'fuel-syntax)
|
|
|
|
|
(require 'fuel-eval)
|
|
|
|
|
(require 'fuel-log)
|
|
|
|
|
|
2009-02-05 04:28:57 -05:00
|
|
|
|
|
|
|
|
|
;;; Aux:
|
|
|
|
|
|
|
|
|
|
(defvar fuel-completion--minibuffer-map
|
|
|
|
|
(let ((map (make-keymap)))
|
|
|
|
|
(set-keymap-parent map minibuffer-local-completion-map)
|
|
|
|
|
(define-key map "?" 'self-insert-command)
|
|
|
|
|
map))
|
|
|
|
|
|
2008-12-15 17:44:13 -05:00
|
|
|
|
|
|
|
|
|
;;; Vocabs dictionary:
|
|
|
|
|
|
|
|
|
|
(defvar fuel-completion--vocabs nil)
|
|
|
|
|
|
|
|
|
|
(defun fuel-completion--vocabs (&optional reload)
|
|
|
|
|
(when (or reload (not fuel-completion--vocabs))
|
|
|
|
|
(fuel--respecting-message "Retrieving vocabs list")
|
|
|
|
|
(let ((fuel-log--inhibit-p t))
|
|
|
|
|
(setq fuel-completion--vocabs
|
|
|
|
|
(fuel-eval--retort-result
|
|
|
|
|
(fuel-eval--send/wait '(:fuel* (fuel-get-vocabs) "fuel" (:array)))))))
|
|
|
|
|
fuel-completion--vocabs)
|
|
|
|
|
|
2009-01-22 15:13:38 -05:00
|
|
|
|
(defun fuel-completion--read-vocab (&optional reload init-input history)
|
2009-02-05 04:28:57 -05:00
|
|
|
|
(let ((minibuffer-local-completion-map fuel-completion--minibuffer-map)
|
|
|
|
|
(vocabs (fuel-completion--vocabs reload)))
|
2009-01-22 15:13:38 -05:00
|
|
|
|
(completing-read "Vocab name: " vocabs nil nil init-input history)))
|
|
|
|
|
|
2008-12-17 18:49:01 -05:00
|
|
|
|
(defsubst fuel-completion--vocab-list (prefix)
|
|
|
|
|
(fuel-eval--retort-result
|
|
|
|
|
(fuel-eval--send/wait `(:fuel* (,prefix fuel-get-vocabs/prefix) t t))))
|
|
|
|
|
|
2008-12-15 20:09:18 -05:00
|
|
|
|
(defun fuel-completion--words (prefix vocabs)
|
|
|
|
|
(let ((vs (if vocabs (cons :array vocabs) 'f))
|
|
|
|
|
(us (or vocabs 't)))
|
2008-12-17 17:50:48 -05:00
|
|
|
|
(fuel-eval--retort-result
|
|
|
|
|
(fuel-eval--send/wait `(:fuel* (,prefix ,vs fuel-get-words) t ,us)))))
|
2008-12-15 17:44:13 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; Completions window handling, heavily inspired in slime's:
|
|
|
|
|
|
|
|
|
|
(defvar fuel-completion--comp-buffer "*Completions*")
|
|
|
|
|
|
|
|
|
|
(make-variable-buffer-local
|
|
|
|
|
(defvar fuel-completion--window-cfg nil
|
|
|
|
|
"Window configuration before we show the *Completions* buffer.
|
|
|
|
|
This is buffer local in the buffer where the completion is
|
|
|
|
|
performed."))
|
|
|
|
|
|
|
|
|
|
(make-variable-buffer-local
|
|
|
|
|
(defvar fuel-completion--completions-window nil
|
|
|
|
|
"The window displaying *Completions* after saving window configuration.
|
|
|
|
|
If this window is no longer active or displaying the completions
|
|
|
|
|
buffer then we can ignore `fuel-completion--window-cfg'."))
|
|
|
|
|
|
2008-12-18 11:31:52 -05:00
|
|
|
|
(defun fuel-completion--save-window-cfg ()
|
2008-12-15 17:44:13 -05:00
|
|
|
|
"Maybe save the current window configuration.
|
|
|
|
|
Return true if the configuration was saved."
|
|
|
|
|
(unless (or fuel-completion--window-cfg
|
|
|
|
|
(get-buffer-window fuel-completion--comp-buffer))
|
|
|
|
|
(setq fuel-completion--window-cfg
|
|
|
|
|
(current-window-configuration))
|
|
|
|
|
t))
|
|
|
|
|
|
|
|
|
|
(defun fuel-completion--delay-restoration ()
|
|
|
|
|
(add-hook 'pre-command-hook
|
2008-12-18 11:31:52 -05:00
|
|
|
|
'fuel-completion--maybe-restore-window-cfg
|
2008-12-15 17:44:13 -05:00
|
|
|
|
nil t))
|
|
|
|
|
|
2008-12-18 11:31:52 -05:00
|
|
|
|
(defun fuel-completion--forget-window-cfg ()
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(setq fuel-completion--window-cfg nil)
|
|
|
|
|
(setq fuel-completion--completions-window nil))
|
|
|
|
|
|
2008-12-18 11:31:52 -05:00
|
|
|
|
(defun fuel-completion--restore-window-cfg ()
|
2008-12-15 17:44:13 -05:00
|
|
|
|
"Restore the window config if available."
|
|
|
|
|
(remove-hook 'pre-command-hook
|
2008-12-18 11:31:52 -05:00
|
|
|
|
'fuel-completion--maybe-restore-window-cfg)
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(when (and fuel-completion--window-cfg
|
|
|
|
|
(fuel-completion--window-active-p))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-window-configuration fuel-completion--window-cfg))
|
|
|
|
|
(setq fuel-completion--window-cfg nil)
|
|
|
|
|
(when (buffer-live-p fuel-completion--comp-buffer)
|
|
|
|
|
(kill-buffer fuel-completion--comp-buffer))))
|
|
|
|
|
|
2008-12-18 11:31:52 -05:00
|
|
|
|
(defun fuel-completion--maybe-restore-window-cfg ()
|
2008-12-15 17:44:13 -05:00
|
|
|
|
"Restore the window configuration, if the following command
|
|
|
|
|
terminates a current completion."
|
|
|
|
|
(remove-hook 'pre-command-hook
|
2008-12-18 11:31:52 -05:00
|
|
|
|
'fuel-completion--maybe-restore-window-cfg)
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(condition-case err
|
|
|
|
|
(cond ((find last-command-char "()\"'`,# \r\n:")
|
2008-12-18 11:31:52 -05:00
|
|
|
|
(fuel-completion--restore-window-cfg))
|
2008-12-15 17:44:13 -05:00
|
|
|
|
((not (fuel-completion--window-active-p))
|
2008-12-18 11:31:52 -05:00
|
|
|
|
(fuel-completion--forget-window-cfg))
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(t (fuel-completion--delay-restoration)))
|
|
|
|
|
(error
|
|
|
|
|
;; Because this is called on the pre-command-hook, we mustn't let
|
|
|
|
|
;; errors propagate.
|
2008-12-18 11:31:52 -05:00
|
|
|
|
(message "Error in fuel-completion--restore-window-cfg: %S" err))))
|
2008-12-15 17:44:13 -05:00
|
|
|
|
|
|
|
|
|
(defun fuel-completion--window-active-p ()
|
|
|
|
|
"Is the completion window currently active?"
|
|
|
|
|
(and (window-live-p fuel-completion--completions-window)
|
|
|
|
|
(equal (buffer-name (window-buffer fuel-completion--completions-window))
|
|
|
|
|
fuel-completion--comp-buffer)))
|
|
|
|
|
|
|
|
|
|
(defun fuel-completion--display-comp-list (completions base)
|
2008-12-18 11:31:52 -05:00
|
|
|
|
(let ((savedp (fuel-completion--save-window-cfg)))
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(with-output-to-temp-buffer fuel-completion--comp-buffer
|
2008-12-15 20:29:24 -05:00
|
|
|
|
(display-completion-list completions base)
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(let ((offset (- (point) 1 (length base))))
|
|
|
|
|
(with-current-buffer standard-output
|
|
|
|
|
(setq completion-base-size offset)
|
|
|
|
|
(set-syntax-table fuel-syntax--syntax-table))))
|
|
|
|
|
(when savedp
|
|
|
|
|
(setq fuel-completion--completions-window
|
|
|
|
|
(get-buffer-window fuel-completion--comp-buffer)))))
|
|
|
|
|
|
|
|
|
|
(defun fuel-completion--display-or-scroll (completions base)
|
|
|
|
|
(cond ((and (eq last-command this-command) (fuel-completion--window-active-p))
|
|
|
|
|
(fuel-completion--scroll-completions))
|
|
|
|
|
(t (fuel-completion--display-comp-list completions base)))
|
|
|
|
|
(fuel-completion--delay-restoration))
|
|
|
|
|
|
|
|
|
|
(defun fuel-completion--scroll-completions ()
|
|
|
|
|
(let ((window fuel-completion--completions-window))
|
|
|
|
|
(with-current-buffer (window-buffer window)
|
|
|
|
|
(if (pos-visible-in-window-p (point-max) window)
|
|
|
|
|
(set-window-start window (point-min))
|
|
|
|
|
(save-selected-window
|
|
|
|
|
(select-window window)
|
|
|
|
|
(scroll-up))))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; Completion functionality:
|
|
|
|
|
|
2008-12-15 20:09:18 -05:00
|
|
|
|
(defun fuel-completion--word-list (prefix)
|
|
|
|
|
(let* ((fuel-log--inhibit-p t)
|
|
|
|
|
(cv (fuel-syntax--current-vocab))
|
|
|
|
|
(vs (and cv `("syntax" ,cv ,@(fuel-syntax--usings)))))
|
|
|
|
|
(fuel-completion--words prefix vs)))
|
2008-12-15 17:44:13 -05:00
|
|
|
|
|
2008-12-16 19:12:15 -05:00
|
|
|
|
(defsubst fuel-completion--all-words-list (prefix)
|
|
|
|
|
(fuel-completion--words prefix nil))
|
|
|
|
|
|
|
|
|
|
(defvar fuel-completion--word-list-func
|
|
|
|
|
(completion-table-dynamic 'fuel-completion--word-list))
|
|
|
|
|
|
|
|
|
|
(defvar fuel-completion--all-words-list-func
|
|
|
|
|
(completion-table-dynamic 'fuel-completion--all-words-list))
|
|
|
|
|
|
2008-12-17 18:49:01 -05:00
|
|
|
|
(defun fuel-completion--complete (prefix vocabs)
|
|
|
|
|
(let* ((words (if vocabs
|
|
|
|
|
(fuel-completion--vocabs)
|
|
|
|
|
(fuel-completion--word-list prefix)))
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(completions (all-completions prefix words))
|
|
|
|
|
(partial (try-completion prefix words))
|
|
|
|
|
(partial (if (eq partial t) prefix partial)))
|
|
|
|
|
(cons completions partial)))
|
|
|
|
|
|
2008-12-17 15:44:41 -05:00
|
|
|
|
(defun fuel-completion--read-word (prompt &optional default history all)
|
2009-02-05 04:28:57 -05:00
|
|
|
|
(let ((minibuffer-local-completion-map fuel-completion--minibuffer-map))
|
|
|
|
|
(completing-read prompt
|
|
|
|
|
(if all fuel-completion--all-words-list-func
|
|
|
|
|
fuel-completion--word-list-func)
|
|
|
|
|
nil nil nil
|
|
|
|
|
history
|
|
|
|
|
(or default (fuel-syntax-symbol-at-point)))))
|
|
|
|
|
|
2009-02-05 04:45:44 -05:00
|
|
|
|
(defvar fuel-completion--vocab-history nil)
|
|
|
|
|
|
2010-02-08 18:58:40 -05:00
|
|
|
|
(defun fuel-completion--read-vocab (refresh &optional init-input)
|
2009-02-05 04:45:44 -05:00
|
|
|
|
(let ((minibuffer-local-completion-map fuel-completion--minibuffer-map)
|
|
|
|
|
(vocabs (fuel-completion--vocabs refresh))
|
|
|
|
|
(prompt "Vocabulary name: "))
|
2009-02-05 04:28:57 -05:00
|
|
|
|
(if vocabs
|
2010-02-08 18:58:40 -05:00
|
|
|
|
(completing-read prompt vocabs nil nil init-input fuel-completion--vocab-history)
|
|
|
|
|
(read-string prompt init-input fuel-completion--vocab-history))))
|
2008-12-16 19:12:15 -05:00
|
|
|
|
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(defun fuel-completion--complete-symbol ()
|
|
|
|
|
"Complete the symbol at point.
|
|
|
|
|
Perform completion similar to Emacs' complete-symbol."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let* ((end (point))
|
2008-12-20 10:51:05 -05:00
|
|
|
|
(beg (fuel-syntax--beginning-of-symbol-pos))
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(prefix (buffer-substring-no-properties beg end))
|
2008-12-17 18:49:01 -05:00
|
|
|
|
(result (fuel-completion--complete prefix (fuel-syntax--in-using)))
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(completions (car result))
|
|
|
|
|
(partial (cdr result)))
|
|
|
|
|
(cond ((null completions)
|
|
|
|
|
(fuel--respecting-message "Can't find completion for %S" prefix)
|
2008-12-18 11:31:52 -05:00
|
|
|
|
(fuel-completion--restore-window-cfg))
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(t (insert-and-inherit (substring partial (length prefix)))
|
|
|
|
|
(cond ((= (length completions) 1)
|
|
|
|
|
(fuel--respecting-message "Sole completion")
|
2008-12-18 11:31:52 -05:00
|
|
|
|
(fuel-completion--restore-window-cfg))
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(t (fuel--respecting-message "Complete but not unique")
|
|
|
|
|
(fuel-completion--display-or-scroll completions
|
|
|
|
|
partial)))))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(provide 'fuel-completion)
|
|
|
|
|
;;; fuel-completion.el ends here
|