One possible simple approach is to use a :try
block to catch an error while trying the *.spec.js
filename and then fallback to the *.test.js
filename if that fails.
Perhaps something as simple as:
command! Spec try | find %:t:r.spec.js | catch /^Vim(find):E345:/ | find %:t:r.test.js | endtry
(Note I used %:t:r
to use just the basename of the file, so that :find
gets a filename only and will use 'path'
to locate it. That's not the case if the original file was in a subdirectory and you used %:r
, in which case it would only look for the *.spec.js
file in the same directory as the original file.)
One small issue with this solution is that, when neither file exists, it will only complain about the latter *.test.js
, which might give the user the wrong impression that that's the preferred filename...
You can fix that by using a second :try
block and issuing a more appropriate error message in that case.
The command gets longer already, so I'll start breaking lines for clarity:
command! Spec
\ try
\ | find %:t:r.spec.js
\ | catch /^Vim(find):E345:/
\ | try
\ | find %:t:r.test.js
\ | catch /^Vim(find):E345:/
\ | echoerr "E345: Can't find file \"".expand("%:t:r").".spec.js\" or \"".expand("%:t:r").".test.js\" in path"
\ | endtry
\ | endtry
At this point it already makes sense to break this out into a function, and have the Spec
command call the function...
If you use a function, you might want to consider using findfile()
to locate an existing file, possibly use a list and a loop to handle possible extensions in a more flexible way, perhaps consider creating or offering to create the file if it doesn't exist...
But then, you're already halfway through writing your own plug-in for this feature, so you might consider adopting one. The vim-projectionist plug-in by Tim Pope is a great plug-in for jumping between related files in a project and it's quite flexible so you can configure it to match the paths in your project.