2
votes

If I use dabbrev-expand for expansion, Emacs searches the current buffer, then other buffers with the same mode. This is handled by dabbrev-friend-buffer-function which by default is set to dabbrev--same-major-mode-p.

This works fine, but I'd like to use hippie-expand.

(setq hippie-expand-try-functions-list
  '(try-expand-dabbrev
    try-expand-dabbrev-all-buffers))

This pulls completions from all buffers, even the buffers that don't match my current major mode.

How can I use hippie-expand with dabbrev completions only coming from buffers using the same major-mode as the current buffer?

2

2 Answers

2
votes

Quick and dirty solution: Copy the source code of the function try-expand-dabbrev-all-buffers to a new location, rename it (say) try-expand-dabbrev-all-buffers-same-mode, and replace the expression (buffer-list) with the expression:

(remove-if-not (lambda (x) (eq major-mode (with-current-buffer x major-mode)))
               (buffer-list))

(You'll need to (require 'cl) to get remove-if-not, or else re-implement it in terms of mapcar and delq.)

Then, of course, replace try-expand-dabbrev-all-buffers with try-expand-dabbrev-all-buffers-same-mode in hippie-expand-try-functions-list.

You can get the source of try-expand-dabbrev-all-buffers using C-hf.

1
votes

Based on Sean's excellent suggestion (and assuming you have the dash.el list utility library installed):

(autoload '--filter "dash" nil t)

;; only consider buffers in the same mode with try-expand-dabbrev-all-buffers
(defun try-expand-dabbrev-matching-buffers (old)
  (let ((matching-buffers (--filter
                           (eq major-mode (with-current-buffer it major-mode))
                           (buffer-list))))
    (flet ((buffer-list () matching-buffers))
      (try-expand-dabbrev-all-buffers old))))