emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/num3-mode fdf4d633e5 2/2: Add datetime highlighting


From: Michał Nazarewicz
Subject: [elpa] externals/num3-mode fdf4d633e5 2/2: Add datetime highlighting
Date: Fri, 26 Aug 2022 12:34:51 -0400 (EDT)

branch: externals/num3-mode
commit fdf4d633e541875a6f765f5c3c8e0d4911122ed3
Author: Peter Mao <peter.mao@gmail.com>
Commit: Michal Nazarewicz <mina86@mina86.com>

    Add datetime highlighting
    
    Add highlighting to timestamps formatted using the basic ISO 8061 basic
    form which is generally hard-to-read, e.g.
        YYYYmmddTHHMMSS.ssssss+HHMM
        ^^^^  ^^ ^^  ^^    ^^^ ^^
    
    * num3-mode.el (num3--number-re): Add regular expression cases for
    matching timestamps.
    (num3--matcher): Add support for the new cases.
    * test.el (num3-mode-datetime): Add test cases for timestamps.
    
    [mina86@mina86.com: rewrote regex to use `rx`, introduced other minor
    refactorings and documented things a bit more]
---
 num3-mode.el | 124 +++++++++++++++++++++++++++++++++++++++++------------------
 test.el      |   8 ++++
 2 files changed, 94 insertions(+), 38 deletions(-)

diff --git a/num3-mode.el b/num3-mode.el
index 667b3de928..3d390f5807 100644
--- a/num3-mode.el
+++ b/num3-mode.el
@@ -5,7 +5,7 @@
 ;; Author: Felix Lee <felix8a@gmail.com>, Michal Nazarewicz <mina86@mina86.com>
 ;; Maintainer: Michal Nazarewicz <mina86@mina86.com>
 ;; Keywords: faces, minor-mode
-;; Version: 1.4
+;; Version: 1.5
 
 ;; 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
@@ -22,10 +22,28 @@
 
 ;;; Commentary:
 
-;; Num3 is a minor mode that makes long numbers more readable by
-;; highlighting groups of 3 (customisable) decimal digits or 4 hex
-;; digits when font-lock is on.  Highlighting alternates between two
-;; faces that can be customised.
+;; Num3 is a minor mode that makes long numbers and other numeric data
+;; more readable by highlighting groups of digits in a string when
+;; font-lock is on.
+;;
+;; For example, an integer ‘28318530’ would be split into 3-digit-long
+;; groups as ‘(28)(318)(530)’ and then each group highlighted using
+;; alternating face.  This improves readability of the number by clearly
+;; denoting millions, thousands and ones.  Besides integers and real
+;; numbers, the mode also supports dates in ‘20151021T0728’ format.
+;;
+;; The mode supports:
+;; - decimal numbers, e.g. 1234567 or 6.2831853,
+;; - hexadecimal integers, e.g. 0x1921FB5, #x1921FB5 or unprefixed 1921FB5,
+;; - octal integers, e.g. 0o1444176 or #o1444176,
+;; - binary integers, e.g. 0b1100100100 or #b1100100100,
+;; - hexadecimal floating point numbers, e.g. 0x1.921FB54p+2,
+;; - timestamps, e.g. 20151021T0728
+;;
+;; Decimal and octal numbers are split into 3-digit-long groups (the
+;; length is customisable); hexadecimal and binary numbers are split
+;; into 4-digit-long groups; timestamps are split based on the part of
+;; the date or time.
 
 ;;; Usage:
 
