emacs 23.2.1: character-by-character copying from the previous line seems broken - emacs

After upgrading to emacs 23.2.1 with Fedora 15 one of my emacs functions is broken and I just can't seem to find the problem. Something has to have changed, but I sure can't find it in the elisp documentation.
I'd really appreciate any suggestions!
What it should do: Pressing Ctl-hyphen should copy the character above the cursor and move the point ahead by 1.
What it does: Keeps copying the character above without advancing the point. HOWEVER, calling it with "M-x insert-char-from-previous-line" or pressing RightArrow between Ctl-hypens works as it should. Adding (forward-char 1) to the end of the script doesn't help.
(defun insert-char-from-previous-line ()
"Copy previous line character by character"
(interactive)
(previous-line 1)
(let ((char-above (following-char) ))
(next-line 1)
(if (not (char-equal char-above ?\n ))
(insert char-above))))
(global-set-key [?\C--] 'insert-char-from-previous-line) ;copy char above

I think your getting caught in a goal column issue. You probably should not use next-line/previous-line for this, rather try this:
(defun insert-char-from-previous-line ()
"Copy previous line character by character"
(interactive)
(let ((curpoint (point))
(curcolumn (current-column)))
(forward-line -1)
(forward-char curcolumn)
(let ((char-above (following-char) ))
(goto-char curpoint)
(if (not (char-equal char-above ?\n ))
(insert char-above)))))
From the docs on pervious-line:
If you are thinking of using this in a Lisp program, consider using
`forward-line' with a negative argument instead. It is usually easier
to use and more reliable (no dependence on goal column, etc.).
(describe-function 'previous-line)

don't move the point for something like this:
(defun i-char (arg)
(interactive "*p")
(let ((start (+ (point-at-bol 0)
(current-column)))))
(insert (buffer-substring-no-properties start (+ start arg))))

Related

Duplicating a line in emacs with Ace-Jump

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 :))

'Semantic' movement across a line

Consider the following line of Lisp code:
(some-function 7 8 | 9) ;; some comment. note the extra indentation
The point is placed between '8' and '9'. If I perform (move-beginning-of-line), the point will be placed at the absolute beginning of the line, rather than at '('.
Same for move-end-of-line: I'd find it more desirable for it to place the point at ')' if I perform it once, and at the absolute end of the line if I perform it a second time. Some IDEs behave like that.
I tried to implement this but got stuck, my solution behaves particularly bad near the end of a buffer, and on the minibuffer as well. Is there a library that provides this functionality?
I don't know of any library, but it can be done in a few lines of Elisp.
For the beginning of line part, the bundled functions beginning-of-line-text and back-to-indentation (M-m) move to the beginning of the “interesting” part of the line. back-to-indentation ignores only whitespace whereas beginning-of-line-text skips over the fill prefix (in a programming language, this is typically the comment marker, if in a comment). See Smart home in Emacs for how to flip between the beginning of the actual and logical line.
For the end of line part, the following function implements what you're describing. The function end-of-line-code moves to the end of the line, except for trailing whitespace and an optional trailing comment. The function end-of-line-or-code does this, except that if the point was already at the target position, or if the line only contains whitespace and a comment, the point moves to the end of the actual line.
(defun end-of-line-code ()
(interactive "^")
(save-match-data
(let* ((bolpos (progn (beginning-of-line) (point)))
(eolpos (progn (end-of-line) (point))))
(if (comment-search-backward bolpos t)
(search-backward-regexp comment-start-skip bolpos 'noerror))
(skip-syntax-backward " " bolpos))))
(defun end-of-line-or-code ()
(interactive "^")
(let ((here (point)))
(end-of-line-code)
(if (or (= here (point))
(bolp))
(end-of-line))))
Some suggestions that almost do what you ask:
In lisp code, you can sort-of do what you want, with the sexp movement commands. To get to the beginning of the expression from somewhere in the middle, use backward-up-list, which is bound to M-C-u. In your example, that would bring you to the open parenthesis. To move backwards over individual elements in the list, use backward-sexp, bound to M-C-b; forward-sexp moves the other way, and is bound to M-C-f. From the beginning of an sexp, you can skip to the next with M-C-n; reverse with M-C-p.
None of these commands are actually looking at the physical line you are on, so they'll go back or forward over multiple lines.
Other options include Ace Jump mode, which is a very slick way to quickly navigate to the beginning of any word visible on the screen. That might eliminate your need to use line-specific commands. For quick movement within a line, I usually use M-f and M-b to jump over words. Holding the M key down while tapping on b or f is quick enough that I end up using that by default most of the time.
Edit:
Forgot one other nice command - back-to-indentation, bound to M-m. This will back you up to the first non-whitespace character in a line. You could advice this to behave normally on the first call, and then to back up to the beginning of the line on the second call:
(defadvice back-to-indentation (around back-to-back)
(if (eq last-command this-command)
(beginning-of-line)
ad-do-it))
(ad-activate 'back-to-indentation)
I just wrote these two functions that have the behavior you are looking for.
(defun move-beginning-indent ()
(interactive)
(if (eq last-command this-command)
(beginning-of-line)
(back-to-indentation))
)
(defun move-end-indent ()
(interactive)
(if (eq last-command this-command)
(end-of-line)
(end-of-line)
(search-backward-regexp "\\s)" nil t) ; searches backwards for a
(forward-char 1)) ; closed delimiter such as ) or ]
)
(global-set-key [f7] 'move-beginning-indent)
(global-set-key [f8] 'move-end-indent)
Just try them out, they should behave exactly the way you'd want them to.
I use this:
(defun beginning-of-line-or-text (arg)
"Move to BOL, or if already there, to the first non-whitespace character."
(interactive "p")
(if (bolp)
(beginning-of-line-text arg)
(move-beginning-of-line arg)))
(put 'beginning-of-line-or-text 'CUA 'move)
;; <home> is still bound to move-beginning-of-line
(global-set-key (kbd "C-a") 'beginning-of-line-or-text)
(defun end-of-code-or-line ()
"Move to EOL. If already there, to EOL sans comments.
That is, the end of the code, ignoring any trailing comment
or whitespace. Note this does not handle 2 character
comment starters like // or /*. Such will not be skipped."
(interactive)
(if (not (eolp))
(end-of-line)
(skip-chars-backward " \t")
(let ((pt (point))
(lbp (line-beginning-position))
(comment-start-re (concat (if comment-start
(regexp-quote
(replace-regexp-in-string
"[[:space:]]*" "" comment-start))
"[^[:space:]][[:space:]]*$")
"\\|\\s<"))
(comment-stop-re "\\s>")
(lim))
(when (re-search-backward comment-start-re lbp t)
(setq lim (point))
(if (re-search-forward comment-stop-re (1- pt) t)
(goto-char pt)
(goto-char lim) ; test here ->
(while (looking-back comment-start-re (1- (point)))
(backward-char))
(skip-chars-backward " \t"))))))
(put 'end-of-code-or-line 'CUA 'move)
;; <end> is still bound to end-of-visual-line
(global-set-key (kbd "C-e") 'end-of-code-or-line)

Change mark-paragraph behaviour

How to change default emacs mark-paragraph function behaviour to not select first empty line?
my emacs http://dl.dropbox.com/u/1019877/e2.PNG
I've made Bohzidars upgraded version and it works for first line too.
(global-set-key (kbd "M-h") (lambda ()
(interactive)
(mark-paragraph)
(if (> (line-number-at-pos) 1)
(next-line))
(beginning-of-line)))
thanks guys for the tips.
The currently accepted answer has two disadvantages: 1) doesn't accept arguments and 2) doesn't allow to mark more paragraphs by repeated calls (especially this is very useful). Here is my solution - it is the original mark-paragraph with a next-line command at the end. The condition assures it works also on the first of the file.
Possibly a more economic solution is to use advices, but I don't know how to use them yet :).
(defun rs-mark-paragraph (&optional arg allow-extend)
"The original default mark-paragraph, but doesn't mark the first
empty line. Put point at beginning of this paragraph, mark at
end. The paragraph marked is the one that contains point or
follows point.
With argument ARG, puts mark at end of a following paragraph, so that
the number of paragraphs marked equals ARG.
If ARG is negative, point is put at end of this paragraph, mark is put
at beginning of this or a previous paragraph.
Interactively, if this command is repeated
or (in Transient Mark mode) if the mark is active,
it marks the next ARG paragraphs after the ones already marked."
(interactive "p\np")
(unless arg (setq arg 1))
(when (zerop arg)
(error "Cannot mark zero paragraphs"))
(cond ((and allow-extend
(or (and (eq last-command this-command) (mark t))
(and transient-mark-mode mark-active)))
(set-mark
(save-excursion
(goto-char (mark))
(forward-paragraph arg)
(point))))
(t
(forward-paragraph arg)
(push-mark nil t t)
(backward-paragraph arg)
(if (/= (line-number-at-pos) 1)
(next-line)))))
You cannot change the behaviour of mark-paragraph, but you can easily bind another command to the C-M-h keystroke (to resemble the original M-h):
(global-set-key (kbd "C-M-h") (lambda ()
(interactive)
(mark-paragraph)
(next-line)
(beginning-of-line)))
Something like this should do the trick.
I'm not sure I see a convenient way to do this. mark-paragraph calls forward-paragraph and backward-paragraph to do the bulk of the work, and in the documentation for backward-paragraph, we have "if the first real line of a paragraph is preceded by a blank line, the paragraph starts at that blank line."
The most relevant variables to look at appear to be paragraph-start and paragraph-separate, two regular expressions used inside paragraphs.el to figure out this sort of thing. I'd be leary of changing them though, as they are going to have quite a lot of other effects.
Another option is to write your own function that does something like the following:
(defun dg-mark-paragraph ()
(interactive)
(mark-paragraph)
(goto-char (region-beginning))
(when (= (string-match paragraph-separate (thing-at-point 'line)) 0)
(forward-line)))

Copy Character Down in Emacs

I wrote an interactive function which inserts the "character above the point" in to the current line. For instance, given a line containing "12345" followed by a line "abcdef" and the point sitting at the letter "c", copy-down would make the second line become "ab3cdef". copy-down again would make the second line become "ab34cdef".
My function fails (using GNU Emacs 23.3.1 under windows 7) the second time I invoke it by inserting the text from the first invocation and not advancing properly. If I put any emacs "manipulations" in-between invocations, it works fine. (For instance if I do a copy-down, "left arrow", "right arrow", copy-down it works fine for both invocations.)
Here's my function:
(defun copy-down ()
"Grab the character in the line above and insert at the current location."
(interactive)
(let ((beg (progn (previous-line 1) (point)))
(end (progn (forward-char) (point))))
(backward-char)
(next-line 1)
(insert-buffer-substring (current-buffer) beg end)))
If it matters, I usually tie my function to a key: (global-set-key [f5] 'copy-down)
PS. I got used to using this capability in the editor I used before switching to emacs many years ago and I miss it in GNU Emacs. :-(
What you have works just fine for me. That said, previous-line has interaction with other settings (specifically goal-column) and generally shouldn't be used when writing elisp. Instead you should use (forward-line -1). But, of course, your code relies on the goal-column... You can test this by running Emacs without your other configurations, ala emacs -q.
Here's a slightly different version of your code that doesn't rely on goal-column:
(defun copy-down ()
"Grab the character in the line above and insert at the current location."
(interactive)
(let* ((col (current-column))
(to-insert (save-excursion
(forward-line -1)
(move-to-column col)
(buffer-substring-no-properties (point) (1+ (point))))))
(insert to-insert)))
If the problem isn't with using previous-line, then I don't imagine my code would make much of a difference.
Another option you have is to try running it in the debugger to see where your code breaks down. Move the point inside the defun for copy-down and type M-x edebug-defun, and the next time you run it you'll be able to step through the code. Docs for edebug can be found here.
You need to use let* instead of let. The former allows you to use earlier values in later forms in the same statement.
BTW, that's an unconventional way to write elisp, you might want to look at some other code samples.
EDIT:
Hey, someone completely rearranged your function! It might work now.
Try
(defun copy-down (arg)
(interactive "p")
(let ((p (+ (current-column) (point-at-bol 0))))
(insert-buffer-substring (current-buffer) p (+ p arg))))
which has the additional functionality of taking a prefix argument to copy n (default to 1) characters down.

How do I get Emacs to fill sentences, but not paragraphs?

I've seen at least two recommendations on StackOverflow to insert newlines between sentences when editing LaTeX documents. The reason being that the practice facilitates source control, diffing, and collaborative editing.
I'm basically convinced, but I'm lazy, and I don't want to have to think about it.
So I'm searching for some emacs incantation to handle it for me. Could be a minor mode, could be a set of variables that need to be set.
I think what I don't want is
Soft wrapping of text (say using the longlines and (set long-lines-auto-wrap 't)). This is because I don't want to impose requirements on my collaborators' editors, and I sometimes use other unix tools to examine these files.
I think what I do want is
For fill-paragraph to fill between newlines that look like they mark the end of a sentence.
A solution that works with auto-fill-mode would be a bonus.
That is:
chat chat chat.
A new sentence
with goofed up wrapping that needs to be fixed.
Mumble mumble
Transformed to:
chat chat chat.
A new sentence with goofed up wrapping that needs to be fixed.
Mumble mumble
Your comments and suggestions are appreciated.
Edit: The suggestion by Jouni K. Seppänen pointed me at LaTeX-fill-break-at-separators, which suggests that emacs almost knows how to do this already. Anyway, I'm off to read some code, and will report back. Thanks again.
More general version of the same question: Editor showdown: Maintain newlines at the ends of sentences. Thanks, dreeves.
Here's what I use, which was mostly cribbed from Luca de Alfaro:
(defun fill-sentence ()
(interactive)
(save-excursion
(or (eq (point) (point-max)) (forward-char))
(forward-sentence -1)
(indent-relative t)
(let ((beg (point))
(ix (string-match "LaTeX" mode-name)))
(forward-sentence)
(if (and ix (equal "LaTeX" (substring mode-name ix)))
(LaTeX-fill-region-as-paragraph beg (point))
(fill-region-as-paragraph beg (point))))))
I bind this to M-j with
(global-set-key (kbd "M-j") 'fill-sentence)
The references to "LaTeX" are for AUCTeX support. If you don't use AUCTeX, the let can be simplified to
(let (beg (point))
(forward-sentence)
(fill-region-as-paragraph beg (point)))
I have been meaning to do this forever and I recently found this blog post which worked fairly well for me. So here is (a slightly modified version of) what I have been using for a few days.
(defun auto-fill-by-sentences ()
(if (looking-back (sentence-end))
;; Break at a sentence
(progn
(LaTeX-newline)
t)
;; Fall back to the default
(do-auto-fill)))
(add-hook 'LaTeX-mode-hook (lambda () (setq auto-fill-function 'auto-fill-by-sentences)))
;; Modified from http://pleasefindattached.blogspot.com/2011/12/emacsauctex-sentence-fill-greatly.html
(defadvice LaTeX-fill-region-as-paragraph (around LaTeX-sentence-filling)
"Start each sentence on a new line."
(let ((from (ad-get-arg 0))
(to-marker (set-marker (make-marker) (ad-get-arg 1)))
tmp-end)
(while (< from (marker-position to-marker))
(forward-sentence)
;; might have gone beyond to-marker---use whichever is smaller:
(ad-set-arg 1 (setq tmp-end (min (point) (marker-position to-marker))))
ad-do-it
(ad-set-arg 0 (setq from (point)))
(unless (or (looking-back "^\\s *")
(looking-at "\\s *$"))
(LaTeX-newline)))
(set-marker to-marker nil)))
(ad-activate 'LaTeX-fill-region-as-paragraph)
If you put a comment marker at the end of each sentence, Emacs knows not to move the next line inside the comment:
chat chat chat.%
A new sentence
with goofed up wrapping that needs to be fixed.%
Mumble mumble%
Then M-q fills each sentence separately, at least in AUCTeX 11.85. (If you test this in Emacs, there seems to be a bug where if this is the first paragraph in the buffer and you type M-q, you get an error message. Just put a newline before the text to work around it.)
If you don't want to type the comment characters, you could take LaTeX-fill-paragraph and modify it so that sentence-ending punctuation at end of line works similarly to comments.
(defun wrap-at-sentences ()
"Fills the current paragraph, but starts each sentence on a new line."
(interactive)
(save-excursion
;; Select the entire paragraph.
(mark-paragraph)
;; Move to the start of the paragraph.
(goto-char (region-beginning))
;; Record the location of the end of the paragraph.
(setq end-of-paragraph (region-end))
;; Wrap lines with 'hard' newlines (i.e., real line breaks).
(let ((use-hard-newlines 't))
;; Loop over each sentence in the paragraph.
(while (< (point) end-of-paragraph)
;; Determine the region spanned by the sentence.
(setq start-of-sentence (point))
(forward-sentence)
;; Wrap the sentence with hard newlines.
(fill-region start-of-sentence (point))
;; Delete the whitespace following the period, if any.
(while (char-equal (char-syntax (preceding-char)) ?\s)
(delete-char -1))
;; Insert a newline before the next sentence.
(insert "\n")))))
(global-set-key (kbd "M-q") 'wrap-at-sentences)
May not work in all circumstances, but:
(defun my-fill-sentence ()
"Fill sentence separated by punctuation or blank lines."
(interactive)
(let (start end)
(save-excursion
(re-search-backward "\\(^\\s-*$\\|[.?!]\\)" nil t)
(skip-syntax-forward "^w")
(setq start (point-at-bol)))
(save-excursion
(re-search-forward "\\(^\\s-*$\\|[.?!]\\)" nil t)
(setq end (point-at-eol)))
(save-restriction
(narrow-to-region start end)
(fill-paragraph nil))))
To make it work with auto-fill-mode, add (setq normal-auto-fill-function 'my-fill-sentence) to your LaTeX mode hook (I think).
I am assuming you know elisp.
There are a few approaches you can take:
Hook into auto-fill-mode. There are a lot of hard-coded
conditionals there, so it might not work for you. You can
potentially play with auto-fill-function and see if you have
the hook you need there.
Make a character (probably .) "electric" so that when you press
it, it inserts itself and then calls a function to determine how
to fill the line you're on.
Set an after-change-hook to call a function that determines how
to fill the sentence. This function will be called after every
change to the buffer, so do it efficiently. (This mechanism is
used by font-lock, so don't worry about it too much. It sounds
slow, but really isn't -- people type slowly.)
Once you have hooked in at the right place, you just have to implement
the filling logic. The source for sentence-at-point (from thingatpt) may be
instructive.
Anyway, I've never heard of anyone doing this... but it is definitely possible. Like most things in Emacs, it's just a Simple Matter Of Programming.
If the other answers are too automatic, here's a semiautomatic approach.
It's basically what you would do repeatedly if you were going to manually reformat, but condensed so you can hit a single key repeatedly instead.
;; - go to the end of the line,
;; - do ^d to suck the previous line onto this one,
;; - make sure there's only one space between the now-concatenated
;; lines, and then
;; - jump to the end and hit space so that (with auto-fill-mode)
;; the line nicely rewraps itself:
;; (turn on auto-fill-mode with M-x auto-fill-mode)
(defalias 'fill-sentence
(read-kbd-macro "C-e C-d SPC M-x just- one- space RET C-e SPC <backspace>"))
(define-key global-map [f4] 'fill-sentence) ; or whatever key you like
I like Chris Conway's macro a lot but it only works after you manually line-break each sentence. I'm a lazy guy so I want emacs to do it for me. This morning I finally sat down and looked into the problem. The solution I have now is to hack the built-in macro fill-region-as-paragraph.
After applying the following hack, a new option newline-after-sentence will be set to true. The standard M-q (fill-paragraph) will automatically fill and create line-breaks between sentences. Note that tests are only done with GNU Emacs 23.3.1 — use it at your own risk.
The full macro is long so I won't post it here. The idea is to add the following loops in fill-region-as-paragraph
...
;; Insert a line break after each sentence
(while (< (point) to)
(forward-sentence)
(if (< (point) to) (fill-newline)))
;; This is the actual filling loop.
(goto-char from)
(let (sentbeg sentend)
(while (< (point) to)
(setq sentbeg (point))
(end-of-line)
(setq sentend (point))
(fill-one-line sentbeg sentend justify) ;; original filling loop
(forward-line)))))
...
You can find the full macro in my git repository. Some details are also written in my blog. In case you don't want to read my poor English, you can simply use
$ curl http://fermi.mycloudnas.com/cgit.cgi/fill/plain/hack.el >> ~/.emacs
to append the hack to your ~/.emacs and give it a try. Comments and bug reports are all welcome.
An alternative approach would be to leave your .tex file as is, and use a tool like latexdiff
(described in this StackExchange post) instead of Unix diff. This produces a .tex file with Word-style track changes marks, and handles whitespace correctly so you don't have to worry about where your sentences end.
I wrote the following which loops over a region and inserts newlines. Instead of using forward-sentence which didn't work for me, I use re-search-forward "[.?!][]\"')}]*\\( \\)", which finds all sentences followed only by two spaces (the regexp is a modified sentence-end). The newline is made using newline-and-indent.
(defun fill-sentences-in-paragraph ()
"Put a newline at the end of each sentence in paragraph."
(interactive)
(save-excursion
(mark-paragraph)
(call-interactively 'fill-sentences-in-region)))
(defun fill-sentences-in-region (start end)
"Put a newline at the end of each sentence in region."
(interactive "*r")
(call-interactively 'unfill-region)
(save-excursion
(goto-char start)
(while (re-search-forward "[.?!][]\"')}]*\\( \\)" end t)
(newline-and-indent))))
To be able to fix improperly formatted text such as the example "chat chat chat...", fill-sentences-in-region first calls unfill-region which gets rid of sentence-breaking whitespace:
(defun unfill-region (beg end)
"Unfill the region, joining text paragraphs into a
single logical line. This is useful, e.g., for use
with 'visual-line-mode'."
(interactive "*r")
(let ((fill-column (point-max)))
(fill-region beg end)))
I use visual-line-mode and replace my default paragraph fill M-q to fill-sentences-in-paragraph with (global-set-key "\M-q" 'fill-sentences-in-paragraph).