>From 4a102722170673a23f80cab7e552bc8696a9c935 Mon Sep 17 00:00:00 2001 Message-Id: <4a102722170673a23f80cab7e552bc8696a9c935.1636553396.git.info@protesilaos.com> From: Protesilaos Stavrou Date: Wed, 10 Nov 2021 16:08:42 +0200 Subject: [PATCH] Make hl-line-mode use semantic line highlighting * etc/NEWS: Document the new face, user option, buffer-local variable, and underlying rationale. * lisp/hl-line.el (hl-line-selection): New face for selection-based user interfaces. (hl-line-selection-ui): User option to toggle the feature. (hl-line-select-line-style): Buffer-local variable intended for major modes to register themselves as relevant for the purposes of selection-based interactivity. (hl-line--face): Helper function to select the appropriate face. (hl-line-make-overlay): Use helper function. --- etc/NEWS | 20 ++++++++++++++++++++ lisp/hl-line.el | 46 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/etc/NEWS b/etc/NEWS index 97da145bc3..624f4c6f5a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -94,6 +94,26 @@ These will take you (respectively) to the next and previous "page". --- *** 'describe-char' now also outputs the name of emoji combinations. +** Semantic hl-line-mode +It is now possible to differentiate between two types of highlighting: +(i) line selection, or (ii) simple line highlight. The former is +appropriate for interfaces that operate on the current line (e.g. a +listing of email threads), while the latter helps identify the point +on the vertical axis. + +Major modes can register themselves as having a selection-based +interface by setting the local variable 'hl-line-select-line-style' to +non-nil. In that case, they will use the new 'hl-line-selection' +face. + +The user option 'hl-line-selection-ui' can be set to nil to disable +this feature altogether, meaning that only the 'hl-line-face' will be +applied. + +Users or theme developers may, in turn, choose to make the 'hl-line' +face more subtle while allowing a more prominent style where it is +really needed via the 'hl-line-selection' face. + ** Outline Minor Mode +++ diff --git a/lisp/hl-line.el b/lisp/hl-line.el index 26cfcc3f9c..2eca090376 100644 --- a/lisp/hl-line.el +++ b/lisp/hl-line.el @@ -79,6 +79,17 @@ (defface hl-line :version "22.1" :group 'hl-line) +(defface hl-line-selection + '((default :extend t) + (((class color) (min-colors 88) (background light)) + :background "#b0d8ff") + (((class color) (min-colors 88) (background dark)) + :background "#103265") + (t :inherit hl-line)) + "Like `hl-line' face, but intended to indicate a selection UI." + :version "29.1" + :group 'lin) + (defcustom hl-line-face 'hl-line "Face with which to highlight the current line in Hl-Line mode." :type 'face @@ -92,6 +103,22 @@ (defcustom hl-line-face 'hl-line (when (overlayp global-hl-line-overlay) (overlay-put global-hl-line-overlay 'face hl-line-face)))) +(defcustom hl-line-selection-ui t + "When non-nil, apply `hl-line-selection' face if possible. +That face is used in major modes that opt-in to supporting the +semantics of a selection-based user interface, instead of the +standard line highlight which may be treated as a means of +identifying the point in the buffer. + +Major modes register themselves for this feature by setting the +buffer-local variable `hl-line-select-line-style' to non-nil. + +When this option is set to nil, the HL-Line mode always applies +the `hl-line-face'." + :type 'boolean + :version "29.1" + :group 'hl-line) + (defcustom hl-line-sticky-flag t "Non-nil means the HL-Line mode highlight appears in all windows. Otherwise Hl-Line mode will highlight only in the selected @@ -128,6 +155,17 @@ (defvar hl-line-overlay-buffer nil (defvar hl-line-overlay-priority -50 "Priority used on the overlay used by hl-line.") +(defvar-local hl-line-select-line-style nil + "When non-nil use `hl-line-selection' instead of `hl-line' face. +This variable is meant to be set to non-nil in major modes where +the line highlight denotes selecting the current entry, rather +than merely highlighting where the cursor is. + +Users/themes can thus differentiate between the faces `hl-line' +and `hl-line-selection' based on their semantics: the former may +be set to a more subtle style, the latter to a more prominent +one.") + ;;;###autoload (define-minor-mode hl-line-mode "Toggle highlighting of the current line (Hl-Line mode). @@ -153,10 +191,16 @@ (define-minor-mode hl-line-mode (hl-line-unhighlight) (remove-hook 'change-major-mode-hook #'hl-line-unhighlight t))) +(defun hl-line--face () + "Use appropriate face for line highlight." + (if (and hl-line-select-line-style hl-line-selection-ui) + 'hl-line-selection + hl-line-face)) + (defun hl-line-make-overlay () (let ((ol (make-overlay (point) (point)))) (overlay-put ol 'priority hl-line-overlay-priority) ;(bug#16192) - (overlay-put ol 'face hl-line-face) + (overlay-put ol 'face (hl-line--face)) ol)) (defun hl-line-highlight () -- 2.33.1