@@ -68,31 +86,31 @@ addition to any other font-lock highlighting."
 ;;;###autoload
 (define-minor-mode num3-mode
   "Toggle num3 minor mode in the current buffer.
-Num3 minor mode makes long numbers more readable by highlighting
-groups of digits when font-lock mode is enabled.
+Num3 minor mode makes long numbers and timestamps more readable
+by highlighting groups of digits when font-lock mode is enabled.
 
 If a number is longer than `num3-threshold', the mode will split
 it into a group of `num3-group-size' (if number is decimal) or
-four (if number is hexadecimal or binary) digits.
-
-Hexadecimal numbers are recognised by \"0x\" or \"#x\"
-prefix (case insensitive) and binary numbers by \"0b\" or \"#b\"
-prefix.  (There is no special handling for octal numbers –
-starting with \"0o\" or \"#o\" – and instead they are handled
-like decimal numbers).
-
-Decimal fractions are recognised as well and grouped from the
-beginning rathar then the end.  For instance, with group size of
-three, a number \"12345.12345\" will be split into groups as
-follows: \"12|345.123|45\".  Fractions without integer part are
-also recognised, eg. \".12345\".
-
-Groups are highlighted alternately using `num3-face-odd' and
-`num3-face-even' faces.  `num3-face-odd' face (which is empty by
-default) is the one used for the group closest to the decimal
-point, i.e. groups are counted starting with one outwards from
-the (place where) decimal point (would be) is."
-  :lighter " num3"
+four (if number is hexadecimal or binary) digits and highlight
+alternating groups using `num3-face-odd' and ‘num3-face-even’
+faces.
+
+Hexadecimal integers are recognised by \"0x\" or \"#x\" prefix
+and binary numbers by \"0b\" or \"#b\" prefix.  There is no
+special handling for octal numbers – starting with \"0o\" or
+\"#o\" – and instead they are handled like decimal numbers.
+
+Decimal and hexadecimal floating-point numbers are recognised as
+well.  Their fractional part is grouped from the beginning rather
+then the end.  For instance \"12345.12345\" will be split into
+groups as follows: \"12|345.123|45\".  Hexadecimal floating-point
+numbers must start with \"0x\" prefix and include the exponent,
+e.g. \"0x1d.2e5p3\" (which equals 29 + 741/4096 * 2⁵)
+
+Timestamps are recognised if they match basic ISO 8061 form (for
+example \"20220805T1258\") and can include seconds, fractions of
+seconds and timezone offset."
+  :lighter    " num3"
   (if num3-mode
       (unless (assoc 'num3--matcher font-lock-keywords)
         (font-lock-add-keywords nil '(num3--matcher) 'append))
@@ -110,6 +128,20 @@ the (place where) decimal point (would be) is."
   ;; grouping.
   (rx
    (or
+    ;; ISO 8601 basic form, e.g. ‘20210203T0405’.  Note that this needs to be
+    ;; placed before other cases because we want it to match before the regex
+    ;; engine matches plain decimal numbers.
+    (submatch-n
+     5                                             ; 5 - date-time
+     (= 8 num)
+     ?T
+     (submatch-n
+      6                                            ; 6 - time
+      (= 2 num)
+      (? (= 2 num)
+         (? (= 2 num)
+            (? ?. (submatch-n 3 (+ num))))))       ; 3 - decimal fraction
+     (? (in "-+") (submatch-n 7 (+ num))))         ; 7 - offset
     ;; ‘#x1234’
     (seq ?# (in "xX") (submatch-n 1 (+ hex)))      ; 1 - hexadecimal integer
     ;; ‘0x1234’ or ‘0x1234.5678p±9’.  Hexadecimal floating point numbers
@@ -154,7 +186,21 @@ Performs fontification of numbers from point to LIM."
       (num3--int  (match-beginning 1) (match-end 1) 4)
       (num3--frac (match-beginning 4) (match-end 4) 4)
       (num3--int  (match-beginning 2) (match-end 2) num3-group-size)
-      (num3--frac (match-beginning 3) (match-end 3) num3-group-size) ))
+      (num3--frac (match-beginning 3) (match-end 3) num3-group-size)
+
+      ;; date-time
+      (when-let ((lo (match-beginning 5)))
+        (num3--put t      lo     (+ lo  4))               ; year
+        (num3--put nil (+ lo  4) (+ lo  6))               ; month
+        (num3--put t   (+ lo  6) (+ lo  8))               ; day
+        (let ((lo (match-beginning 6)) (hi (match-end 6)))
+          (num3--frac lo (min hi (+ 6 lo)) 2 0 t))        ; hhmmss
+        ;; hhmm of the timezone offset, but check length in case it’s too long
+        ;; to be an offset and then treat it like a number.
+        (when-let ((lo (match-beginning 7)) (hi (match-end 7)))
+          (if (<= (- hi lo) 4)
+              (num3--frac lo hi 2 0 t)
+            (num3--int lo hi num3-group-size))))))
   nil)
 
 (defun num3--int (lo hi n)
@@ -170,18 +216,20 @@ faces.  Grouping is done from the end, eg. (12)(345)."
         (num3--put even (max lo (- hi n)) hi)
         (setq hi (- hi n) even (not even))))))
 
-(defun num3--frac (lo hi n)
+(defun num3--frac (lo hi n &optional threshold even)
   "Highlight groups of digits in a long number.
 LO and HI arguments specify the range where the number is
-located.  If the length of that region exceeds `num3-threshold',
-the function will split it into groups of N digits and fontify
-tham alternately using `num3-face-odd' and `num3-face-even'
-faces.  Grouping is done from the beginning, eg. (123)(45)."
-  (when (and lo (>= (- hi lo) num3-threshold))
-    (let (even)
-      (while (< lo hi)
-        (num3--put even lo (min hi (+ lo n)))
-        (setq lo (+ lo n) even (not even))))))
+located.  If the length of that region exceeds THRESHOLD (or
+`num3-threshold' if that argument is nil), the function will
+split it into groups of N digits and fontify tham alternately
+using `num3-face-odd' and `num3-face-even' faces.  Grouping is
+done from the beginning, eg. (123)(45).  EVEN argument specify
+whether the first group should be highlighted using even or odd
+face."
+  (when (and lo (>= (- hi lo) (or threshold num3-threshold)))
+    (while (< lo hi)
+      (num3--put even lo (min hi (+ lo n)))
+      (setq lo (+ lo n) even (not even)))))
 
 (defun num3--put (even lo hi)
   "Add font lock text property to highlight a single group of digit.
diff --git a/test.el b/test.el
index aa57df8ad0..dd1bf51876 100644
--- a/test.el
+++ b/test.el
@@ -104,4 +104,12 @@ caret (‘^’).  For example:
   (num3-mode-test "0x6a.12345 0x23456.28318"
                   "0x6a.___^^ 0x^____.___^^"))
 
+(ert-deftest num3-mode-datetime ()
+  (num3-mode-test
+   "20220804T20 20220804T2057 20220804T205700 20220804T205730.123 
20220804T205730.12345"
+   "^^^^__^^T^^ ^^^^__^^T^^__ ^^^^__^^T^^__^^ ^^^^__^^T^^__^^.123 
^^^^__^^T^^__^^.___^^")
+  (num3-mode-test
+   "20220804T20-07 20220804T2057+1030 20220804T205700+0700 
20220804T205730.123+0000 20220804T205730.12345+1000"
+   "^^^^__^^T^^-^^ ^^^^__^^T^^__+^^__ ^^^^__^^T^^__^^+^^__ 
^^^^__^^T^^__^^.123+^^__ ^^^^__^^T^^__^^.___^^+^^__"))
+
 ;;; test.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]