cmake_format
cmake_format copied to clipboard
Need more empty lines
I often separate blocks of CMake statements by two and sometimes three empty lines, simulating something akin sections and subsection -- it greatly enhances readability. Especially so, when you mix cmake with markup comments. So I would appreciate option to not touch multiple empty lines when they are less than N. Or (better?) don't touch empty lines < N when next line is comment.
# EXPL:(-std=c++20): enable instead of -std=gnu++20
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# EXPL:(-std=c11): enable instead of -std=gnu11
set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
# EXPL:(compile_commands.json): generate cmdline database in build directory
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
This is quite possible.
I was in the process of implementing this and it seems kind of silly to add a configuration option for such a specific case. I also don't like introducing any feature where the input formatting can influence the output formatting.
If you want additional newlines to separate things, why not just add a blank line comment:
# EXPL:(-std=c++20): enable instead of -std=gnu++20
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
#
# EXPL:(-std=c11): enable instead of -std=gnu11
set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
#
# EXPL:(compile_commands.json): generate cmdline database in build directory
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
Seems like it gives you the flexibility of deciding how many lines to use wherever you think additional visual separation is appropriate beyond the "usual". Alternatively would you utilize a "number of lines before statement prefix-comment" as a consistent way to achieve additional visual separation in the specific case of a comment before a statement?
Blindingly simple but tempting solution. OK, in a couple of days I will reformat one of my codebases by this novel suggestion and will share personal experience of staring into the abyss :)
Edit:
Yes, it was actually good enough. Currently spotted cons:
- It become less clean and aerial, when looking at code, but I hope it's a problem of habit.
#
# EXPL:(-std=c11): enable instead of -std=gnu11
set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
#
#
# EXPL:(compile_commands.json): generate cmdline database in build directory
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
- Somebody will start making these comments symmetrical like in GNU configs, and due to increased distance between code and comments they will become less standing out and may even become totally dangling and unrelated. It's again a matter of perception and discipline, but look here and try to see like comments and code started feeling like two separated entities instead of unified one:
#
# EXPL:(-std=c11): enable instead of -std=gnu11
#
set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
#
#
# EXPL:(compile_commands.json): generate cmdline database in build directory
#
#
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
Nevertheless, this approach also has some procs:
- Logically, spaces belong to the section below it, not above -- i.e. spaces are separators before starting new section, not trailing space after ending section. Therefore rearranging paragraphs in vim by
dap
become easier -- they are no more moving trailing spaces with them. - Sections themselves become more homogeneous, having only single space between them
Overall I think, with such solution there is no need to keep this issue open for now -- at least until new pain arise.
OK, I was too hasty, my bad. Actually, there is still the case, which comments can't solve gracefully:
find_program(mkrc_exe NAMES elf-resource-make)
#
function(make_resource_from_each)
...
endfunction()
#
function(make_resource nm src)
I thinks, it's worth doing the same way as PEP8 in python -- two lines before any global function definition, and one line between everything else. Because that standalone #
is as ugly as hell.
Personally I don't particularly mind single hash though I don't generally write uncommented function definitions. Regardless, for this feature:
Would the desired behavior be:
Insert
n
spaces before a function or macro definition
or
Insert
n
spaces before a statement which opens scope
In other words, same rule for if()
and foreach()
, etc.?
Also, given your experimentation, would you still like either of these features or do you think it would be covered by the above?:
- Insert
n
spaces before a comment preceeding a statement - Preserve up to
n
spaces before a comment preceeding a statement
Insert n spaces before a statement which opens scope In other words, same rule for if() and foreach(), etc.?
If they are inside function/macro -- keep no more then one space before if/foreach
or their preceding comment. Otherwise functions will look visually too much teared up.
However, if if() / foreach()
are outside function/macro, it... depends:
- small
if()
blocks tend to have single empty line between them. - large blocks are varying depending on logical closeness of them.
- nested
if()
are generally mix of above rules inside of them, but outermost always has >= 2 spaces.
Given that it's often hard to make reasonable name to standalone block of if/foreach
-- it's often no less hard to add useful comment to them. Therefore we again have a problem of wild single #
.
Insert n spaces before a comment preceeding a statement Preserve up to n spaces before a comment preceeding a statement
I assume for if/foreach
statements preserving is more useful than inserting, and for function/macro
vice versa inserting is more recommended than preserving.
it seems kind of silly to add a configuration option for such a specific case
I don't see how it is silly or this case being too specific. In fact, I'd be very glad to see configuration for blank lines, because blank line of 1 is not enough.
There is potential for the following settings:
max_blank_lines_code
Max number of blank lines between separate statements. Function/macro definition (from function() to endfunction()
) is treated as one statement (controlled further by max_blank_lines_function
). Everything else is treated as separate statement. Control statement such as if, foreach has its subparts (if(), endif()) treated as separate statements. Comments are treated as separate statements with the exception of comment with 0 blank lines until next statement below. In this case it is treated as one piece with that statement. This is necessary to omit introduction of <max|min>_blank_lines_before_*
and <max|min>_blank_lines_after_*
options that would manage blank lines before and after terms. Introduction of such options would be necessary in the use-case when comment is documentation for function and therefore should be expected to not have any blank lines between itself and function definition (which is treated as a single statement according to the rule above). Default to 2.
When set to 2, this piece should not be reformatted at blank line level:
a(b)
c()
# foo
function(d)
k()
endfunction()
# bar
macro(e)
endmacro()
max_blank_lines_statement
Max number of blank lines inside a single statement. Default to 0.
When set to 1, this piece should not be reformatted at blank line level:
foo(tgt
source1
# foo
source2)
max_blank_lines_function
Max number of blank lines inside function/macro definition. Default to 1.
When set to 2, this piece should not be reformatted at blank line level:
function(foo)
a()
# bar
b()
endfunction()
OP would set max_blank_lines_code=3
for minimal repro of his example.
There is also a point to introduce min_blank_lines_*
settings, but that is out-of-scope here. I can think of at least a few rules: for function/macro definition targeting another function/macro definition (e.g. set min spacing between functions to 2 lines, 1 by default), control statements targeting control statements (e.g. set min spacing between if's/foreach's to 1 line, 0 by default).