commit 55f1fbded030295a9325228f258304fcbaeb65a4
parent 9ba6c8e751a1bf236b6e3f0839121d78a4a940f7
Author: Kris Yotam <krisyotam@protonmail.com>
Date: Sun, 15 Feb 2026 23:06:42 -0600
Add suckless coding style reference to CLAUDE.md
Diffstat:
| M | .claude/CLAUDE.md | | | 202 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- |
1 file changed, 179 insertions(+), 23 deletions(-)
diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md
@@ -53,39 +53,194 @@ cd ~/.local/src/dwm && git pull && sudo make clean install
---
-## Code Style (Suckless C Conventions)
+## Suckless Coding Style
-### Formatting
-- **Indentation:** Tabs (width 8). Never spaces for indentation.
-- **Brace style:** K&R — opening brace on same line, closing at column 0.
-- **Line length:** ~80 characters preferred, not strictly enforced.
-- **No trailing whitespace.**
+Reference: https://suckless.org/coding_style/
-### Naming
-- `CamelCase` for types and structs: `Client`, `Monitor`, `Layout`, `Key`, `Button`
-- `lowercase` or `lowercasemultiword` for functions: `focusmon`, `tagmon`, `sendmon`, `killclient`
-- `UPPERCASE` for macros and constants: `MODKEY`, `NUMTAGS`, `CLEANMASK`, `SHCMD`
-- Enum values: `SchemeNorm`, `SchemeSel`, `NetSupported`
+The following are guidelines. The most important aspect of style is **consistency**.
+
+Recommended reading:
+- https://man.openbsd.org/style
+- http://doc.cat-v.org/bell_labs/pikestyle
+- https://www.kernel.org/doc/Documentation/process/coding-style.rst
+
+### File Layout
+
+Organize files in this order:
+
+1. Comment with LICENSE and file/tool explanation
+2. Headers
+3. Macros
+4. Types
+5. Function declarations (include variable names; group logically)
+6. Global variables
+7. Function definitions matching declaration order
+8. `main`
+
+### C Features
+
+- Use **C99 without extensions** (ISO/IEC 9899:1999).
+- Use **POSIX.1-2008**: define `_POSIX_C_SOURCE 200809L` or `_XOPEN_SOURCE 700`.
+- **Do not mix declarations and code.**
+- **Do not use for loop initial declarations** (e.g., `for (int i = 0; ...)`).
+- Use `/* */` for comments, **not `//`**.
+- Variadic macros are acceptable but be cautious with `__VA_ARGS__`.
+
+### Blocks
+
+- All variable declarations at the **top of the block**.
+- `{` on the same line, preceded by a single space (except for function definitions).
+- `}` on its own line unless continuing a statement (`} else {`).
+
+Use blocks for single statements only when the inner statement needs blocks:
+```c
+for (;;) {
+ if (foo) {
+ bar;
+ baz;
+ }
+}
+```
+
+Use blocks when any branch requires them:
+```c
+if (foo) {
+ bar;
+} else {
+ baz;
+ qux;
+}
+```
+
+### Leading Whitespace
+
+- Use **tabs for indentation** and **spaces for alignment**.
+- No tabs except at the beginning of a line.
+- Use **spaces** (not tabs) for multiline macros, as the indentation level is 0.
### Functions
+
+- Return type and modifiers on a **separate line**.
+- Function name and argument list on the next line.
+- Opening `{` on its **own line** (function definitions only).
+- Functions not used outside the translation unit must be `static`.
+
```c
static void
-functionname(const Arg *arg)
+usage(void)
{
- /* body indented with tabs */
+ eprintf("usage: %s [file ...]\n", argv0);
}
```
-- Return type on its own line.
-- Function name on the next line.
-- Opening brace on its own line (for function definitions only — NOT for if/for/while).
-- Minimize variable declarations; declare at top of scope.
-
-### Comments
-- `/* C89-style block comments */` preferred in source.
-- `// C99 inline comments` acceptable in config files for brief annotations.
+
+### Variables
+
+- Global variables not used outside the translation unit must be `static`.
+- In pointer declarations, `*` is adjacent to the **variable name**, not the type:
+ ```c
+ char *p; /* correct */
+ char* p; /* wrong */
+ ```
+
+### Keywords
+
+- Use a **space after** `if`, `for`, `while`, `switch` (they are not function calls).
+- **No space** after `(` or before `)`.
+- Preferably use `()` with `sizeof`.
+- **No space** with `sizeof()`:
+ ```c
+ sizeof(int) /* correct */
+ sizeof (int) /* wrong */
+ ```
+
+### Switch Statements
+
+- **Do not indent cases** another level.
+- **Comment cases that fall through.**
+
+```c
+switch (value) {
+case 0: /* FALLTHROUGH */
+case 1:
+case 2:
+ break;
+default:
+ break;
+}
+```
+
+### Headers
+
+- Place **system/libc headers first**, in alphabetical order.
+- Add comments if a specific inclusion order is required.
+- Place **local headers after an empty line**.
+- Avoid cyclic dependencies; include headers only where needed.
+
+### User Defined Types
+
+- **Do not use `type_t` naming** (reserved for POSIX, less readable).
+- Typedef opaque structs.
+- **Do not typedef builtin types.**
+- Use **`CamelCase`** for typedef'd types.
+
+### Line Length
+
+Keep lines to a reasonable length: **max 79 characters**.
+
+### Tests and Boolean Values
+
+- **Do not use C99 `bool`** types. Stick to integer types.
+- Use compound assignment and tests unless lines grow too long:
+ ```c
+ if (!(p = malloc(sizeof(*p))))
+ hcf();
+ ```
+
+### Error Handling
+
+- When functions return `-1` for error, **test against `0`**, not `-1`:
+ ```c
+ if (func() < 0)
+ hcf();
+ ```
+- Use `goto` to unwind and cleanup when necessary, instead of multiple nested levels.
+- `return` or `exit` early on failures instead of deeply nesting.
+- Unreachable code should have a `/* NOTREACHED */` comment.
+- For fatal errors in one-shot programs, memory freeing may be skipped, but temporary files should be cleaned.
+
+### Enums and #define
+
+Use enums for semantically grouped values. Use `#define` otherwise:
+```c
+#define MAXSZ 4096
+#define MAGIC1 0xdeadbeef
+
+enum {
+ DIRECTION_X,
+ DIRECTION_Y,
+ DIRECTION_Z
+};
+```
+
+---
+
+## DWM-Specific Conventions
+
+### Naming in dwm
+
+- `CamelCase` for types and structs: `Client`, `Monitor`, `Layout`, `Key`, `Button`
+- `lowercase` or `lowercasemultiword` for functions: `focusmon`, `tagmon`, `sendmon`, `killclient`
+- `UPPERCASE` for macros and constants: `MODKEY`, `NUMTAGS`, `CLEANMASK`, `SHCMD`
+- Enum values: `SchemeNorm`, `SchemeSel`, `NetSupported`
+
+### Comments in Config Files
+
+- `/* C89-style block comments */` in `.c` source files (mandatory per suckless style).
+- `// C99 inline comments` are acceptable in `config.def.h` for brief binding annotations only.
- Preprocessor guards: `#endif // PATCH_NAME`
### Conditional Compilation (Patch Guards)
+
```c
#if SOME_PATCH
/* patch-specific code */
@@ -94,8 +249,9 @@ functionname(const Arg *arg)
- Always include the patch name in the `#endif` comment.
- Custom (non-patch) code added to `config.def.h` does NOT need guards.
-### Example: Adding a Custom Function in config.def.h
-Custom functions go **before** the `static const Key keys[]` array. They can reference any forward-declared function from `dwm.c` (`sendmon`, `focusmon`, `arrange`, `focus`, `selmon`, `mons`, etc.) because `config.h` is included after all declarations in `dwm.c`.
+### Adding a Custom Function in config.def.h
+
+Custom functions go **before** the `static const Key keys[]` array. They can reference any forward-declared function from `dwm.c` (`sendmon`, `focusmon`, `arrange`, `focus`, `selmon`, `mons`, etc.) because `config.h` is included after all declarations in `dwm.c` (line 878).
---