11

Is there anything like

eval("is_recording()")

that I can call in my vimscript to find out if I am currently recording a macro? I would have thought this works:

eval("mode(1)")

but that just returns "n".

Not sure if it matters, but I am using neovim, so if it's exclusive to neovim, that is okay.

3
  • 3
    IMHO it would be a bad idea - "recording", in that case, would became a false name :) Don't know what you are trying to do, but perhaps asking that question could provide different ways to solve it. – VanLaser Mar 23 '16 at 19:21
  • @VanLaser What do you mean by false name? – DJMcMayhem Mar 23 '16 at 19:35
  • 1
    If a Vim action is different when you're recording it, it means the recording process itself affects the action, when it should only "store" it for later repetition. What do you expect to happen when you run the macro? – VanLaser Mar 23 '16 at 19:39
4

Firstly, I think that your problem is mainly a XY problem. You should give us more information about what you are trying to do in the end and I think we could find another solution.

Now here is a workaround, it is probably not ideal and certainly not very robust but you could add these lines to your .vimrc:

let g:isRecording = 0
nnoremap Q :call ToggleRecording()<CR>q

function! ToggleRecording()
    let g:isRecording = !g:isRecording
    echo "is recording " . g:isRecording
endfunction

The idea is that the "recording mode" is toggled exclusively when you press q in normal mode.

Based on that you create a variable g:isRecording which will be toggled each time you start or stop a recording. This way when you start recording g:isRecording will be set to 1 and to 0 when you stop recording. You can then access the recording state via the value of the variable.

The "drawback" is that to avoid recursive mapping, you'll have to use Shit-q to start and stop recording instead of q. (Note that it is not such a big problem: I've been using shift-q to toggle record mode for some time because I don't like the original shift-q behavior)

The main problem of this solution is that if you forgot about it and use q the variable will not be toggled but you can't disable q (e.g. with nnoremap q <nop>) because if you do the shift-q won't' work anymore.

2

This is a pretty curious request since there is no "mode" for recording a macro. After digging through some docs I found the following in usr_10

You start by moving to the first character of the first line. Next you execute the following commands:

qa Start recording a macro in register a.

^ Move to the beginning of the line.

i#include " Insert the string #include " at the beginning of the line.

$ Move to the end of the line.

a" Append the character double quotation mark (") to the end of the line.

j Go to the next line.

q Stop recording the macro.

The standout thing to me was the line about "Start recording a macro in register a"

Since each macro is going to be saved to a register by default I was hoping that we'd be able to see it in the :reg list. It turns out it works like a charm!

Example:

In normal mode: qaisomething<Esc>

and inside of :reg we see the entry!

"a   isomething^[

With that knowledge you should be able to "spy" on the registers to confirm that a macro is being recorded (use a named register on every recording [map q to always use the same register (or something like that )]

If you run into problems let me know and I'll try to help you out (since this functionality is new to me too :D)

edit To address the issue of a register being used during yank I'd recommend to look into a special type of register that you can use only for the vimL you are writing (no yank would ever be engaged on the register ("ay))

Here's a bit of info from :help registers on the available registers

There are ten types of registers: registers E354

  1. The unnamed register ""

  2. 10 numbered registers "0 to "9

  3. The small delete register "-

  4. 26 named registers "a to "z or "A to "Z

  5. three read-only registers ":, "., "%

  6. alternate buffer register "#

  7. the expression register "=

  8. The selection and drop registers "*, "+ and "~

  9. The black hole register "_

  10. Last search pattern register "/

Assuming that you have a register that you are going to use now the issue becomes "how do I know when recording has stopped?". To take care of this I'd take a look at the autocmd-event for CursorHold; the note in the help docs looks pretty promising (I'd try to figure out how I could differentiate normal cursorHold vs the idle/non-existant event that occurs when your register is being written to for the purposes of the macro)

CursorHold

When the user doesn't press a key for the time specified with 'updatetime'. Not re-triggered until the user has pressed a key (i.e. doesn't fire every 'updatetime' ms if you leave Vim to make some coffee. :) See |CursorHold-example| for previewing tags. This event is only triggered in Normal mode. It is not triggered when waiting for a command argument to be typed, or a movement after an operator. While recording the CursorHold event is not triggered. |q|

5
  • I don't really see how it solves the problem: when you finish recording your macro a string is saved in the register but how do you differentiate when the register contains a macro or when it contains something coming from a yank command for example. Also the register is saved as one shot when you finish recording so when you see that the content of the register has changed you're not in recording mode anymore. – statox Mar 23 '16 at 20:28
  • My hope was that you'd be able to use something like the blackhole register (a register that is not going to be yanked to ever). If you have that register locked down then you could checkout CursorHold which has some special behavior when in recording mode (will update my answer with some more info to see if that helps ya) – Dan Bradbury Mar 23 '16 at 20:59
  • added some info on the other registers (way to avoid conflicts with yank) and a hint on how we might be able to catch "recording" with CursorHold not being active during macro recording. If you are still fighting this after those notes let me know and I can try to implement it after work is over. As a note the blackhole register was only mentioned as a hint and an interesting vim tidbit that might lead to something (it would not be useful to use when recording macros; as @_ is not usable. ) in fact you cant even attempt to save the macro to it.. – Dan Bradbury Mar 23 '16 at 21:08
  • I spent some time on this last night (post beer keyboard smashing) and found it incredibly difficult to figure out exactly when recording is occurring and ends. My hunch about CursorHold seems to be an impossible dream due to the lag of the CursorHold actually happening (made a simple global increment to happen everytime to watch this). Still incredibly interested in coming up with a way to do this and will continue smashing my face against the keys till we have a solution.. – Dan Bradbury Mar 25 '16 at 0:11
  • In my opinion you don't have a thousand different options: you have to override the behavior of q and make it toggle a variable and start/stop recording. An autocomand can't be reliable here since no autocmd triggers on a key press, and it is not possible to make a polling function due to the monothread nature of Vim. Good luck with your future experimentations :-) – statox Mar 25 '16 at 6:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.