config: generate vim configs at comptime

This commit is contained in:
Mitchell Hashimoto
2023-12-22 08:19:17 -08:00
parent 4f01aafdba
commit eb46161b5e
4 changed files with 100 additions and 150 deletions

View File

@ -8,12 +8,12 @@ const apprt = @import("src/apprt.zig");
const font = @import("src/font/main.zig");
const renderer = @import("src/renderer.zig");
const terminfo = @import("src/terminfo/main.zig");
const config_vim = @import("src/config/vim.zig");
const WasmTarget = @import("src/os/wasm/target.zig").Target;
const LibtoolStep = @import("src/build/LibtoolStep.zig");
const LipoStep = @import("src/build/LipoStep.zig");
const XCFrameworkStep = @import("src/build/XCFrameworkStep.zig");
const Version = @import("src/build/Version.zig");
const VimStep = @import("src/build/VimStep.zig");
// Do a comptime Zig version requirement. The required Zig version is
// somewhat arbitrary: it is meant to be a version that we feel works well,
@ -404,12 +404,17 @@ pub fn build(b: *std.Build) !void {
}
// Vim plugin
const vim_step = VimStep.create(b);
b.installDirectory(.{
.source_dir = vim_step.getDirectory(),
.install_dir = .prefix,
.install_subdir = "share/vim/vimfiles",
});
{
const wf = b.addWriteFiles();
_ = wf.add("syntax/ghostty.vim", config_vim.syntax);
_ = wf.add("ftdetect/ghostty.vim", config_vim.ftdetect);
_ = wf.add("ftplugin/ghostty.vim", config_vim.ftplugin);
b.installDirectory(.{
.source_dir = wf.getDirectory(),
.install_dir = .prefix,
.install_subdir = "share/vim/vimfiles",
});
}
// App (Linux)
if (target.isLinux()) {

View File

@ -1,143 +0,0 @@
//! A Zig build step that generates Vim plugin files for Ghostty's configuration
//! file.
const VimStep = @This();
const std = @import("std");
const Step = std.Build.Step;
const Config = @import("../config/Config.zig");
step: *Step,
// The build step that generates the file contents
generate_step: Step,
pub fn create(b: *std.Build) *VimStep {
const self = b.allocator.create(VimStep) catch @panic("OOM");
const write_file = Step.WriteFile.create(b);
self.* = .{
.step = &write_file.step,
.generate_step = Step.init(.{
.id = .custom,
.name = "generate Vim plugin files",
.owner = b,
.makeFn = make,
}),
};
write_file.step.dependOn(&self.generate_step);
return self;
}
pub fn getDirectory(self: *VimStep) std.Build.LazyPath {
const wf = @fieldParentPtr(Step.WriteFile, "step", self.step);
return wf.getDirectory();
}
fn make(step: *Step, prog_node: *std.Progress.Node) !void {
_ = prog_node;
const self = @fieldParentPtr(VimStep, "generate_step", step);
const wf = @fieldParentPtr(Step.WriteFile, "step", self.step);
const b = step.owner;
// syntax/ghostty.vim
{
var buf = std.ArrayList(u8).init(b.allocator);
defer buf.deinit();
const writer = buf.writer();
try writer.print(
\\" Vim syntax file
\\" Language: Ghostty config file
\\" Maintainer: Ghostty <https://github.com/mitchellh/ghostty>
\\"
\\" THIS FILE IS AUTO-GENERATED
\\
\\if exists('b:current_syntax')
\\ finish
\\endif
\\
\\let b:current_syntax = 'ghostty'
\\
\\let s:cpo_save = &cpo
\\set cpo&vim
\\
\\
, .{});
const config_fields = @typeInfo(Config).Struct.fields;
var keywords = try std.ArrayList([]const u8).initCapacity(
b.allocator,
config_fields.len,
);
defer keywords.deinit();
inline for (config_fields) |field| {
// Ignore fields which begin with _
if (field.name[0] != '_') {
keywords.appendAssumeCapacity(field.name);
}
}
try writer.print(
\\syn keyword ghosttyConfigKeyword
\\ \ {s}
\\
\\syn match ghosttyConfigComment /#.*/ contains=@Spell
\\
\\hi def link ghosttyConfigComment Comment
\\hi def link ghosttyConfigKeyword Keyword
\\
\\let &cpo = s:cpo_save
\\unlet s:cpo_save
\\
, .{
try std.mem.join(b.allocator, "\n\t\\ ", keywords.items),
});
_ = wf.add("syntax/ghostty.vim", buf.items);
}
// ftdetect/ghostty.vim
{
_ = wf.add(
"ftdetect/ghostty.vim",
"au BufRead,BufNewFile */.config/ghostty/config set ft=ghostty\n",
);
}
// ftplugin/ghostty.vim
{
var buf = std.ArrayList(u8).init(b.allocator);
defer buf.deinit();
const writer = buf.writer();
try writer.writeAll(
\\" Vim filetype plugin file
\\" Language: Ghostty config file
\\" Maintainer: Ghostty <https://github.com/mitchellh/ghostty>
\\"
\\" THIS FILE IS AUTO-GENERATED
\\
\\if exists('b:did_ftplugin')
\\ finish
\\endif
\\let b:did_ftplugin = 1
\\
\\setlocal commentstring=#%s
\\setlocal iskeyword+=-
\\
\\" Use syntax keywords for completion
\\setlocal omnifunc=syntaxcomplete#Complete
\\
\\let b:undo_ftplugin = 'setl cms< isk< ofu<'
\\
);
_ = wf.add("ftplugin/ghostty.vim", buf.items);
}
}

View File

@ -21,4 +21,7 @@ pub const Wasm = if (!builtin.target.isWasm()) struct {} else @import("config/Wa
test {
@import("std").testing.refAllDecls(@This());
// Vim syntax file, not used at runtime but we want to keep it tested.
_ = @import("config/vim.zig");
}

85
src/config/vim.zig Normal file
View File

@ -0,0 +1,85 @@
const std = @import("std");
const Config = @import("Config.zig");
/// This is the associated Vim file as named by the variable.
pub const syntax = comptimeGenSyntax();
pub const ftdetect = "au BufRead,BufNewFile */.config/ghostty/config set ft=ghostty\n";
pub const ftplugin =
\\" Vim filetype plugin file
\\" Language: Ghostty config file
\\" Maintainer: Ghostty <https://github.com/mitchellh/ghostty>
\\"
\\" THIS FILE IS AUTO-GENERATED
\\
\\if exists('b:did_ftplugin')
\\ finish
\\endif
\\let b:did_ftplugin = 1
\\
\\setlocal commentstring=#%s
\\setlocal iskeyword+=-
\\
\\" Use syntax keywords for completion
\\setlocal omnifunc=syntaxcomplete#Complete
\\
\\let b:undo_ftplugin = 'setl cms< isk< ofu<'
\\
;
/// Generates the syntax file at comptime.
fn comptimeGenSyntax() []const u8 {
comptime {
var counting_writer = std.io.countingWriter(std.io.null_writer);
try writeSyntax(&counting_writer.writer());
var buf: [counting_writer.bytes_written]u8 = undefined;
var stream = std.io.fixedBufferStream(&buf);
try writeSyntax(stream.writer());
return stream.getWritten();
}
}
/// Writes the syntax file to the given writer.
fn writeSyntax(writer: anytype) !void {
try writer.writeAll(
\\" Vim syntax file
\\" Language: Ghostty config file
\\" Maintainer: Ghostty <https://github.com/mitchellh/ghostty>
\\"
\\" THIS FILE IS AUTO-GENERATED
\\
\\if exists('b:current_syntax')
\\ finish
\\endif
\\
\\let b:current_syntax = 'ghostty'
\\
\\let s:cpo_save = &cpo
\\set cpo&vim
\\
\\syn keyword ghosttyConfigKeyword
);
const config_fields = @typeInfo(Config).Struct.fields;
inline for (config_fields) |field| {
if (field.name[0] == '_') continue;
try writer.print("\n\t\\ {s}", .{field.name});
}
try writer.writeAll(
\\
\\
\\syn match ghosttyConfigComment /#.*/ contains=@Spell
\\
\\hi def link ghosttyConfigComment Comment
\\hi def link ghosttyConfigKeyword Keyword
\\
\\let &cpo = s:cpo_save
\\unlet s:cpo_save
\\
);
}
test {
_ = syntax;
}