1

I have some files with names as below

long-ordinary-filename-del-1.tex
long-ordinary-filename-del-2.tex
long-ordinary-filename-del-3.tex

Is it possible to define a command to cycle between these files? More concretely if I have long-ordinary-filename-2.tex executing the command should take me to long-ordinary-filename-3.tex and doing it again should give me long-ordinary-filename-1.tex.

I would have posted what I have tried, but I have no idea how to search replace in commands. I know I can get the curent filename using :pwd or expand('%:r').

EDIT: Using the solution from my previous question I was able to create this solution

" Swaps between similarly named files
func! IncrementDel(in) 
    let l:del = 1 + strcharpart(a:in, 4, 1)
    if l:del > "3"
        let l:del = 1
    endif
    return "del-" . l:del
endfunc

:nnoremap <localleader>nd o<Esc>"%p<S-V>:s/del-\d/\=IncrementDel(submatch(0))/<CR>:nohls<CR>dd:edit <C-r>"<CR>
  • Pasting into the current file to switch files seems very barbaric, can this be avoided?
2

You can create an argument list of files and cycle through them. Built in :h :next won't wrap from last to first, so a custom map or command is necessary:

nnoremap <leader>a :exe ( argidx() == argc() - 1 ? 'first' : 'next') <cr>

To populate argument list when you start vim:

vim long-ordinary-filename-del-*.text

To change argument list after you start vim:

:args long-ordinary-filename-del-*.text

You use :h :args to check your current argument list.

update

To create a dedicated solution to this problem only:

function! s:next_of_3()

  " do nothing if current filename doesn't match
  if @% !~# '\v[123]\.tex$'
    return
  endif

  " open next file
  let fname = substitute(@%, '\v[123]\ze\.tex$', '\=submatch(0)%3+1', '')
  if filereadable(fname)
    exec 'e ' . fname
  endif
endfunction

nnoremap <leader>3 :call <sid>next_of_3()<cr>

:h quote% is name of current file. :h :s\= is used to get the matching text.

  • this works great. Is there a way to define a similar command that decreases instead of increases? I tried let fnameA = substitute(@%, '\v[1234]\ze\.', '\(\=submatch(0)-1\)%4', '') and a few other similar commands, alas nothing worked. – N3buchadnezzar Jun 9 at 19:52
  • You can't separate the leading \ and = , otherwise it's a pure string. – dedowsdi Jun 10 at 0:29

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.