toml-lang / toml

Tom's Obvious, Minimal Language
https://toml.io
MIT License
19.38k stars 845 forks source link

A style guide for toml? #608

Closed yjqiang closed 5 years ago

yjqiang commented 5 years ago

We shouldn't force user to follow the rules since it would be hard for developers to verify the style and parse toml file. But I think we can make a style guide just like https://www.python.org/dev/peps/pep-0008/ . For example, Use 4 spaces per indentation level. or Limit all lines to a maximum of 79 characters..

bd82 commented 5 years ago

A style guide is interesting.

I've created a Prettier Toml Plugin which could enforce (most of?) the rules of such a style guide. https://github.com/bd82/toml-tools/tree/master/packages/prettier-plugin-toml

LongTengDao commented 5 years ago

How about this?

# comment

[chapter]

w = [ "...", "..." ]

uu = [
  "......",
  "......",
]

[chapter.section]

w = { w = "...", uu = "..." }

uu = """
...
..."""
  1. Never use indent unless in multi-line inline array of long items (2 spaces indent for writing convenience), for multi-line strings writing convenience, and not to be YAML (otherwise, the most special design of whole table keys chain in TOML is useless—wordy and not aligned).
  2. Single space and empty line as the sample above showed (Don't align =).
yjqiang commented 5 years ago

How about this?

# comment

[chapter]

w = [ "...", "..." ]

uu = [
   "...",
   "...",
]

[chapter.section]

w = { w = "...', uu = "..." }

uu = """
..."""
  1. Never use indent unless in inline array, for multi-line strings written.
  2. Single space as the sample above showed.

Maybe no need to add one line in the same part?

[chapter]
w = [ "...", "..." ]
uu = [
   "...",
   "...",
]
LongTengDao commented 5 years ago

Maybe no need to add one line in the same part?

Each below is not clear...

# comment
[chapter]
w = [ "...", "..." ]
uu = [
  "......",
  "......",
]
[chapter.section]
w = { w = "...", uu = "..." }
uu = """
...
..."""
# comment

[chapter]
w = [ "...", "..." ]
uu = [
  "......",
  "......",
]

[chapter.section]
w = { w = "...", uu = "..." }
uu = """
...
..."""
# comment

[chapter]

w = [ "...", "..." ]
uu = [
  "......",
  "......",
]

[chapter.section]

w = { w = "...", uu = "..." }
uu = """
...
..."""
yjqiang commented 5 years ago

And in readme, you can see this, using indent to declare different level

# From README
[servers]

  # Indentation (tabs and/or spaces) is allowed but not required
  [servers.alpha]
  ip = "10.0.0.1"
  dc = "eqdc10"

  [servers.beta]
  ip = "10.0.0.2"
  dc = "eqdc10"

And the key/value pair.

# From README
[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true

But here is the problem, what if we mix them(sub-table and key/value pair)?👇 Now I'm confused, do we need indent to declare the leve?

# From README
[[fruit]]
  name = "apple"

  [[fruit.variety]]
    name = "red delicious"

  # This table conflicts with the previous table
  [fruit.variety]
    name = "granny smith"
LongTengDao commented 5 years ago

But here is the problem, what if we mix them(sub-table and key/value pair)?👇 Now I'm confused, do we need indent to declare the leve?

I understand what you said. So I prefer "no", never indent unless in multi-line inline array.

otherwise, the most special design of whole table key chain in TOML is useless—wordy and not aligned

yjqiang commented 5 years ago

I understand what you said. So I prefer "no", never indent unless in multi-line inline array.

I like python. So if we don't care about the readme, I prefer this.

# I wrote by myself
[database]
  server = "192.168.1.1"
  ports = [ 8001, 8001, 8002 ]
  connection_max = 5000
  enabled = true

I understand what you said.

Sorry for my poor English skills. 😂

LongTengDao commented 5 years ago

I like python. So if we don't care about the readme, I prefer this.

# I wrote by myself
[database]
  server = "192.168.1.1"
  ports = [ 8001, 8001, 8002 ]
  connection_max = 5000
  enabled = true

Then why not YAML...

I understand what you said.

Sorry for my poor English skills. 😂

Oh, I mean I got your use case, not about the language. I'm also Chinese.

yjqiang commented 5 years ago

Then why not YAML...

Good idea. lol

Oh, I mean I got your use case, not about the language. I'm also Chinese.

Yeah. I noticed that.

LongTengDao commented 5 years ago

Then why not YAML...

Good idea. lol

It's just a rhetorical question. In fact, I have wrote an article to recommend TOML, and compare it with INI/JSON/JSON5/YAML. https://ZhuanLan.ZhiHu.com/p/50412485 (English: https://github.com/LongTengDao/TOML/wiki/0)

The advantage of TOML (compare with YAML) is:

  1. Editing and reading indent-base config file always make people nervous, being afraid of counting levels incorrectly, especially using 2 spaces indent.
  2. In trite editing UI, which not support multi-line indent/back-indent together or auto indent while breaking line, editing indent-base config file is very bothering.
  3. Here is too much magic in YAML, which you need all know in the beginning, even if you only want to use the basic features. e. g., what's the rule for bare key name? Would you quote all key names?
  4. How to specify a multi-line string precisely? I mean precisely control the starting and ending empty lines.

JSON/JSON5 is not based on indent, but without indent, you can't read it. And you will be f***ed when you want to write a multi-line string. Even there is JSON6 (template string), it will still hurt your head, because the lines returned to the top of line in it, and indents tree looks bad then.

Then TOML comes. It use whole table key chain to avoid using indent. (It's so luxurious to use indent in TOML...)

pradyunsg commented 5 years ago

Thanks for filing this @yjqiang!

Having a style guide might not be needed for TOML given that it's already a fairly strict language in some senses and additionally, it is designed for being human-consumable.

That said, I do see that there might be some value in having a guide and I welcome folks to do so as an "external" effort for this; to see if the community of TOML users care enough. I'll be more than happy to adopt a popular style guide as the "TOML Style Guide" if a popular style guide emerges. I welcome @bd82 or @yjqiang to champion such an effort, if they wish to.

@LongTengDao That's a nice blog post. Thanks for writing it.


I'll close this issue since I don't think there's anything actionable for me here but please feel free to mention me, if you feel like there's more discussion to be had here. :)

sisrfeng commented 1 year ago

never use indent in toml unless ...

Indent is elegant and clear. Personally, I use indent to make the structure of the file very clear. And I use vim with set foldmethod=indent for most filetypes, like python, vimL, (vim's) help, tex, man, lua ...

why not yaml

Because we ,as a user, can not use yaml if the tool is configured through toml file.

update: Please see my next reply. New reader can ignore content below:

  1. I have concealed " with no cchar, so there are hidden.
  2. The syntax highlights for "Boolean" and string in " were badly configured in this screenshot.

Using indent: (In nvim with conceal)

eksortso commented 1 year ago

@sisrfeng I'm sorry, but your example is not just confusing, but also invalid.

I understand why you would prefer to use indents, even though they aren't necessary. But It's important to maintain clarity by not implying that indentation is significant. For instance:

[pager]
    # ...

    [[columns]]  # NOTE: Not pager.columns!
        # ...

The table pager and the array columns are both located at the same level, in the root table. The indentation used here is deceptive, because the columns array is not part of the pager table! Avoid indentation that may lead to this confusion.

I can also understand why you want to align your equals signs. The extra whitespace keeps the keys and the values separated visually. The downside to this, though, is that if your keys' names are significantly shorter than the longest name, you visually lose the connection between the name and the value. Since keys within a table need not be listed in any particular order, what would happen if you changed the order of your keys, when you relied heavily upon their order when writing your config files? Save yourself some trouble, and keep keys close to their values.

In TOML, all strings must be written in quotes. Unlike YAML, bare words can never be strings. This prevents ambiguity, which to this day still plagues YAML. Your pager table, without the extra lines, ought to look like the following:

[pager]
mode = "Disable"
detect_width = false  # this is a boolean
command = "bat"

You may use indentation and alignment however you wish, but keep this advice in mind. And always write strings in quotes.

sisrfeng commented 1 year ago

your example is not just confusing, but also invalid. Sorry for not being clear.

Pls see my update above. And honestly, I misunderstood [[ columns ]].

After correction:
(with nvim's set conceallevel=2)
(Update: Why indent [[columns]] like this? See my next reply)

with nvim's set conceallevel=0

marzer commented 1 year ago

Why are you indenting [[columns]] like that? It is misleading.

sisrfeng commented 1 year ago

The indent implies that the following parts share similar meaning, not implying that [[ columns]] belongs to a [ XXX ]. I think it's quite clear with this comment, which acts like a header: # [[ columns ]] : an aarray of table I use indent to make the hierarchy clear, with these in nvim:

  1. set foldmethod=indent
  2. nnoremap f :set foldmethod=indent<CR>zazz (this make it easy to toggle folding)

with folding:

no folding:

eksortso commented 1 year ago

Oh, that is interesting. Your personal style and setup is then attempting to treat the array and its tables as distinct entities, so that you can fold several tables at once. This goes beyond simple style considerations, then. That may work for you. But it ought to be noted that array-of-table entries do not need to be listed one after another.

Like tables in general in TOML, the elements of an array of tables can be listed in any order, even mixed with tables that aren't part of the array's contents. The result is the same, an array consisting of the tables in the order that they were specified. But such a split arrangement would make it impossible to fold the entire array in the way that you're doing it.

In most applications that I've seen, keeping all the tables in a table array together makes sense. But TOML is not JSON, and there exist legitimate arrangements of tables that would make more sense in certain situations if table array entries were split apart.

sisrfeng commented 1 year ago

@eksortso Thank you! I show my config (though it may be a little bit too personal) mainly for arguing against this:

never use indent in toml unless ...

sisrfeng commented 1 year ago

Something similar for indent in yaml:

(from https://www.redhat.com/sysadmin/yaml-tips)

image

rtgiskard commented 1 year ago

It'll be good to dumps with indentation for human readers

a config with identation (with pelletier/go-toml/v2):

another without indentation:

another without indentation

I believe that everyone would prefer the first config file

eksortso commented 1 year ago

It'll be good to dumps with indentation for human readers

Nothing prevents current TOML emitters from indenting as they see fit.

I personally dislike indented sections; nesting is already implicit in the table headers, and indentation should never be made mandatory. But with inline tables allowing line breaks once TOML v1.1.0 is released, I would certainly indent arrays and inline tables.

Just my opinion.

sisrfeng commented 1 year ago

I personally dislike indented sections; nesting is already implicit in the table headers

I want to learn how most people fold their code.

As I mentioned, "Indent is elegant and clear. Personally, I use indent to make the structure of the file very clear. And I use vim with set foldmethod=indent for most filetypes". Without indent, how to make folding easy to toggle? For vim users, {{{ and }}} is offen used(I have nerver seen it on vscode users), but I think the mark is ugly and dirty, introducing extra visible characters in the file. As a python developer, I like indent.

indentation should never be made mandatory. I use indentation in vimL, lua, zsh/bash, man, etc, in which indentation is not mandatory, to make most languages seem like python, at least for the aspect of outlook.

I think most developers (at least for python) use 4spaces for indentation , and think that 2 spaces indent is too short and ugly.

I hope to read others' toml with proper indentation as often as possible. Users like me may feel upset if this is in the official toml style guide: "Never use indent unless in multi-line inline array of long items (2 spaces indent for writing convenience), for multi-line strings writing convenience"

rtgiskard commented 1 year ago

I do agree that "indentation should never be made mandatory", the meaning should be independent of the expression, just like coding with c++/golang, but actually the code style is import though optional for the language spec.

As it's stated that 'TOML aims to be a minimal configuration file format that's easy to read due to obvious semantics', configfile is more often to be read and then edit by human users, for which the expression should be important too, even though it's optional. Indent the level of configs will make it much more intuitive for readers to understand, I think this means a lot for the destination 'easy to read'.

As for the width of indentation, I prefer a tab over specific number of space, tab is originally used for indent things, it's a single character and means indent to next level only, the user choose how many spaces it looks like by setting tab width. This is what a indentation should be. As for the general practice that replace tab with spaces, I think it's unnecessary with modern editors like vim/nvim, notepad3, and etc.

For the suggestion of the looking style for Tab, 2 spaces might be useful for config with deep levels, but anyway, when tab is used, users are free too choose any width they like.

thernstig commented 10 months ago

Developers in this thread seem to be debating this from a vantage point of what they subjectively feel.

There is clear research showing that indentation does help readability, especially when the amount of code increases. For example a pyproject.toml could become rather large when a lot of Python tools are used.

See for example https://www.diva-portal.org/smash/get/diva2:1112978/FULLTEXT01.pdf

I thus believe that since research shows that indentation does help readability, any style guide should recommend indentation.

eksortso commented 10 months ago

First off, TOML is not a programming language. A TOML document isn't code in the same sense as Python or Rust is code. But let's ignore this overlooked distinction for now.

The study that you cite says, right in the abstract, that although some conventions may be helpful,

As for code indentation and syntax highlighting, no visible improvement was observed.

So the use of indentation is not as clear-cut as you make it out to be. I'd personally indent inline tables now that they can span multiple lines. But that's my personal take, which I arrived at through everyday use of the standard for my own projects.

Since this issue was closed years ago, I'll remind you that you're free to indent TOML however you think it will help you the most. You'll be maintaining your own configs. You can set their styles however you and your teams see best. Until overwhelming evidence for a particular format is presented to us though (preferably in a new issue), expect no further changes in the standard to encourage or deprecate indentation in any significant way.

thernstig commented 10 months ago

First off, TOML is not a programming language. A TOML document isn't code in the same sense as Python or Rust is code. But let's ignore this overlooked distinction for now.

I cannot see how that is relevant. TOML is a "markup language" or a "minimal language". From a perspective of how an eye reads structured semantics such as this, I cannot see that holding any bearing.

The study later on in the ending summary says it does matter, as well as in other places.

This shows that indentation and syntax highlighting play a big role in code readability

Conclusion We can now answer the research question; Can the readability and interpretation of code be visibly improved by adding features such as syntax highlighting, code indentation, comments and logical variable naming?

I added this bit of information as the entire discussion in here is subjective, when there in reality is an objective measurement if indention helps or not.

If a style guide is created by someone, I believe this is very relevant if they happen to read this thread.

However, if it is true that it objectively is easier to read a simpler, minimal markup language like TOML without indentation, then I also completely agree it should not contain indentation. My goal was just to say that subjective opinions should not trump an objective measurement, if there is one for this case.