Last week I happen to have written my first Vimscript function. As I was working in a CADINP file, I felt I had enough of searching for the right report file to open after the execution of a SOFiSTiK module.
The basic workflow when using SOFiSTiK's native text editor Teddy is to either click on the icon "Report Browser" in the top ribbon or to press F11 to start said report browser with the results of the last calculation. However, this workflow has a caveat: if you work with different .plb files (.plb is the file extension of SOFiSTiK report files), this won't work. In fact, hitting F11 or clicking on "Report Browser" opens the .plb file with the same name as the input file (.dat) you're currently editing. That means that if you're a tidy user sorting their report files with system commands between the modules such as
$ Example module with subsequent system line to copy the report file to
$ another file with a custom name
+PROG [module name]
HEAD [module heading]
[module content]
END
*SYS COPY $(NAME).plb .\custom-report-name.plb
*SYS DEL $(NAME).plb
then Teddy will not open the correct report file.
So you end up in a situation where you open the Windows file explorer (preferentially from the Teddy ribbon to land in the project folder) and search for the report file you wish to open.
Maybe you sorted the files by modification date, so it's at the top of the list, maybe you can handily find it by hitting the first letters of the file name.
But maybe the report file is in a subfolder (what about the following system line *SYS COPY $(NAME).plb .\plb\custom-report-name.plb?) so you still have to navigate and click a few items before your report appears on the screen.
In the course of last year I ditched Teddy for Vim, which is a much more powerful editor and my workflow had improved, so that I only had to place the cursor on the file path in the line
*SYS COPY $(NAME).plb .\custom-report-name.plb
^^^^^^^^^^^^^^^^^^^^^^^^
place the cursor anywhere here
and enter :!<C-R><C-F><Enter> (5 keystrokes1) so that it would open the file in the report browser.
Assuming that the system line above (with the report file path) is visible on the screen (which happens most of the time when working with short module snippets), it was a matter of
<num>j or <num>gg$ (which is the last character of the path as you can see in the code snippet above):!<C-R><C-F><Enter>(I guess by now I that lost everyone who's not familiar with Vim.)
This Vim workflow was OK for some months, but I kept telling myself: "It would be better to just press a key and have the right file open."
I had already mapped F11 to the same behaviour as in Teddy, but as previously noted, it was not a satisfactory workflow.
I wanted to do something like :!/\.\S\+.plb$ and map it to a key, the idea being "run the next hit of this search", where the search pattern is the next thing that looks like a path to a .plb file at the end of a line.
It was pretty clear to me that :! would not work, then I read about :execute in Steve Losh's formidable introduction to Vimscript.
Now I could start experimenting.
But my first attempts at cramming everything into a single-line command starting with : (Vimspeak: "Ex command") failed.
I had problems executing an external command (i. e. invoking the report browser) from Vim and passing the result of the search to the command line as the argument.
I understood that I could not do everything in one line so I guessed that I needed a function to return a value or something for :execute to work on.
And so I thought that I could store the result of the search as a variable and use it in my :execute command.
Somehow I looked up :help search(), which pointed to matchbufline(), which I vaguely remembered from some other example in the Vim help pages.
So I opened a split window where I fiddled with my function.
The first milestone was printing the result of the next search hit to the status line. From then on, it was just simple experimentation and it did not take so long until I had worked out a simple function that I could call.
" open next report
function! OpenNextReport()
let CurrentBuffer = bufnr("%")
let CurrentLine = line(".")
let ReportFiles = matchbufline(CurrentBuffer,'\.\S\+.plb$',CurrentLine,"$")
let w:NextReportFile = ReportFiles[0].text
execute '!start ursula.exe' w:NextReportFile
endfunction
nmap <F11> :call OpenNextReport()<CR>
During this two-hours journey, I learned to work on dictionaries, how they are different from lists, how to adress a certain position of a dictionary. I learned that the current window is a possible scope for a variable, which is very useful for the purpose of this function. As so often, I felt that a big (the main?) obstacle was quoting. I'm still struggling to get it right and I have the impression that every program and every langage has a different approach to quoting.
Looking back at it two weeks later, it was less daunting to write a function then I thought. I originally did not plan to do it. It just happened. It happened bit by bit and at the end, it was the result of many small steps. And it's a very gratifying feeling to see that one's work, well, works! Press F11, open the next report file!
I use Vim notation here: <C-R> means Ctrl+R for mere mortals, <C-F> is then Ctrl+F, and for real aficionados, the dull "Enter" key is actually "carriage return" (<CR>). ↩