;;; zcomplete.el --- highlight and natural move throw *Completions* buffer -*- lexical-binding: t -*- ;; Copyright (C) 2020 Free Software Foundation, Inc. ;; Author: Jimmy Aguilar Mena ;; Created: Aug 2020 Jimmy Aguilar Mena spacibba@aol.com ;; Keywords: help, abbrev ;; This file is part of GNU Emacs. ;; GNU Emacs 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. ;; GNU Emacs 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 GNU Emacs. If not, see . ;;; Commentary: ;; This package has 2 different functionalities: ;; 1) zcomplete-mode: To auto-skip the completion buffers more often ;; 1) zcomplete-highlight-mode: To highlight current candidate ;;; Code: (require 'simple) (require 'minibuffer) ;; zcomplete-highlight-mode ========================================== (defgroup zcomplete nil "Highlight candidates in completions buffer." :version "28.1" :group 'completion) (defface zcomplete-highlight '((t :inherit highlight :extend t)) "Default face for highlighting the current line in Hl-Line mode." :version "28.1" :group 'zcomplete) (defvar zcomplete--overlay nil "Overlay to use when `zcomplete-highlight-mode' is enabled.") (defun zcomplete-highlight--pre-hook () "Highlight current candidate in *Completions* when ``zcomplete-highlight''." (when (overlayp zcomplete--overlay) (delete-overlay zcomplete--overlay))) (defun zcomplete-highlight--highlight () "Highlight current candidate if point in a candidate." (let* ((point (point)) (hpoint (or (and (get-text-property point 'mouse-face) point) (and (get-text-property (1- point) 'mouse-face) (1- point))))) (when hpoint (move-overlay zcomplete--overlay (previous-single-property-change (1+ hpoint) 'mouse-face nil (point-min)) (next-single-property-change hpoint 'mouse-face nil (point-max)))))) (defun zcomplete-highlight--setup-hook () "Function to call when enabling the `completion-highlight-mode' mode. It is called when showing the *Completions* buffer." (with-current-buffer "*Completions*" (zcomplete-highlight--highlight) (add-hook 'pre-command-hook #'zcomplete-highlight--pre-hook nil t) (add-hook 'post-command-hook #'zcomplete-highlight--highlight nil t))) ;;;###autoload (define-minor-mode zcomplete-highlight-mode "Completion highlight mode to enable candidates highlight in the minibuffer." :global t :group 'minibuffer (cond (zcomplete-highlight-mode (setq zcomplete--overlay (make-overlay 0 0)) (overlay-put zcomplete--overlay 'face 'zcomplete-highlight) (add-hook 'completion-setup-hook #'zcomplete-highlight--setup-hook t)) (t (remove-hook 'completion-setup-hook #'zcomplete-highlight--setup-hook) (delete-overlay zcomplete--overlay)))) ;; zcomplete-mode ==================================================== (defvar-keymap zcomplete-map :doc "Keymap used in *Completions* on ``zcomplete-mode''" :parent completion-list-mode-map "z" nil "n" nil "p" nil "q" nil "g" nil "h" nil "DEL" nil) (defun zcomplete--try-on-minibuffer () "Try to execute the binding on minibuffer." (switch-to-minibuffer) (if-let ((command (lookup-key (current-active-maps) (this-single-command-keys)))) (progn (minibuffer-hide-completions) (call-interactively command) t) (switch-to-completions) nil)) (defun zcomplete--pre-hook () "Try on minibuffer when the command is not in *Completions* map." (when (eq this-command 'undefined) (zcomplete--try-on-minibuffer))) (defun zcomplete--hack (data context signal) "Alternative to command-error-default-function. This will try to execute on minibuffer, else emits the error" (unless (and (string= (buffer-name) "*Completions*") (zcomplete--try-on-minibuffer)) (command-error-default-function data context signal))) (defun zcomplete--setup-hook () "Function to call when enabling the `completion-highlight-mode' mode. It is called when showing the *Completions* buffer." (with-current-buffer "*Completions*" (setq-local command-error-function #'zcomplete--hack mode-line-format nil) (use-local-map zcomplete-map) (add-hook 'pre-command-hook #'zcomplete--pre-hook nil t))) ;;;###autoload (define-minor-mode zcomplete-mode "Completion auto-jump to the minibuffer." :global t :group 'minibuffer (if zcomplete-mode (add-hook 'completion-setup-hook #'zcomplete--setup-hook t) (remove-hook 'completion-setup-hook #'zcomplete--setup-hook))) (provide 'zcomplete) ;;; zcomplete.el ends here