;; Time-stamp: <2026-03-22 11h47 GMT (anker)> (use-package savehist :ensure t :init (savehist-mode)) ;; ----------------------------------------------------------------------------- ;; General configuration (use-package emacs :init ;; Add prompt indicator to `completing-read-multiple'. (defun crm-indicator (args) (cons (concat "[CRM] " (car args)) (cdr args))) (advice-add #'completing-read-multiple :filter-args #'crm-indicator) ;; Grow and shrink minibuffer ;;(setq resize-mini-windows t) ;; Do not allow the cursor in the minibuffer prompt (setq minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt)) (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) ;; Enable recursive minibuffers (setq enable-recursive-minibuffers t)) (use-package icomplete :hook ((after-init . (lambda () (icomplete-vertical-mode 1))) (icomplete-minibuffer-setup . (lambda () (setq truncate-lines t)))) :init (defun my-completing-read-in-region (start end collection &optional predicate) "Prompt for completion of region in the minibuffer if non-unique. Use as a value for `completion-in-region-function'." (let* ((initial (buffer-substring-no-properties start end)) (all (completion-all-completions initial collection predicate (length initial))) (metadata (completion-metadata initial collection predicate)) (exit-fn (completion-metadata-get metadata 'exit-function)) (completion (cond ((atom all) nil) ((and (consp all) (atom (cdr all))) (car all)) (t (completing-read "Completion: " collection predicate t initial))))) (cond (completion (let* ((bounds (completion-boundaries completion collection nil "")) (prefix-len (car bounds)) ;; If completion includes a prefix portion, adjust start (new-start (if (> prefix-len 0) (max start (- end prefix-len)) start))) (completion--replace new-start end completion) (when exit-fn (funcall exit-fn completion 'finished))) t) (t (message "No completion") nil)))) (defun my-icomplete-backspace () "Delete back to previous / in paths, or normal backspace otherwise." (interactive) (if (looking-back "[^/]/" (line-beginning-position)) (let ((slash-pos (save-excursion (backward-word 1) (search-backward "/" nil t)))) (delete-region (1+ slash-pos) (point))) (delete-backward-char 1))) (defun my-switch-to-buffer-with-recentf () "Switch to buffer or recent file with visual separation." (interactive) (let* ((current-buffer (buffer-name (current-buffer))) (buffers (seq-remove (lambda (b) (or (string-prefix-p " " b) (string= b current-buffer))) (mapcar #'buffer-name (buffer-list)))) (recent-files (seq-take recentf-list 20)) (separator "─── Recent Files ───") (buffer-cands (mapcar (lambda (buf) (propertize buf 'multi-category (cons 'buffer buf))) buffers)) (header-cand (propertize separator 'multi-category (cons 'separator t))) (file-cands (mapcar (lambda (file) (propertize file 'multi-category (cons 'file file))) recent-files)) (all-cands (append buffer-cands (list header-cand) file-cands)) (my-table (lambda (string pred action) (pcase action ('metadata '(metadata (category . multi-category) (cycle-sort-function . identity))) ('all all-cands) ('lambda (or (try-completion string all-cands pred) string)) (_ (seq-filter (lambda (c) (string-prefix-p string (substring-no-properties c))) all-cands)))))) (let ((result (completing-read "Switch to: " my-table nil t))) (unless (string-empty-p result) (cond ((string= result separator) nil) ((file-exists-p result) (find-file result)) (t (switch-to-buffer result))))))) :bind (("C-x b" . my-switch-to-buffer-with-recentf) (:map icomplete-minibuffer-map ("TAB" . icomplete-force-complete) ("RET" . icomplete-force-complete-and-exit) ("" . my-icomplete-backspace))) :config (setq icomplete-compute-delay 0 icomplete-show-matches-on-no-input t icomplete-hide-common-prefix nil icomplete-prospects-height 10 icomplete-max-delay-chars 0 icomplete-scroll t) (setq completion-styles '(flex basic partial-completion) completion-ignore-case t) (advice-add 'completion-at-point :after #'minibuffer-hide-completions) (setq completion-in-region-function #'my-completing-read-in-region)) ;; ----------------------------------------------------------------------------- ;; Marginalia (use-package marginalia :ensure t :bind (:map minibuffer-local-map ("M-A" . marginalia-cycle)) :init (marginalia-mode))