Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
marvel
GitHub Repository: marvel/qnf
Path: blob/master/elisp/slime/contrib/slime-fuzzy.el
990 views
1
2
(define-slime-contrib slime-fuzzy
3
"Fuzzy symbol completion."
4
(:authors "Brian Downing <[email protected]>"
5
"Tobias C. Rittweiler <[email protected]>"
6
"Attila Lendvai <[email protected]>")
7
(:license "GPL")
8
(:swank-dependencies swank-fuzzy)
9
(:on-load
10
(define-key slime-mode-map "\C-c\M-i" 'slime-fuzzy-complete-symbol)
11
(when (featurep 'slime-repl)
12
(define-key slime-repl-mode-map "\C-c\M-i" 'slime-fuzzy-complete-symbol))))
13
14
(defcustom slime-fuzzy-completion-in-place t
15
"When non-NIL the fuzzy symbol completion is done in place as
16
opposed to moving the point to the completion buffer."
17
:group 'slime-mode
18
:type 'boolean)
19
20
(defcustom slime-fuzzy-completion-limit 300
21
"Only return and present this many symbols from swank."
22
:group 'slime-mode
23
:type 'integer)
24
25
(defcustom slime-fuzzy-completion-time-limit-in-msec 1500
26
"Limit the time spent (given in msec) in swank while gathering
27
comletitions."
28
:group 'slime-mode
29
:type 'integer)
30
31
(defcustom slime-when-complete-filename-expand nil
32
"Use comint-replace-by-expanded-filename instead of
33
comint-dynamic-complete-as-filename to complete file names"
34
:group 'slime-mode
35
:type 'boolean)
36
37
38
(defvar slime-fuzzy-target-buffer nil
39
"The buffer that is the target of the completion activities.")
40
(defvar slime-fuzzy-saved-window-configuration nil
41
"The saved window configuration before the fuzzy completion
42
buffer popped up.")
43
(defvar slime-fuzzy-start nil
44
"The beginning of the completion slot in the target buffer.
45
This is a non-advancing marker.")
46
(defvar slime-fuzzy-end nil
47
"The end of the completion slot in the target buffer.
48
This is an advancing marker.")
49
(defvar slime-fuzzy-original-text nil
50
"The original text that was in the completion slot in the
51
target buffer. This is what is put back if completion is
52
aborted.")
53
(defvar slime-fuzzy-text nil
54
"The text that is currently in the completion slot in the
55
target buffer. If this ever doesn't match, the target buffer has
56
been modified and we abort without touching it.")
57
(defvar slime-fuzzy-first nil
58
"The position of the first completion in the completions buffer.
59
The descriptive text and headers are above this.")
60
(defvar slime-fuzzy-last nil
61
"The position of the last completion in the completions buffer.
62
If the time limit has exhausted during generation possible completion
63
choices inside SWANK, an indication is printed below this.")
64
(defvar slime-fuzzy-current-completion nil
65
"The current completion object. If this is the same before and
66
after point moves in the completions buffer, the text is not
67
replaced in the target for efficiency.")
68
(defvar slime-fuzzy-current-completion-overlay nil
69
"The overlay representing the current completion in the completion
70
buffer. This is used to hightlight the text.")
71
72
;;;;;;; slime-target-buffer-fuzzy-completions-mode
73
;; NOTE: this mode has to be able to override key mappings in slime-mode
74
75
;; FIXME: clean this up
76
77
(defun slime-mimic-key-bindings (from-keymap to-keymap bindings-or-operation operation)
78
"Iterate on BINDINGS-OR-OPERATION. If an element is a symbol then
79
try to look it up (as an operation) in FROM-KEYMAP. Non symbols are taken
80
as default key bindings when none to be mimiced was found in FROM-KEYMAP.
81
Set the resulting list of keys in TO-KEYMAP to OPERATION."
82
(let ((mimic-keys nil)
83
(direct-keys nil))
84
(dolist (key-or-operation bindings-or-operation)
85
(if (symbolp key-or-operation)
86
(setf mimic-keys (append mimic-keys (where-is-internal key-or-operation from-keymap nil t)))
87
(push key-or-operation direct-keys)))
88
(dolist (key (or mimic-keys direct-keys))
89
(define-key to-keymap key operation))))
90
91
(defvar slime-target-buffer-fuzzy-completions-map
92
(let* ((map (make-sparse-keymap)))
93
(flet ((remap (keys to)
94
(slime-mimic-key-bindings global-map map keys to)))
95
96
(remap (list 'keyboard-quit (kbd "C-g")) 'slime-fuzzy-abort)
97
98
(remap (list 'slime-fuzzy-indent-and-complete-symbol
99
'slime-indent-and-complete-symbol
100
(kbd "<tab>"))
101
'slime-fuzzy-select-or-update-completions)
102
(remap (list 'previous-line (kbd "<up>")) 'slime-fuzzy-prev)
103
(remap (list 'next-line (kbd "<down>")) 'slime-fuzzy-next)
104
(remap (list 'isearch-forward (kbd "C-s"))
105
(lambda ()
106
(interactive)
107
(select-window (get-buffer-window (slime-get-fuzzy-buffer)))
108
(call-interactively 'isearch-forward)))
109
110
;; some unconditional direct bindings
111
(dolist (key (list (kbd "<return>") (kbd "RET") (kbd "<SPC>") "(" ")" "[" "]"))
112
(define-key map key 'slime-fuzzy-select-and-process-event-in-target-buffer)))
113
map)
114
"Keymap for slime-target-buffer-fuzzy-completions-mode. This will override the key
115
bindings in the target buffer temporarily during completion.")
116
117
;; Make sure slime-fuzzy-target-buffer-completions-mode's map is
118
;; before everything else.
119
(setf minor-mode-map-alist
120
(stable-sort minor-mode-map-alist
121
(lambda (a b)
122
(eq a 'slime-fuzzy-target-buffer-completions-mode))
123
:key #'car))
124
125
126
(define-minor-mode slime-fuzzy-target-buffer-completions-mode
127
"This minor mode is intented to override key bindings during fuzzy
128
completions in the target buffer. Most of the bindings will do an implicit select
129
in the completion window and let the keypress be processed in the target buffer."
130
nil
131
nil
132
slime-target-buffer-fuzzy-completions-map)
133
134
(add-to-list 'minor-mode-alist
135
'(slime-fuzzy-target-buffer-completions-mode
136
" Fuzzy Target Buffer Completions"))
137
138
(define-derived-mode slime-fuzzy-completions-mode
139
fundamental-mode "Fuzzy Completions"
140
"Major mode for presenting fuzzy completion results.
141
142
When you run `slime-fuzzy-complete-symbol', the symbol token at
143
point is completed using the Fuzzy Completion algorithm; this
144
means that the token is taken as a sequence of characters and all
145
the various possibilities that this sequence could meaningfully
146
represent are offered as selectable choices, sorted by how well
147
they deem to be a match for the token. (For instance, the first
148
choice of completing on \"mvb\" would be \"multiple-value-bind\".)
149
150
Therefore, a new buffer (*Fuzzy Completions*) will pop up that
151
contains the different completion choices. Simultaneously, a
152
special minor-mode will be temporarily enabled in the original
153
buffer where you initiated fuzzy completion (also called the
154
``target buffer'') in order to navigate through the *Fuzzy
155
Completions* buffer without leaving.
156
157
With focus in *Fuzzy Completions*:
158
Type `n' and `p' (`UP', `DOWN') to navigate between completions.
159
Type `RET' or `TAB' to select the completion near point.
160
Type `q' to abort.
161
162
With focus in the target buffer:
163
Type `UP' and `DOWN' to navigate between completions.
164
Type a character that does not constitute a symbol name
165
to insert the current choice and then that character (`(', `)',
166
`SPACE', `RET'.) Use `TAB' to simply insert the current choice.
167
Use C-g to abort.
168
169
Alternatively, you can click <mouse-2> on a completion to select it.
170
171
172
Complete listing of keybindings within the target buffer:
173
174
\\<slime-target-buffer-fuzzy-completions-map>\
175
\\{slime-target-buffer-fuzzy-completions-map}
176
177
Complete listing of keybindings with *Fuzzy Completions*:
178
179
\\<slime-fuzzy-completions-map>\
180
\\{slime-fuzzy-completions-map}"
181
(use-local-map slime-fuzzy-completions-map)
182
(set (make-local-variable 'slime-fuzzy-current-completion-overlay)
183
(make-overlay (point) (point) nil t nil)))
184
185
(defvar slime-fuzzy-completions-map
186
(let* ((map (make-sparse-keymap)))
187
(flet ((remap (keys to)
188
(slime-mimic-key-bindings global-map map keys to)))
189
(remap (list 'keyboard-quit (kbd "C-g")) 'slime-fuzzy-abort)
190
(define-key map "q" 'slime-fuzzy-abort)
191
192
(remap (list 'previous-line (kbd "<up>")) 'slime-fuzzy-prev)
193
(remap (list 'next-line (kbd "<down>")) 'slime-fuzzy-next)
194
195
(define-key map "n" 'slime-fuzzy-next)
196
(define-key map "\M-n" 'slime-fuzzy-next)
197
198
(define-key map "p" 'slime-fuzzy-prev)
199
(define-key map "\M-p" 'slime-fuzzy-prev)
200
201
(define-key map "\d" 'scroll-down)
202
203
(remap (list 'slime-fuzzy-indent-and-complete-symbol
204
'slime-indent-and-complete-symbol
205
(kbd "<tab>"))
206
'slime-fuzzy-select)
207
208
(define-key map (kbd "<mouse-2>") 'slime-fuzzy-select/mouse))
209
210
(define-key map (kbd "RET") 'slime-fuzzy-select)
211
(define-key map (kbd "<SPC>") 'slime-fuzzy-select)
212
213
map)
214
"Keymap for slime-fuzzy-completions-mode when in the completion buffer.")
215
216
(defun slime-fuzzy-completions (prefix &optional default-package)
217
"Get the list of sorted completion objects from completing
218
`prefix' in `package' from the connected Lisp."
219
(let ((prefix (etypecase prefix
220
(symbol (symbol-name prefix))
221
(string prefix))))
222
(slime-eval `(swank:fuzzy-completions ,prefix
223
,(or default-package
224
(slime-current-package))
225
:limit ,slime-fuzzy-completion-limit
226
:time-limit-in-msec ,slime-fuzzy-completion-time-limit-in-msec))))
227
228
(defun slime-fuzzy-selected (prefix completion)
229
"Tell the connected Lisp that the user selected completion
230
`completion' as the completion for `prefix'."
231
(let ((no-properties (copy-sequence prefix)))
232
(set-text-properties 0 (length no-properties) nil no-properties)
233
(slime-eval `(swank:fuzzy-completion-selected ,no-properties
234
',completion))))
235
236
(defun slime-fuzzy-indent-and-complete-symbol ()
237
"Indent the current line and perform fuzzy symbol completion. First
238
indent the line. If indenting doesn't move point, complete the
239
symbol. If there's no symbol at the point, show the arglist for the
240
most recently enclosed macro or function."
241
(interactive)
242
(let ((pos (point)))
243
(unless (get-text-property (line-beginning-position) 'slime-repl-prompt)
244
(lisp-indent-line))
245
(when (= pos (point))
246
(cond ((save-excursion (re-search-backward "[^() \n\t\r]+\\=" nil t))
247
(slime-fuzzy-complete-symbol))
248
((memq (char-before) '(?\t ?\ ))
249
(slime-echo-arglist))))))
250
251
(defun* slime-fuzzy-complete-symbol ()
252
"Fuzzily completes the abbreviation at point into a symbol."
253
(interactive)
254
(when (save-excursion (re-search-backward "\"[^ \t\n]+\\=" nil t))
255
(return-from slime-fuzzy-complete-symbol
256
;; don't add space after completion
257
(let ((comint-completion-addsuffix '("/" . "")))
258
(if slime-when-complete-filename-expand
259
(comint-replace-by-expanded-filename)
260
(comint-dynamic-complete-as-filename)))))
261
(let* ((end (move-marker (make-marker) (slime-symbol-end-pos)))
262
(beg (move-marker (make-marker) (slime-symbol-start-pos)))
263
(prefix (buffer-substring-no-properties beg end)))
264
(destructuring-bind (completion-set interrupted-p)
265
(slime-fuzzy-completions prefix)
266
(if (null completion-set)
267
(progn (slime-minibuffer-respecting-message
268
"Can't find completion for \"%s\"" prefix)
269
(ding)
270
(slime-fuzzy-done))
271
(goto-char end)
272
(cond ((slime-length= completion-set 1)
273
(insert-and-inherit (caar completion-set)) ; insert completed string
274
(delete-region beg end)
275
(goto-char (+ beg (length (caar completion-set))))
276
(slime-minibuffer-respecting-message "Sole completion")
277
(slime-fuzzy-done))
278
;; Incomplete
279
(t
280
(slime-fuzzy-choices-buffer completion-set interrupted-p beg end)
281
(slime-minibuffer-respecting-message "Complete but not unique")))))))
282
283
284
(defun slime-get-fuzzy-buffer ()
285
(get-buffer-create "*Fuzzy Completions*"))
286
287
(defvar slime-fuzzy-explanation
288
"For help on how the use this buffer, see `slime-fuzzy-completions-mode'.
289
290
Flags: boundp fboundp generic-function class macro special-operator package
291
\n"
292
"The explanation that gets inserted at the beginning of the
293
*Fuzzy Completions* buffer.")
294
295
(defun slime-fuzzy-insert-completion-choice (completion max-length)
296
"Inserts the completion object `completion' as a formatted
297
completion choice into the current buffer, and mark it with the
298
proper text properties."
299
(destructuring-bind (symbol-name score chunks classification-string) completion
300
(let ((start (point))
301
(end))
302
(insert symbol-name)
303
(setq end (point))
304
(dolist (chunk chunks)
305
(put-text-property (+ start (first chunk))
306
(+ start (first chunk)
307
(length (second chunk)))
308
'face 'bold))
309
(put-text-property start (point) 'mouse-face 'highlight)
310
(dotimes (i (- max-length (- end start)))
311
(insert " "))
312
(insert (format " %s %s\n"
313
classification-string
314
score))
315
(put-text-property start (point) 'completion completion))))
316
317
(defun slime-fuzzy-insert (text)
318
"Inserts `text' into the target buffer in the completion slot.
319
If the buffer has been modified in the meantime, abort the
320
completion process. Otherwise, update all completion variables
321
so that the new text is present."
322
(with-current-buffer slime-fuzzy-target-buffer
323
(cond
324
((not (string-equal slime-fuzzy-text
325
(buffer-substring slime-fuzzy-start
326
slime-fuzzy-end)))
327
(slime-fuzzy-done)
328
(beep)
329
(message "Target buffer has been modified!"))
330
(t
331
(goto-char slime-fuzzy-start)
332
(delete-region slime-fuzzy-start slime-fuzzy-end)
333
(insert-and-inherit text)
334
(setq slime-fuzzy-text text)
335
(goto-char slime-fuzzy-end)))))
336
337
(defun slime-fuzzy-choices-buffer (completions interrupted-p start end)
338
"Creates (if neccessary), populates, and pops up the *Fuzzy
339
Completions* buffer with the completions from `completions' and
340
the completion slot in the current buffer bounded by `start' and
341
`end'. This saves the window configuration before popping the
342
buffer so that it can possibly be restored when the user is
343
done."
344
(let ((new-completion-buffer (not slime-fuzzy-target-buffer))
345
(connection (slime-connection)))
346
(when new-completion-buffer
347
(setq slime-fuzzy-saved-window-configuration
348
(current-window-configuration)))
349
(slime-fuzzy-enable-target-buffer-completions-mode)
350
(setq slime-fuzzy-target-buffer (current-buffer))
351
(setq slime-fuzzy-start (move-marker (make-marker) start))
352
(setq slime-fuzzy-end (move-marker (make-marker) end))
353
(set-marker-insertion-type slime-fuzzy-end t)
354
(setq slime-fuzzy-original-text (buffer-substring start end))
355
(setq slime-fuzzy-text slime-fuzzy-original-text)
356
(slime-fuzzy-fill-completions-buffer completions interrupted-p)
357
(pop-to-buffer (slime-get-fuzzy-buffer))
358
(setq slime-buffer-connection connection)
359
(when new-completion-buffer
360
;; Hook to nullify window-config restoration if the user changes
361
;; the window configuration himself.
362
(when (boundp 'window-configuration-change-hook)
363
(add-hook 'window-configuration-change-hook
364
'slime-fuzzy-window-configuration-change))
365
(slime-add-local-hook 'kill-buffer-hook 'slime-fuzzy-abort)
366
(set (make-local-variable 'cursor-type) nil)
367
(setq buffer-quit-function 'slime-fuzzy-abort)) ; M-Esc Esc
368
(when slime-fuzzy-completion-in-place
369
;; switch back to the original buffer
370
(if (minibufferp slime-fuzzy-target-buffer)
371
(select-window (minibuffer-window))
372
(switch-to-buffer-other-window slime-fuzzy-target-buffer)))))
373
374
(defun slime-fuzzy-fill-completions-buffer (completions interrupted-p)
375
"Erases and fills the completion buffer with the given completions."
376
(with-current-buffer (slime-get-fuzzy-buffer)
377
(setq buffer-read-only nil)
378
(erase-buffer)
379
(slime-fuzzy-completions-mode)
380
(insert slime-fuzzy-explanation)
381
(let ((max-length 12))
382
(dolist (completion completions)
383
(setf max-length (max max-length (length (first completion)))))
384
385
(insert "Completion:")
386
(dotimes (i (- max-length 10)) (insert " "))
387
;; Flags: Score:
388
;; ... ------- --------
389
;; bfgctmsp
390
(let* ((example-classification-string (fourth (first completions)))
391
(classification-length (length example-classification-string))
392
(spaces (- classification-length (length "Flags:"))))
393
(insert "Flags:")
394
(dotimes (i spaces) (insert " "))
395
(insert " Score:\n")
396
(dotimes (i max-length) (insert "-"))
397
(insert " ")
398
(dotimes (i classification-length) (insert "-"))
399
(insert " --------\n")
400
(setq slime-fuzzy-first (point)))
401
402
(dolist (completion completions)
403
(setq slime-fuzzy-last (point)) ; will eventually become the last entry
404
(slime-fuzzy-insert-completion-choice completion max-length))
405
406
(when interrupted-p
407
(insert "...\n")
408
(insert "[Interrupted: time limit exhausted]"))
409
410
(setq buffer-read-only t))
411
(setq slime-fuzzy-current-completion
412
(caar completions))
413
(goto-char 0)
414
(slime-fuzzy-next)))
415
416
(defun slime-fuzzy-enable-target-buffer-completions-mode ()
417
"Store the target buffer's local map, so that we can restore it."
418
(unless slime-fuzzy-target-buffer-completions-mode
419
; (slime-log-event "Enabling target buffer completions mode")
420
(slime-fuzzy-target-buffer-completions-mode 1)))
421
422
(defun slime-fuzzy-disable-target-buffer-completions-mode ()
423
"Restores the target buffer's local map when completion is finished."
424
(when slime-fuzzy-target-buffer-completions-mode
425
; (slime-log-event "Disabling target buffer completions mode")
426
(slime-fuzzy-target-buffer-completions-mode 0)))
427
428
(defun slime-fuzzy-insert-from-point ()
429
"Inserts the completion that is under point in the completions
430
buffer into the target buffer. If the completion in question had
431
already been inserted, it does nothing."
432
(with-current-buffer (slime-get-fuzzy-buffer)
433
(let ((current-completion (get-text-property (point) 'completion)))
434
(when (and current-completion
435
(not (eq slime-fuzzy-current-completion
436
current-completion)))
437
(slime-fuzzy-insert
438
(first (get-text-property (point) 'completion)))
439
(setq slime-fuzzy-current-completion
440
current-completion)))))
441
442
(defun slime-fuzzy-post-command-hook ()
443
"The post-command-hook for the *Fuzzy Completions* buffer.
444
This makes sure the completion slot in the target buffer matches
445
the completion that point is on in the completions buffer."
446
(condition-case err
447
(when slime-fuzzy-target-buffer
448
(slime-fuzzy-insert-from-point))
449
(error
450
;; Because this is called on the post-command-hook, we mustn't let
451
;; errors propagate.
452
(message "Error in slime-fuzzy-post-command-hook: %S" err))))
453
454
(defun slime-fuzzy-next ()
455
"Moves point directly to the next completion in the completions
456
buffer."
457
(interactive)
458
(with-current-buffer (slime-get-fuzzy-buffer)
459
(let ((point (next-single-char-property-change (point) 'completion nil slime-fuzzy-last)))
460
(set-window-point (get-buffer-window (current-buffer)) point)
461
(goto-char point))
462
(slime-fuzzy-highlight-current-completion)))
463
464
(defun slime-fuzzy-prev ()
465
"Moves point directly to the previous completion in the
466
completions buffer."
467
(interactive)
468
(with-current-buffer (slime-get-fuzzy-buffer)
469
(let ((point (previous-single-char-property-change (point) 'completion nil slime-fuzzy-first)))
470
(set-window-point (get-buffer-window (current-buffer)) point)
471
(goto-char point))
472
(slime-fuzzy-highlight-current-completion)))
473
474
(defun slime-fuzzy-highlight-current-completion ()
475
"Highlights the current completion, so that the user can see it on the screen."
476
(let ((pos (point)))
477
(when (overlayp slime-fuzzy-current-completion-overlay)
478
(move-overlay slime-fuzzy-current-completion-overlay
479
(point) (1- (search-forward " ")))
480
(overlay-put slime-fuzzy-current-completion-overlay
481
'face 'secondary-selection))
482
(goto-char pos)))
483
484
(defun slime-fuzzy-abort ()
485
"Aborts the completion process, setting the completions slot in
486
the target buffer back to its original contents."
487
(interactive)
488
(when slime-fuzzy-target-buffer
489
(slime-fuzzy-done)))
490
491
(defun slime-fuzzy-select ()
492
"Selects the current completion, making sure that it is inserted
493
into the target buffer. This tells the connected Lisp what completion
494
was selected."
495
(interactive)
496
(when slime-fuzzy-target-buffer
497
(with-current-buffer (slime-get-fuzzy-buffer)
498
(let ((completion (get-text-property (point) 'completion)))
499
(when completion
500
(slime-fuzzy-insert (first completion))
501
(slime-fuzzy-selected slime-fuzzy-original-text
502
completion)
503
(slime-fuzzy-done))))))
504
505
(defun slime-fuzzy-select-or-update-completions ()
506
"If there were no changes since the last time fuzzy completion was started
507
this function will select the current completion. Otherwise refreshes the completion
508
list based on the changes made."
509
(interactive)
510
; (slime-log-event "Selecting or updating completions")
511
(if (string-equal slime-fuzzy-original-text
512
(buffer-substring slime-fuzzy-start
513
slime-fuzzy-end))
514
(slime-fuzzy-select)
515
(slime-fuzzy-complete-symbol)))
516
517
(defun slime-fuzzy-process-event-in-completions-buffer ()
518
"Simply processes the event in the target buffer"
519
(interactive)
520
(with-current-buffer (slime-get-fuzzy-buffer)
521
(push last-input-event unread-command-events)))
522
523
(defun slime-fuzzy-select-and-process-event-in-target-buffer ()
524
"Selects the current completion, making sure that it is inserted
525
into the target buffer and processes the event in the target buffer."
526
(interactive)
527
; (slime-log-event "Selecting and processing event in target buffer")
528
(when slime-fuzzy-target-buffer
529
(let ((buff slime-fuzzy-target-buffer))
530
(slime-fuzzy-select)
531
(with-current-buffer buff
532
(slime-fuzzy-disable-target-buffer-completions-mode)
533
(push last-input-event unread-command-events)))))
534
535
(defun slime-fuzzy-select/mouse (event)
536
"Handle a mouse-2 click on a completion choice as if point were
537
on the completion choice and the slime-fuzzy-select command was
538
run."
539
(interactive "e")
540
(with-current-buffer (window-buffer (posn-window (event-end event)))
541
(save-excursion
542
(goto-char (posn-point (event-end event)))
543
(when (get-text-property (point) 'mouse-face)
544
(slime-fuzzy-insert-from-point)
545
(slime-fuzzy-select)))))
546
547
(defun slime-fuzzy-done ()
548
"Cleans up after the completion process. This removes all hooks,
549
and attempts to restore the window configuration. If this fails,
550
it just burys the completions buffer and leaves the window
551
configuration alone."
552
(when slime-fuzzy-target-buffer
553
(set-buffer slime-fuzzy-target-buffer)
554
(slime-fuzzy-disable-target-buffer-completions-mode)
555
(if (slime-fuzzy-maybe-restore-window-configuration)
556
(bury-buffer (slime-get-fuzzy-buffer))
557
;; We couldn't restore the windows, so just bury the fuzzy
558
;; completions buffer and let something else fill it in.
559
(pop-to-buffer (slime-get-fuzzy-buffer))
560
(bury-buffer))
561
(pop-to-buffer slime-fuzzy-target-buffer)
562
(goto-char slime-fuzzy-end)
563
(setq slime-fuzzy-target-buffer nil)
564
(remove-hook 'window-configuration-change-hook
565
'slime-fuzzy-window-configuration-change)))
566
567
(defun slime-fuzzy-maybe-restore-window-configuration ()
568
"Restores the saved window configuration if it has not been
569
nullified."
570
(when (boundp 'window-configuration-change-hook)
571
(remove-hook 'window-configuration-change-hook
572
'slime-fuzzy-window-configuration-change))
573
(if (not slime-fuzzy-saved-window-configuration)
574
nil
575
(set-window-configuration slime-fuzzy-saved-window-configuration)
576
(setq slime-fuzzy-saved-window-configuration nil)
577
t))
578
579
(defun slime-fuzzy-window-configuration-change ()
580
"Called on window-configuration-change-hook. Since the window
581
configuration was changed, we nullify our saved configuration."
582
(setq slime-fuzzy-saved-window-configuration nil))
583
584
(provide 'slime-fuzzy)
585