0

I have re-defined blink-cursor-timer-function for the cursor to change colour. How can I modify this without re-defining the build-in function?

(defvar ramona-indicator-colour
  (list "#FFA500" "#8A8AFF" "#FF6161" "#61FF61"
        "#FFFF00" "#E859E8" "#FFFFFF" "#FFC370" "#C370FF")
  "Define list of cursor colours.")

(defvar ramona-indicator-point 0
  "Set colour of cursor defined by position in indicator colour list.")

(defun blink-cursor-timer-function ()
  "Blinks the cursor"

  (let ( (i ramona-indicator-point)
         (n (length ramona-indicator-colour)) )

    (when (not (internal-show-cursor-p))
      (when (>= i n) (setq i 0))
      (set-cursor-color (nth i ramona-indicator-colour))
      (setq i (+ 1 i))
      (setq ramona-indicator-point i))
    (internal-show-cursor nil (not (internal-show-cursor-p))) ))
5
  • If the purpose is to change the behavior of an original function that has already been defined, then a common approach is to redefine that function in order to achieve the desired modified behavior. There is no need to modify the source code containing the original function -- all that is needed is to ensure the library containing the original function has been loaded, and thereafter evaluate the new/modified function. Emacs will use the redefined function instead of the original once the aforementioned has occurred.
    – lawlist
    Commented Nov 30, 2022 at 16:03
  • What if others want to use the original? What can they do, besides commenting it out?
    – Dilna
    Commented Nov 30, 2022 at 16:43
  • One approach would be to define a variable that the user can customize and bind the variable to a default function, which the user can set to a different function if so desired. The code that uses the variable would use something like (funcall VARIABLE) For example, have a look at the variable initial-major-mode -- M-x find-variable RET initial-major-mode RET. It is bound to the function lisp-interaction-mode.
    – lawlist
    Commented Nov 30, 2022 at 16:58
  • Right. I fail to see what to do in my case though. If I need to call a different function, then I cannot use my implementation because I change the original function.
    – Dilna
    Commented Nov 30, 2022 at 17:20
  • Alternatives to redefining a function, include, but are not limited to advice. To temporarily let-bind a function to something different, you might be interested in cl-letf: stackoverflow.com/a/39564067
    – lawlist
    Commented Nov 30, 2022 at 17:23

1 Answer 1

0

If you only want to add a changing cursor color, then, as mentioned already by @lawlist, it is probably best to advice the function as follows:

(defvar ramona-indicator-colour
  (list "#FFA500" "#8A8AFF" "#FF6161"
        "#61FF61" "#FFFF00" "#E859E8"
        "#FFFFFF" "#FFC370" "#C370FF")
  "List of cursor colours.")

(defun ramona-blink-timer-advice ()
  (when (= blink-cursor-blinks-done 2) 
    (let* ((current-color (frame-parameter nil 'cursor-color))
           (next-color (cadr (member current-color ramona-indicator-colour))))
      (set-cursor-color
       (or next-color (car ramona-indicator-colour))))
    (setq blink-cursor-blinks-done 0)))

(advice-add 'blink-cursor-timer-function :before #'ramona-blink-timer-advice)

We reset the blink-cursor-blinks-done to 0 on each second call of the function, as the function is called twice for a single blink.

2
  • Cursor starts blinking but then it stops.
    – Dilna
    Commented Dec 1, 2022 at 7:15
  • Ah okay, I did not know that this was Emacs standard behavior. I have updated the answer. Commented Dec 1, 2022 at 8:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.