It turns out that the problem is caused by the Emacs LINE-MOVE-VISUAL function in "simple.el". PREVIOUS-LINE calls LINE-MOVE which calls the LINE-MOVE-VISUAL function if the LINE-MOVE-VISUAL variable is true.
From the commentary in LINE-MOVE-VISUAL:
Code: Select all
;; Check if the previous command was a line-motion command, or if
;; we were called from some other command.
(if (and (consp temporary-goal-column)
(memq last-command `(next-line previous-line ,this-command)))
;; If so, there's no need to reset `temporary-goal-column',
;; but we may need to hscroll.
This means that if you call the LINE-MOVE-VISUAL function from another function several times in a row then the TEMPORARY-GOAL-COLUMN variable doesn't get updated and the cursor moves always to the same position in the previous line (IMO this is a bug.)
A workaround would be either to set the TEMPORARY-GOAL-COLUMN variable explicitely to NIL inside the COPY-CHAR-FROM-LINE-ABOVE function or just simply shadow the variable with a local LET variable of the same name like shown below. Notice the additional TEMPORARY-GOAL-COLUMN variable in the LET form:
Code: Select all
(defun copy-char-from-line-above ()
"Copies one character from same column but previous row"
(interactive)
(let (c temporary-goal-column)
(save-excursion
(previous-line)
(setq c (buffer-substring-no-properties (point) (+ (point) 1))))
(insert c)))
(defalias 'cup 'copy-char-from-line-above)
(global-set-key "\C-i" 'copy-char-from-line-above)
With me and GNU Emacs 23.2.1 - x86_64-pc-linux-gnu, GTK+ Version 2.20.1, on Debian Squeeze this works as you wanted.
- edgar