Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Suppress emacs auto-fill in a selected region

Tags:

emacs

latex

elisp

I use emacs to edit everything. On some of my LateX documents I would like to automatically disable auto-fill mode when I am editing tables and code. Basically, I'd like to have two tags, like:

   %%% BEGIN NO FILL
   %%% END NO FILL

and nothing between them will be autofilled.

Can anybody think of a way to do this? I would need to figure out whether or not the cursor is inside the region and then have to toggle the mode, and would need to do that every time the cursor moved. Or is there a better way to do it?

like image 814
vy32 Avatar asked Jan 05 '10 20:01

vy32


2 Answers

If you are using AUCTeX (you should be) then you may want to check out LaTeX-indent-environment-list. Adding an environment to this variable will make it so that (among other things) M-q doesn't refill the paragraph. Unfortunately it doesn't seem work for auto-fill-mode. The following largely untested code added to LaTeX-mode-hook might do what you want.

(setq auto-fill-function
  (lambda ()
    (unless (> (save-excursion (or (search-backward "%%% BEGIN NO FILL" (point-min) t) 0))
               (save-excursion (or (search-backward "%%% END NO FILL"   (point-min) t) 0)))
      (do-auto-fill))))

It's very stupid and inefficient, but seems to be fast enough on my machine. It doesn't allow nesting, and requires that you manually mark up all sections that you don't want filled. What I am thinking of adding to my .emacs (until I read your question I didn't realize how much this bugged me) is below which keys off of the current environment so there is no need for special markup (though it only looks at the innermost environment (I'm not sure how much of a problem that will cause in practice)). Combining the two is left as an exercise to the interested reader.

;; You can use the following to unset the variables and play around with them
;; (makunbound 'auto-fill-ignore-environments)
;; (makunbound 'auto-fill-ignore-environments-regexp)
(defcustom auto-fill-ignore-environments
  (mapcar 'car LaTeX-indent-environment-list)
  "List of environments for which `auto-fill-mode' should be
disabled.  Used to generate `auto-fill-ignore-environments-regexp'."
  :type '(sexp)
  )
(defcustom auto-fill-ignore-environments-regexp
  (regexp-opt auto-fill-ignore-environments)
  "Regexp matching LaTeX environments for which `auto-fill-mode'
should be disabled.  If not set, automatically generated from
`auto-fill-ignore-environments'"
  :type '(string)
  :set-after '(auto-fill-ignore-environments)
  )
(add-hook 'LaTeX-mode-hook
          (lambda ()
            (setq auto-fill-function
                  (lambda ()
                    (unless (string-match auto-fill-ignore-environments-regexp
                                          (LaTeX-current-environment))
                      (do-auto-fill))))))

I have never used defcustom before so I'm sure that part could be improved quite a bit.

like image 198
Ivan Andrus Avatar answered Oct 18 '22 07:10

Ivan Andrus


Got it. Check this out:

(defun in-no-auto-fill-region ()
  (> (save-excursion (or (search-backward "%%% BEGIN NO FILL" (point-min) t) 0))
     (save-excursion (or (search-backward "%%% END NO FILL"   (point-min) t) 0))
     ))

(defun previous-line-checking-auto-fill (arg)
  (interactive "P")
  (previous-line arg)
  (if (in-no-auto-fill-region)
      (turn-off-auto-fill)
    (turn-on-auto-fill)))

(defun next-line-checking-auto-fill (arg)
  (interactive "P")
  (next-line arg)
  (if (in-no-auto-fill-region)
      (turn-off-auto-fill)
    (turn-on-auto-fill)))

(add-hook 'LaTeX-mode-hook
      '(lambda nil
     (local-set-key "C-p" 'previous-line-checking-auto-fill)
     (local-set-key "C-n" 'next-line-checking-auto-fill)
     (auto-fill-mode 1)
     ))
like image 21
vy32 Avatar answered Oct 18 '22 05:10

vy32