Skip to content

Instantly share code, notes, and snippets.

@mbork
Last active July 4, 2018 18:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mbork/9ee1bd8216424e07342e88739fe65547 to your computer and use it in GitHub Desktop.
Save mbork/9ee1bd8216424e07342e88739fe65547 to your computer and use it in GitHub Desktop.
Smart yanking for Emacs. See http://mbork.pl/2018-07-02_Smart_yanking for details.
(defun has-space-at-boundary-p (string)
"Check whether STRING has any whitespace on the boundary.
Return 'left, 'right, 'both or nil."
(let ((result nil))
(when (string-match-p "^[[:space:]]+" string)
(setq result 'left))
(when (string-match-p "[[:space:]]+$" string)
(if (eq result 'left)
(setq result 'both)
(setq result 'right)))
result))
(defun is-there-space-around-point-p ()
"Check whether there is whitespace around point.
Return 'left, 'right, 'both or nil."
(let ((result nil))
(when (< (save-excursion
(skip-chars-backward "[:space:]"))
0)
(setq result 'left))
(when (> (save-excursion
(skip-chars-forward "[:space:]"))
0)
(if (eq result 'left)
(setq result 'both)
(setq result 'right)))
result))
(defun set-point-before-yanking (string)
"Put point in the appropriate place before yanking STRING."
(let ((space-in-yanked-string (has-space-at-boundary-p string))
(space-at-point (is-there-space-around-point-p)))
(cond ((and (eq space-in-yanked-string 'left)
(eq space-at-point 'left))
(skip-chars-backward "[:space:]"))
((and (eq space-in-yanked-string 'right)
(eq space-at-point 'right))
(skip-chars-forward "[:space:]")))))
(defun set-point-before-yanking-if-in-text-mode (string)
"Invoke `set-point-before-yanking' in text modes."
(when (derived-mode-p 'text-mode)
(set-point-before-yanking string)))
(advice-add
'insert-for-yank
:before
#'set-point-before-yanking-if-in-text-mode)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment