feat: port GTK version fallbacks, helpgen, bench modes, CLI leftovers
- apprt-gtk: Ghostty's runtime+build-time version gating (at_least) with cargo features adw_1_3/adw_1_4/adw_1_5/gtk_4_16 (default on) and the fallbacks for older libraries: MessageDialog (adw < 1.5), clipboard dialog without SwitchRow, pre-Banner debug warning and child-exited widgets, the old about dialog, GTK 4.16 CSS error source bytes. The minimum stays GTK 4.14 / libadwaita 1.5 (Ghostty's floor). The root build links with -z lazy so version-gated symbols don't keep older libraries from loading. - ghostty-helpgen (port of helpgen.zig) generates CLI action help and keybinding action docs from doc comments at build time, replacing the checked-in help/*.txt; +help and +list-actions --docs stay byte-identical to Ghostty 1.3.1. - ghostty-bench: libc wcwidth mode and separate simd/table and uucode/table code paths like Zig. - ghostty-cli: Windows branches of edit-config, list-colors, list-keybinds and boo; ssh-cache DiskCache flock locking (no-op on Windows, as in Zig) with an exclusivity test. Test Plan: - cargo test --workspace - diff <(cargo run -q -- +list-actions --docs) \ <(ghostty +list-actions --docs)
This commit is contained in:
1 parent
020beb2d75
commit
4787565397
51 files changed
+2426
-1621
No files matched your search
@@ -180,6 +180,16 @@ impl Boo {
|
||||
|
||||
/// The `boo` command is used to display the animation from the Ghostty website in the terminal
|
||||
pub fn run(args: &[String]) -> Result<u8, Error> {
|
||||
// Disable on non-desktop systems.
|
||||
if cfg!(not(any(
|
||||
windows,
|
||||
target_os = "macos",
|
||||
target_os = "linux",
|
||||
target_os = "freebsd"
|
||||
))) {
|
||||
return Ok(1);
|
||||
}
|
||||
|
||||
let mut opts = Options;
|
||||
crate::parse_options(&mut opts, args)?;
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
//! `+edit-config` (ZIG/src/cli/edit_config.zig).
|
||||
|
||||
use std::{io::Write, os::unix::process::CommandExt};
|
||||
use std::io::Write;
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::process::CommandExt;
|
||||
|
||||
use ghostty_config::config::Config;
|
||||
|
||||
@@ -62,6 +64,31 @@ fn run_inner(stderr: &mut dyn Write) -> Result<u8, Error> {
|
||||
let path = ghostty_config::file_load::preferred_default_file_path()
|
||||
.map_err(|e| Error::Other(e.to_string()))?;
|
||||
|
||||
// We don't currently support Windows because we use the exec syscall.
|
||||
#[cfg(windows)]
|
||||
{
|
||||
write_windows_unsupported(stderr, &path)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
exec_editor(stderr, &path)
|
||||
}
|
||||
|
||||
/// Windows branch of `run`: print the path and fail.
|
||||
#[cfg(windows)]
|
||||
fn write_windows_unsupported(stderr: &mut dyn Write, path: &str) -> Result<u8, Error> {
|
||||
write!(
|
||||
stderr,
|
||||
"The `ghostty +edit-config` command is not supported on Windows.\n\
|
||||
Please edit the configuration file manually at the following path:\n\
|
||||
\n\
|
||||
{path}\n"
|
||||
)?;
|
||||
Ok(1)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn exec_editor(stderr: &mut dyn Write, path: &str) -> Result<u8, Error> {
|
||||
// Get our editor
|
||||
let Some(editor) = find_editor() else {
|
||||
// If we don't have `$EDITOR` set then we can't do anything
|
||||
@@ -87,7 +114,7 @@ fn run_inner(stderr: &mut dyn Write) -> Result<u8, Error> {
|
||||
|
||||
// Flush before exec so no output is lost.
|
||||
let _ = stderr.flush();
|
||||
let err = std::process::Command::new(&editor).arg(&path).exec();
|
||||
let err = std::process::Command::new(&editor).arg(path).exec();
|
||||
|
||||
// If we reached this point then exec failed.
|
||||
let err = match err.kind() {
|
||||
|
||||
@@ -148,23 +148,9 @@ impl Action {
|
||||
/// function, i.e. `help_strings.Action.<name>`), without trailing newline.
|
||||
#[must_use]
|
||||
pub fn help_text(self) -> &'static str {
|
||||
match self {
|
||||
Action::Version => include_str!("help/version.txt"),
|
||||
Action::Help => include_str!("help/help.txt"),
|
||||
Action::ListFonts => include_str!("help/list-fonts.txt"),
|
||||
Action::ListKeybinds => include_str!("help/list-keybinds.txt"),
|
||||
Action::ListThemes => include_str!("help/list-themes.txt"),
|
||||
Action::ListColors => include_str!("help/list-colors.txt"),
|
||||
Action::ListActions => include_str!("help/list-actions.txt"),
|
||||
Action::SshCache => include_str!("help/ssh-cache.txt"),
|
||||
Action::EditConfig => include_str!("help/edit-config.txt"),
|
||||
Action::ShowConfig => include_str!("help/show-config.txt"),
|
||||
Action::ValidateConfig => include_str!("help/validate-config.txt"),
|
||||
Action::ShowFace => include_str!("help/show-face.txt"),
|
||||
Action::CrashReport => include_str!("help/crash-report.txt"),
|
||||
Action::Boo => include_str!("help/boo.txt"),
|
||||
Action::NewWindow => include_str!("help/new-window.txt"),
|
||||
}
|
||||
// Generated by `build.rs` (via `ghostty-helpgen`) from the doc
|
||||
// comment of each action's `run` function.
|
||||
include!(concat!(env!("OUT_DIR"), "/action_help.rs"))
|
||||
}
|
||||
|
||||
/// Run the action. `args` is the full argument vector (including
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
The `boo` command is used to display the animation from the Ghostty website in the terminal
|
||||
@@ -1,6 +0,0 @@
|
||||
The `crash-report` command is used to inspect and send crash reports.
|
||||
|
||||
When executed without any arguments, this will list existing crash reports.
|
||||
|
||||
This command currently only supports listing crash reports. Viewing
|
||||
and sending crash reports is unimplemented and will be added in the future.
|
||||
@@ -1,20 +0,0 @@
|
||||
The `edit-config` command opens the Ghostty configuration file in the
|
||||
editor specified by the `$VISUAL` or `$EDITOR` environment variables.
|
||||
|
||||
IMPORTANT: This command will not reload the configuration after
|
||||
editing. You will need to manually reload the configuration using the
|
||||
application menu, configured keybind, or by restarting Ghostty. We
|
||||
plan to auto-reload in the future, but Ghostty isn't capable of
|
||||
this yet.
|
||||
|
||||
The filepath opened is the default user-specific configuration
|
||||
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.ghostty`.
|
||||
On macOS, whichever path exists and is non-empty will be prioritized,
|
||||
prioritizing the Application Support directory if neither are
|
||||
non-empty.
|
||||
|
||||
This command prefers the `$VISUAL` environment variable over `$EDITOR`,
|
||||
if both are set. If neither are set, it will print an error
|
||||
and exit.
|
||||
@@ -1,5 +0,0 @@
|
||||
The `help` command shows general help about Ghostty. Recognized as either
|
||||
`-h, `--help`, or like other actions `+help`.
|
||||
|
||||
You can also specify `--help` or `-h` along with any action such as
|
||||
`+list-themes` to see help for a specific action.
|
||||
@@ -1,7 +0,0 @@
|
||||
The `list-actions` command is used to list all the available keybind
|
||||
actions for Ghostty. These are distinct from the CLI Actions which can
|
||||
be listed via `+help`
|
||||
|
||||
Flags:
|
||||
|
||||
* `--docs`: will print out the documentation for each action.
|
||||
@@ -1,7 +0,0 @@
|
||||
The `list-colors` command is used to list all the named RGB colors in
|
||||
Ghostty.
|
||||
|
||||
Flags:
|
||||
|
||||
* `--plain`: will disable formatting and make the output more
|
||||
friendly for Unix tooling. This is default when not printing to a tty.
|
||||
@@ -1,24 +0,0 @@
|
||||
The `list-fonts` command is used to list all the available fonts for
|
||||
Ghostty. This uses the exact same font discovery mechanism Ghostty uses to
|
||||
find fonts to use.
|
||||
|
||||
When executed with no arguments, this will list all available fonts, sorted
|
||||
by family name, then font name. If a family name is given with `--family`,
|
||||
the sorting will be disabled and the results instead will be shown in the
|
||||
same priority order Ghostty would use to pick a font.
|
||||
|
||||
Flags:
|
||||
|
||||
* `--bold`: Filter results to specific bold styles. It is not guaranteed
|
||||
that only those styles are returned. They are only prioritized.
|
||||
|
||||
* `--italic`: Filter results to specific italic styles. It is not guaranteed
|
||||
that only those styles are returned. They are only prioritized.
|
||||
|
||||
* `--style`: Filter results based on the style string advertised by a font.
|
||||
It is not guaranteed that only those styles are returned. They are only
|
||||
prioritized.
|
||||
|
||||
* `--family`: Filter results to a specific font family. The family handling
|
||||
is identical to the `font-family` set of Ghostty configuration values, so
|
||||
this can be used to debug why your desired font may not be loading.
|
||||
@@ -1,17 +0,0 @@
|
||||
The `list-keybinds` command is used to list all the available keybinds for
|
||||
Ghostty.
|
||||
|
||||
When executed without any arguments this will list the current keybinds
|
||||
loaded by the config file. If no config file is found or there aren't any
|
||||
changes to the keybinds it will print out the default ones configured for
|
||||
Ghostty
|
||||
|
||||
Flags:
|
||||
|
||||
* `--default`: will print out all the default keybinds
|
||||
|
||||
* `--docs`: currently does nothing, intended to print out documentation
|
||||
about the action associated with the keybinds
|
||||
|
||||
* `--plain`: will disable formatting and make the output more
|
||||
friendly for Unix tooling. This is default when not printing to a tty.
|
||||
@@ -1,37 +0,0 @@
|
||||
The `list-themes` command is used to preview or list all the available
|
||||
themes for Ghostty.
|
||||
|
||||
If this command is run from a TTY, a TUI preview of the themes will be
|
||||
shown. While in the preview, `F1` will bring up a help screen and `ESC` will
|
||||
exit the preview. Other keys that can be used to navigate the preview are
|
||||
listed in the help screen.
|
||||
|
||||
If this command is not run from a TTY, or the output is piped to another
|
||||
command, a plain list of theme names will be printed to the screen. A plain
|
||||
list can be forced using the `--plain` CLI flag.
|
||||
|
||||
Two different directories will be searched for themes.
|
||||
|
||||
The first directory is the `themes` subdirectory of your Ghostty
|
||||
configuration directory. This is `$XDG_CONFIG_HOME/ghostty/themes` or
|
||||
`~/.config/ghostty/themes`.
|
||||
|
||||
The second directory is the `themes` subdirectory of the Ghostty resources
|
||||
directory. Ghostty ships with a multitude of themes that will be installed
|
||||
into this directory. On macOS, this directory is the
|
||||
`Ghostty.app/Contents/Resources/ghostty/themes`. On Linux, this directory
|
||||
is the `share/ghostty/themes` (wherever you installed the Ghostty "share"
|
||||
directory). If you're running Ghostty from the source, this is the
|
||||
`zig-out/share/ghostty/themes` directory.
|
||||
|
||||
You can also set the `GHOSTTY_RESOURCES_DIR` environment variable to point
|
||||
to the resources directory.
|
||||
|
||||
Flags:
|
||||
|
||||
* `--path`: Show the full path to the theme.
|
||||
|
||||
* `--plain`: Force a plain listing of themes.
|
||||
|
||||
* `--color`: Specify the color scheme of the themes included in the list.
|
||||
This can be `dark`, `light`, or `all`. The default is `all`.
|
||||
@@ -1,62 +0,0 @@
|
||||
The `new-window` will use native platform IPC to open up a new window in a
|
||||
running instance of Ghostty.
|
||||
|
||||
If the `--class` flag is not set, the `new-window` command will try and
|
||||
connect to a running instance of Ghostty based on what optimizations the
|
||||
Ghostty CLI was compiled with. Otherwise the `new-window` command will try
|
||||
and contact a running Ghostty instance that was configured with the same
|
||||
`class` as was given on the command line.
|
||||
|
||||
All of the arguments after the `+new-window` argument (except for the
|
||||
`--class` flag) will be sent to the remote Ghostty instance and will be
|
||||
parsed as command line flags. These flags will override certain settings
|
||||
when creating the first surface in the new window. Currently, only
|
||||
`--working-directory`, `--command`, and `--title` are supported. `-e` will
|
||||
also work as an alias for `--command`, except that if `-e` is found on the
|
||||
command line all following arguments will become part of the command and no
|
||||
more arguments will be parsed for configuration settings.
|
||||
|
||||
If `--working-directory` is found on the command line and is a relative
|
||||
path (i.e. doesn't start with `/`) it will be resolved to an absolute path
|
||||
relative to the current working directory that the `ghostty +new-window`
|
||||
command is run from. `~/` prefixes will also be expanded to the user's home
|
||||
directory.
|
||||
|
||||
If `--working-directory` is _not_ found on the command line, the working
|
||||
directory that `ghostty +new-window` is run from will be passed to Ghostty.
|
||||
|
||||
GTK uses an application ID to identify instances of applications. If Ghostty
|
||||
is compiled with release optimizations, the default application ID will be
|
||||
`com.mitchellh.ghostty`. If Ghostty is compiled with debug optimizations,
|
||||
the default application ID will be `com.mitchellh.ghostty-debug`. The
|
||||
`class` configuration entry can be used to set up a custom application
|
||||
ID. The class name must follow the requirements defined [in the GTK
|
||||
documentation](https://docs.gtk.org/gio/type_func.Application.id_is_valid.html)
|
||||
or it will be ignored and Ghostty will use the default as defined above.
|
||||
|
||||
On GTK, D-Bus activation must be properly configured. Ghostty does not need
|
||||
to be running for this to open a new window, making it suitable for binding
|
||||
to keys in your window manager (if other methods for configuring global
|
||||
shortcuts are unavailable). D-Bus will handle launching a new instance
|
||||
of Ghostty if it is not already running. See the Ghostty website for
|
||||
information on properly configuring D-Bus activation.
|
||||
|
||||
Only supported on GTK.
|
||||
|
||||
Flags:
|
||||
|
||||
* `--class=<class>`: If set, open up a new window in a custom instance of
|
||||
Ghostty. The class must be a valid GTK application ID.
|
||||
|
||||
* `--command`: The command to be executed in the first surface of the new window.
|
||||
|
||||
* `--working-directory=<directory>`: The working directory to pass to Ghostty.
|
||||
|
||||
* `--title`: A title that will override the title of the first surface in
|
||||
the new window. The title override may be edited or removed later.
|
||||
|
||||
* `-e`: Any arguments after this will be interpreted as a command to
|
||||
execute inside the first surface of the new window instead of the
|
||||
default command.
|
||||
|
||||
Available since: 1.2.0
|
||||
@@ -1,27 +0,0 @@
|
||||
The `show-config` command shows the current configuration in a valid Ghostty
|
||||
configuration file format.
|
||||
|
||||
When executed without any arguments this will output the current
|
||||
configuration that is different from the default configuration. If you're
|
||||
using the default configuration this will output nothing.
|
||||
|
||||
If you are a new user and want to see all available options with
|
||||
documentation, run `ghostty +show-config --default --docs`.
|
||||
|
||||
The output is not in any specific order, but the order should be consistent
|
||||
between runs. The output is not guaranteed to be exactly match the input
|
||||
configuration files, but it will result in the same behavior. Comments,
|
||||
whitespace, and other formatting is not preserved from user configuration
|
||||
files.
|
||||
|
||||
Flags:
|
||||
|
||||
* `--default`: Show the default configuration instead of loading
|
||||
the user configuration.
|
||||
|
||||
* `--changes-only`: Only show the options that have been changed
|
||||
from the default. This has no effect if `--default` is specified.
|
||||
|
||||
* `--docs`: Print the documentation above each option as a comment,
|
||||
This is very noisy but is very useful to learn about available
|
||||
options, especially paired with `--default`.
|
||||
@@ -1,21 +0,0 @@
|
||||
The `show-face` command shows what font face Ghostty will use to render a
|
||||
specific codepoint. Note that this command does not take into consideration
|
||||
grapheme clustering or any other Unicode features that might modify the
|
||||
presentation of a codepoint, so this may show a different font face than
|
||||
Ghostty uses to render a codepoint in a terminal session.
|
||||
|
||||
Flags:
|
||||
|
||||
* `--cp`: Find the face for a single codepoint. The codepoint may be specified
|
||||
in decimal (`--cp=65`), hexadecimal (`--cp=0x41`), octal (`--cp=0o101`), or
|
||||
binary (`--cp=0b1000001`).
|
||||
|
||||
* `--string`: Find the face for all of the codepoints in a string. The
|
||||
string must be a valid UTF-8 sequence.
|
||||
|
||||
* `--style`: Search for a specific style. Valid options are `regular`, `bold`,
|
||||
`italic`, and `bold_italic`.
|
||||
|
||||
* `--presentation`: If set, force searching for a specific presentation
|
||||
style. Valid options are `text` and `emoji`. If unset, the presentation
|
||||
style of a codepoint will be inferred from the Unicode standard.
|
||||
@@ -1,23 +0,0 @@
|
||||
Manage the SSH terminfo cache for automatic remote host setup.
|
||||
|
||||
When SSH integration is enabled with `shell-integration-features = ssh-terminfo`,
|
||||
Ghostty automatically installs its terminfo on remote hosts. This command
|
||||
manages the cache of successful installations to avoid redundant uploads.
|
||||
|
||||
The cache stores hostnames (or user@hostname combinations) along with timestamps.
|
||||
Entries older than the expiration period are automatically removed during cache
|
||||
operations. By default, entries never expire.
|
||||
|
||||
Only one of `--clear`, `--add`, `--remove`, or `--host` can be specified.
|
||||
If multiple are specified, one of the actions will be executed but
|
||||
it isn't guaranteed which one. This is entirely unsafe so you should split
|
||||
multiple actions into separate commands.
|
||||
|
||||
Examples:
|
||||
ghostty +ssh-cache # List all cached hosts
|
||||
ghostty +ssh-cache --host=example.com # Check if host is cached
|
||||
ghostty +ssh-cache --add=example.com # Manually add host to cache
|
||||
ghostty +ssh-cache --add=user@example.com # Add user@host combination
|
||||
ghostty +ssh-cache --remove=example.com # Remove host from cache
|
||||
ghostty +ssh-cache --clear # Clear entire cache
|
||||
ghostty +ssh-cache --expire-days=30 # Set custom expiration period
|
||||
@@ -1,9 +0,0 @@
|
||||
The `validate-config` command is used to validate a Ghostty config file.
|
||||
|
||||
When executed without any arguments, this will load the config from the default
|
||||
location.
|
||||
|
||||
Flags:
|
||||
|
||||
* `--config-file`: can be passed to validate a specific target config file in
|
||||
a non-default location
|
||||
@@ -1,2 +0,0 @@
|
||||
The `version` command is used to display information about Ghostty. Recognized as
|
||||
either `+version` or `--version`.
|
||||
@@ -2,12 +2,13 @@
|
||||
//! (ZIG/src/cli/ssh-cache/DiskCache.zig). The cache only stores metadata
|
||||
//! (hostname, terminfo value, etc.) and does not store any sensitive data.
|
||||
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::fs::{OpenOptionsExt, PermissionsExt};
|
||||
use std::{
|
||||
collections::BTreeMap,
|
||||
fs::{File, OpenOptions},
|
||||
io::{Read, Write},
|
||||
net::Ipv6Addr,
|
||||
os::unix::fs::{OpenOptionsExt, PermissionsExt},
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
@@ -87,13 +88,11 @@ impl DiskCache {
|
||||
}
|
||||
|
||||
// Open or create cache file with secure permissions
|
||||
let file = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(false)
|
||||
.mode(0o600)
|
||||
.open(&self.path)?;
|
||||
let mut open = OpenOptions::new();
|
||||
open.read(true).write(true).create(true).truncate(false);
|
||||
#[cfg(unix)]
|
||||
open.mode(0o600);
|
||||
let file = open.open(&self.path)?;
|
||||
fixup_permissions(&file)?;
|
||||
|
||||
// Lock
|
||||
@@ -196,12 +195,11 @@ impl DiskCache {
|
||||
let tmp_path = cache_dir.join(tmp_name);
|
||||
|
||||
let result = (|| -> std::io::Result<()> {
|
||||
let mut f = OpenOptions::new()
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.mode(0o600)
|
||||
.open(&tmp_path)?;
|
||||
let mut open = OpenOptions::new();
|
||||
open.write(true).create(true).truncate(true);
|
||||
#[cfg(unix)]
|
||||
open.mode(0o600);
|
||||
let mut f = open.open(&tmp_path)?;
|
||||
f.write_all(data.as_bytes())?;
|
||||
f.sync_all()?;
|
||||
std::fs::rename(&tmp_path, &self.path)
|
||||
@@ -227,6 +225,18 @@ impl Drop for Lock<'_> {
|
||||
/// Zig: `_ = file.tryLock(.exclusive) catch return error.CacheIsLocked;`
|
||||
/// The boolean result is ignored upstream, so a lock held by someone else
|
||||
/// does not fail; only a real error does.
|
||||
///
|
||||
/// Zig skips locking entirely on Windows
|
||||
/// (`if (comptime builtin.os.tag != .windows)`), so we do too. On unix
|
||||
/// `File::try_lock` is `flock(LOCK_EX | LOCK_NB)`, the same call as Zig's
|
||||
/// `File.tryLock(.exclusive)`.
|
||||
#[cfg(windows)]
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn lock(_file: &File) -> Result<Lock<'_>, Error> {
|
||||
Ok(Lock(None))
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn lock(file: &File) -> Result<Lock<'_>, Error> {
|
||||
match file.try_lock() {
|
||||
Ok(()) => Ok(Lock(Some(file))),
|
||||
@@ -235,7 +245,20 @@ fn lock(file: &File) -> Result<Lock<'_>, Error> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(windows, allow(clippy::unnecessary_wraps))]
|
||||
fn fixup_permissions(file: &File) -> Result<(), Error> {
|
||||
// Windows does not support chmod
|
||||
#[cfg(windows)]
|
||||
{
|
||||
let _ = file;
|
||||
Ok(())
|
||||
}
|
||||
#[cfg(unix)]
|
||||
fixup_permissions_unix(file)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn fixup_permissions_unix(file: &File) -> Result<(), Error> {
|
||||
// Ensure file has correct permissions (readable/writable by
|
||||
// owner only)
|
||||
let meta = file.metadata()?;
|
||||
@@ -323,6 +346,34 @@ fn is_valid_user(user: &str) -> bool {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#![allow(clippy::unwrap_used)]
|
||||
#[cfg(not(windows))]
|
||||
#[test]
|
||||
fn lock_is_exclusive_until_dropped() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let path = dir.path().join("lock");
|
||||
let a = File::create(&path).unwrap();
|
||||
let b = File::options().read(true).write(true).open(&path).unwrap();
|
||||
|
||||
let held = super::lock(&a).unwrap();
|
||||
assert!(held.0.is_some());
|
||||
// A second handle can't take the lock; Zig ignores that result.
|
||||
assert!(matches!(
|
||||
b.try_lock(),
|
||||
Err(std::fs::TryLockError::WouldBlock)
|
||||
));
|
||||
assert!(super::lock(&b).unwrap().0.is_none());
|
||||
drop(held);
|
||||
// Unlocked on drop.
|
||||
assert!(b.try_lock().is_ok());
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[test]
|
||||
fn lock_is_noop_on_windows() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let a = File::create(dir.path().join("lock")).unwrap();
|
||||
assert!(super::lock(&a).unwrap().0.is_none());
|
||||
}
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
@@ -389,8 +440,9 @@ mod tests {
|
||||
assert_eq!(vec![std::ffi::OsString::from("cache")], names);
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn disk_cache_file_permissions_and_invalid_host() {
|
||||
fn disk_cache_file_permissions() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let cache = DiskCache {
|
||||
path: tmp.path().join("sub/cache"),
|
||||
@@ -398,6 +450,15 @@ mod tests {
|
||||
cache.add("example.com").unwrap();
|
||||
let mode = std::fs::metadata(&cache.path).unwrap().permissions().mode();
|
||||
assert_eq!(0o600, mode & 0o777);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn disk_cache_invalid_host() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let cache = DiskCache {
|
||||
path: tmp.path().join("sub/cache"),
|
||||
};
|
||||
cache.add("example.com").unwrap();
|
||||
assert!(matches!(
|
||||
cache.add("bad host"),
|
||||
Err(Error::HostnameIsInvalid)
|
||||
|
||||
@@ -264,9 +264,20 @@ fn write_style_change(w: &mut dyn Write, cursor: &Style, next: &Style) -> std::i
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Fixed `(cols, rows)` used on Windows instead of querying the tty.
|
||||
#[cfg(windows)]
|
||||
const WINDOWS_WINSIZE: (u16, u16) = (120, 24);
|
||||
|
||||
/// The terminal size in columns and rows (`vaxis.Tty.getWinsize`).
|
||||
#[must_use]
|
||||
pub fn window_size() -> (u16, u16) {
|
||||
// On Windows we use some default; it doesn't really matter for what we're
|
||||
// doing because we don't do any wrapping (rows = 24, cols = 120).
|
||||
#[cfg(windows)]
|
||||
{
|
||||
WINDOWS_WINSIZE
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
ratatui::crossterm::terminal::size().unwrap_or((80, 24))
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user