14

This is similar to Editing files with one-sentence-per-line (in function as well as motive), but I wish to have a full, flowing paragraph rather than visual breaks at every sentence.

I would like to have a minor mode that, when active, will visually join lines from the same paragraph (not separated by \n\n or paragraph-separate or ...) and then activate behavior (perhaps derived from visual-line-mode) that will wrap the line without actually inserting \n.

Does such a mode exist? If not, how would I go about the process of altering a paragraph's display properties to achieve the result? (After all, this is the crux of such a mode and one could be developed from the snippet.)

Sean Allred
  • 6,861
  • 16
  • 85
  • [...] will visually join [...]. Do you mean keep the underlying `\n` (if present), or do you want it to actually remove the newlines to provide 1-paragraph-per-line? – Jonathan Leech-Pepin Dec 12 '14 at 16:52
  • 1
    Perhaps you could use the `buffer-display-table` to make the new-lines `\n` appear to be something else like spaces or something -- see the following example in the link: http://stackoverflow.com/a/24842771/2112489 The advantage with this would be that the text in the document is **not** modified. The new line can be just about anything -- e.g., a smiley face, spaces, a pilcrow symbol, etc. The visual effect is that wrapping will occur. – lawlist Dec 12 '14 at 17:01
  • @JonathanLeech-Pepin I want to keep the newlines where present. In fact, I would like to force the newline on a sentence-end, but this can be done via separate hook. – Sean Allred Dec 12 '14 at 17:10
  • 1
    @lawlist the visual effect is that newlines will be gone everywhere, isn't it? Won't all paragraphs be collapsed into one? – Malabarba Dec 12 '14 at 17:30
  • @Malabarba -- Yes, that is correct -- it affects the whole buffer. I guess a workaround might be to use a special symbol to separate paragraphs -- e.g., form-feed or something like that, and turn that form-feed into a visual `\n` using the `buffer-display-table`. – lawlist Dec 12 '14 at 17:40
  • 1
    I'm sympathetic to this request but think that the minor-mode described by OP is not the correct solution. The underlying problem is that diff doesn't work well for text as it was designed for code. Working around this issue in Emacs is a possible but not a clean solution for various reasons. It would be much better to improve diff to work well with text. – tmalsburg Jan 07 '15 at 11:24
  • @tmalsburg Good point. I wonder if there any such difftools – but I further wonder if `git` would work with it. Regardless, it's still an interesting question. :) – Sean Allred Jan 21 '15 at 00:15
  • You might find this package https://github.com/andersjohansson/tex-fold-linebreaks interesting – zakkak Feb 02 '16 at 20:56

2 Answers2

3

As Tom said, putting a display property on the newlines will kind of work.

The problem is to figure out which lines to wrap.

Here is an example to get you started:

(let ((eol-regexp "[[:graph:]] ?\\(\n\\)[^\t\n ]"))
  (font-lock-add-keywords nil
   `((,eol-regexp 1 '(face default display " ")))))

(visual-line-mode 1)

This will "remove" newlines if it is preceded by graphical characters and the next line is not indented or empty. You will have to experiment to find something that works for you.

Some more explanations:

  1. font-lock-add-keywords adds a list of rules to font locking (so font lock must be enabled. The first argument can be a mode (e.g. text-mode); in our case it is nil, which means add the rule only for the current buffer.
  2. Our "rule" is (,eol-regexp 1 '(face default display " ")). The first element is the regular expression we built earlier; the second is the subexpression we are interested in; the third is the "face" we want to apply.
  3. While using a face for the newlines is of no use for us, we can also add text properties. So we use the default face and than add a display property witch replaces the substring 1 (i.e. the newline) with a space.
  4. If you shoot yourself in the foot, delete the buffer or remove the keyword with font-lock-remove-keywords.
  5. You might also want to add display to font-lock-extra-managed-props (I have not tried this).
  6. The tricky part is to get the regexp right. "\(\n\)[^\n]" would match any newline that is not immediatly followed by another one. ".\{30,\}\(\n\)" would only match newlines preceeded by at least 30 characters.
olaf b
  • 556
  • 2
  • 7
  • One can find an implementation of the above as a package at https://github.com/andersjohansson/tex-fold-linebreaks – zakkak Feb 02 '16 at 20:58
0

If I understand the problem correctly, it is that you would like to preserve all the newlines in the buffer as they are; but you would like to display some of them as spaces. Then, you'd like word-wrapping.

For word-wrapping I think you can use visual-line-mode.

For dealing with the newlines, I think you could perhaps put a display property with " " (a string consisting of a single space) as a value on the newlines you want to display differently.

Tom Tromey
  • 759
  • 4
  • 8