2

When transposing words, the cursor moves to the end of the word, how can the cursor be kept at the same location relative to the word?

2 Answers 2

3

What about

(defun ideasman42-transpose-words (arg) (interactive "*p") (let ((chars-to-word-end (let ((point (point))) (if (or ; cases to behave like plain transpose-words. (looking-at "\\>") (looking-at "\\(?:[ \t]*\n\\)*[ \t]*\\<") ) 0 (save-excursion (forward-word) (- (point) point)))))) (transpose-words arg) (backward-char chars-to-word-end))) 

as a start?

1
  • I was hoping to avoid duplicating logic to delimit the word under the cursor, any mismatch in logic between this and forward-word's logic will cause bugs. Commented Nov 28, 2019 at 18:41
0

This can be done by getting the boundaries under the cursor from thing-at-point, then using them to set the cursor after transposing the word.

Unlike regular transpose-word.

  • The cursor stays on the same character of the word.
  • When there is no word to transpose with, the cursor doesn't move and a message is printed.
(defun transpose-words--impl (arg) (let ((bounds (bounds-of-thing-at-point 'word))) (when bounds (let* ((pt-init (point)) (pt-end-of-word (cdr bounds)) (pt-offset (- pt-init pt-end-of-word)) (pt-transpose (save-excursion ;; Without this, the first character will move the previous word. (goto-char pt-end-of-word) (if (condition-case err (progn (transpose-words arg) t) (message err)) (+ (point) pt-offset) nil)))) (when pt-transpose (goto-char pt-transpose)))))) (defun transpose-words-backward () (interactive) (transpose-words--impl -1)) (defun transpose-words-forward () (interactive) (transpose-words--impl 1)) 

Use with evil mode for eg:

(define-key evil-normal-state-map (kbd "C-M-l") 'transpose-words-forward) (define-key evil-normal-state-map (kbd "C-M-h") 'transpose-words-backward) 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.