I have some code that loads a file into a temp buffer and tries to do some sub-string operations on the temp buffer. But I have noticed that the same code and file sometimes gives different results and cannot figure out what I'm doing wrong.
I have simplified the code to create a minimal example:
file test.txt:
aaaaaaaaaa aaaaaaaaaa aaaaaaaaaa aaaaaaaaaa aaaaaaaaaa aaaaaaaaaa aaaaaaaaaa aaaaaaaaaa aaaaaaaaaa aaaaaaaaaa so just 10 lines of 'a'.
Then I have some code that goes to a given position, the beginning of the line and then moves one line up with line-move-1 (using line-move shows the same effect):
(defun move-around (pos) (goto-char pos) (goto-char (line-beginning-position)) (message "above: pos %s point %s" pos (point)) (line-move-1 -1) (message "point now is %s" (point))) And the code that loads the file and calls the function:
(defun test-move () (with-temp-buffer (insert-file-contents-literally "./test.txt" nil nil nil t) (move-around 108))) When I call this with:
(test-move) I expected the code to deterministically always return the same result. However, most of the time, the result is "point now is 89" (which is the result I expect), but sometimes the result is "point now is 91" or "point now is 93"
Example Output in Messages:
above: pos 108 point 100 point now is 89 "point now is 89" above: pos 108 point 100 point now is 93 "point now is 93" above: pos 108 point 100 point now is 93 "point now is 93" above: pos 108 point 100 point now is 93 "point now is 93" above: pos 108 point 100 point now is 89 "point now is 89" above: pos 108 point 100 point now is 89 "point now is 89" above: pos 108 point 100 point now is 89 "point now is 89" above: pos 108 point 100 point now is 89 "point now is 89" What could be the cause for the same code giving different results?
The point before the call to line-move-1 is at the first character of the last line, so I don't see how it could result in point being 91 or 93 afterwards, which is in the middle of the second to last line, rather than the beginning of that line.
I can only reproduce this when I run the code multiple times by using eval-last-sexp, and it seems to matter if I move the cursor around in my code buffer in between invocations of eval-last-sexp. When I do
(defun call-often () (dotimes (i 100) (test-move))) all 100 times I get the same "89" result.
Any advice on how I can debug further what exactly is happening here? What can influence movements within with-temp-buffer while the code is running?
Edit: I can reproduce this not only on my main machine, but also on my Phone running emacs in Android Termux and my Notebook.
I think the best way I can reproduce it is by doing this:
put the functions and the invocation into a file so the file looks like:
(defun move-around (pos) (goto-char pos) (goto-char (pos-bol)) (message "above: pos %s point %s, buffer-size %s" pos (point) (buffer-size)) (line-move-1 -1) (message "point now is %s, buffer-size %s" (point) (buffer-size))) (defun test-move () (with-temp-buffer (insert-file-contents-literally "./test.txt" nil nil nil t) (move-around 108))) (test-move)eval-last-sexpthe functions and then the (test-move) It returns 89 as expectedadd a two new lines below, insert three space characters, go a line back up (so cursor is back at the line just below
(test-move))eval-last-sexpnow returns 91 quite reliably for meIt seems like the exact result depends on the number of spaces I entered between invocations.
eval-last-sexp. But you can try printing the(buffer-size)additionally... see if that is constant.message, and just doM-x debug-on-entry RET test-move RET. Then walk through the debugger withd(orcto skip through a step). That should show you exactly what's going on.line-move-1definition says it is the gut ofprevious-line, I have tried usingprevious-linealso, then the behavior is even more weird. Also, I have tried(forward -1)in which case the function seems to work correctly. Furthermore, I have used all variants ofmove-aroundwithintest.txtitself, in which case all variants seem to work fine. I have no idea what happens here (you could file a bug and you might get an answer), but at least using(forward-line -1)seems to work correctly.