-1

I read books. A lot of books :)

When a mate asked how many books I read a week he couldn't believe it was in the 3+ range so I started recording them by author and Month read since 2013. I wrote a function that removes the existing numbering and renumbers as I add new books by the author, who may have been added in 2013,

My brain works differently so the globall subsitute is not efficient but that's how I understand things.

It's a tad slow because the macor that renumbers is running 2500 times, at least that's my assumption.

I'd like to find the last book number in the file search('\v\s\d+\s+\d+$','b') then go to end of that line and yank the /\v(\d+)$ into a register, within the function, and call the macro that many plus say 50 times, I rarely let this go more than a week without renumbering.

I replace spaces/tabs with 5 spaces as I editon a variety of platforms, in Vim or the phone etc. The last line is a book that hasn't been numbered yet. I want the macro/yank to a register to find 7. Rogue Alpha Jun 2023 1437 and yank 1437 to a macro or a register, local is fine.

Example of file

Function I want to change the :norm! 2500@l to :norm! reg+50@l

"Top of authors.txt
vim:tw=88:ts=5:sw=5:ft=txt:nowrap:conceallevel=2:concealcursor=n

"Function function! BookNum() "clear out existing numbers :let save_view = winsaveview() :setl nowrapscan "Set starting number :call setreg('a',1,'c') "Remove Book count from all entries :%s/\v^(\s+\S+.*20[1-9][0-9]\s+)(\d+)/\1/ge :let zreg=@z :let ireg=@i :let ureg=@u "From the beginning :norm! gg "Set up the macro "see image about set reg

"run it 2500 times. Change this :norm! 2500@l :setl wrapscan "Make :%s/ / /ge :%s/\v^(\s{1,4})(\S)/ &/ge :%s/\v\s{6,}/ /ge :norm! G "set up a register to check for errors let @p='%s/\v^\s+\S/&/gn' :call winrestview(save_view) endfunction

Setreg Can't past special characters for some reason

SetReg

Vivian De Smedt
  • 16,336
  • 3
  • 18
  • 37
Steve
  • 276
  • 1
  • 13

1 Answers1

1

You can use variable's value in a command via execute:

execute 'norm!' @z + 50 .. @l

However, given your file format and existing code, there's a simpler method. You can make register l into a recursive macro by adding @l to the end of it and then just run it once. It will continue running until there are no more search matches in the file, when it will stop.

:call setreg('l', ' /\v^\s+\S+.*\s20[1-9][0-9]\s+$^MA^Ra^[:let @a=@a+1^M0@l', 'c')

There are a few other things I'd have done differently from your code. You didn't ask for a code review, so I won't write them all up now, but let me know if you're interested and I'll edit in some further notes.

Rich
  • 31,891
  • 3
  • 72
  • 139
  • thanks. I'd forgotten about recursive macros. I'm happy for a code review if you have the time – Steve Jul 05 '23 at 19:30
  • 1
    @Steve to keep things manageable, I'd suggest a code review in a separate question. Please also include some sample inputs/outputs. – D. Ben Knoble Jul 06 '23 at 13:41