cheshirekow / cmake_format

Source code formatter for cmake listfiles.
GNU General Public License v3.0
958 stars 105 forks source link

Disable wrap for custom functions #139

Closed amerlyq closed 4 years ago

amerlyq commented 4 years ago

It seems some of custom functions are much better to be totally unaffected by formatting. I.e. they must be left with original formatting (verbatim) -- because aesthetic rules may be very fuzzy.

catch_or_die_at(_tag ${repo} ${GIT} describe --always --dirty --tags --match "*.*.*")

catch_or_die_at(
  _tag
  ${repo}
  ${GIT}
  describe
  --always
  --dirty
  --tags
  --match
  "*.*.*"
)
cheshirekow commented 4 years ago

We have an --always-wrap config option. We can add a --never-wrap as well. Though I think the real feature here is the ability to tag positional argument groups as "commands". cmake-format knows that for COMMAND keyword arguments to never format them as a vertical list. But there is no way to currently specify that for non-"COMMAND" keywords or for positional argument groups.

What you can do right now is re-implement your custom function to take a "COMMAND" keyword argument in which case add this to your config:

additional_commands = {
  "catch_or_die_at" : { 
    "kwargs": {
        "COMMAND": "*"
    }
  }
}

And the formatting will be

catch_or_die_at(
  COMMAND
    _tag ${repo} ${GIT} describe --always --dirty --tags --match "*.*.*")

But ideally one would be able to indicate that a positional argument group is a command.

Note to self: See bug cfa3c02

Edit 1: forgot the word "never"

cheshirekow commented 4 years ago

Or, the command part is probably ${GIT} describe right? In that case:

additional_commands = {
  "catch_or_die_at" : { 
    "pargs": 2,
    "kwargs": {
        "COMMAND": "*"
    }
  }
}

yielding:

catch_or_die_at(
  _tag ${repo}
  COMMAND
    ${GIT} describe --always --dirty --tags --match "*.*.*")

P.S. I wouldn't have expected the command to nest under COMMAND like that, but I think I know why that is. Note to self (eefbde3): Don't count command pargs against max-pargs-hwrap in which case the format should be:

catch_or_die_at(
  _tag ${repo}
  COMMAND ${GIT} describe --always --dirty --tags --match "*.*.*")

assuming line-width is exceeded, or

catch_or_die_at(_tag ${repo} COMMAND ${GIT} describe --always --dirty --tags --match "*.*.*")

if it all fits on one line

amerlyq commented 4 years ago

Thanks for the tips. Idea with no-op COMMAND can be rather usable untill tagging implemented. Of course, if it would work without registering custom function inside formatter -- it would be even better. E.g. register in formatter only keyword COMMAND -- and all functions with this keyword will be formatted accordingly and similarly -- according to keyword itself preferences.

Still even with this enhancement I would prefer to use Lisp syntax according to reasons described in #137

# Very short -- single line
catch_or_die_at(_tag ${repo} COMMAND ${GIT} describe --match "*.*.*")

# Short -- brace on same line
catch_or_die_at(_tag ${repo}
  COMMAND ${GIT} describe --always --dirty --tags --match "*.*.*")

# Longer multiline -- more indent and brace wrapped
catch_or_die_at(_tag ${repo}
  COMMAND 
    ${GIT} describe --always --dirty --tags --match "*.*.*"
)

# Very long line -- nested command indent
catch_or_die_at(_tag ${repo}
  COMMAND 
    ${GIT} describe --always
      --dirty --tags --match "*.*.*"
  [COMMAND]
   ...
)
cheshirekow commented 4 years ago

Of course, if it would work without registering custom function inside formatter -- it would be even better.

amerlyq commented 4 years ago

Thanks for your hard work! In that case we will wait and see how this new idea will work out. Maybe this issue can be closed then -- or on the contrary become more fine-detailed as comparison to that future implementation.

cheshirekow commented 4 years ago

Let's leave it open. I like having the reminder and the discussion is useful.

cheshirekow commented 4 years ago

There were four potential features discussed here, and two of them are implemented in v0.6.7. You can tag a positional argument group as a cmdline in the specification. Doing so will inhibit vertical wrapping of those arguments. I also have an early implementation of automatically generating command specifications for anything that uses cmake_parse_arguments.

I think I will likely do both of the other two things I mentioned above, but they are already tracked in other issues.

I'm going to close this bug since I think the cmdline tag should allow you to get what you want. Feel free to comment further on this discussion though.