Como Ingo Karkat escreveu, uma solução pode ser encontrada usando c_CTRL-\_e
. Aqui está a versão que estou usando, que é idêntica à solução original, exceto pelo padrão regex. (Uma vez que esta é apenas a resposta de Ingo Karkat com uma melhora modesta sugerida por Ingo Karkat, eu não acho que ela realmente merece a sua própria resposta, mas eu acho que estou vencida: link )
function! TranslateBackslashN()
if getcmdtype() ==# ':' && getcmdline() =~#
\ '[%>]s\([um]\w*\)\?\(.\).\{-}\(\\)\@<!.*\$'
return getcmdline() . 'r'
endif
return getcmdline() . 'n'
endfunction
cnoremap n <C-\>eTranslateBackslashN()<CR>
Explicação do padrão de expressão regular:
-
[%>]s
garante que a substituição ocorra somente quando s
vier imediatamente após um intervalo
-
\([um]\w*\)\?
corresponde às variações do comando s
, como smagic
.
-
\(.\)
será o primeiro caractere não pertencente à palavra, já que todos os caracteres da palavra já serão comidos por \w
no grupo opcional. Observe que este é o grupo 2
. Esse é o caractere separador, que geralmente é /
. Observe que _
, que é um caractere de palavra, também é um separador válido, portanto, o padrão não funcionará corretamente se _
for usado dessa maneira. Eu nunca uso o _
como separador, então não vou me preocupar com isso. Da mesma forma, existem alguns caracteres que não são caracteres de palavras, mas que não devem ser usados como separadores, mas eu não estou preocupado com isso aqui, porque nesse caso o comando deve falhar de qualquer maneira. Eu queria usar \W
aqui, mas por alguma razão isso não funcionou quando eu testei.
-
.\{-}
deve corresponder ao padrão ( \{-}
é como *?
do Perl).
-
\(\\)\@<!
corresponde à próxima instância do caractere separador não precedida por uma barra invertida. O equivalente em Perl seria (?<!\)
.
-
.*
corresponde ao que está na string de substituição até o momento.
-
\$
corresponde apenas se o comando até agora terminar com uma barra invertida.