Hi, I am now using Emacs 23 with visual-line-mode turned of for text editing but keep hitting M-q out of habit (thus adding hard-wrapping line endings...). I wonder if there is a way to add a conditional to disable fill-paragraph (or remove the binding to M-q) for modes in which visual-line-mode is turned on, but to re-enable it for those in which I am still using the auto-fill-mode? Thanks!
+4
A:
(defun maybe-fill-paragraph (&optional justify region)
"Fill paragraph at or after point (see `fill-paragraph').
Does nothing if `visual-line-mode' is on."
(interactive (progn
(barf-if-buffer-read-only)
(list (if current-prefix-arg 'full) t)))
(or visual-line-mode
(fill-paragraph justify region)))
;; Replace M-q with new binding:
(global-set-key "\M-q" 'maybe-fill-paragraph)
Instead of using global-set-key
, you can also rebind M-q
only in specific modes. (Or, you could change the global binding, and then bind M-q
back to fill-paragraph
in a specific mode.) Note that many modes are autoloaded, so their keymap may not be defined until the mode is activated. To set a mode-specific binding, I usually use a function like this:
(add-hook 'text-mode-hook
(defun cjm-fix-text-mode ()
(define-key text-mode-map "\M-q" 'maybe-fill-paragraph)
(remove-hook 'text-mode-hook 'cjm-fix-text-mode)))
(The remove-hook
isn't strictly necessary, but the function only needs to run once.)
cjm
2009-09-12 21:38:35
globally setting `M-q` is evil, because it affects all modes. if you have to do this, use `substitute-key-definition` (or use defadvice or fset instead)
mihi
2009-09-12 21:47:01
But that was the whole point. M-q is already a global binding. He wanted it rebound to a function that checked visual-line-mode.
cjm
2009-09-12 21:52:59
Hmmm... also a great option... Global setting of M-q may be dangerous but the function is simple enough (and elegant) that its consequences are predictable?
Stephen
2009-09-12 22:03:31
ok you won. I thought is was only bound in text-like modes, but I noticed it is bound everywhere, it's `fill-paragraph-function` that's doing the magic in the other modes...
mihi
2009-09-12 22:05:23
Thanks for your post and edit! [So I am relatively new at this but wouldn't (add-hook 'text-mode-hook '(lambda () (define-key text-mode-map "\M-q" 'maybe-fill-paragraph))) also do it?]
Stephen
2009-09-12 22:39:35
Yes, that will work. I just happen to prefer using a real named function instead of an anonymous one.
cjm
2009-09-12 23:00:49
+5
A:
you can use an advise for this.
For your .emacs:
(defadvice fill-paragraph (around disable-for-visual-line-mode activate)
(unless visual-line-mode
ad-do-it))
This will change fill-paragraph to do nothing when visual-line-mode is on. You can also add an error if you prefer that.
mihi
2009-09-12 21:43:36
Note that this will completely disable `fill-paragraph` when visual-line-mode is on, even if it's being called from an elisp function. You probably don't want to be that drastic.
cjm
2009-09-12 21:50:30
I agree, very pretty... but cjm has a point... though I don't know how often fill-paragraph is called from within elisp functions.
Stephen
2009-09-12 21:59:06
(I love defadvice though because you can also turn it off without rebooting emacs)
Stephen
2009-09-12 22:00:39
**Usage Note:** Advice is useful for altering the behavior of existing calls to an existing function. If you want the new behavior for new calls, or for key bindings, you should define a new function (or a new command) which uses the existing function. (http://www.gnu.org/software/emacs/manual/html_node/elisp/Advising-Functions.html#Advising-Functions)
cjm
2009-09-12 22:01:18
Re: "(I love defadvice though because you can also turn it off without rebooting emacs)"You can also bind M-q back to fill-paragraph (either globally or in a specific mode) without restarting Emacs.
cjm
2009-09-12 22:03:07
So one point where I saw this might cause conflict was org-mode, where I do use visual-line-mode, but it looks like fill-paragraph is used internally to arrange the table layout. org.el:;; We use our own fill-paragraph function, to make sure that tables;; and fixed-width regions are not wrapped. That function will pass;; through to `fill-paragraph' when appropriate.so I guess I'm a bit queasy about modifying 'fill-paragraph' directly - though it certainly is the sweetest of eye candies!
Stephen
2009-09-12 22:15:23