taplo icon indicating copy to clipboard operation
taplo copied to clipboard

reorder_keys does not sort if there are comments

Open tv42 opened this issue 1 year ago • 8 comments

$  taplo --version
taplo 0.9.3

$ cat bug.toml
[pleasesort]
z = 2
# test
a = 1

$ cat bug.toml | taplo format --no-auto-config -o reorder_keys=true bug.toml -
[pleasesort]
z = 2
# test
a = 1

$ grep -v '^#' bug.toml | taplo format --no-auto-config -o reorder_keys=true -
[pleasesort]
a = 1
z = 2

tv42 avatar Sep 13 '24 21:09 tv42

It seems a blank line will also prevent reorder_keys.

tv42 avatar Sep 13 '24 21:09 tv42

This is correct behaviour, a comment might refer to specific line so it shouldn't be moved anywhere else

panekj avatar Sep 13 '24 21:09 panekj

You could choose to do what a lot of code refactoring does: assume a full-line comment describes an immediately-following non-comment line.

tv42 avatar Sep 13 '24 21:09 tv42

But that is a wrong assumption because that comment doesn't have to refer to next line

for example:

[workspace.dependencies]
ahash              = { version = "0.8.3" }
anyhow             = { version = "1.0.53" }
arc-swap           = { version = "1.5.0" }
async-trait        = { version = "0.1.52" }
either             = { version = "1.6.1" }
futures            = { version = "0.3.5" }
# getrandom          = { version = "0.2", default-features = false }
glob               = { version = "0.3" }

In this case, the comment doesn't relate to next line or previous line, it's standalone

but in below case, comment is referring directly to next line:

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
ansi_term      = { version = "0.12" }
async-ctrlc    = { version = "1.2.0", features = ["stream"], optional = true }
atty           = { version = "0.2.14" }
lsp-async-stub = { path = "../lsp-async-stub", features = ["tokio-tcp", "tokio-stdio"] }
# `prettydiff` is also a CLI that pulls in `clap` by default
prettydiff = { version = "0.6.1", default-features = false }
tokio      = { workspace = true, features = ["sync", "fs", "time", "io-std", "rt-multi-thread", "parking_lot"] }

(generally comments should be on the same line as the line they refer to)

panekj avatar Sep 13 '24 21:09 panekj

Yet, it is the assumption made all over the place in code formatters. If you want to write a comment that not about the following line, you put a blank line after it.

tv42 avatar Sep 13 '24 21:09 tv42

Even in the world you are advocating for where comments cannot be tied to uncommented lines, commenting out a line silently breaking reordering sounds unpleasant :-(

tv42 avatar Sep 13 '24 21:09 tv42

Here's another reason full line comments seem superior to me -- this would be hard to express legibly with an inline comment.

[[rule]]
include = ["deny.toml"]
# WAITING https://github.com/tamasfe/taplo/issues/608
#keys = ["graph.targets", "licenses.allow", "licenses.exceptions.allow"]
keys = ["graph", "licenses"]
formatting = { reorder_arrays = true }

tv42 avatar Sep 13 '24 21:09 tv42

I also think this is a bug. And it applies to the "reorder_arrays" option too. E.g. running taplo fmt --option "reorder_arrays=true" on the following:

[foo]
bar = [
  'z',
  'a',
  'e',
  # The letter c is really important
  'c',
  'b',
  'd',
]

Produce this output:

[foo]
bar = [
  'a',
  'e',
  'z',
  # The letter c is really important
  'b',
  'c',
  'd',
]

but I now have two independently sorted parts of the array. This is surprising to me as I expected the entire array to be sorted as a whole. The presence or absence of full-line comments should not have any impact on the actual items being sorted. In addition to the bad sorting, my comment is now also in the wrong spot.

Another tool, toml-sort has the "correct" behaviour; it sorts all items and moves comments along with the items. With the example above placed in foo.toml, running toml-sort --sort-inline-arrays foo.toml produces:

[foo]
bar = [
  'a',
  'b',
  # The letter c is really important
  'c',
  'd',
  'e',
  'z'
]

I think taplo should adopt the same behaviour. If not by default, at least with an option, e.g. "reoder_all_entries=true"

user27182 avatar Nov 12 '24 21:11 user27182