My editor of choice is . It is fast, modern and minimal. My compiler is (which is a modernised Watcom) ancient and idiosyncratic but correct for the IBM XT target I am writing for. The problem is that , the language server that Zed uses for C and C++ code, has opinions about my code - strong opinions.
As I have argued elsewhere, modern language servers and retro compilers are not natural bedfellows. Clangd expects C17, not 8086 assembly with __fastcall calling conventions and inline __asm blocks. Open Watcom accepts all of that happily, because it was built for the retro target, but clangd was not. The two do not speak the same dialect, and the result, without configuration, is an editor full of red squiggly underlines under perfectly valid code.
Consider then, a typical function from my codebase:
void __fastcall cga_hi_res_plot(cga_coord_t x, cga_coord_t y, cga_colour_t colour) {
__asm {
.8086
mov ax, x
etc...
}
} Clangd flags __fastcall as an unsupported calling convention. It flags __asm as unknown syntax. It has no idea what .8086 means. The code compiles without complaint under Watcom and the XT runs it beautifully, but my editor thinks I am writing nonsense.
The Solution a .clangd File
The most reduced form of a working configuration for this problem is a .clangd yaml file in the project root directory that Zed will honour:
CompileFlags
Add-xc -Wno-ignored-attributes -fms-extensions
Remove-std=c99The -xc flag forces clangd to treat the code as C rather than Objective-C++, which for reasons I do not fully understand is sometimes the default. The -Wno-ignored-attributes flag suppresses the warning about __fastcall being unsupported, which is a lie but a lie we can live with. The -fms-extensions flag embraces the Microsoft and Watcom dialect, which helps with the rest of the weirdness. Removing -std=c99 prevents clangd from insisting on a language standard that my code does not fully follow because neither does Watcom.
The Include That Was Not Unused
A second problem emerged after the squiggles were gone. I have a lookup table for CGA row offsets:
// clangd says: unused and paints it with yellow squigglesThe header is used extensively, but it is used inside __asm blocks. Clangd cannot see past the veil of inline assembly, so it flags the include as dead code. This is a false positive, but it is a persistent one.
The solution is a pragma from the Include-What-You-Use (IWYU) tooling:
// IWYU pragma: keepThis communicates to the analyser that the inclusion is intentional, even if the static analysis cannot observe its usage. The warning disappears, the header remains, and the code continues to work.
Conclusion
So, fellow retro programmers, you can have best of both worlds. With Zed and .clangd configuration you can transform a hostile language server into a useful assistant. The defining properties of such a configuration are that it accepts non-standard calling conventions with -Wno-ignored-attributes, accepts the Watcom dialect with -fms-extensions, preserves includes hidden behind assembly with // IWYU pragma: keep





