Hacker News new | past | comments | ask | show | jobs | submit login
Par: Paragraph reformatter, vaguely similar to fmt, but better (nicemice.net)
104 points by ingve 10 months ago | hide | past | favorite | 33 comments



I've been using par for about twenty years, and 100% agree with its own apology: "Its only redeeming features are that it is extremely useful".

I literally have no clue what my $PAR* vars do, or what the odious string in my mutt config does. However, it works perfectly so I simply trust I won't have to figure it out again.

--

Oh, and check out his X-Advice¹ doc. It was a really great idea that sadly never caught on. Scanning a years worth of my own mail to write this comment tells me it is just me and one friend who use it, and only for "should read whenever" for messages between eachother :/

¹ http://www.nicemice.net/amc/advice-header/


Fellow Mutt user, here. I have an AWK script I use to filter my messages before displaying them that has logic for wrapping while respecting ">" indentation among other things. I would be interested in know what your "par" invocation in Mutt is.


I used to use par before I switched to far (https://cgdct.moe/blog/far/) which produces better looking paragraphs in my opinion by minimizing the variance between lines while using the fewest number of lines possible.

There is a native emacs version as well, at https://github.com/eshrh/far.el (i wrote it)


Vim users can do "set formatprg=par" to use par for formatting ("gq"). Super great for keeping comments <80 chars


But doesn’t that overwrite the format algorithm for the filetype altogether? I mean, does it break formatting for the rest of the document (the non-comment)? Or does this somehow play nice with formatlistpat?


par tops out at 72 by default afaik, so if you 80 is your preferred limit, I'd suggest `par -w79`


What does it use by default?


So speaking of line widths, I'm curious what people generally use for programming and enforce with auto-formatters. I know there tends to be a lot of debate about this wholly subjective question, but I'm wondering what reasoning people have for their preferred line length. It seems many tools still default to 80 characters. This does feel restrictive, but, on the other hand, I personally find shorter line lengths to be quite pleasant. Still 80 feels too restrictive and I think its being a default is just a historical accident, right (punch cards and early monitors/terminals)? Anyhow, just curious if there's any interesting reasoning to prefer one limit over another or if it all comes down to personal aesthetic preferences.


My preference is 100 characters. I find it usually takes up half the screen, allowing split screen editing (on modern screen sizes).

But while on the subject, I can't help bringing up the QEMU coding style[0]:

> Some people like to tile their 24” screens with a 6x4 matrix of 80x24 xterms and use vi in all of them. The best way to punish them is to let them keep doing it.

[0]: https://qemu-project.gitlab.io/qemu/devel/style.html#line-wi...


That's a silly quote. Everybody knows it's only a vector since a tall 80x84 or whatever is always useful for keeping more of the file on the screen.

Also, for reference, a table of font sizes and number of terminals beside each other that fit on a given size screen:

            1t      2t      3t      4t      5t      6t
    6px     480     960     1440    1920    2400    2880
    7px     560     1120    1680    2240    2800    3360
    8px     640     1280    1920    2560    3200    3840
    9px     720     1440    2160    2880    3600    4320
    10px    800     1600    2400    3200    4000    4800
    12px    960     1920    2880    3840    4800    5760
    14px    1120    2240    3360    4480    5600    6720
    16px    1280    2560    3840    5120    6400    7680
On a screen with the traditional ~100 DPI, a 6px wide font is quite readable so on 1920x1080 you get exactly 4 columns of terminals (just beware window decorations trying to steal extra pixels). If the height is 13px (so it's about a 9.5pt font IF point size is measured honestly) you get about 75 lines depending on taskbar and window headers.


I stick to 80 columns, as with it I can better use my screen space. Even on modern wide screens.

Even if some lines are long, a lot of lines are short. So the end-of-line side of a text editor is less densely used than the start of line side. This may not show too much with 80 columns line, but with longer lines one can notice that the end-of-line space is mostly blank, with low information density.

So instead of using long lines, I'm using 80 columns lines but with several (3 in practice) text panes in parallel. Basically, my work set-up is 3 columns of text panes, with 80 columns of characters each. That allows working on a module body with its header still visible, and the header of another used module shown too. Or to see two different parts of the same file easily (head with declaration, bottom with code). In other words, it's easy to find productive use for 3 parallel text panes. And each one is "information dense".

I'd like to have a little more than 80 columns. 100 would be a good number (higher waste space on the EOL side). But with this I can't fit 3 parallel panes on some screen. So I stick with 80 characters, which is OK too. 80 characters can be annoying when manually formatting code, but when using an automatic formatter (clang-format, yapf, black...) it's not such a big deal.

Anyway, there's a big subjective part in this so just use what's fine by you (and your team). Still, the information density part is an objective thing. So if you can use 3 parallel text panes with your editor, I suggest you try it. That may make you stick to 80 chars too, and not only for historical reasons ;)


The maximum width of a line from the first printing character to the last should be limited to about 40 characters.

The absolute line length should not be subject to a hard limit.

This is because code indents:

  ------
    -----
    -----
      ------
        ------
          ------
What I don't want to be obnoxiously long is any of the ----- content itself, regardless of how much or how little indentation is in front of it.

I don't like ridiculous nesting, but imposing some hard limit like 80 columns or 100 is counterproductive; let that naturally limit itself.

When confronted with these limits, programmers do ugly things, like start using shorter and shorter lines at deeper nesting levels, those lines being awkwardly split to fit:

             fun(arg,   // 80th column here
                 arg,   //
                 term + //
                 term + //
                 term); //
Please, just go over 80 and write fun(arg, arg, term + term + term)!

The counterargument is that if you ever have to produce hard copy, it's good if the code sticks to reasonable number of columns. I think we are past the era where people bring hardcopies of code to code reviews, though. We also care about code histories a lot more; printing out a program on paper is no longer considered a viable way to preserve it for future generations, since it loses the change history.


Forcing people to split their function into subfunctions to reduce nesting usually works well. Occasionally I'm reluctant to do so, but whenever I do, the code seems to get better. Obviously don't take it to the extreme but if you're 5 levels deep already there's probably a nicer way to write that.


Helper functions that are called only once can easily make the logic harder to read than the original function. Now you have to jump around through detours to recover the linear flow. If the functions aren't inlined, it can slow things down for the machine too.


I like the approach of aiming for ~80 chars, allowing ~88 chars but not being anal about it and allowing judicious use of disabling rules on a per-line basis.

This seems common in Python using a combination of black to do the formatting and flake8 to enforce it. It works well in almost all cases. I've not encountered many situations where one could argue >88 chars leads to the most readable code.


I like 120 or so but I give 0 shits if my personal code gets very wide. At work they force 80 and normally that's fine but every now and then it produces some gnarly code and I just LOL at whoever has to review it because I have 0 patience for Fighting against the auto formatter and or style committee. They created this mess, they can live with it.


I still like 80 as it is just perfect to be able to see two split diffs simultaneously on my screen without any line wrapping whatsoever (in a roughly 350 column terminal) which is a pretty common use case for me.


Same, mainly because I like a fairly large font size, 17pt. Makes it tough with long line codebases though...


I used to pipe to fmt out of Vim quite a bit. The gq reformatting improved so I just use that. It understands comments, e.g.

   /* long comment ... */
reformats to

   /* long comment ...
    * ...
    * .... */
and similarly with other kinds of comments.


> Someday I ought to reexamine the problem, and redesign a new, clean solution from scratch. I don't know when I might get enough free time to start on such a project. Text files may be obsolete by then.

One can always hope... but I think there will still be plenty of text files to parse in the year 2033... or 2123.


Why the hate on text files? Every now and then someone proposes moving away from them but I can think of nothing better. Every time a wysiwyg does something dumb I wish I could just write plain old text. Give me a preview window on the side if applicable but I want to control every single character without ambiguity and without being restricted to a particular editor.


much love to AMC for par. it is always useful.


#muchlove! Native Windows builds of Par, Vim and the Pine email client (now Alpine) made using Windows bearable.


Is there something similar for Emacs?


There a built-in similar function, `fill-paragraph`, tied to M-q.

I use it routinely and it's very nice. It has some language smart, and for example understand code comments, and can format comments nicely. It also has smart to recognize line header, and reformat while keeping those headers, with possibly a different first line. So if you introduce item (unnumbered list) with a "-" for example, you can either align the second line to the "-" or to the start of the text after, your choice. `fill-paragraph` will recognize this and stick to your choice when reformatting the paragraph.

I can't compare with `par`, which I've never used. But I'm a very happy user of Emacs M-q.


Emacs calls the concept "fill", and has had it as a basic built-in feature for decades.

This documentation page "https://www.gnu.org/software/emacs/manual/html_node/emacs/Fi..." doesn't do it justice, because Emacs will often do smart language- and context-appropriate things in different buffer modes.

For example, I use this feature heavily to help make my Markdown files appear semi-wysiwyg to anyone viewing them in plain text (e.g., different levels of bulleted/numbered lists are formatted).

It also keeps my code comments tidy, and encourages me to keep them up to date, because I don't have to mess with formatting.

There's also a command to temporarily set a "fill prefix" based on the point in the current line, such as if you want to fill something differently than how Emacs would do it by default.


It's an external filter, you can run it from emacs.

shell-command-on-region, IIRC.


Thank you for that. I figured Emacs would permit use of external filters, glad to know the actual incantation.


The keyboard shortcut is M-|

If you want to replace a section of text, not just see the output in another buffer, use C-u M-|


Yes, that's it exactly.


I’m not an emacs user but that gives me strong powershell vibes! (Not a derogatory remark.)


M-x eshell

  Welcome to the Emacs shell
  
  /tmp $ set-variable `x 6; echo $x
  6
  /tmp $ 
M-: (term "pwsh")

  PowerShell 7.4.0
  PS /tmp> set-variable `x 6; echo $x
  6
  PS /tmp> 
Disturbing.


any way of integrating this in vscode for git commit messages?




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: