8

I have the following function, adapted slightly from here:

;; Insert text around a region. In this case, it's
;; the LaTeX code environment from the listings package 
(defun wrap-code (start end)
  "Insert a \begin{code} and \end{code} around a region."
  (interactive "r")
  (save-excursion
    (goto-char start) (insert "\\begin{code}")
    (goto-char end) (insert "\\end{code}")
    ))
;; Assign its shortcut
(global-set-key (kbd "C-c p") 'wrap-code) 

If I then select a region and apply my function, it inserts the \end{code} at the wrong place:

\begin{code}while :; do
      echo this is\end{code} a test
done

2 Answers 2

9

That's because when you insert your first chunk of code after start, end remains constant and now point in the middle of something (since more characters have been added before it).

A quick solution for your use case is to insert text at the end before:

;; Insert text around a region. In this case, it's
;; the LaTeX code environment from the listings package 
(defun wrap-code (start end)
  "Insert a \begin{code} and \end{code} around a region."
  (interactive "r")
  (save-excursion
    (goto-char end) (insert "\\end{code}")
    (goto-char start) (insert "\\begin{code}")))
;; Assign its shortcut
(global-set-key (kbd "C-c p") 'wrap-code)

A more general solution would involve markers instead of positions

3

end is a number, an exact position in the buffer. So when you go to start and insert text, the rest of the text gets pushed forward, and end is no longer pointing to the end of "done" but rather still the position "done" used to be at.

The easiest solution is to just insert the end{code} text first, the the begin.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.