[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/hl-block-mode 877e14c064 01/64: Initial block highlighting
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/hl-block-mode 877e14c064 01/64: Initial block highlighting mode. |
Date: |
Thu, 7 Jul 2022 12:00:00 -0400 (EDT) |
branch: elpa/hl-block-mode
commit 877e14c0645397aa8c1a45eb34ea70f3ecd21280
Author: Campbell Barton <ideasman42@gmail.com>
Commit: Campbell Barton <ideasman42@gmail.com>
Initial block highlighting mode.
---
hl-block-mode.el | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 158 insertions(+)
diff --git a/hl-block-mode.el b/hl-block-mode.el
new file mode 100644
index 0000000000..f8e0d4a487
--- /dev/null
+++ b/hl-block-mode.el
@@ -0,0 +1,158 @@
+;;; hl-block-mode.el --- minor mode for highlighting blocks
+
+;; Author: Campbell Barton <ideasman42@gmail.com>
+;; Version: 0.1
+
+;;; Commentary:
+
+;; TODO.
+;; - More control of alpha blending.
+;; - Options to highlight bracket types besides '{}'.
+
+;;; Code:
+
+(defcustom hl-block-delay 0.3
+ "Idle time before highlighting."
+ :group 'hl-block-mode
+ :type 'float)
+(defcustom hl-block-color-tint "#040404"
+ "Color to add/subtract from the background each scope step."
+ :group 'hl-block-mode
+ :type 'float)
+
+(defun hl-block--syntax-prev-curly-brace (pt)
+ (let
+ ((start (ignore-errors (elt (syntax-ppss pt) 1)))
+ )
+ (when start
+ (if (char-equal ?{ (char-after start))
+ start
+ (hl-block--syntax-prev-curly-brace (1- start))
+ )
+ )
+ )
+ )
+(defun hl-block--find-all-ranges (pt)
+ "Return a list of ranges starting from 'pt', outer-most to inner-most."
+ (let*
+ (
+ (start
+ ;; (ignore-errors (elt (syntax-ppss pt) 1))) ;; works for lisp
+ (hl-block--syntax-prev-curly-brace pt))
+ (end
+ (when start (or (ignore-errors (scan-sexps start 1)) pt)))
+ (range_prev
+ (when start (hl-block--find-all-ranges start)))
+ )
+ (when start
+ (if range_prev
+ (cons (list start end) range_prev)
+ (list (list start end))
+ )
+ )
+ )
+ )
+(defun hl-block--color-values-as-string (r g b)
+ "Build a color from R G B.
+Inverse of `color-values'."
+ (format
+ "#%02x%02x%02x"
+ (ash r -8)
+ (ash g -8)
+ (ash b -8)))
+(defun hl-block--overlay-clear ()
+ (when (boundp 'hl-block-overlay)
+ (mapc 'delete-overlay hl-block-overlay))
+ (setq hl-block-overlay (list))
+ )
+(defun hl-block--overlay-refresh ()
+ (hl-block--overlay-clear)
+ (let
+ ((block-list (save-excursion (hl-block--find-all-ranges (point)))))
+ (when block-list
+ (let*
+ (
+ ;; (start-prev (point-min))
+ ;; (end-prev (point-max))
+ (block-list
+ (if (cdr block-list)
+ (reverse block-list)
+ (cons (list (point-min) (point-max)) block-list)
+ )
+ )
+ (start-prev (nth 0 (nth 0 block-list)))
+ (end-prev (nth 1 (nth 0 block-list)))
+ (block-list-len (length block-list))
+ (block-list-last (1- block-list-len))
+ (bg-color (color-values (face-attribute 'default :background)))
+ (bg-color-tint (color-values hl-block-color-tint))
+ ;; Check dark background is light/dark.
+ (do-highlight (> 98304 (apply '+ bg-color)))
+ )
+ (seq-map-indexed
+ (lambda (elem_range i)
+ (let*
+ (
+ (i-next (1+ i))
+ (i-tint (- block-list-len i))
+ (start (nth 0 elem_range))
+ (end (nth 1 elem_range))
+ (elem-overlay-start (make-overlay start start-prev))
+ (elem-overlay-end (make-overlay end-prev end))
+ (bg-color-blend
+ (apply 'hl-block--color-values-as-string
+ (if do-highlight
+ (cl-mapcar '(lambda (a b) (+ a (* i-tint b))) bg-color
bg-color-tint)
+ (cl-mapcar '(lambda (a b) (- a (* i-tint b))) bg-color
bg-color-tint)
+ )
+ )
+ )
+ )
+ (overlay-put elem-overlay-start 'face `(:background
,bg-color-blend))
+ (overlay-put elem-overlay-end 'face `(:background
,bg-color-blend))
+ (add-to-list 'hl-block-overlay elem-overlay-start)
+ (add-to-list 'hl-block-overlay elem-overlay-end)
+ (setq start-prev start)
+ (setq end-prev end)
+ )
+ )
+ (cdr block-list)
+ )
+ )
+ )
+ )
+ )
+;; Timer
+(defvar hl-block--delay-timer nil)
+(defun hl-block--overlay-delay ()
+ (when (timerp hl-block--delay-timer)
+ (cancel-timer hl-block--delay-timer))
+ (setq hl-block--delay-timer
+ (run-with-idle-timer hl-block-delay t
+ 'hl-block--overlay-refresh)
+ )
+ )
+(defun hl-block-mode-enable ()
+ (add-hook 'post-command-hook 'hl-block--overlay-delay)
+ )
+(defun hl-block-mode-disable ()
+ (hl-block--overlay-clear)
+ (when (timerp hl-block--delay-timer)
+ (cancel-timer hl-block--delay-timer))
+ (remove-hook 'post-command-hook 'hl-block--overlay-delay)
+ )
+
+;;;###autoload
+(define-minor-mode hl-block-mode
+ "Highlight block under the cursor."
+ :lighter ""
+ (if hl-block-mode
+ (progn
+ (jit-lock-unregister 'hl-block-mode-enable)
+ (hl-block-mode-enable))
+ (progn
+ (jit-lock-unregister 'hl-block-mode-enable)
+ (hl-block-mode-disable))))
+
+(provide 'hl-block-mode)
+;;; hl-block-mode.el ends here
- [nongnu] branch elpa/hl-block-mode created (now 7e0452c768), ELPA Syncer, 2022/07/07
- [nongnu] elpa/hl-block-mode 877e14c064 01/64: Initial block highlighting mode.,
ELPA Syncer <=
- [nongnu] elpa/hl-block-mode 6f9dfee5f7 26/64: Cleanup: use two space indentation, ELPA Syncer, 2022/07/07
- [nongnu] elpa/hl-block-mode 5436b8b210 41/64: Cleanup: minor changes to internal logic, ELPA Syncer, 2022/07/07
- [nongnu] elpa/hl-block-mode cceb66c9d7 16/64: Declare hl-block-overlay as a local variable, ELPA Syncer, 2022/07/07
- [nongnu] elpa/hl-block-mode 913447abd7 15/64: Fix typo, ELPA Syncer, 2022/07/07
- [nongnu] elpa/hl-block-mode ed833baa1a 21/64: add global mode to usage docs, ELPA Syncer, 2022/07/07
- [nongnu] elpa/hl-block-mode 6310fc8563 05/64: Create LICENSE, ELPA Syncer, 2022/07/07
- [nongnu] elpa/hl-block-mode f957c01cf8 06/64: Docs: add missing sections to header, ELPA Syncer, 2022/07/07
- [nongnu] elpa/hl-block-mode 054dc21949 08/64: Enforce use of spaces for indentation, ELPA Syncer, 2022/07/07
- [nongnu] elpa/hl-block-mode bb35a6c56b 47/64: Add hl-block-single-level & hl-block-style, ELPA Syncer, 2022/07/07
- [nongnu] elpa/hl-block-mode 54ab1d6aba 60/64: Fix bracket display highlighting a character next to (point), ELPA Syncer, 2022/07/07