Skip to content

working with prettified symbols #2007

Description

@aloispichler

I use these advices for seamless editing prettified symbols:

;;	╭───────────────────────────────────────────────
;;	│	evil – advices for handling prettify-symbols-mode
;;	│	 1. The Helper Function
(defun my/get-pretty-range (beg end)
  "Expand BEG and END to encompass full prettified symbols."
  ;; Check if CUA rectangle or Evil block is active
  (if (or (and (boundp 'cua--rectangle) cua--rectangle)
          (and (boundp 'evil-visual-selection) (eq evil-visual-selection 'block)))
      (cons beg end) ;; Return original range if in block mode to avoid skewed boxes
    (let ((new-beg (or (get-text-property beg 'prettify-symbols-start) beg))
          ;; Find the end property at the end of the range
          (new-end (max end (or (get-text-property (max (point-min) (1- end)) 'prettify-symbols-end) end))))
      (cons new-beg new-end))))

;;	│	 2. The Advice Functions
(defun my/adv-delete-back (orig-func n &optional killflag)
  "Atomic backspace for pretty symbols."
  (let* ((range (my/get-pretty-range (max (point-min) (1- (point))) (point)))
         (p-start (car range))
         (p-end   (cdr range)))
    ;; If we are at the end of a symbol, delete the whole thing
    (if (and (= n 1) (/= p-start (max (point-min) (1- (point)))))
        (if killflag (kill-region p-start p-end) (delete-region p-start p-end))
      (funcall orig-func n killflag))))

(defun my/adv-evil-edit (orig-func beg end &rest args)
  "Generic advice for evil commands (d, x, s, y) to respect symbols."
  (let ((range (my/get-pretty-range beg end)))
    (apply orig-func (car range) (cdr range) args)))

(defun myi/adv-evil-paste-after (orig-func count &rest args)
  "Ensure paste happens after the full pretty symbol."
  (let* ((end-prop (get-text-property (point) 'prettify-symbols-end))
         (offset (if (and end-prop (> end-prop (point))) (- end-prop (point)) 0)))
    (when (> offset 0) (goto-char end-prop))
    (apply orig-func count args)))

;; 	│	3. Activation
(advice-add 'delete-backward-char :around #'my/adv-delete-back)
(advice-add 'evil-delete-char     :around #'my/adv-evil-edit)
(advice-add 'evil-delete          :around #'my/adv-evil-edit)
(advice-add 'evil-substitute      :around #'my/adv-evil-edit)
(advice-add 'evil-replace         :around #'my/adv-evil-edit)
(advice-add 'evil-yank            :around #'my/adv-evil-edit)
(advice-add 'evil-paste-after     :around #'my/adv-evil-paste-after)
  1. I believe this should be evil and Emacs standard behavior;
  2. It does, however, not work in block-editing (or with cua-mode). Any help appreciated with many thanks!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions