radian-software / apheleia

🌷 Run code formatter on buffer contents without moving point, using RCS patches and dynamic programming.
MIT License
558 stars 75 forks source link

RCS patch wrongly applied results in incorrect file #299

Open guillaumebrunerie opened 5 months ago

guillaumebrunerie commented 5 months ago

Consider the following file in a Javascript project with Prettier and the plugin https://github.com/IanVS/prettier-plugin-sort-imports (which makes Prettier automatically sort imports):

import {
    firstLongImport,
    secondLongImport,
    thirdLongImport,
} from "longDependency";
import { fourthImport } from "dependency";

Formatting it in Emacs with Apheleia results in the following invalid code:

import {
import { fourthImport } from "dependency";
    firstLongImport,
    secondLongImport,
    thirdLongImport,
} from "longDependency";

(the expected behavior is that fourthImport is moved to the first line).

Running apheleia-npx from the terminal with the correct arguments correctly formats the file, so the issue seems to be in Apheleia, not in the formatter. Here is the RCS diff I get, running diff in the terminal with the same arguments as Apheleia):

a0 1
import { fourthImport } from "dependency";
d6 1

Could it be that the a0 line isn’t handled correctly?

guillaumebrunerie commented 5 months ago

I believe it can be fixed with the following patch (it is indeed the a0 which is not handled properly).

diff --git a/apheleia-rcs.el b/apheleia-rcs.el
index e462921..3d73181 100644
--- a/apheleia-rcs.el
+++ b/apheleia-rcs.el
@@ -100,7 +100,7 @@ contains the patch."
              ;; Account for the off-by-one error in the RCS patch spec
              ;; (namely, text is added *after* the line mentioned in
              ;; the patch).
-             (when (eq (alist-get 'command command) 'addition)
+             (when (and (eq (alist-get 'command command) 'addition) (> (alist-get 'start command) 0))
                (forward-line))
              (push `(marker . ,(point-marker)) command)
              (push command commands)

I’m not sure how to run the tests to make sure it doesn’t break anything else, running make fmt-build FORMATTERS=prettier-javascript fails with the error

build-image.bash: tagging apheleia-formatters:latest
build-image.bash: will install all formatters by default
test/formatters/build-image.bash: line 30: args[@]: unbound variable

I suspect the script is being run in Zsh, no idea why or how to make it run in Bash instead. Not sure anymore, running the script directly with Bash makes no difference. I’m on Mac OS Sonoma if it matters.