;;; Shortening of names
+(defvar erc-track--shortened-names nil
+ "A cons of the last novel name-shortening params and the result.
+The CAR is a hash of environmental inputs such as options and
+parameters passed to `erc-track-shorten-function'. Its effect is
+only really noticeable during batch processing.")
+
+(defvar erc-track--shortened-names-current-hash nil)
+
+(defun erc-track--shortened-names-set (_ shortened)
+ "Remember SHORTENED names with hash of contextual params."
+ (cl-assert erc-track--shortened-names-current-hash)
+ (setq erc-track--shortened-names
+ (cons erc-track--shortened-names-current-hash shortened)))
+
+(defun erc-track--shortened-names-get (channel-names)
+ "Cache CHANNEL-NAMES with various contextual parameters.
+For now, omit relevant options like `erc-track-shorten-start' and
+friends, even though they do affect the outcome, because they
+likely change too infrequently to matter over sub-second
+intervals and are unlikely to be let-bound or set locally."
+ (when-let ((hash (setq erc-track--shortened-names-current-hash
+ (sxhash-equal (list channel-names
+ (buffer-list)
+ erc-track-shorten-function))))
+ (erc-track--shortened-names)
+ ((= hash (car erc-track--shortened-names))))
+ (cdr erc-track--shortened-names)))
+
+(gv-define-simple-setter erc-track--shortened-names-get
+ erc-track--shortened-names-set)
+
(defun erc-track-shorten-names (channel-names)
"Call `erc-unique-channel-names' with the correct parameters.
This function is a good value for `erc-track-shorten-function'.
(or (buffer-name buf)
""))
buffers))
- (short-names (if (functionp erc-track-shorten-function)
- (funcall erc-track-shorten-function
- long-names)
- long-names))
+ (erc-track--shortened-names-current-hash nil)
+ (short-names
+ (if (functionp erc-track-shorten-function)
+ (with-memoization
+ (erc-track--shortened-names-get long-names)
+ (funcall erc-track-shorten-function long-names))
+ long-names))
strings)
(while buffers
(when (car short-names)
'("#emacs" "#vi"))
'("#e" "#v"))) ))
+(ert-deftest erc-track--shortened-names ()
+ (let (erc-track--shortened-names
+ erc-track--shortened-names-current-hash
+ results)
+
+ (with-memoization (erc-track--shortened-names-get
+ '("apple" "banana" "cherries"))
+ '("a" "b" "c"))
+ (should (integerp (car erc-track--shortened-names)))
+ (should (equal (cdr erc-track--shortened-names) '("a" "b" "c")))
+ (push erc-track--shortened-names results)
+
+ ;; Redundant call doesn't run.
+ (with-memoization (erc-track--shortened-names-get
+ '("apple" "banana" "cherries"))
+ (should-not 'run)
+ '("a" "b" "c"))
+ (should (equal erc-track--shortened-names (car results)))
+
+ ;; Change in environment or context forces run.
+ (with-temp-buffer
+ (with-memoization (erc-track--shortened-names-get
+ '("apple" "banana" "cherries"))
+ '("x" "y" "z")))
+ (should (and (integerp (car erc-track--shortened-names))
+ (/= (car erc-track--shortened-names) (caar results))))
+ (should (equal (cdr erc-track--shortened-names) '("x" "y" "z")))
+ (push erc-track--shortened-names results)
+
+ (with-memoization (erc-track--shortened-names-get
+ '("apple" "banana" "cherries"))
+ '("1" "2" "3"))
+ (should (and (integerp (car erc-track--shortened-names))
+ (/= (car erc-track--shortened-names) (caar results))))
+ (should (equal (cdr erc-track--shortened-names) '("1" "2" "3")))))
+
(ert-deftest erc-track--erc-faces-in ()
"`erc-faces-in' should pick up both 'face and 'font-lock-face properties."
(let ((str0 (copy-sequence "is bold"))