bug-gnu-emacs
[Top][All Lists]
Advanced

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

bug#22873: #22873 (multiple fake cursors)


From: Keith David Bershatsky
Subject: bug#22873: #22873 (multiple fake cursors)
Date: Wed, 27 Dec 2017 17:20:46 -0800

John:  Here is an example modification to the most recent version Magnar's 
multiple-cursors package to make use of #22873 with the patch.diff from earlier 
today for Emacs 26.  I like yellow for even numbered columns and red for odd 
numbered columns, and I like the vertical bar fake cursor, so that is what is 
used in this example.

(require 'multiple-cursors-core)
(require 'cl) ;; for oddp and evenp

(add-hook 'multiple-cursors-mode-disabled-hook
          (lambda () (kill-local-variable 'mc-glyph-list)))

(defvar mc/use-built-in-cursors t
"Whether to use the built-in fake cursors.")

(defun mc/create-fake-cursor-at-point (&optional id)
  "Add a fake cursor and possibly a fake active region overlay based on point 
and mark.
Saves the current state in the overlay to be restored later."
  (unless mc--max-cursors-original
    (setq mc--max-cursors-original mc/max-cursors))
  (when mc/max-cursors
    (unless (< (mc/num-cursors) mc/max-cursors)
      (if (yes-or-no-p (format "%d active cursors. Continue? " 
(mc/num-cursors)))
          (setq mc/max-cursors (read-number "Enter a new, temporary maximum: "))
        (mc/remove-fake-cursors)
        (error "Aborted: too many cursors"))))
  (let ((overlay
          (if mc/use-built-in-cursors
            (make-overlay (point) (point))
            (mc/make-cursor-overlay-at-point))))
    (overlay-put overlay 'mc-id (or id (mc/create-cursor-id)))
    (overlay-put overlay 'type 'fake-cursor)
    (overlay-put overlay 'priority 100)
    (mc/store-current-state-in-overlay overlay)
    (when (use-region-p)
      (overlay-put overlay 'region-overlay
                   (mc/make-region-overlay-between-point-and-mark)))
    overlay))

(defun mc/execute-this-command-for-all-cursors-1 ()
  "Used with post-command-hook to execute supported commands for all cursors.
  It uses two lists of commands to know what to do: the run-once
list and the run-for-all list. If a command is in neither of these lists,
it will prompt for the proper action and then save that preference.
  Some commands are so unsupported that they are even prevented for
the original cursor, to inform about the lack of support."
  (unless mc--executing-command-for-fake-cursor
    (if (eq 1 (mc/num-cursors)) ;; no fake cursors? disable mc/mode
        (mc/mode 0)
      (when this-original-command
        (let ((original-command (or mc--this-command
                                    (command-remapping this-original-command)
                                    this-original-command)))
          ;; skip keyboard macros, since they will generate actual commands 
that are
          ;; also run in the command loop - we'll handle those later instead.
          (when (functionp original-command)
            ;; if it's a lambda, we can't know if it's supported or not
            ;; - so go ahead and assume it's ok, because we're just optimistic 
like that
            (if (or (not (symbolp original-command))
                    ;; lambda registered by smartrep
                    (string-prefix-p "(" (symbol-name original-command)))
                (mc/execute-command-for-all-fake-cursors original-command)
              ;; smartrep `intern's commands into own obarray to help
              ;; `describe-bindings'.  So, let's re-`intern' here to
              ;; make the command comparable by `eq'.
              (setq original-command (intern (symbol-name original-command)))
              ;; otherwise it's a symbol, and we can be more thorough
              (if (get original-command 'mc--unsupported)
                  (message "%S is not supported with multiple cursors%s"
                           original-command
                           (get original-command 'mc--unsupported))
                (when (and original-command
                           (not (memq original-command 
mc--default-cmds-to-run-once))
                           (not (memq original-command mc/cmds-to-run-once))
                           (or (memq original-command 
mc--default-cmds-to-run-for-all)
                               (memq original-command mc/cmds-to-run-for-all)
                               (mc/prompt-for-inclusion-in-whitelist 
original-command)))
                  (mc/execute-command-for-all-fake-cursors original-command))))
            (when mc/use-built-in-cursors
              (let* ((win (selected-window))
                     (window-start (window-start win))
                     (window-end (window-end win))
                     (overlays (mc/all-fake-cursors))
                     (lst
                       (mapcar
                         (lambda (x)
                           (let* ((pos (overlay-start x))
                                  (current-column
                                    (if (and (>= pos window-start)
                                             (<= pos window-end))
                                      (save-excursion
                                        (goto-char pos)
                                        (current-column))
                                      0)))
                             (cond
                               ((oddp current-column)
                                 (list pos "bar" "#FF0000")) ;; red or [1.0 0.0 
0.0]
                               ((evenp current-column)
                                 (list pos "bar" "yellow"))))) ;; [1.0 1.0 0.0]
                         overlays)))
                (setq mc-glyph-list lst)))))))))


(defun mc/execute-this-command-for-all-cursors-1 ()
  "Used with post-command-hook to execute supported commands for all cursors.

It uses two lists of commands to know what to do: the run-once
list and the run-for-all list. If a command is in neither of these lists,
it will prompt for the proper action and then save that preference.

Some commands are so unsupported that they are even prevented for
the original cursor, to inform about the lack of support."
  (unless mc--executing-command-for-fake-cursor

    (if (eq 1 (mc/num-cursors)) ;; no fake cursors? disable mc-mode
        (multiple-cursors-mode 0)
      (when this-original-command
        (let ((original-command (or mc--this-command
                                    (command-remapping this-original-command)
                                    this-original-command)))

          ;; skip keyboard macros, since they will generate actual commands 
that are
          ;; also run in the command loop - we'll handle those later instead.
          (when (functionp original-command)

            ;; if it's a lambda, we can't know if it's supported or not
            ;; - so go ahead and assume it's ok, because we're just optimistic 
like that
            (if (or (not (symbolp original-command))
                    ;; lambda registered by smartrep
                    (string-prefix-p "(" (symbol-name original-command)))
                (mc/execute-command-for-all-fake-cursors original-command)

              ;; smartrep `intern's commands into own obarray to help
              ;; `describe-bindings'.  So, let's re-`intern' here to
              ;; make the command comparable by `eq'.
              (setq original-command (intern (symbol-name original-command)))

              ;; otherwise it's a symbol, and we can be more thorough
              (if (get original-command 'mc--unsupported)
                  (message "%S is not supported with multiple cursors%s"
                           original-command
                           (get original-command 'mc--unsupported))
                (when (and original-command
                           (not (memq original-command 
mc--default-cmds-to-run-once))
                           (not (memq original-command mc/cmds-to-run-once))
                           (or mc/always-run-for-all
                               (memq original-command 
mc--default-cmds-to-run-for-all)
                               (memq original-command mc/cmds-to-run-for-all)
                               (mc/prompt-for-inclusion-in-whitelist 
original-command)))
                  (mc/execute-command-for-all-fake-cursors 
original-command))))))

            (when mc/use-built-in-cursors
              (let* ((win (selected-window))
                     (window-start (window-start win))
                     (window-end (window-end win))
                     (overlays (mc/all-fake-cursors))
                     (lst
                       (mapcar
                         (lambda (x)
                           (let* ((pos (overlay-start x))
                                  (current-column
                                    (if (and (>= pos window-start)
                                             (<= pos window-end))
                                      (save-excursion
                                        (goto-char pos)
                                        (current-column))
                                      0)))
                             (cond
                               ((oddp current-column)
                                 (list pos "bar" "#FF0000")) ;; red or [1.0 0.0 
0.0]
                               ((evenp current-column)
                                 (list pos "bar" "yellow"))))) ;; [1.0 1.0 0.0]
                         overlays)))
                (setq mc-glyph-list lst))) ))))





reply via email to

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