Skip to content

Commit

Permalink
Start using completion-at-point.
Browse files Browse the repository at this point in the history
That saves us the complex code to display the list of completions.
Unfortunately, slime-complete-symbol-function doesn't work well to
customize it.  Had to introduce a replacment:
slime-completion-at-point-functions.

* slime.el (slime-complete-symbol): Use completion-at-point.
(slime-completion-at-point-functions): New.
(slime--completion-at-point-functions): New helper.
(slime-complete-symbol-function): Obsolete, but have to keep it
around for some time.
(slime-simple-completion-at-point): Renamed from
slime-simple-complete-symbol to avoid confusion.
(slime-filename-completion): Renamed from
slime-maybe-complete-as-filename.
(slime-simple-complete-symbol): Backward compatible replacement.

(slime-completions-buffer-name)
(slime-complete-saved-window-configuration)
(slime-completions-window)
(slime-complete-maybe-save-window-configuration)
(slime-complete-delay-restoration)
(slime-complete-forget-window-configuration)
(slime-complete-restore-window-configuration)
(slime-complete-maybe-restore-window-configuration)
(slime-completion-window-active-p, slime-display-completion-list)
(slime-display-or-scroll-completions, slime-scroll-completions)
(slime-minibuffer-respecting-message): Move to
contrib/slime-c-p-c.el

* slime-tests.el (complete-symbol): Update tests.
* doc/slime.texi: Update documentation for symbol completion.
  • Loading branch information
ellerh committed Jul 17, 2015
1 parent d9215bf commit ff9bf80
Show file tree
Hide file tree
Showing 6 changed files with 243 additions and 185 deletions.
36 changes: 36 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
2015-07-17 Helmut Eller <heller@common-lisp.net>

Start using completion-at-point.

That saves us the complex code to display the list of completions.
Unfortunately, slime-complete-symbol-function doesn't work well to
customize it. Had to introduce a replacment:
slime-completion-at-point-functions.

* slime.el (slime-complete-symbol): Use completion-at-point.
(slime-completion-at-point-functions): New.
(slime--completion-at-point-functions): New helper.
(slime-complete-symbol-function): Obsolete, but have to keep it
around for some time.
(slime-simple-completion-at-point): Renamed from
slime-simple-complete-symbol to avoid confusion.
(slime-filename-completion): Renamed from
slime-maybe-complete-as-filename.
(slime-simple-complete-symbol): Backward compatible replacement.

(slime-completions-buffer-name)
(slime-complete-saved-window-configuration)
(slime-completions-window)
(slime-complete-maybe-save-window-configuration)
(slime-complete-delay-restoration)
(slime-complete-forget-window-configuration)
(slime-complete-restore-window-configuration)
(slime-complete-maybe-restore-window-configuration)
(slime-completion-window-active-p, slime-display-completion-list)
(slime-display-or-scroll-completions, slime-scroll-completions)
(slime-minibuffer-respecting-message): Move to
contrib/slime-c-p-c.el

* slime-tests.el (complete-symbol): Update tests.
* doc/slime.texi: Update documentation for symbol completion.

2015-07-15 Helmut Eller <heller@common-lisp.net>

Use *READ-SUPPRESS* more often while searching source locations.
Expand Down
7 changes: 7 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
* SLIME News -*- mode: outline; coding: utf-8 -*-
* 2.15 (July 2015)
** Core
*** Completions are now displayed with `completion-at-point'.
The new variable `slime-completion-at-point-functions' should now be
used to customize completion. The old variable
`slime-complete-symbol-function' still works, but it is considered
obsolete and will be removed eventually.

* 2.14 (June 2015)
** Core
Expand Down
122 changes: 122 additions & 0 deletions contrib/slime-c-p-c.el
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,128 @@ If false, move point to the end of the inserted text."
:group 'slime-mode
:type 'boolean)


;; FIXME: this is the old code to display completions. Remove it once
;; `slime-complete-symbol*' and `slime-fuzzy-complete-symbol' can be
;; used together with `completion-at-point'.

(defvar slime-completions-buffer-name "*Completions*")

;; FIXME: can probably use quit-window instead
(make-variable-buffer-local
(defvar slime-complete-saved-window-configuration 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 slime-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 `slime-complete-saved-window-configuration'."))

