Normally hitting TAB a second time after a completion
will take you to a suggestions buffer where you can select from
alternate completions. This bit of elisp hackery will instead use a
pop-up list via auto-competion mode. Make sure this is executed after pabbrev is loaded. (require 'auto-complete)
(defun pabbrevx-ac-on-pre-command () (if (or (eq this-command 'self-insert-command) (and (not (ac-trigger-command-p)) (or (not (symbolp this-command)) (not (string-match "^ac-" (symbol-name this-command)))))) (progn (remove-hook 'post-command-hook 'pabbrevx-ac-on-post-command t) (remove-hook 'pre-command-hook 'pabbrevx-ac-on-pre-command t) (ac-abort))))
(defun pabbrevx-ac-on-post-command () (if (and (not isearch-mode) (ac-trigger-command-p)) (pabbrevx-ac-start)))
(defun pabbrevx-ac-start () (let ((candidates (mapcar 'car pabbrev-expansion-suggestions))) (add-hook 'pre-command-hook 'pabbrevx-ac-on-pre-command nil t) (add-hook 'post-command-hook 'pabbrevx-ac-on-post-command nil t) ;; ripped straight from ac-start (let* ((point (save-excursion (funcall ac-prefix-function))) (reposition (or (not (equal ac-point point)) ;; If menu direction is positive and next visual line belongs ;; to same buffer line, then need reposition (and (> ac-menu-direction 0) (ac-menu-at-wrapped-line))))) (if (null point) (progn ;; need to nil this so pabbrev-expand-maybe-full we won't try ;; pabbrev expansion if user hits another TAB after ac aborts (setq pabbrev-last-expansion-suggestions nil) (ac-abort)) (setq ac-buffer (current-buffer)) (setq ac-point point) (when (not (equal ac-point ac-old-point)) (setq ac-old-point point)) (setq ac-prefix (buffer-substring-no-properties point (point))) (setq ac-limit ac-candidate-limit) (if (or reposition (null ac-menu)) (save-excursion (funcall ac-init-function))) (let (;;candidates width (current-width (if ac-menu (ac-menu-width ac-menu) 0))) ;; (setq candidates (if (or ac-completing ;; (not (integerp ac-auto-start)) ;; (>= (length ac-prefix) ac-auto-start)) ;; (save-excursion ;; (funcall ac-candidate-function)))) ;;(if ac-candidate-filter-function ;; (setq candidates (funcall ac-candidate-filter-function candidates))) (setq width (let ((w '(0)) s) (dotimes (i ac-candidate-menu-height) (setq s (nth i candidates)) (if (stringp s) (push (string-width s) w))) (apply 'max w))) (if (or reposition (null ac-menu) (> width current-width) (< width (- current-width 10))) (ac-setup (* (ceiling (/ width 10.0)) 10))) (ac-update-candidates candidates))))))
(defun pabbrevx-suggestions-goto-buffer (suggestions) (pabbrevx-ac-start))
;;; pabbrev.el --- Predictive abbreviation expansion
;; Author: Phillip Lord <p.lord@russet.org.uk>
;; Maintainer: Phillip Lord <p.lord@russet.org.uk>
;; Maintainer (XEmacs): Martin Kuehl (martin.kuehl@gmail.com)
;; Website: http://www.russet.org.uk
;;; Commentary:
;;
;; The code provides a abbreviation expansion for Emacs. Its fairly
;; similar to "dabbrev" expansion, which works based on the contents
;; of the current buffer (or other buffers).
;;
;; Predictive abbreviation expansion works based on the previously
;; written text. Unlike dynamic abbreviation, the text is analysed
;; during idle time, while Emacs is doing nothing else. `pabbrev-mode'
;; tells you when this is happening. If this irritates you unset
;; `pabbrev-idle-timer-verbose'. The advantage of this is that its
;; very quick to look up potential abbreviations, which means that the
;; can be constantly displayed, without interfering with the user as
;; they type. Certainly it works for me, on an old laptop, typing as
;; fast as I can (which is fast, since I learnt to type with four
;; fingers).
;;
;; pabbrev's main entry point is through the minor mode
;; `pabbrev-mode'. There is also a global minor mode, called
;; `global-pabbrev-mode', which does the same in all appropriate
;; buffers.
;; The current user interface looks like so...
;;
;; p[oint]
;; pr[ogn]
;; pre[-command-hook]
;; pred[ictive]
;;
;; As the user types the system narrows down the possibilities. The
;; narrowing is based on how many times the words have been used
;; previously. By hitting [tab] at any point the user can complete the
;; word. The [tab] key is normally bound to `indent-line'.
;; `pabbrev-mode' preserves access to this command (or whatever else
;; [tab] was bound to), if there is not current expansion.
;;
;; Sometimes you do not want to select the most commonly occurring
;; word, but a less frequently occurring word. You can access this
;; functionality by hitting [tab] for a second time. This takes you
;; into a special suggestions buffer, from where you can select
;; secondary selections. See `pabbrev-select-mode' for more
;; details. There is also an option `pabbrev-minimal-expansion-p'
;; which results in the shortest substring option being offered as the
;; first replacement.
;;
;; But is this actually of any use? Well having use the system for a
;; while now, I can say that it is sometimes. I originally thought
;; that it would be good for text, but in general its not so
;; useful. By the time you have realised that you have an expansion
;; that you can use, hit tab, and checked that its done the right
;; thing, you could have just typed the word directly in. It's much
;; nicer in code containing buffers, where there tend to be lots of
;; long words, which is obviously where an abbreviation expansion
;; mechanism is most useful.
;;
;; Currently pabbrev builds up a dictionary on a per major-mode basis.
;; While pabbrev builds up this dictionary automatically, you can also
;; explicitly add a buffer, or a region to the dictionary with
;; `pabbrev-scavenge-buffer', or `pabbrev-scavenge-region'. There is
;; also a command `pabbrev-scavenge-some' which adds some words from
;; around point. pabbrev remembers the word that it has seen already, ;; so run these commands as many times as you wish.
(fset 'pabbrev-suggestions-goto-buffer 'pabbrevx-suggestions-goto-buffer)
|