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?
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.
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)
))
Alternately, you can turn off auto-fill-mode and use M-q to format paragraphs. I don't love auto-fill's jumpiness so I use this in every mode.
If you want to go the route of advising/redefining all the movement functions, this should help:
(defmacro movement-advice (func)
`(defadvice ,func (after ; run this after the original function is done (and point has moved)
;; Give it a unique name
,(intern (concat (symbol-name func) "-auto-fill-auto-off"))
;; Hopefully this satisfies the arguments of any function we can throw at it
(&rest args)
;; turn it on
activate
)
"Turn auto-fill-mode on or off automatically."
(auto-fill-mode (not (in-no-auto-fill-region)))))
(dolist (func '(next-line
previous-line
forward-paragraph
backward-paragraph
mouse-drag-region
;; Whatever you use
))
(eval `(movement-advice ,func)))
Related
I'm fairly new to elisp, but one thing that I really want to figure out is either how to wait for ace-jump to end before executing instructions or how get a position from ace-jump instead of moving my cursor. My goal is to be able to select a line with ace-jump, copy it, then paste it right above my current line. I started by first trying to go to a line with ace-jump then duplicate it in place, but that hasn't worked. Here is what I have for that:
(defun ace-jump-yank-line-above ()
(interactive)
(ace-jump-line-mode)
(kill-ring-save (line-beginning-position) (line-beginning-position 2) )
(yank)
)
But this gives me strange behavior
You can have a look at the source of my project lispy.el.
It's got several functions that use ace-jump-mode and do something after.
For instance lispy-ace-symbol will ace-jump to symbol and mark it.
Here's the implementation detail - the key is setting ace-jump-mode-hook:
(defun lispy--ace-do (x bnd &optional filter func no-narrow)
"Use `ace-jump-do' to X within BND when FILTER return t.
When FUNC is not nil, call it after a successful move.
When NO-NARROW is not nil, don't narrow to BND."
(require 'ace-jump-mode)
(lispy--recenter-bounds bnd)
(unless no-narrow
(narrow-to-region (car bnd) (cdr bnd)))
(when func
(setq ace-jump-mode-end-hook
(list `(lambda()
(setq ace-jump-mode-end-hook)
(,func)))))
(let ((ace-jump-mode-scope 'window)
(ace-jump-search-filter filter))
(ace-jump-do x))
(widen))
I use something similar to ace-jump rather than ace-jump itself, but something like this should work (can't be sure about the call to ace-jump-line-mode):
(defun ace-jump-yank-line-above ()
(interactive)
(let ((loc (point-at-bol))
(line nil))
(save-excursion
(ace-jump-line-mode)
(setq line (buffer-substring-no-properties
(point-at-bol) (point-at-eol)))
(goto-char (1- loc))
(if (bobp)
(insert (concat line "\n"))
(insert (concat "\n" line))))))
Okay, none of these worked for me, but I used these answers to create a script that works. Here is the code that I used:
;; The base function for the line-based ones
(defun ace-jump-end-do (dfunc afunc)
;; Save where to return to as a marker
(setq ace-jump-do-retpos (make-marker))
(set-marker ace-jump-do-retpos (point))
;; Add our during function to the hook
(setq ace-jump-mode-end-hook
(list `(lambda()
(progn
(setq ace-jump-mode-end-hook)
(,dfunc)
(goto-char ace-jump-do-retpos)
(set-marker ace-jump-do-retpos nil)
(,afunc)
))))
(ace-jump-line-mode)
)
;; Copy the line above the current line
(defun ace-jump-yank-line-above ()
(interactive)
(ace-jump-end-do
;; At the line
(lambda ()
;; Store the line in a variable
(setq line (buffer-substring-no-properties (point-at-bol) (point-at-eol)))
)
;; Upon returning
(lambda ()
(save-excursion
(goto-char (point-at-bol))
(insert (concat line "\n"))
)
(when (bolp) (goto-char (point-at-bol 2)))
)))
Unfortunately, this resets the end hook of ace-jump every time it's called. It works for me though since I don't have anything else hooked to it. If I run into issues, I'll need to figure something else out.
ace-jump-mode is really silly... calling it just goes into some useless minor-mode where you pick the hints, but it is non-blocking: any code afterwards is executed immediately.
There is so much potential for this kind of interaction and ace-jump-mode completely wastes it away with crazy implementation. It also doesn't work at all with save-excursion and you wound need to hack around that with various hooks and state-saving variables.
I've written a new package addressing all these issues, you can find it at https://github.com/Fuco1/better-jump Hopefully people will pick it up, but it serves me well at least. Took me about 2 hours to write the basic working prototype and it already covers all the functionality of packages like ace-link, ace-window and ace-whatever-else-you-can-find (also ace-jump, obviously :))
I want to set custom color background in tags, but other do not touch
(define-derived-mode php-mode fundamental-mode
"php-mode"
:syntax-table php-syntax-table
(setq font-lock-defaults '(php-keywords)))
(defvar php-syntax-table (make-syntax-table) "Syntax table for php-mode")
(make-face 'php-region-face)
(set-face-background 'php-region-face "red")
(setq php-keywords '(("<\\?php[[:ascii:]]*?\\?>" 0 'php-region-face t)))
But highlight background tags is not correctly, see below:
You'll want to setup multiline font-lock and define the boundaries of the font-lock search (so it doesn't take too much time). My information (and this code) comes from this SO question.
Here, I define multiline font-locking to take place within tags (< ... >). If this is added to your define-derived mode, it works as you describe.
(set (make-local-variable 'font-lock-multiline) t)
(add-hook 'font-lock-extend-region-functions
'test-font-lock-extend-region)
(defun test-font-lock-extend-region ()
"Extend the search region to include an entire SGML tag."
;; Avoid compiler warnings about these global variables from font-lock.el.
;; See the documentation for variable `font-lock-extend-region-functions'.
(eval-when-compile (defvar font-lock-beg) (defvar font-lock-end))
(save-excursion
(goto-char font-lock-beg)
(let ((found (or (re-search-backward "<" nil t) (point-min))))
(goto-char font-lock-end)
(when (re-search-forward ">" nil t)
(beginning-of-line)
(setq font-lock-end (point)))
(setq font-lock-beg found))))
EDIT: for some reason, SO doesn't like my code formatting.
I have most of my bookmarks prefixed by a letter in a way that
the first letter almost always uniquely determines the bookmark.
This way I can, for instance,
jump to my source folder (bookmarked as "s: source") with M-x bookmark-jump RET s RET.
I have it on a shortcut, so it's actually ~ s RET.
I'd like to get rid of RET in the end,
i.e. get M-x bookmark-quick-jump RET s or ~ s
to do the aforementioned job.
I'd also like it to fall back to the default behavior: to show me all bookmarks
that start with the given letter, in case there's not just one variant.
So far, I've got:
(defun bookmark-do-quick-jump (str)
(let ((completions (all-completions str bookmark-alist)))
(bookmark-jump
(if (eq 1 (length completions))
(car completions)
(completing-read "Jump to bookmark: " bookmark-alist nil t str)))))
There's still two hiccups:
Firstly, I need to jump into minibuffer somehow and stick in there this map (don't know how to do this):
(setq bookmark-quick-jump-map
(let ((map (make-sparse-keymap)))
(mapcar (lambda (key)
(define-key map key
(lambda()
(interactive)
(bookmark-do-quick-jump key))))
(loop for c from ?a to ?z
collect (string c)))
map))
Secondly, when I do a call
(bookmark-do-quick-jump "o")
It comes back with 3 variants (org-capture-last-stored, org-capture-last-stored-marker...).
I'm in minibuffer now, but I still need to press RET RET
to see these 3 variants. I'd like this to be done automatically.
I'd appreciate any responses that either directly answer my two sub-problems,
or an altogether different approach, as long as I can get the behavior and usability
that I described.
UPD:
I've solved the second thing by switching from completing-read to ido-completing-read:
(defun bookmark-do-quick-jump (str)
(let ((completions (all-completions str bookmark-alist)))
(bookmark-jump
(if (eq 1 (length completions))
(car completions)
(ido-completing-read "Jump to bookmark: " completions nil t str)))))
Btw, I forgot to mention that I use bookmark+. I'm not sure if jumping to dired
is supported by the default bookmark-jump.
We can remap self-insert-command during the completing-read to trigger the auto-completion and auto-acceptance behaviour.
I originally used (or (minibuffer-complete-and-exit) (minibuffer-completion-help)) which at first glance worked very nicely but, as noted in the comments, is less than ideal when one bookmark's name is the prefix of another, as it will immediately accept the shorter name, hence making the longer one inaccessible.
Calling minibuffer-complete and minibuffer-completion-help together breaks the completion functionality, however, so instead I've copied the relevant part of minibuffer-complete-and-exit to a new function. Using this resolves all of the earlier problems.
(require 'bookmark)
(defvar bookmark-do-quick-jump-map (copy-keymap minibuffer-local-must-match-map)
"Keymap for `bookmark-do-quick-jump'.
`minibuffer-local-must-match-map' is used by `completing-read' when its
REQUIRE-MATCH argument is t.
In `bookmark-do-quick-jump' we bind this modified copy to use in its place.")
(define-key bookmark-do-quick-jump-map
[remap self-insert-command] 'my-self-insert-complete-and-exit)
(defun bookmark-do-quick-jump ()
"Jump to specified bookmark with auto-completion and auto-acceptance."
(interactive)
(bookmark-maybe-load-default-file)
(let ((minibuffer-local-must-match-map bookmark-do-quick-jump-map))
(bookmark-jump
(completing-read "Jump to bookmark: " bookmark-alist nil t))))
(defun my-self-insert-complete-and-exit (n)
"Insert the character, then attempt to complete the current string,
automatically exiting when only one option remains, and displaying the
completion options otherwise."
(interactive "p")
(self-insert-command n)
(my-minibuffer-complete)
(let ((my-completions (completion-all-sorted-completions)))
(if (and my-completions (eq 0 (cdr my-completions)))
(exit-minibuffer)
(minibuffer-completion-help))))
(defun my-minibuffer-complete ()
"Copied from `minibuffer-complete-and-exit'."
(interactive)
(condition-case nil
(completion--do-completion nil 'expect-exact)
(error 1)))
Edit:
I took another stab at this using ido. It's a little unfortunate that you don't get the next 'important character' highlighted the way that you do with the regular minibuffer completion (as that was a nice indicator of what to type next), but this seems to work nicely in other respects.
(require 'bookmark)
(require 'ido)
(defvar bookmark-ido-quick-jump-map (copy-keymap minibuffer-local-map)
"Keymap for `bookmark-ido-quick-jump'.
Every time `ido-completing-read' is called it re-initializes
`ido-common-completion-map' and sets its parent to be `minibuffer-local-map'.
In `bookmark-ido-quick-jump' we provide this modified copy as a replacement
parent.")
(define-key bookmark-ido-quick-jump-map
[remap self-insert-command] 'my-self-insert-and-ido-complete)
(defun bookmark-ido-quick-jump ()
"Jump to selected bookmark, using auto-completion and auto-acceptance."
(interactive)
(bookmark-maybe-load-default-file)
(let ((minibuffer-local-map bookmark-ido-quick-jump-map)
(ido-enable-prefix t))
(bookmark-jump
(ido-completing-read "Jump to bookmark: "
(loop for b in bookmark-alist collect (car b))))))
(defun my-self-insert-and-ido-complete (n)
"Insert the character, then attempt to complete the current string,
automatically exiting when only one option remains."
(interactive "p")
(self-insert-command n)
;; ido uses buffer-local pre- and post-command hooks, so we need to
;; co-operate with those. We append our post-command function so that
;; it executes after ido has finished processing our self-insert.
(add-hook 'post-command-hook
'my-self-insert-and-ido-complete-post-command t t))
(defun my-self-insert-and-ido-complete-post-command ()
(remove-hook 'post-command-hook
'my-self-insert-and-ido-complete-post-command t)
;; Now that ido has finished its normal processing for the current
;; command, we simulate a subsequent `ido-complete' command.
(ido-tidy) ;; pre-command-hook
(ido-complete)
(ido-exhibit)) ;; post-command-hook
Here's another take:
(defun bookmark-do-quick-jump (str)
(let ((completions (all-completions str bookmark-alist)))
(if (null (cdr completions))
(bookmark-jump (car completions))
(minibuffer-with-setup-hook
(lambda () (insert str)
(minibuffer-completion-help))
(call-interactively 'bookmark-jump)))))
Or yet another (even more guaranteed untested):
(defadvice bookmark-jump (around quick-bookmarks activate)
(minibuffer-with-setup-hook
(lambda ()
(add-hook 'post-self-insert-hook
(lambda ()
(let ((completions
(all-completions (minibuffer-contents)
bookmark-alist)))
(if (cdr completions)
(minibuffer-completion-help)
(minibuffer-complete-and-exit))))
nil t))
ad-do-it))
Sounds like you're doing a lot of extra work. Just use Icicles.
User option icicle-incremental-completion non-nil and non-t means show all matches as soon as you type input.
Option icicle-top-level-when-sole-completion-flag non-nil means accept a solitary match without your needing to hit a key (e.g. RET).
Instead of customizing the options to have these values in general, you can just bind them to the values in your own command.
I use M-q for fill-paragraph, can I do the un-fill-paragraph in auto-fill-mode?
With org mode, I sometimes enter [[Very long HTML][Name with spaces]], and for the 'Name with spaces' the auto-fill mode break the whole line based on the inserted space, which makes it very ugly.
Is there a command something like un-fill-paragraph? Or, is there a way disable auto-fill-mode temporarily/locally?
Emacs does not record what was your line before calling fill-paragraph. So the only thing you can do is C-_ which runs the command undo. It can undo your fill-paragraph command but only if it is the preceding command call.
If you want to put a multi-line paragraph on one line you could do like this :
Select the region
C-M-% C-q C-j RET SPACE RET !
Xah Lee has updated his code since monotux's answer, and I refactored it somewhat for readability:
(defun my-toggle-fill-paragraph ()
;; Based on http://xahlee.org/emacs/modernization_fill-paragraph.html
"Fill or unfill the current paragraph, depending upon the current line length.
When there is a text selection, act on the region.
See `fill-paragraph' and `fill-region'."
(interactive)
;; We set a property 'currently-filled-p on this command's symbol
;; (i.e. on 'my-toggle-fill-paragraph), thus avoiding the need to
;; create a variable for remembering the current fill state.
(save-excursion
(let* ((deactivate-mark nil)
(line-length (- (line-end-position) (line-beginning-position)))
(currently-filled (if (eq last-command this-command)
(get this-command 'currently-filled-p)
(< line-length fill-column)))
(fill-column (if currently-filled
most-positive-fixnum
fill-column)))
(if (region-active-p)
(fill-region (region-beginning) (region-end))
(fill-paragraph))
(put this-command 'currently-filled-p (not currently-filled)))))
To remake a long line out of a paragraph in Org mode, I gave myself a new command. Here is the associated Emacs Lisp code:
(defun fp-unfill-paragraph (&optional justify region)
(interactive (progn
(barf-if-buffer-read-only)
(list (if current-prefix-arg 'full) t)))
(interactive)
(let ((fill-column 100000))
(fill-paragraph justify region)))
(global-set-key "\C-ceu" 'fp-unfill-paragraph)
Of course, you adjust the command keybinding as you see fit!
I use the following snippet to fill and un-fill paragraphs (using only M-q), it is really, really handy. I borrowed it from Xah Lee, but removed some comments and whitespace in order to make it fit in here. The link in the first comment goes to his original code.
;; http://xahlee.org/emacs/modernization_fill-paragraph.html
(defun compact-uncompact-block ()
"Remove or add line endings on the current block of text.
This is similar to a toggle for fill-paragraph and unfill-paragraph
When there is a text selection, act on the region.
When in text mode, a paragraph is considered a block. When in programing
language mode, the block defined by between empty lines.
Todo: The programing language behavior is currently not done.
Right now, the code uses fill* functions, so does not work or work well
in programing lang modes. A proper implementation to compact is replacing
newline chars by space when the newline char is not inside string.
"
(interactive)
(let (bds currentLineCharCount currentStateIsCompact
(bigFillColumnVal 4333999) (deactivate-mark nil))
(save-excursion
(setq currentLineCharCount
(progn
(setq bds (bounds-of-thing-at-point 'line))
(length (buffer-substring-no-properties (car bds) (cdr bds)))))
(setq currentStateIsCompact
(if (eq last-command this-command)
(get this-command 'stateIsCompact-p)
(if (> currentLineCharCount fill-column) t nil)))
(if (and transient-mark-mode mark-active)
(if currentStateIsCompact
(fill-region (region-beginning) (region-end))
(let ((fill-column bigFillColumnVal))
(fill-region (region-beginning) (region-end)))
)
(if currentStateIsCompact
(fill-paragraph nil)
(let ((fill-column bigFillColumnVal))
(fill-paragraph nil))))
(put this-command 'stateIsCompact-p
(if currentStateIsCompact
nil t)))))
(global-set-key (kbd "M-q") 'compact-uncompact-block)
There are plenty of ways to fold code in Emacs and I've settled in on using the outline minor mode... it works great!
However, I really want my folding to be persisted when I close and re-open files. It is quite frustrating to have folding set up in a file the way I like it, only to have that lost when I restart Emacs.
Has anyone found a way to keep the folding state of a file persistent?
Edit: Now that I understand the question...
How about something like the following nippet of code. It seems to work for me, though I haven't figured out how to avoid being prompted for the file local variable every time.
(defvar omm-state nil
"file local variable storing outline overlays")
(defun omm-state-mode (&optional arg)
"poor man's minor mode to re-apply the outline overlays "
(interactive)
(omm-re-enable-outline-state)
(add-hook 'before-save-hook 'omm-state-save))
(defun omm-get-all-overlays ()
"return a list of outline information for all the current buffer"
(save-excursion
(let ((all-overlays (overlays-in (point-min) (point-max))))
(mapcar (lambda (o)
(list (overlay-start o) (overlay-end o) (overlay-get o 'invisible)))
(reverse all-overlays)))))
(defun omm-re-enable-outline-state (&optional arg)
"turn on outline-minor-mode and re-apply the outline information"
(outline-minor-mode 1)
(when (listp omm-state)
(mapcar (lambda (p)
(apply 'outline-flag-region p))
omm-state)))
(defun omm-state-save ()
"save the outline state in a file local variable
Note: this just replaces the existing value, you need to start
it off by adding something like this to your file:
# Local Variables:
# omm-state:()
# mode:omm-state
# End:
"
(ignore-errors
(save-excursion
(goto-char (point-max))
(when (search-backward "omm-state:" nil t)
(goto-char (match-end 0))
(kill-sexp)
(princ (omm-get-all-overlays) (current-buffer)))))
nil)
This solution requires you "seeding" your file with something like:
# Local Variables:
# omm-state:()
# mode:omm-state
# End:
I realize this is an old post but FWIW I created a minor mode that complements hs-minor-mode, outline-mode etc. I also "really want my folding to be persisted when I close and re-open files". :)
The package is in MELPA as of today and called persistent-overlays.
It is also available directly on github: https://github.com/mneilly/Emacs-Persistent-Overlays