Add `.ghostty` extension to `config` (#8885)
Resolves #8689 For various reason, ghostty wants to have a unique file extension for the config files. The name was settled on `config.ghostty`. This will help with tooling. See #8438 (original discussion) for more details. This PR introduces the preferred default of `.ghostty` while still supporting the previous `config` file. If both files exist, a warning log is sent. The docs / website will need to be updated to reflect this change. > [!NOTE] > Only tested on macOS 26.0. --------- Co-authored-by: Mitchell Hashimoto <m@mitchellh.com>pull/9170/head
parent
37b3c27020
commit
cbeb6890c9
|
|
@ -14,7 +14,7 @@ struct SettingsView: View {
|
|||
VStack(alignment: .leading) {
|
||||
Text("Coming Soon. 🚧").font(.title)
|
||||
Text("You can't configure settings in the GUI yet. To modify settings, " +
|
||||
"edit the file at $HOME/.config/ghostty/config and restart Ghostty.")
|
||||
"edit the file at $HOME/.config/ghostty/config.ghostty and restart Ghostty.")
|
||||
.multilineTextAlignment(.leading)
|
||||
.lineLimit(nil)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||
// 'ghostty.sublime-syntax' file from zig-out to the '~.config/bat/syntaxes'
|
||||
// directory. The syntax then needs to be mapped to the correct language in
|
||||
// the config file within the '~.config/bat' directory
|
||||
// (ex: --map-syntax "/Users/user/.config/ghostty/config:Ghostty Config").
|
||||
// (ex: --map-syntax "/Users/user/.config/ghostty/config.ghostty:Ghostty Config").
|
||||
{
|
||||
const run = b.addRunArtifact(build_data_exe);
|
||||
run.addArg("+sublime");
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
# FILES
|
||||
|
||||
_\$XDG_CONFIG_HOME/ghostty/config_
|
||||
_\$XDG_CONFIG_HOME/ghostty/config.ghostty_
|
||||
|
||||
: Location of the default configuration file.
|
||||
|
||||
_\$HOME/Library/Application Support/com.mitchellh.ghostty/config_
|
||||
_\$HOME/Library/Application Support/com.mitchellh.ghostty/config.ghostty_
|
||||
|
||||
: **On macOS**, location of the default configuration file. This location takes
|
||||
precedence over the XDG environment locations.
|
||||
|
||||
_\$LOCALAPPDATA/ghostty/config_
|
||||
_\$LOCALAPPDATA/ghostty/config.ghostty_
|
||||
|
||||
: **On Windows**, if _\$XDG_CONFIG_HOME_ is not set, _\$LOCALAPPDATA_ will be searched
|
||||
for configuration files.
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
# FILES
|
||||
|
||||
_\$XDG_CONFIG_HOME/ghostty/config_
|
||||
_\$XDG_CONFIG_HOME/ghostty/config.ghostty_
|
||||
|
||||
: Location of the default configuration file.
|
||||
|
||||
_\$HOME/Library/Application Support/com.mitchellh.ghostty/config_
|
||||
_\$HOME/Library/Application Support/com.mitchellh.ghostty/config.ghostty_
|
||||
|
||||
: **On macOS**, location of the default configuration file. This location takes
|
||||
precedence over the XDG environment locations.
|
||||
|
||||
_\$LOCALAPPDATA/ghostty/config_
|
||||
_\$LOCALAPPDATA/ghostty/config.ghostty_
|
||||
|
||||
: **On Windows**, if _\$XDG_CONFIG_HOME_ is not set, _\$LOCALAPPDATA_ will be searched
|
||||
for configuration files.
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@
|
|||
|
||||
To configure Ghostty, you must use a configuration file. GUI-based configuration
|
||||
is on the roadmap but not yet supported. The configuration file must be placed
|
||||
at `$XDG_CONFIG_HOME/ghostty/config`, which defaults to `~/.config/ghostty/config`
|
||||
at `$XDG_CONFIG_HOME/ghostty/config.ghostty`, which defaults to `~/.config/ghostty/config.ghostty`
|
||||
if the [XDG environment is not set](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html).
|
||||
|
||||
**If you are using macOS, the configuration file can also be placed at
|
||||
`$HOME/Library/Application Support/com.mitchellh.ghostty/config`.** This is the
|
||||
`$HOME/Library/Application Support/com.mitchellh.ghostty/config.ghostty`.** This is the
|
||||
default configuration location for macOS. It will be searched before any of the
|
||||
XDG environment locations listed above.
|
||||
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ pub const Options = struct {
|
|||
/// this yet.
|
||||
///
|
||||
/// The filepath opened is the default user-specific configuration
|
||||
/// file, which is typically located at `$XDG_CONFIG_HOME/ghostty/config`.
|
||||
/// file, which is typically located at `$XDG_CONFIG_HOME/ghostty/config.ghostty`.
|
||||
/// On macOS, this may also be located at
|
||||
/// `~/Library/Application Support/com.mitchellh.ghostty/config`.
|
||||
/// `~/Library/Application Support/com.mitchellh.ghostty/config.ghostty`.
|
||||
/// On macOS, whichever path exists and is non-empty will be prioritized,
|
||||
/// prioritizing the Application Support directory if neither are
|
||||
/// non-empty.
|
||||
|
|
@ -73,7 +73,7 @@ fn runInner(alloc: Allocator, stderr: *std.Io.Writer) !u8 {
|
|||
defer config.deinit();
|
||||
|
||||
// Find the preferred path.
|
||||
const path = try Config.preferredDefaultFilePath(alloc);
|
||||
const path = try configpkg.preferredDefaultFilePath(alloc);
|
||||
defer alloc.free(path);
|
||||
|
||||
// We don't currently support Windows because we use the exec syscall.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
const builtin = @import("builtin");
|
||||
|
||||
const file_load = @import("config/file_load.zig");
|
||||
const formatter = @import("config/formatter.zig");
|
||||
pub const Config = @import("config/Config.zig");
|
||||
pub const conditional = @import("config/conditional.zig");
|
||||
|
|
@ -12,6 +13,7 @@ pub const ConditionalState = conditional.State;
|
|||
pub const FileFormatter = formatter.FileFormatter;
|
||||
pub const entryFormatter = formatter.entryFormatter;
|
||||
pub const formatEntry = formatter.formatEntry;
|
||||
pub const preferredDefaultFilePath = file_load.preferredDefaultFilePath;
|
||||
|
||||
// Field types
|
||||
pub const BoldColor = Config.BoldColor;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ const cli = @import("../cli.zig");
|
|||
|
||||
const conditional = @import("conditional.zig");
|
||||
const Conditional = conditional.Conditional;
|
||||
const file_load = @import("file_load.zig");
|
||||
const formatterpkg = @import("formatter.zig");
|
||||
const themepkg = @import("theme.zig");
|
||||
const url = @import("url.zig");
|
||||
|
|
@ -2071,7 +2072,7 @@ keybind: Keybinds = .{},
|
|||
|
||||
/// When this is true, the default configuration file paths will be loaded.
|
||||
/// The default configuration file paths are currently only the XDG
|
||||
/// config path ($XDG_CONFIG_HOME/ghostty/config).
|
||||
/// config path ($XDG_CONFIG_HOME/ghostty/config.ghostty).
|
||||
///
|
||||
/// If this is false, the default configuration paths will not be loaded.
|
||||
/// This is targeted directly at using Ghostty from the CLI in a way
|
||||
|
|
@ -3397,7 +3398,7 @@ pub fn loadIter(
|
|||
/// `path` must be resolved and absolute.
|
||||
pub fn loadFile(self: *Config, alloc: Allocator, path: []const u8) !void {
|
||||
assert(std.fs.path.isAbsolute(path));
|
||||
var file = openFile(path) catch |err| switch (err) {
|
||||
var file = file_load.open(path) catch |err| switch (err) {
|
||||
error.NotAFile => {
|
||||
log.warn(
|
||||
"config-file {s}: not reading because it is not a file",
|
||||
|
|
@ -3461,31 +3462,60 @@ fn writeConfigTemplate(path: []const u8) !void {
|
|||
}
|
||||
|
||||
/// Load configurations from the default configuration files. The default
|
||||
/// configuration file is at `$XDG_CONFIG_HOME/ghostty/config`.
|
||||
/// configuration file is at `$XDG_CONFIG_HOME/ghostty/config.ghostty`.
|
||||
///
|
||||
/// On macOS, `$HOME/Library/Application Support/$CFBundleIdentifier/config`
|
||||
/// On macOS, `$HOME/Library/Application Support/$CFBundleIdentifier/`
|
||||
/// is also loaded.
|
||||
///
|
||||
/// The legacy `config` file (without extension) is first loaded,
|
||||
/// then `config.ghostty`.
|
||||
pub fn loadDefaultFiles(self: *Config, alloc: Allocator) !void {
|
||||
// Load XDG first
|
||||
const xdg_path = try defaultXdgPath(alloc);
|
||||
const legacy_xdg_path = try file_load.legacyDefaultXdgPath(alloc);
|
||||
defer alloc.free(legacy_xdg_path);
|
||||
const xdg_path = try file_load.defaultXdgPath(alloc);
|
||||
defer alloc.free(xdg_path);
|
||||
const xdg_loaded: bool = xdg_loaded: {
|
||||
const legacy_xdg_action = self.loadOptionalFile(alloc, legacy_xdg_path);
|
||||
const xdg_action = self.loadOptionalFile(alloc, xdg_path);
|
||||
if (xdg_action != .not_found and legacy_xdg_action != .not_found) {
|
||||
log.warn("both config files `{s}` and `{s}` exist.", .{ legacy_xdg_path, xdg_path });
|
||||
log.warn("loading them both in that order", .{});
|
||||
break :xdg_loaded true;
|
||||
}
|
||||
|
||||
break :xdg_loaded xdg_action != .not_found or
|
||||
legacy_xdg_action != .not_found;
|
||||
};
|
||||
|
||||
// On macOS load the app support directory as well
|
||||
if (comptime builtin.os.tag == .macos) {
|
||||
const app_support_path = try defaultAppSupportPath(alloc);
|
||||
const legacy_app_support_path = try file_load.legacyDefaultAppSupportPath(alloc);
|
||||
defer alloc.free(legacy_app_support_path);
|
||||
const app_support_path = try file_load.preferredAppSupportPath(alloc);
|
||||
defer alloc.free(app_support_path);
|
||||
const app_support_loaded: bool = loaded: {
|
||||
const legacy_app_support_action = self.loadOptionalFile(alloc, legacy_app_support_path);
|
||||
const app_support_action = self.loadOptionalFile(alloc, app_support_path);
|
||||
if (app_support_action != .not_found and legacy_app_support_action != .not_found) {
|
||||
log.warn("both config files `{s}` and `{s}` exist.", .{ legacy_app_support_path, app_support_path });
|
||||
log.warn("loading them both in that order", .{});
|
||||
break :loaded true;
|
||||
}
|
||||
|
||||
break :loaded app_support_action != .not_found or
|
||||
legacy_app_support_action != .not_found;
|
||||
};
|
||||
|
||||
// If both files are not found, then we create a template file.
|
||||
// For macOS, we only create the template file in the app support
|
||||
if (app_support_action == .not_found and xdg_action == .not_found) {
|
||||
if (app_support_loaded and xdg_loaded) {
|
||||
writeConfigTemplate(app_support_path) catch |err| {
|
||||
log.warn("error creating template config file err={}", .{err});
|
||||
};
|
||||
}
|
||||
} else {
|
||||
if (xdg_action == .not_found) {
|
||||
if (xdg_loaded) {
|
||||
writeConfigTemplate(xdg_path) catch |err| {
|
||||
log.warn("error creating template config file err={}", .{err});
|
||||
};
|
||||
|
|
@ -3493,102 +3523,6 @@ pub fn loadDefaultFiles(self: *Config, alloc: Allocator) !void {
|
|||
}
|
||||
}
|
||||
|
||||
/// Default path for the XDG home configuration file. Returned value
|
||||
/// must be freed by the caller.
|
||||
fn defaultXdgPath(alloc: Allocator) ![]const u8 {
|
||||
return try internal_os.xdg.config(
|
||||
alloc,
|
||||
.{ .subdir = "ghostty/config" },
|
||||
);
|
||||
}
|
||||
|
||||
/// Default path for the macOS Application Support configuration file.
|
||||
/// Returned value must be freed by the caller.
|
||||
fn defaultAppSupportPath(alloc: Allocator) ![]const u8 {
|
||||
return try internal_os.macos.appSupportDir(alloc, "config");
|
||||
}
|
||||
|
||||
/// Returns the path to the preferred default configuration file.
|
||||
/// This is the file where users should place their configuration.
|
||||
///
|
||||
/// This doesn't create or populate the file with any default
|
||||
/// contents; downstream callers must handle this.
|
||||
///
|
||||
/// The returned value must be freed by the caller.
|
||||
pub fn preferredDefaultFilePath(alloc: Allocator) ![]const u8 {
|
||||
switch (builtin.os.tag) {
|
||||
.macos => {
|
||||
// macOS prefers the Application Support directory
|
||||
// if it exists.
|
||||
const app_support_path = try defaultAppSupportPath(alloc);
|
||||
if (openFile(app_support_path)) |f| {
|
||||
f.close();
|
||||
return app_support_path;
|
||||
} else |_| {}
|
||||
|
||||
// Try the XDG path if it exists
|
||||
const xdg_path = try defaultXdgPath(alloc);
|
||||
if (openFile(xdg_path)) |f| {
|
||||
f.close();
|
||||
alloc.free(app_support_path);
|
||||
return xdg_path;
|
||||
} else |_| {}
|
||||
defer alloc.free(xdg_path);
|
||||
|
||||
// Neither exist, use app support
|
||||
return app_support_path;
|
||||
},
|
||||
|
||||
// All other platforms use XDG only
|
||||
else => return try defaultXdgPath(alloc),
|
||||
}
|
||||
}
|
||||
|
||||
const OpenFileError = error{
|
||||
FileNotFound,
|
||||
FileIsEmpty,
|
||||
FileOpenFailed,
|
||||
NotAFile,
|
||||
};
|
||||
|
||||
/// Opens the file at the given path and returns the file handle
|
||||
/// if it exists and is non-empty. This also constrains the possible
|
||||
/// errors to a smaller set that we can explicitly handle.
|
||||
fn openFile(path: []const u8) OpenFileError!std.fs.File {
|
||||
assert(std.fs.path.isAbsolute(path));
|
||||
|
||||
var file = std.fs.openFileAbsolute(
|
||||
path,
|
||||
.{},
|
||||
) catch |err| switch (err) {
|
||||
error.FileNotFound => return OpenFileError.FileNotFound,
|
||||
else => {
|
||||
log.warn("unexpected file open error path={s} err={}", .{
|
||||
path,
|
||||
err,
|
||||
});
|
||||
return OpenFileError.FileOpenFailed;
|
||||
},
|
||||
};
|
||||
errdefer file.close();
|
||||
|
||||
const stat = file.stat() catch |err| {
|
||||
log.warn("error getting file stat path={s} err={}", .{
|
||||
path,
|
||||
err,
|
||||
});
|
||||
return OpenFileError.FileOpenFailed;
|
||||
};
|
||||
switch (stat.kind) {
|
||||
.file => {},
|
||||
else => return OpenFileError.NotAFile,
|
||||
}
|
||||
|
||||
if (stat.size == 0) return OpenFileError.FileIsEmpty;
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
/// Load and parse the CLI args.
|
||||
pub fn loadCliArgs(self: *Config, alloc_gpa: Allocator) !void {
|
||||
switch (builtin.os.tag) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ const assert = std.debug.assert;
|
|||
const Allocator = std.mem.Allocator;
|
||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||
const internal_os = @import("../os/main.zig");
|
||||
const file_load = @import("file_load.zig");
|
||||
|
||||
/// The path to the configuration that should be opened for editing.
|
||||
///
|
||||
|
|
@ -89,20 +90,16 @@ fn configPath(alloc_arena: Allocator) ![]const u8 {
|
|||
/// Returns a const list of possible paths the main config file could be
|
||||
/// in for the current OS.
|
||||
fn configPathCandidates(alloc_arena: Allocator) ![]const []const u8 {
|
||||
var paths: std.ArrayList([]const u8) = try .initCapacity(alloc_arena, 2);
|
||||
var paths: std.ArrayList([]const u8) = try .initCapacity(alloc_arena, 4);
|
||||
errdefer paths.deinit(alloc_arena);
|
||||
|
||||
if (comptime builtin.os.tag == .macos) {
|
||||
paths.appendAssumeCapacity(try internal_os.macos.appSupportDir(
|
||||
alloc_arena,
|
||||
"config",
|
||||
));
|
||||
paths.appendAssumeCapacity(try file_load.defaultAppSupportPath(alloc_arena));
|
||||
paths.appendAssumeCapacity(try file_load.legacyDefaultAppSupportPath(alloc_arena));
|
||||
}
|
||||
|
||||
paths.appendAssumeCapacity(try internal_os.xdg.config(
|
||||
alloc_arena,
|
||||
.{ .subdir = "ghostty/config" },
|
||||
));
|
||||
paths.appendAssumeCapacity(try file_load.defaultXdgPath(alloc_arena));
|
||||
paths.appendAssumeCapacity(try file_load.legacyDefaultXdgPath(alloc_arena));
|
||||
|
||||
return paths.items;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,166 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const internal_os = @import("../os/main.zig");
|
||||
|
||||
const log = std.log.scoped(.config);
|
||||
|
||||
/// Default path for the XDG home configuration file. Returned value
|
||||
/// must be freed by the caller.
|
||||
pub fn defaultXdgPath(alloc: Allocator) ![]const u8 {
|
||||
return try internal_os.xdg.config(
|
||||
alloc,
|
||||
.{ .subdir = "ghostty/config.ghostty" },
|
||||
);
|
||||
}
|
||||
|
||||
/// Ghostty <1.3.0 default path for the XDG home configuration file.
|
||||
/// Returned value must be freed by the caller.
|
||||
pub fn legacyDefaultXdgPath(alloc: Allocator) ![]const u8 {
|
||||
return try internal_os.xdg.config(
|
||||
alloc,
|
||||
.{ .subdir = "ghostty/config" },
|
||||
);
|
||||
}
|
||||
|
||||
/// Preferred default path for the XDG home configuration file.
|
||||
/// Returned value must be freed by the caller.
|
||||
pub fn preferredXdgPath(alloc: Allocator) ![]const u8 {
|
||||
// If the XDG path exists, use that.
|
||||
const xdg_path = try defaultXdgPath(alloc);
|
||||
if (open(xdg_path)) |f| {
|
||||
f.close();
|
||||
return xdg_path;
|
||||
} else |_| {}
|
||||
|
||||
// Try the legacy path
|
||||
errdefer alloc.free(xdg_path);
|
||||
const legacy_xdg_path = try legacyDefaultXdgPath(alloc);
|
||||
if (open(legacy_xdg_path)) |f| {
|
||||
f.close();
|
||||
alloc.free(xdg_path);
|
||||
return legacy_xdg_path;
|
||||
} else |_| {}
|
||||
|
||||
// Legacy path and XDG path both don't exist. Return the
|
||||
// new one.
|
||||
alloc.free(legacy_xdg_path);
|
||||
return xdg_path;
|
||||
}
|
||||
|
||||
/// Default path for the macOS Application Support configuration file.
|
||||
/// Returned value must be freed by the caller.
|
||||
pub fn defaultAppSupportPath(alloc: Allocator) ![]const u8 {
|
||||
return try internal_os.macos.appSupportDir(alloc, "config.ghostty");
|
||||
}
|
||||
|
||||
/// Ghostty <1.3.0 default path for the macOS Application Support
|
||||
/// configuration file. Returned value must be freed by the caller.
|
||||
pub fn legacyDefaultAppSupportPath(alloc: Allocator) ![]const u8 {
|
||||
return try internal_os.macos.appSupportDir(alloc, "config");
|
||||
}
|
||||
|
||||
/// Preferred default path for the macOS Application Support configuration file.
|
||||
/// Returned value must be freed by the caller.
|
||||
pub fn preferredAppSupportPath(alloc: Allocator) ![]const u8 {
|
||||
// If the app support path exists, use that.
|
||||
const app_support_path = try defaultAppSupportPath(alloc);
|
||||
if (open(app_support_path)) |f| {
|
||||
f.close();
|
||||
return app_support_path;
|
||||
} else |_| {}
|
||||
|
||||
// Try the legacy path
|
||||
errdefer alloc.free(app_support_path);
|
||||
const legacy_app_support_path = try legacyDefaultAppSupportPath(alloc);
|
||||
if (open(legacy_app_support_path)) |f| {
|
||||
f.close();
|
||||
alloc.free(app_support_path);
|
||||
return legacy_app_support_path;
|
||||
} else |_| {}
|
||||
|
||||
// Legacy path and app support path both don't exist. Return the
|
||||
// new one.
|
||||
alloc.free(legacy_app_support_path);
|
||||
return app_support_path;
|
||||
}
|
||||
|
||||
/// Returns the path to the preferred default configuration file.
|
||||
/// This is the file where users should place their configuration.
|
||||
///
|
||||
/// This doesn't create or populate the file with any default
|
||||
/// contents; downstream callers must handle this.
|
||||
///
|
||||
/// The returned value must be freed by the caller.
|
||||
pub fn preferredDefaultFilePath(alloc: Allocator) ![]const u8 {
|
||||
switch (builtin.os.tag) {
|
||||
.macos => {
|
||||
// macOS prefers the Application Support directory
|
||||
// if it exists.
|
||||
const app_support_path = try preferredAppSupportPath(alloc);
|
||||
const app_support_file = open(app_support_path) catch {
|
||||
// Try the XDG path if it exists
|
||||
const xdg_path = try preferredXdgPath(alloc);
|
||||
const xdg_file = open(xdg_path) catch {
|
||||
// If neither file exists, use app support
|
||||
alloc.free(xdg_path);
|
||||
return app_support_path;
|
||||
};
|
||||
xdg_file.close();
|
||||
alloc.free(app_support_path);
|
||||
return xdg_path;
|
||||
};
|
||||
app_support_file.close();
|
||||
return app_support_path;
|
||||
},
|
||||
|
||||
// All other platforms use XDG only
|
||||
else => return try preferredXdgPath(alloc),
|
||||
}
|
||||
}
|
||||
|
||||
const OpenFileError = error{
|
||||
FileNotFound,
|
||||
FileIsEmpty,
|
||||
FileOpenFailed,
|
||||
NotAFile,
|
||||
};
|
||||
|
||||
/// Opens the file at the given path and returns the file handle
|
||||
/// if it exists and is non-empty. This also constrains the possible
|
||||
/// errors to a smaller set that we can explicitly handle.
|
||||
pub fn open(path: []const u8) OpenFileError!std.fs.File {
|
||||
assert(std.fs.path.isAbsolute(path));
|
||||
|
||||
var file = std.fs.openFileAbsolute(
|
||||
path,
|
||||
.{},
|
||||
) catch |err| switch (err) {
|
||||
error.FileNotFound => return OpenFileError.FileNotFound,
|
||||
else => {
|
||||
log.warn("unexpected file open error path={s} err={}", .{
|
||||
path,
|
||||
err,
|
||||
});
|
||||
return OpenFileError.FileOpenFailed;
|
||||
},
|
||||
};
|
||||
errdefer file.close();
|
||||
|
||||
const stat = file.stat() catch |err| {
|
||||
log.warn("error getting file stat path={s} err={}", .{
|
||||
path,
|
||||
err,
|
||||
});
|
||||
return OpenFileError.FileOpenFailed;
|
||||
};
|
||||
switch (stat.kind) {
|
||||
.file => {},
|
||||
else => return OpenFileError.NotAFile,
|
||||
}
|
||||
|
||||
if (stat.size == 0) return OpenFileError.FileIsEmpty;
|
||||
|
||||
return file;
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ pub const ftdetect =
|
|||
\\"
|
||||
\\" THIS FILE IS AUTO-GENERATED
|
||||
\\
|
||||
\\au BufRead,BufNewFile */ghostty/config,*/ghostty/themes/* setf ghostty
|
||||
\\au BufRead,BufNewFile */ghostty/config,*/ghostty/themes/*,*.ghostty setf ghostty
|
||||
\\
|
||||
;
|
||||
pub const ftplugin =
|
||||
|
|
|
|||
Loading…
Reference in New Issue