Isso era algo que eu estava perdendo no Vim, e zap-to-char
não pareceu entender direito.
Aqui está minha humilde tentativa de recriar "ci" e "ca":
(defun change-outer (str)
(interactive "sChange outer: ")
(condition-case nil
(search-backward str (line-beginning-position))
(error (search-forward str (line-end-position))
(forward-char -1)))
(kill-sexp)
)
(defun change-inner (str)
(interactive "sChange inner: ")
(condition-case nil
(search-backward str (line-beginning-position))
(error (search-forward str (line-end-position))
(forward-char -1)))
(push-mark)
(forward-sexp)
(forward-char -1)
(exchange-point-and-mark)
(forward-char 1)
(kill-region (point) (mark))
)
Normalmente, o caso-condição não é necessário, já que o terceiro parâmetro (opcional) de pesquisa-encaminhamento / pesquisa-retrocesso serve para indicar o que fazer caso a pesquisa falhe. Mas, por algum motivo, colocar a segunda pesquisa como o terceiro parâmetro para a primeira gera um comportamento estranho.