I made an Odin formatter

Link to source

I made a very minimalist Odin formatter for myself. I have tried odinfmt in the past. I have nothing against it, but I prefer something that leaves the code more as it is. I like it when the formatter lets me add newlines to anything, and doesn’t ever introduce newlines. That’s a big one for me.

So, lucyfmt’s killer features are:

  • It leaves your code alone! Plus, it does the following:
  • Indents lines with 1 tab per scope level, except for when blocks.
  • Adds one indent level to parameters if they were broken up into multiple lines.
  • There’s no way to configure this formatter. This is a great feature, actually. I’ll tell you why:
    • Keeps it simple.
    • There’s no way for you to screw it up.
    • Every file formatted with lucyfmt is formatted exactly the same.

Showcase

// Adds indentation, **only** if you break up a function call in multiple lines.
ct.window = sdl.CreateWindow(
	"lucydx12",
	sdl.WINDOWPOS_UNDEFINED,
	sdl.WINDOWPOS_UNDEFINED,
	WINDOW_WIDTH,
	WINDOW_HEIGHT,
	{.ALLOW_HIGHDPI, .SHOWN, .RESIZABLE},
)
// This will _not_ get broken up into multiple lines! lucyfmt respects the programmer.
ct.window = sdl.CreateWindow("lucydx12", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, {.ALLOW_HIGHDPI, .SHOWN, .RESIZABLE})
// Same to struct initializers
to_render_target_barrier := dx.RESOURCE_BARRIER {
	Type = .TRANSITION,
	Flags = {},
	Transition = {
		pResource = g_dx_context.targets[g_dx_context.frame_index],
		StateBefore = dx.RESOURCE_STATE_PRESENT,
		StateAfter = {.RENDER_TARGET},
		Subresource = dx.RESOURCE_BARRIER_ALL_SUBRESOURCES,
	},
}
// `case` lines don't get indented.
for &s in g_scenes {
	st := scene_status_load(&s.status)
	#partial switch st {
	case .Ready:
		scene_status_store(&s.status, .QueuedForDeletion)
	case .Free:
		if !found_free {
			scene_schedule_load(&s, new_scene)
		}
		found_free = true
	}
}
// It doesn't over-indent if you open more than 1 bracket or paren in the same line.
scene_walk(scene, nil, proc(node: Node, scene: Scene, data: rawptr) {
	ct := &g_dx_context

	if node.mesh == -1 {
		return
	}

	mesh_to_render := scene.meshes[node.mesh]

	for prim in mesh_to_render.primitives {
		dc := DrawConstants {
			mesh_index = u32(g_mesh_drawn_count),
			material_index = u32(prim.material_index),
		}
		ct.cmdlist->SetGraphicsRoot32BitConstants(0, 2, &dc, 0)
		ct.cmdlist->DrawIndexedInstanced(prim.index_count, 1, prim.index_offset, 0, 0)
	}
})

LucyDX12 is formatted with lucyfmt. Why do you think the code looks so pretty?

Feedback

I want other people to use this. I’m sure it’s not only me that I want something like this. So please, let me know if you are interested in using this, but it’s not exactly to your liking. Maybe we can make it work.