summaryrefslogtreecommitdiff
path: root/completion-conf.el
blob: e567eb716a4fdb433372a347d7b9b023f6f871cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
;;; completion-conf.el --- My configurations for completions inside Emacs  -*- lexical-binding: t; -*-

;; Author: JSDurand <mmemmew@gmail.com>
;; Created: 2021-01-22 21:41:30
;; Version: 0.0.1
;; Keywords: matching

;; This file is NOT part of GNU/Emacs.

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <https://www.gnu.org/licenses/>.

;;; Commentary:

;; Thsi file is my configurations of the built in completion framework
;; in Emacs. I intend to configure it to use my yet-to-come completion
;; style using suffix trees.

;;; Code:

(require 'minibuffer)
(require 'simple)

(setq completion-styles '(substring partial-completion flex))
(setq completion-category-defaults nil)
(setq completion-flex-nospace nil)
(setq completion-pcm-complete-word-inserts-delimiters t)
(setq completion-show-help nil)
(setq completion-ignore-case t)
(setq read-file-name-completion-ignore-case t)
(setq read-buffer-completion-ignore-case t)
(setq resize-mini-windows t)

(define-key minibuffer-local-completion-map (vector 'down) #'durand-embark-scroll-down-or-go-to-completions)
(define-key minibuffer-local-completion-map (vector 'up) #'durand-embark-scroll-up-or-go-to-completions)
(define-key completion-list-mode-map (vector 'down) #'durand-completion-scroll-down-or-go-to-minibuffer)
(define-key completion-list-mode-map (vector 'up) #'durand-completion-scroll-up-or-go-to-minibuffer)

;;;###autoload
(defvar durand-headlong-entered-minibuffer-p nil
  "Whether or not we have entered minibuffer.

This is used for determining if we shall exit the minibuffer when
there is only one candidate left.")

;;;###autoload
(defun durand-headlong-minibuffer-setup-hook ()
  "The entry for the completion to be headlong.
Simply add this function to `minibuffer-setup-hook'."
  ;; NOTE: When we run this function we first enter minibuffer, so we
  ;; set a variable to its appropriate value.
  (set 'durand-headlong-entered-minibuffer-p nil)
  (add-hook 'post-command-hook 'durand-headlong-post-command-hook t)
  (add-hook 'minibuffer-exit-hook 'durand-headlong-minibuffer-exit-hook))

;;;###autoload
(defun durand-headlong-post-command-hook ()
  "Exit the minibuffer if there is only one candidate left.

In practice, when we first enter minibuffer, there is some
abnormal behaviour, so we only check when we have entered the
minibuffer as usual."
  (let ((comps (completion-all-completions
                (minibuffer-contents)
                minibuffer-completion-table minibuffer-completion-predicate
                (- (point) (minibuffer-prompt-end)))))
    (cond
     ((and durand-headlong-entered-minibuffer-p
           comps
           (not (consp (cdr comps))))
      (minibuffer-force-complete-and-exit))
     (t (set 'durand-headlong-entered-minibuffer-p t)))))

;;;###autoload
(defun durand-headlong-minibuffer-exit-hook ()
  "Remove the hooks we added."
  (remove-hook 'post-command-hook 'durand-headlong-post-command-hook)
  (remove-hook 'minibuffer-setup-hook 'durand-headlong-minibuffer-setup-hook)
  (remove-hook 'minibuffer-exit-hook 'durand-headlong-minibuffer-exit-hook))


(provide 'completion-conf)
;;; completion-conf.el ends here