clojure-emacs/clojure-mode

Adaptive fill mode broken in docstring

lgrapenthin opened this issue · 5 comments

When filling in a docstring, there is no proper adaptive filling and it always seems to fill to the beginning column of the docstring. This problem has annoyed me for more than 5 years, so I stepped a bit through the debugger, but I don't understand Emacs Lisp well enough to provide a proper fix.

An arg - asdfasdfasd sadf as dfas df asdf asdf as df as df asd
	 fas df asdf asdf asdf as df asd fa sd fa sdf as df asdf as dfa sdf

Put the cursor somewhere into the indented section and press M-q. In Clojure mode, it will ruin the indentation. Proper adaptive filling will cut as dfa sdf and put in on the next line at col 9.

My best solution so far is to set adaptive-fill-function to ignore and fill-paragraph-function to nil. So far, I haven't observed any adverse side effects but sure it breaks something.

In general, there seems to be a bunch of logic implemented around docstrings in Clojure mode, but it is not very well documented and probably not working properly. Probably one could draw inspiration for how docstring indentation is solved in other LISP major modes.

I noticed that in Emacs Lisp for instance, docstrings have no special indentation behavior, and in Clojure there are two spaces prepended to each line. Its a weird convention but it seems to be somehow rooted in Clojure core? Is that what all the logic is about? Maybe getting rid of that is too much to ask for, but it would be nice if you can make adaptive filling work.

;;; Workaround, use at your own risk
(add-hook 'clojure-mode-hook
		      (lambda ()
			(interactive)
			(setq-local fill-paragraph-function nil)
			(setq-local adaptive-fill-function 'ignore)))

That's related to #241, right?

I'm not entirely sure. There is somebody complaining about forcing every line to be indented after two spaces in a docstring, if I understand correctly overriding other intended indentation effects. In that regard the issue would be related.
It would be good to clarify what exactly clojure-mode is trying to achieve with special indentation of docstrings. Apparently, two spaces at the beginning at each line are "correct", but looking at the code makes it hard to believe that this is the only functionality implemented. At least, the way it is implemented, it conflicts with Emacs adaptive filling functionality.

I was under the impression that it is a standard to have the 2 leading spaces indentation on every line in Clojure docstrings. I don't recall seeing many (any?) docstrings formatted differently.

Indeed, also many Clojure core docstrings are formatted like this. Some research shows that it affects how clojure.repl/doc prints them.
Anyways, it should be possible to achieve that without breaking adaptive fill.

Interestingly, many core 'nses have their docstring without the two-space indent. The two space rule seems somewhat inconsequential. Could it be that it was just overlooked in Rich's editor settings when he wrote docstrings for clojure.core and somehow became a "convention"?

Edit: Indeed its different. I took some metrics manually

clojure.zip - 2
clojure.walk - 0
clojure.test - 3
clojure.string - 0
clojure.reflect - 0
clojure.pprint - 0
clojure.core.reducers - 6 (1)

So these ns'es all have different second line indendation in their docstring and clojure.repl/doc prints them differently bad (ymmv, I wouldn't care, but users seem to).

Still for function docstrings users can hold up the argument that 2 spaces became a convention and that probably its irreversible.

Anyways, maybe these data points are more relevant to the other ticket. This ticket was supposed to point out a bug with respect to adaptive fill mode not working in docstrings. I think it can be solved without changing anything about the two space indent.