(defun slime-complete-maybe-save-window-configuration ()
"Maybe save the current window configuration.
Return true if the configuration was saved."
(unless (or slime-complete-saved-window-configuration
(get-buffer-window slime-completions-buffer-name))
(setq slime-complete-saved-window-configuration
(current-window-configuration))
t))

(defun slime-complete-delay-restoration ()
(add-hook 'pre-command-hook
'slime-complete-maybe-restore-window-configuration
'append
'local))

(defun slime-complete-forget-window-configuration ()
(setq slime-complete-saved-window-configuration nil)
(setq slime-completions-window nil))

(defun slime-complete-restore-window-configuration ()
"Restore the window config if available."
(remove-hook 'pre-command-hook
'slime-complete-maybe-restore-window-configuration)
(when (and slime-complete-saved-window-configuration
(slime-completion-window-active-p))
(save-excursion (set-window-configuration
slime-complete-saved-window-configuration))
(setq slime-complete-saved-window-configuration nil)
(when (buffer-live-p slime-completions-buffer-name)
(kill-buffer slime-completions-buffer-name))))

(defun slime-complete-maybe-restore-window-configuration ()
"Restore the window configuration, if the following command
terminates a current completion."
(remove-hook 'pre-command-hook
'slime-complete-maybe-restore-window-configuration)
(condition-case err
(cond ((cl-find last-command-event "()\"'`,# \r\n:")
(slime-complete-restore-window-configuration))
((not (slime-completion-window-active-p))
(slime-complete-forget-window-configuration))
(t
(slime-complete-delay-restoration)))
(error
;; Because this is called on the pre-command-hook, we mustn't let
;; errors propagate.
(message "Error in slime-complete-restore-window-configuration: %S"
err))))

(defun slime-completion-window-active-p ()
"Is the completion window currently active?"
(and (window-live-p slime-completions-window)
(equal (buffer-name (window-buffer slime-completions-window))
slime-completions-buffer-name)))

(defun slime-display-completion-list (completions base)
(let ((savedp (slime-complete-maybe-save-window-configuration)))
(with-output-to-temp-buffer slime-completions-buffer-name
(display-completion-list completions)
(let ((offset (- (point) 1 (length base))))
(with-current-buffer standard-output
(setq completion-base-position offset)
(set-syntax-table lisp-mode-syntax-table))))
(when savedp
(setq slime-completions-window
(get-buffer-window slime-completions-buffer-name)))))

(defun slime-display-or-scroll-completions (completions base)
(cond ((and (eq last-command this-command)
(slime-completion-window-active-p))
(slime-scroll-completions))
(t
(slime-display-completion-list completions base)))
(slime-complete-delay-restoration))

(defun slime-scroll-completions ()
(let ((window slime-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))))))

(defun slime-minibuffer-respecting-message (format &rest format-args)
"Display TEXT as a message, without hiding any minibuffer contents."
(let ((text (format " [%s]" (apply #'format format format-args))))
(if (minibuffer-window-active-p (minibuffer-window))
(minibuffer-message text)
(message "%s" text))))

(defun slime-maybe-complete-as-filename ()
"If point is at a string starting with \", complete it as filename.
Return nil if point is not at filename."
(when (save-excursion (re-search-backward "\"[^ \t\n]+\\="
(max (point-min)
(- (point) 1000)) t))
(let ((comint-completion-addsuffix '("/" . "\"")))
(comint-replace-by-expanded-filename)
t)))


(defun slime-complete-symbol* ()
"Expand abbreviations and complete the symbol at point."
;; NB: It is only the name part of the symbol that we actually want
Expand Down
52 changes: 24 additions & 28 deletions doc/slime.texi
Original file line number Diff line number Diff line change
Expand Up @@ -486,15 +486,8 @@ can add one of the following to your init file:

@example
(add-hook 'slime-load-hook
#'(lambda ()
(define-key slime-prefix-map (kbd "M-h") 'slime-documentation-lookup)))
@end example

Or just:

@example
(eval-after-load 'slime
`(define-key slime-prefix-map (kbd "M-h") 'slime-documentation-lookup))
(lambda ()
(define-key slime-prefix-map (kbd "M-h") 'slime-documentation-lookup)))
@end example

The former technique works only for @SLIME{}'s core keymaps, not it's
Expand Down Expand Up @@ -951,7 +944,7 @@ completion tries harder.
@c @itemx C-M-i
Complete the symbol at point. Note that three styles of completion are
available in @SLIME{}; the default is similar to normal Emacs
completion (@pxref{slime-complete-symbol-function}).
completion (@pxref{slime-completion-at-point-functions}).

@end table

Expand Down Expand Up @@ -1694,16 +1687,19 @@ buffers popped up by @SLIME{}. This is @code{t} by default, which
ensures that lines do not wrap in backtraces, apropos listings, and so
on. It can however cause information to spill off the screen.

@anchor{slime-complete-symbol-function}
@vindex slime-complete-symbol-function
@item slime-complete-symbol-function
The function to use for completion of Lisp symbols. Three completion
styles are available: @code{slime-simple-complete-symbol},
@anchor{slime-completion-at-point-functions}
@vindex slime-completion-at-point-functions
@item slime-completion-at-point-functions
A list of functions used for completion of Lisp symbols. This works
as the standard
@code{completion-at-point-functions}
(@pxref{Completion in Buffers,,,elisp}). Three completion
styles are available: @code{slime-simple-completion-at-point},
@code{slime-complete-symbol*} (@pxref{Compound Completion}),
and @code{slime-fuzzy-complete-symbol} (@pxref{Fuzzy Completion}).

The default is @code{slime-simple-complete-symbol}, which completes in
the usual Emacs way.
The default is @code{slime-simple-completion-at-point}, which
completes in the usual Emacs way.

@vindex slime-filename-translations
@item slime-filename-translations
Expand Down Expand Up @@ -2608,21 +2604,21 @@ For example, the effect of @code{:nearest-package} can be also achieved
by specifying the following custom filter in @file{~/.swank.lisp}:
@example
(setf *fuzzy-duplicate-symbol-filter*
#'(lambda (cur-package all-packages dedup-table)
(declare (ignore cur-package all-packages))
#'(lambda (symbol)
(unless (gethash (symbol-name symbol) dedup-table)
(setf (gethash (symbol-name symbol) dedup-table) t)))))
(lambda (cur-package all-packages dedup-table)
(declare (ignore cur-package all-packages))
(lambda (symbol)
(unless (gethash (symbol-name symbol) dedup-table)
(setf (gethash (symbol-name symbol) dedup-table) t)))))
@end example
And instead of @code{:home-package}, the following can be used:
@example
(setf *fuzzy-duplicate-symbol-filter*
#'(lambda (cur-package all-packages dedup-table)
(declare (ignore dedup-table))
(let ((packages (mapcar #'find-package
(remove cur-package all-packages))))
#'(lambda (symbol)
(not (member (symbol-package symbol) packages))))))
(lambda (cur-package all-packages dedup-table)
(declare (ignore dedup-table))
(let ((packages (mapcar #'find-package
(remove cur-package all-packages))))
(lambda (symbol)
(not (member (symbol-package symbol) packages))))))
@end example

@node slime-autodoc-mode
Expand Down
22 changes: 10 additions & 12 deletions slime-tests.el
Original file line number Diff line number Diff line change
Expand Up @@ -586,18 +586,16 @@ confronted with nasty #.-fu."
(def-slime-test complete-symbol
(prefix expected-completions)
"Find the completions of a symbol-name prefix."
'(("cl:compile" (("cl:compile" "cl:compile-file" "cl:compile-file-pathname"
"cl:compiled-function" "cl:compiled-function-p"
"cl:compiler-macro" "cl:compiler-macro-function")
"cl:compile"))
("cl:foobar" (nil ""))
("swank::compile-file" (("swank::compile-file"
"swank::compile-file-for-emacs"
"swank::compile-file-if-needed"
"swank::compile-file-output"
"swank::compile-file-pathname")
"swank::compile-file"))
("cl:m-v-l" (nil "")))
'(("cl:compile" ("cl:compile" "cl:compile-file" "cl:compile-file-pathname"
"cl:compiled-function" "cl:compiled-function-p"
"cl:compiler-macro" "cl:compiler-macro-function"))
("cl:foobar" ())
("swank::compile-file" ("swank::compile-file"
"swank::compile-file-for-emacs"
"swank::compile-file-if-needed"
"swank::compile-file-output"
"swank::compile-file-pathname"))
("cl:m-v-l" ()))
(let ((completions (slime-simple-completions prefix)))
(slime-test-expect "Completion set" expected-completions completions)))

Expand Down
Loading

0 comments on commit ff9bf80

Please sign in to comment.