dfmt icon indicating copy to clipboard operation
dfmt copied to clipboard

Option to format brace struct initializers one field per line

Open helikopterodaktyl opened this issue 5 years ago • 2 comments

When doing struct initialization, dfmt will try to wrap fields to match the line length, like this:

void main()
{
    MyStruct foo = {
        long_field_name_a: 1, long_field_name_b: 2, long_field_name_c: 3, long_field_name_d: "hello world",
        long_field_name_e: 123456, longfieldname_asdf: "longfield"
    };
}

It'd be nice to have a config option to abandon wrapping and just put each field on a separate line. :

void main()
{
    MyStruct foo = {
        long_field_name_a: 1,
        long_field_name_b: 2,
        long_field_name_c: 3,
        long_field_name_d: "hello world",
        long_field_name_e: 123456,
        longfieldname_asdf: "longfield"
    };
}

It results in a cleaner look, especially when nesting struct initializers.

helikopterodaktyl avatar Oct 17 '20 13:10 helikopterodaktyl

big +1

Here's a particularly egregious example:

        VkInstanceCreateInfo createInfo = {
            pApplicationInfo: &appInfo, enabledExtensionCount: cast(uint) extensions.length, ppEnabledExtensionNames: extensions
                .map!toStringz.array.ptr, enabledLayerCount: cast(uint) desiredValidationLayers.length, ppEnabledLayerNames: desiredValidationLayers
                .map!toStringz.array.ptr, pNext: cast(VkDebugUtilsMessengerCreateInfoEXT*)&debugInfo
        };

I think other opinionated formatters (thinking of Prettier for JS and Black for Python) tend to format as a single line for very small declarations, but switch to one-field-per-line when they would be forced to wrap (or perhaps its a smarter heuristic that looks at a combination of line length and number of fields, I'm not sure).

JEphron avatar Apr 12 '21 01:04 JEphron

This would really be nice for larger blocks. I would even suggest making it configurable to be staggered. Currently looking at:

Scene scene = {
	camera: camera, lights: [Light(Vec!3(2, 2, -2), Vec!3(1, 1, 1))], indices: mesh.index.attr.getContent!3()
		.dup, positions: (cast(Vec!3*) mesh.attributeSet.position.content.ptr)[0
			.. mesh.attributeSet.position.elementCount].dup, normals: (
			cast(Vec!3*) mesh.attributeSet.normal.content.ptr)[0 .. mesh.attributeSet.normal.elementCount].dup,
	colors: (cast(Vec!4*) mesh.attributeSet.color[0].content.ptr)[0 .. mesh.attributeSet.color[0].elementCount]
		.dup, backgroundColor: Vec!4(0, 0.8, 0, 1),
};

Before formatting this was:

	Scene scene = {
		camera: camera,
		lights: [Light(Vec!3(2, 2, -2), Vec!3(1, 1, 1))],
		indices: mesh.index.attr.getContent!3().dup,
		positions: (cast(Vec!3*) mesh.attributeSet.position.content.ptr)[0
		.. mesh.attributeSet.position.elementCount].dup,
		normals: (cast(Vec!3*) mesh.attributeSet.normal.content.ptr)[0 .. mesh.attributeSet.normal.elementCount].dup,
		colors: (cast(Vec!4*) mesh.attributeSet.color[0].content.ptr)[0 .. mesh.attributeSet.color[0].elementCount].dup,
		backgroundColor: Vec!4(0, 0.8, 0, 1),
	};

If done staggered, this would even looks a tidy as:

Scene scene = {
	camera:
		camera,
	lights:
		[Light(Vec!3(2, 2, -2), Vec!3(1, 1, 1))],
	indices:
		mesh.index.attr.getContent!3().dup,
	positions:
		(cast(Vec!3*) mesh.attributeSet.position.content.ptr)[0.. mesh.attributeSet.position.elementCount].dup,
	normals:
		(cast(Vec!3*) mesh.attributeSet.normal.content.ptr)[0 .. mesh.attributeSet.normal.elementCount].dup,
	colors:
		(cast(Vec!4*) mesh.attributeSet.color[0].content.ptr)[0 .. mesh.attributeSet.color[0].elementCount].dup,
	backgroundColor:
		Vec!4(0, 0.8, 0, 1),
};

HuskyNator avatar Nov 15 '23 16:11 HuskyNator