diff --git a/docs/manual/release-notes/rl-0.9.md b/docs/manual/release-notes/rl-0.9.md index a1c95e9f..925796b6 100644 --- a/docs/manual/release-notes/rl-0.9.md +++ b/docs/manual/release-notes/rl-0.9.md @@ -402,6 +402,8 @@ - Added `asmfmt` and `nasmfmt` formatters to `languages.asm`. +- Added `astyle`, `indent` and `clang-format` to `languages.clang` formatters. + - Added `biome-check` and `biome-organize-imports` formatters to `languages.ts`. - Added [`biomejs`](https://biomejs.dev/) as extra diagnostics provider to diff --git a/modules/plugins/languages/clang.nix b/modules/plugins/languages/clang.nix index 844074a5..7e30b1f6 100644 --- a/modules/plugins/languages/clang.nix +++ b/modules/plugins/languages/clang.nix @@ -8,9 +8,12 @@ inherit (lib.options) mkEnableOption mkOption literalExpression; inherit (lib.types) bool enum package listOf; inherit (lib) genAttrs; + inherit (lib.meta) getExe getExe'; inherit (lib.modules) mkIf mkMerge; inherit (lib.nvim.types) mkGrammarOption; + inherit (lib.generators) mkLuaInline; inherit (lib.nvim.dag) entryAfter; + inherit (lib.nvim.attrsets) mapListToAttrs; cfg = config.vim.languages.clang; @@ -45,6 +48,54 @@ ''; }; }; + + defaultFormat = ["clang-format"]; + formats = { + astyle = { + command = getExe pkgs.astyle; + stdin = false; + args = mkLuaInline '' + function(self, ctx) + local args = { + "$FILENAME", + } + + if not vim.bo[ctx.buf].expandtab then + table.insert(args, "--indent=tab=" .. ctx.shiftwidth) + else + table.insert(args, "--indent=spaces=" .. ctx.shiftwidth) + end + + return args + end + ''; + }; + indent = { + command = getExe pkgs.indent; + stdin = true; + args = mkLuaInline '' + function(self, ctx) + local args = { + "--indent-level", ctx.shiftwidth, + "--tab-size", ctx.shiftwidth, + } + + if not vim.bo[ctx.buf].expandtab then + table.insert(args, "--use-tabs") + else + table.insert(args, "--no-tabs") + end + + return args + end + ''; + # Default is GNU style. Nobody likes that one. + # This is under `append_args`, to allow easy editing of this argument, + # without having to redefine everything as a user. + append_args = ["--linux-style"]; + }; + clang-format.command = getExe' pkgs.clang-tools "clang-format"; + }; in { options.vim.languages.clang = { enable = mkEnableOption "C/C++ language support"; @@ -102,6 +153,21 @@ in { default = debuggers.${cfg.dap.debugger}.package; }; }; + + format = { + enable = + mkEnableOption "C formatting" + // { + default = config.vim.languages.enableFormat; + defaultText = literalExpression "config.vim.languages.enableFormat"; + }; + + type = mkOption { + type = listOf (enum (attrNames formats)); + default = defaultFormat; + description = "C formatter to use"; + }; + }; }; config = mkIf cfg.enable (mkMerge [ @@ -127,5 +193,23 @@ in { vim.debugger.nvim-dap.enable = true; vim.debugger.nvim-dap.sources.clang-debugger = debuggers.${cfg.dap.debugger}.dapConfig; }) + + (mkIf cfg.format.enable { + vim.formatter.conform-nvim = { + enable = true; + setupOpts = { + formatters_by_ft = { + c = cfg.format.type; + cpp = cfg.format.type; + }; + formatters = + mapListToAttrs (name: { + inherit name; + value = formats.${name}; + }) + cfg.format.type; + }; + }; + }) ]); }