Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FR] Select two arbitrary characters and copy the content between them #367

Open
NightMachinery opened this issue Sep 14, 2023 · 1 comment

Comments

@NightMachinery
Copy link

I want to easily copy text in the style of evil-avy-goto-char. This is particularly useful in magit, where normal evil bindings don't work. If we could have avy-copy-from-char-to-char, this would solve the problem.

@NightMachinery
Copy link
Author

NightMachinery commented Sep 14, 2023

I wrote this myself with a little help from GPT4. (it's amazing how GPT4 actually knows the internal avy functions.)

(cl-defun night/read-char-or-cancel
    (&optional prompt inherit-input-method seconds
               &key (cancel-chars '(27)))
  "Read a character from the user, but cancel if one of CANCEL-CHARS is pressed.
CANCEL-CHARS is a list of characters that will trigger a cancellation.
By default, it contains only the escape character (27)."
  (let ((char (read-char prompt inherit-input-method seconds)))
    (if (memq char cancel-chars)
        (progn
          (message "Cancelled!")
          nil)
      char)))

(defun night/avy-copy-from-char-to-char ()
    "Copy text between two characters using avy."
    ;; [[https://github.com/abo-abo/avy/issues/367][{FR} Select two arbitrary characters and copy the content between them · Issue #367 · abo-abo/avy]]
;;;
    (interactive)
    ;; Get the starting position
    (save-excursion
      (when-let ((start-char (night/read-char-or-cancel "Start char: ")))
        ;; (message "start-char: %s" start-char)
        (let (start-pos end-pos)
          (setq start-pos (avy-process (avy--regex-candidates (string start-char))))
          ;; If a starting position is selected
          (when (and
                 start-pos
                 (listp start-pos))
            (when-let ((end-char (night/read-char-or-cancel "End char: ")))
              (setq end-pos (avy-process (avy--regex-candidates (string end-char))))
              ;; If an ending position is selected, copy the text
              (when (and
                     end-pos
                     (listp end-pos))
                ;; (message "start: %s, end: %s" start-pos end-pos)
                ;; start: (3417 . 3418), end: (3419 . 3420)
                (let ((start-pos (car start-pos))
                      (end-pos (cdr end-pos)))
                  (kill-ring-save
                   start-pos
                   end-pos)
                  (nav-flash-show start-pos end-pos nil 1)))))))))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant