# Alternate vim mapping

I have a file that looks something like this

\usepackage{tex/Forkurs-1p-2p-laererutdanning-2018-V}

\usepackage{../Sty/hyper}

\begin{document}

\input{tex/Forkurs-1p-2p-laererutdanning-2018-V-frontmatter.tex}

\input{tex/Forkurs-1p-2p-laererutdanning-2018-V-del-1.tex}

\input{tex/Forkurs-1p-2p-laererutdanning-2018-V-del-2.tex}

\end{document}


I am trying to create two commands

nmap <leader>en


To increase and decrease the year in the file and swap H with V and V with H. Invoking <leader>en should increase the year when the year is preceeded by an H. e.g YEAR-H. While the command should swap H with V and V with H.

2018-V
2018-H
2019-V
2019-H
2020-V
2020-H
.
.
.


Similarly <leader>ep should decrease the numbers when the number is preceeded by V. Always swap V with H and vice versa.

2018-V
2017-H
2017-V
2016-H
2016-V
2015-H
.
.
.


However I am not sure how to perform a conditional search replace from vim. Any suggestions?

EDIT: To clarify the increase function should work like this

IF H
Increase year
Toggle VH (Change H to V and V to H)


So only increase the year when the text contains YEAR-H. Always swap H and V.

The decrease function should work similarly

IF V
Decrease year
Toggle VH (Change H to V and V to H)


So only decrease the year when the text contains YEAR-V. Always swap H with V and vice-versa.

The requirements, which were unclear originally, have been updated. Result: much of my original answer is out the window. Here's the new one...

We can't reasonably wedge logic into global commands and/or Normal mode commands so in this case it makes more sense to use a function...to be called from a sub-replace-expression

The function:

func! ProcessYHV(in, incr)
let l:year = strcharpart(a:in, 0, 4)
let l:code = strcharpart(a:in, 5, 1)
if l:code == "H"
if a:incr
let l:year = l:year + 1
endif
let l:code = "V"
else
if ! a:incr
let l:year = l:year - 1
endif
let l:code = "H"
endif
return l:year . "-" . l:code
endfunc


First parameter is a string that matches the key pattern, \d\{4}-[HV], second parameter is "boolean" (0 or 1) that determines if it's an increment or decrement operation, and the function returns the proper replacement string based on the specified logic.

Then we just use this function in a substitution command by leveraging expression evaluation...

:%s/\d\{4}-[HV]/\=ProcessYHV(submatch(0), 1)/    " decrement
:%s/\d\{4}-[HV]/\=ProcessYHV(submatch(0), 0)/    " increment


This "sub-replace-expression" (help link at beginning of this answer) works like this: everything to the right of the \= is evaluated as an expression and the result becomes the replacement text. submatch(0) returns the entire pattern match and we're passing that as the first param to our function.

The mappings...

:nnoremap <Leader>en :%s/\d\{4}-[HV]/\=ProcessYHV(submatch(0), 1)/<cr>

• You were on the right track with sub-replace-expression and submatch. Jun 9 '19 at 9:59