spacemacs icon indicating copy to clipboard operation
spacemacs copied to clipboard

Evil macro recorded characters don't match with inserted ones

Open Invertisment opened this issue 2 years ago • 34 comments

Description :octocat:

Macro that inserts chars in insertion mode doubles o symbol when o is inserted in evil insertion mode. (This sometimes inserts i and in some other cases even multiple characters but I couldn't isolate these) (It's also possible that f gets inserted instead of some other letter and I couldn't isolate that one too)

Reproduction guide :beetle:

  • Start Emacs
  • Use VI editing bindings
  • Open a buffer (I tried in clojure and scratch layers, they work the same)
  • You may add some newlines, this doesn't have any effect
  • Record a macro using VI bindings (press these keys): qqafoo
  • Then press <Enter>, <Esc> and q to end the macro.
  • Then Repeat the macro one or several times: @q

Observed behaviour: :eyes: :broken_heart: In this particular example the macro prints fooo instead of foo. This throws me off and shows that something doesn't bind up correctly in the macro replay or recording.

Expected behaviour: :heart: :smile: The macro should've inserted foo instead of fooo. If you'd open vim and you'd press these keys on a buffer then you'd get foo and not fooo. I think this is a long time problem with the macro recorder but I didn't report it for a long time as I only insert oo so much.

System Info :computer:

  • OS: gnu/linux
  • Emacs: 27.2
  • Spacemacs: 0.999.0
  • Spacemacs branch: develop (rev. 6774f37fc)
  • Graphic display: t
  • Distribution: spacemacs
  • Editing style: vim
  • Completion: helm
  • Layers:
(windows-scripts asciidoc yaml
                 (python :variables python-test-runner 'pytest)
                 javascript
                 (typescript :variables typescript-backend 'lsp typescript-linter 'eslint typescript-fmt-on-save t)
                 html yaml
                 (go :variables go-use-golangci-lint t go-format-before-save t gofmt-command "goimports" go-tab-width 2)
                 (lsp :variables lsp-ui-doc-enable nil lsp-ui-sideline-enable t lsp-ui-sideline-show-code-actions t lsp-headerline-breadcrumb-enable nil)
                 (clojure :variables clojure-enable-clj-refactor t clojure-backend 'cider clojure-enable-linters 'clj-kondo clojure-pprint-fn 'fipp)
                 react
                 (java :variables java-backend 'lsp lsp-java-vmargs
                       '("java.format.settings.url" : "https://raw.githubusercontent.com/google/styleguide/gh-pages/eclipse-java-google-style.xml"))
                 (auto-completion :variables auto-completion-enable-help-tooltip nil)
                 (plantuml :variables plantuml-jar-path "~/bin/plantuml.jar")
                 emacs-lisp helm lsp spell-checking
                 (syntax-checking :variables syntax-checking-enable-tooltips nil)
                 treemacs sql sqls)
  • System configuration features: XPM JPEG TIFF GIF PNG RSVG CAIRO SOUND GPM DBUS GSETTINGS GLIB NOTIFY INOTIFY ACL GNUTLS LIBXML2 FREETYPE HARFBUZZ M17N_FLT LIBOTF ZLIB TOOLKIT_SCROLL_BARS GTK3 X11 XDBE XIM MODULES THREADS LIBSYSTEMD JSON PDUMPER LCMS2 GMP

Backtrace :paw_prints:

  • The interesting thing is that the recording already contains the three o. This is the value of the register q from the :reg menu:
q          a f o o o <return> <escape>

I'm not sure why the recorded macro register contains three o characters to replay. This may probably be some artifact from the past.

Invertisment avatar Apr 09 '22 05:04 Invertisment

This is something really peculiar. Because this time I was trying to rerun the experiment and I entered this to be recorded:

foo

But the register now contains only this:

q          o f o o <return> <escape>

And then I tried to enter more text and it came back:

q          a h e l l o SPC f o o o SPC h i <return> <escape>

And then I tried to enter foo again and it's back:

q          o f o o o <return> <escape>

Invertisment avatar Apr 09 '22 11:04 Invertisment

@Invertisment I was not able to reproduce the issue. I also tried recording a new macro with more text inserted and was still unable to reproduce the issue.

q          a h e l l o SPC w o r l d SPC f o o SPC b a r SPC b a z z <backspace> <backspace> <backspace> <backspace> d o SPC Y o u SPC <C-backspace> <C-backspace> D o SPC y o u SPC l i k e SPC J a z z ? <return> <escape>

System Info :computer:

  • OS: gnu/linux
  • Emacs: 27.2
  • Spacemacs: 0.999.0
  • Spacemacs branch: release-management-message-change (rev. dfd64bbe7)
  • Graphic display: t
  • Distribution: spacemacs
  • Editing style: vim
  • Completion: helm
  • Layers:
(asciidoc
 (auto-completion :variables auto-completion-enable-help-tooltip t)
 better-defaults csv emacs-lisp
 (ess :variables ess-r-backend ’eglot ess-use-company ’t markdown-code-block-braces t polymode-lsp-integration nil :config
      (add-to-list ’auto-mode-alist
                   ’("\\.[rR]md\\’" . poly-markdown+r-mode)))
 (git :variables git-enable-magit-todos-plugin t :config
      (with-eval-after-load ’magit-mode
        (add-hook ’after-save-hook ’magit-after-save-refresh-status t)))
 helm html info javascript lsp
 (markdown :variables markdown-live-preview-engine ’vmd)
 (org :variables org-enable-hugo-support t)
 python
 (shell :variables shell-default-height 30 shell-default-position ’bottom)
 spacemacs-navigation spell-checking
 (sql :variables sql-backend ’lsp sql-lsp-sqls-workspace-config-path nil)
 syntax-checking systemd themes-megapack treemacs yaml)
  • System configuration features: XPM JPEG TIFF GIF PNG RSVG CAIRO SOUND DBUS GSETTINGS GLIB NOTIFY INOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE HARFBUZZ M17N_FLT LIBOTF ZLIB TOOLKIT_SCROLL_BARS GTK3 X11 XDBE XIM MODULES THREADS XWIDGETS LIBSYSTEMD JSON PDUMPER GMP

bryce-carson avatar Apr 27 '22 06:04 bryce-carson

For a moment I thought that if you couldn't reproduce it then it magically fixed itself. But it didn't :/

I also tried to click random chars and got this instead (first line is me recording a macro with backspaces and so on and two remaining lines is macro replay):

afa88af8a8aaffffoofofoofofofoasasaiqiqiqiqi     9090()___affoofoofooo
afaa88af88a8aaffffoofoofooofoofoofooasasaiqiqiqiqi     9090()___affoofooofoooo
afaa88af88a8aaffffoofoofooofoofoofooasasaiqiqiqiqi     9090()___affoofooofoooo

I wrote a and it printed aa. And then it... didn't duplicate the a. And then it produced f88 from f8 and oo from o. I think it's somehow related to f key. It recorded this (:reg):

q          a a f a a 8 8 a f 8 8 a 8 a a f f f f o o f o o f o o o f o o f o o f o o a s a s a i q i q i q i q i q <backspace> SPC SPC SPC <backspace> SPC SPC SPC <backspace> SPC 9 0 9 0 ( ) _ _ _ a f f o o f o o o f o o o o <return> <escape>

I use Lithuanian language with number row at the top. And I had this issue in my previous laptop too. It's low impact but it's still a problem sometimes when I replace text and need to do a second pass to fix it.

How do I even debug this then :/

This is my keyboard layout (it's a Lithuanian one but 1-9 row is numbers and special letters are accessible with AltGr; I have ANSI keyboard): image

Also currenctly I upgraded spacemacs to this version:

commit abc028e24 (HEAD -> develop, origin/develop, origin/HEAD)

Invertisment avatar Apr 27 '22 09:04 Invertisment

Also I tried to play with it more and I got this result which is completely strange (first is my line, second is macro line):

foofoofoo
foofoofooo
foofoofooo

:reg output:

q          a f o o f o o f o o o <return> <escape>

Then I tried this (good recording, good replay):

foasdasjdaf8f7f6f5f4f3f2foo123
foasdasjdaf8f7f6f5f4f3f2foo123

And then got this one (more chars got inserted into this one):

hello123one123foofoofoofoofoofoofoofoofoo
hello123one123foofoofooofooofooofooofooofooofooo

:reg:

q          a h e l l o 1 2 3 o n e 1 2 3 f o o f o o f o o o f o o o f o o o f o o o f o o o f o o o f o o o <return> <escape>

Invertisment avatar Apr 27 '22 09:04 Invertisment

Perhaps M-x set-input-method and selecting Lithuanian will help things, if Emacs isn't already running in "Lithuanian-mode" per se. I'm not sure, honestly. It may be something with evil, Emacs, or environment variables related to locale. It's a tricky thing!

  • https://www.gnu.org/software/emacs/manual/html_node/emacs/Language-Environments.html
  • https://stackoverflow.com/questions/27773044/evil-mode-bindings-for-non-english-languages

bryce-carson avatar Apr 27 '22 10:04 bryce-carson

Could you try recording foofoofoo yourself? Because it was the third that got the additional char. I think it's the same key codes. It could probably be the recorder. I'll try it.

Invertisment avatar Apr 27 '22 10:04 Invertisment

I followed your reproduction steps exactly before trying the new macro I described.

For parity, I'll try foofoofoo again now.

foofoofoo
foofooofooo
foofooofooo
foofooofooo

Okay, interesting! It appears qqa foo return escape was not enough, but foofoofoo is reproducible.

bryce-carson avatar Apr 27 '22 10:04 bryce-carson

I tried to change my set-input-method to lithuanian-numeric and got this result:

foofoofoo
fooofooofooo

That's... very... consistent... Also lithuanian-keyboard gives me the same result. What do you use in that field? I think I had some kind of default value as I didn't know about that variable.

Invertisment avatar Apr 27 '22 10:04 Invertisment

@Invertisment It appears that the problem is caused by evil-record-macro. I was not able to reproduce the issue with the foofoofoo string using kmacro-start-macro-or-insert-counter, which by default is bound to F3.

To use Emacs "holy-mode" macro recording:

  1. Press F3 to begin recording the macro
  2. Input text or perform commands: a foofoofoo Return Escape
  3. Press F4 to finish the defintion
  4. Press F4 to play the macro

Can you try using the non-evil macro recording to double check?

bryce-carson avatar Apr 27 '22 10:04 bryce-carson

I tried to change my set-input-method to lithuanian-numeric and got this result:

foofoofoo
fooofooofooo

That's... very... consistent... Also lithuanian-keyboard gives me the same result. What do you use in that field? I think I had some kind of default value as I didn't know about that variable.

I don't use anything non-English, so I have the (unfortunate) benefit of that in my computing experience.

Try unsetting the variable using toggle-input-method to undo what set-input-method did (which was set the input method to Lithuanian, from whatever it was before).

bryce-carson avatar Apr 27 '22 10:04 bryce-carson

This one was recorded using F3. Then I stopped the recording using F4. Then I clicked <Enter> twice, then <Esc> and replayed it using F4:

fffffoofofofofofofoofoofoofoo

fffffoofoofoofofofofoofooofooofooo

Edit: This text was inserted using evil a key after starting to record the macro

Invertisment avatar Apr 27 '22 10:04 Invertisment

;; Using a with kmacro-start-macro-or-insert-counter: foofoofoo foofoofoo foofoofoo

;; Using i with kmacro-start-macro-or-insert-counter: foofoofoo foofoofoo foofoofoo

;; Using a with evil-record-macro: foofoofoo foofoofoo foofoofoo

;; Using i with evil-record-macro: foofoofoo foofoofooo foofoofooo foofoofooo foofoofooo

This is quite a strange bug. It was occuring with a, calling evil-append, then it wasn't (while using evil-record-macro). Then when I decided to move on to i for evil-insert it reared its strange, evil head again.


I have no idea what's going on with the formatting here, pardon it.

bryce-carson avatar Apr 27 '22 10:04 bryce-carson

This one was recorded after entering the insertion mode with o key in VI mode and (after that) pressing F3 and F4 to end the macro (i.e. I'm in the insertion mode throughout the whole macro recording):

ffffffofofofofofofoofoofoofoofoofooofooo
ffffffofofofoofoofoofooofooofooofooofooofoooofoooo

Invertisment avatar Apr 27 '22 10:04 Invertisment

This one was recorded after entering the insertion mode with o key in VI mode and (after that) pressing F3 and F4 to end the macro (i.e. I'm in the insertion mode throughout the whole macro recording):

ffffffofofofofofofoofoofoofoofoofooofooo
ffffffofofofoofoofoofooofooofooofooofooofoooofoooo

o runs the command evil-open-below, but yeah.


  1. F3 to begin recording
  2. Do things
  3. F4 to end recording
  4. F4 to play the recording

I assume you meant that. I'm not sure what pressing F3 during a recording would do... Let's find out:

foofoofoo0foofoofoo1
foofoofoo2foofoofoo3foofoofoo4foofoofoo5foofoofoo6foofoofoo7foofoofoo8foofoofoo9foofoofoo10foofoofoo11

Ah, that's the ⸻or-insert-counter part of the "holy" macro recording command name. That's actually neato.

bryce-carson avatar Apr 27 '22 10:04 bryce-carson

No. I didn't know what F3 would do inside of a recorded macro. What I did was I tried to isolate one more case where a macro is started by the holy-mode but with minimal interaction with evil-mode. I.e. I go into insertion mode before I click F3 and then I click F3. And I begin and end my macro in insertion mode.

Invertisment avatar Apr 27 '22 10:04 Invertisment

I'm curious about this part of your issue:

ffffffofofofofofofoofoofoofoofoofooofooo
ffffffofofofoofoofoofooofooofooofooofooofoooofoooo

I can't think of anything that would cause that.

bryce-carson avatar Apr 27 '22 10:04 bryce-carson

No. I didn't know what F3 would do inside of a recorded macro. What I did was I tried to isolate one more case where a macro is started by the holy-mode but with minimal interaction with evil-mode. I.e. I go into insertion mode before I click F3 and then I click F3. And I begin and end my macro in insertion mode.

That's good debugging. Minimizing the influence of evil-mode was a good idea.

I'm not sure whether it is taking some blame away from evil-mode and putting it on Emacs' in general because you are able to reproduce the issue with kmacro-start-macro-or-insert-counter, whereas I am unable to reproduce it.

bryce-carson avatar Apr 27 '22 10:04 bryce-carson

foofoofoo

foofoofoofoofoofoofoofoofoo
foofoofoofoofoofoofoofoofoofoofoofoofoofoofoo
foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo

This was recorded using the built-in, non-evil recording facilities while evil-insert-state was active.

bryce-carson avatar Apr 27 '22 10:04 bryce-carson

What does it mean? I can't understand what it is. Did you record foofoofoo and then repeated that a lot and it... worked as expected? So it's not emacs recorder?

Invertisment avatar Apr 27 '22 10:04 Invertisment

In either case, I think kmacro-step-edit-macro will help debug this. It is interactive and proceeds one command at a time; thanks be to Emacs, single keypresses of f or o are single commands (our lovely friend insert-char).

Can you read this section of the Emacs manual, and see what you can dig up editing the macro interactively, step-wise?

  • https://www.gnu.org/software/emacs/manual/html_node/emacs/Keyboard-Macro-Step_002dEdit.html

bryce-carson avatar Apr 27 '22 10:04 bryce-carson

What does it mean? I can't understand what it is. Did you record foofoofoo and then repeated that a lot and it... worked as expected? So it's not emacs recorder?

Yes, I should have said that. foofoofoo was recorded, and then played back with many taps of F4 and a couple taps of Return.

bryce-carson avatar Apr 27 '22 10:04 bryce-carson

The docs are too much for me. I also have to do some work. Maybe later. Also thanks for the messages. Didn't know about the F3 way of starting a macro.

Invertisment avatar Apr 27 '22 10:04 Invertisment

Okay, that's alright. The documentation can be difficult, but it is worthwhile. I'll try a couple things. If and when you do try, can you use this HTML template for your message so I can see when and where things are done, and we can make direct comparisons between what I try and what you try?

Make your macro definitions, and replay them, inside the <pre> tags in the "Definition:" and "Replay:" sections of the template.

Using <pre>a</pre> with <pre>kmacro-start-macro-or-insert-counter</pre>:
Definition:
<div align="center">
    <pre>
    </pre>
</div>

Replay:
<pre>
</pre>
<hr>

Using <pre>i</pre> with <pre>kmacro-start-macro-or-insert-counter</pre>:
Definition:
<div align="center">
    <pre>
    </pre>
</div>

Replay:
<pre>
</pre>
<hr>

Using <pre>a</pre> with <pre>evil-record-macro</pre>
Definition:
<div align="center">
    <pre>
    </pre>
</div>

Replay:
<pre>
</pre>

Using <pre>i</pre> with <pre>evil-record-macro</pre>:
Definition:
<div align="center">
    <pre>
    </pre>
</div>

Replay:
<pre>
</pre>

bryce-carson avatar Apr 27 '22 10:04 bryce-carson

Using

a
with
kmacro-start-macro-or-insert-counter
:
foofoofoo
</pre>

Replay:

foofoofooo
foofoofooo
foofoofooo

Nevermind, don't use that template. It's bad.

As you can see, however, I was able to reproduce the issue with Emacs' built-in macro recorder now. kmacro-step-edit-macro is going to be indispensible here.

bryce-carson avatar Apr 27 '22 11:04 bryce-carson

I forgot about your Backtrace, which already showed that the three os appear in the macro ring:

Backtrace

  • The interesting thing is that the recording already contains the three o. This is the value of the register q from the :reg menu:
q          a f o o o <return> <escape>

I'm not sure why the recorded macro register contains three o characters to replay. This may probably be some artifact from the past.

I'm exhausted of ideas at this point!

bryce-carson avatar Apr 27 '22 11:04 bryce-carson

#10811 reported the same issue four years ago. It's still a valid issue.

bryce-carson avatar Apr 27 '22 11:04 bryce-carson

I haven't been able to reproduce the issue in vanilla GNU Emacs, or with Rational Emacs (using evil). This is very strange.

bryce-carson avatar Apr 27 '22 20:04 bryce-carson

I wanted to see what commands were being called while doing more testing, so I installed command-log-mode and was then unable to reproduce the issue. After finding nothing, because I couldn't reproduce the issue, I removed command-log-mode and was then able to reproduce the issue again.

There may be some interesting state effect with features, libraries, or deferred loads.

Can you add command-log-mode to your dotspacemacs-additional-packages list and add (use-package 'command-log-mode) to your dotspacemacs/user-config function in your .spacemacs, then tell me if you can reproduce the issue after restarting after installing the package?

  1. Specify command-log-mode as an additional package and use-package it.
  2. SPC f e R
  3. SPC q R
  4. Again, SPC q R
  5. Try to reproduce the issue

bryce-carson avatar Apr 27 '22 20:04 bryce-carson

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Please let us know if this issue is still valid!

github-actions[bot] avatar Apr 27 '23 20:04 github-actions[bot]

I've moved on to NVIM. They also don't have this macro problem.

Now I edit Clojure using Conjure and my own small mod/shim to make it trigger Clojure's nREPL test runner (when you go to Conjure readme you can see my plugins are also listed under Mods there): https://github.com/olical/conjure#mods https://gitlab.com/invertisment/conjure-clj-additions-cider-nrepl-mw

Demo: https://asciinema.org/a/gttCs2OFslyjSmdDEVhw5DIh5

Invertisment avatar Apr 29 '23 05:04 Invertisment