lassik / emacs-format-all-the-code

Auto-format source code in many languages with one command
https://melpa.org/#/format-all
MIT License
605 stars 105 forks source link

Regex for link to file location like in compilation #50

Open bradyt opened 5 years ago

bradyt commented 5 years ago

For M-x dart-server-format, they provide the following regex,

(defvar dart-server--formatter-compilation-regexp
  '("^line \\([0-9]+\\), column \\([0-9]+\\) of \\([^ \n]+\\):" 3 1 2)
  "Regular expresion to match errors in the formatter's output.
See `compilation-error-regexp-alist' for help on their format.")

(add-to-list 'compilation-error-regexp-alist-alist
             (cons 'dart-server-formatter dart-server--formatter-compilation-regexp))
(add-to-list 'compilation-error-regexp-alist 'dart-server-formatter)

This made it easy to jump to the location from error contents such as the following:

Could not format because the source could not be parsed:

line 17, column 1 of main.dart: Expected to find ')'.
   ╷
17 │ }
   │ ^
   ╵

Perhaps it is possible if your buffer is *compilation* then any regex like the above will apply to to your formatter?

lassik commented 5 years ago

I like that idea. We could have a per-formatter regexp. Even better would be if all the formatters could emit to a standard error format. But that may be too much to hope for, at least in the near future.

lassik commented 5 years ago

Should have been more specific in my response. I don't have a lot of time/energy to implement features at the moment so if someone wants to speed this along, please collect some samples of what errors/warnings look like from the different formatters supported by format-all. I hope there are enough commonalities in the error output formats that we could have just one global regexp that covers most formatters. If there are lots of differences, we'll have to add an :error-regexp field to define-format-all-formatter. Thanks to anyone who volunteers to do the legwork :)

lassik commented 5 years ago

Most compilers use a format like file.ext:line:column: error|warning: message. It would be nice if we could convince most of the formatter authors to switch to that format (or add a command line flag to support it).

bradyt commented 5 years ago

The *compilation* buffer just uses a list of regex and checks them all.

  1. Can we have the format-all error buffer use compilation mode to get a lot of file linking for free?
  2. Or we could use the regex alist already existing there anyways, though I realize you might later want something more precise and deliberate.
  3. Or, format-all could also take the approach of running through a custom and user-editable list of regex, at least for the short term future.

Maybe using compilation mode is the most idiomatic? As one IRC'er puts it,

13:50 it would make things easier and more consistent
13:51 generally I tend to reuse the built-in stuff unless I can't for some reason

I have the project cloned, but I'll have to find time to learn where to "insert" (compilation-mode), etc.

lassik commented 5 years ago

Thanks for taking this up :)

Unfortunately it may not be as straightforward as re-using compilation-mode since it is geared toward running a subprocess. For one, it binds the g key to recompile which won't be natural for format-all (if you press g in *format-all-errors* it would be surprising if it runs a compiler instead of a formatter). There may be other things like that. There is define-derived-mode that we might be able to use to subclass compilation-mode but future versions of Emacs may add more stuff to compilation-mode, so we'd get into an arms race where they add new stuff and we put in code to remove it :)

From reading the Emacs source, compilation-mode does most of its magic by running the compilation-setup function. Maybe we could call that one, or copy/paste the relevant stuff from it.

If we can have a global list of regexps and always run through all of them, that's definitely better than adding another per-formatter field to the definitions. It won't be slow even if there are useless regexps since formatters don't print tons of messages per file.

lassik commented 5 years ago

The place to insert this stuff is in the format-all--show-or-hide-errors function.