mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-07 01:51:14 -03:00
fallback: extract into crate
For faster incremental builds and to enable subsequent extraction. Closes #12183
This commit is contained in:
committed by
Johannes Altmanninger
parent
caef2c309d
commit
67d78fb258
20
Cargo.lock
generated
20
Cargo.lock
generated
@@ -161,6 +161,7 @@ dependencies = [
|
||||
"fish-build-helper",
|
||||
"fish-build-man-pages",
|
||||
"fish-common",
|
||||
"fish-fallback",
|
||||
"fish-gettext",
|
||||
"fish-gettext-extraction",
|
||||
"fish-gettext-mo-file-parser",
|
||||
@@ -205,6 +206,25 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "fish-common"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"nix",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fish-fallback"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"fish-build-helper",
|
||||
"fish-common",
|
||||
"fish-wchar",
|
||||
"fish-widecharwidth",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"rsconf",
|
||||
"widestring",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fish-gettext"
|
||||
|
||||
@@ -18,6 +18,7 @@ errno = "0.3.0"
|
||||
fish-build-helper = { path = "crates/build-helper" }
|
||||
fish-build-man-pages = { path = "crates/build-man-pages" }
|
||||
fish-common = { path = "crates/common" }
|
||||
fish-fallback = { path = "crates/fallback" }
|
||||
fish-gettext = { path = "crates/gettext" }
|
||||
fish-gettext-extraction = { path = "crates/gettext-extraction" }
|
||||
fish-gettext-maps = { path = "crates/gettext-maps" }
|
||||
@@ -93,6 +94,7 @@ errno.workspace = true
|
||||
fish-build-helper.workspace = true
|
||||
fish-build-man-pages = { workspace = true, optional = true }
|
||||
fish-common.workspace = true
|
||||
fish-fallback.workspace = true
|
||||
fish-gettext = { workspace = true, optional = true }
|
||||
fish-gettext-extraction = { workspace = true, optional = true }
|
||||
fish-printf.workspace = true
|
||||
|
||||
@@ -6,5 +6,10 @@ version = "0.0.0"
|
||||
repository.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
libc.workspace = true
|
||||
nix.workspace = true
|
||||
once_cell.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
use libc::STDIN_FILENO;
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::env;
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
// These are in the Unicode private-use range. We really shouldn't use this
|
||||
// range but have little choice in the matter given how our lexer/parser works.
|
||||
// We can't use non-characters for these two ranges because there are only 66 of
|
||||
@@ -26,3 +31,30 @@ pub fn subslice_position<T: Eq>(a: &[T], b: &[T]) -> Option<usize> {
|
||||
}
|
||||
a.windows(b.len()).position(|aw| aw == b)
|
||||
}
|
||||
|
||||
/// This function attempts to distinguish between a console session (at the actual login vty) and a
|
||||
/// session within a terminal emulator inside a desktop environment or over SSH. Unfortunately
|
||||
/// there are few values of $TERM that we can interpret as being exclusively console sessions, and
|
||||
/// most common operating systems do not use them. The value is cached for the duration of the fish
|
||||
/// session. We err on the side of assuming it's not a console session. This approach isn't
|
||||
/// bullet-proof and that's OK.
|
||||
pub fn is_console_session() -> bool {
|
||||
static IS_CONSOLE_SESSION: OnceCell<bool> = OnceCell::new();
|
||||
// TODO(terminal-workaround)
|
||||
*IS_CONSOLE_SESSION.get_or_init(|| {
|
||||
nix::unistd::ttyname(unsafe { std::os::fd::BorrowedFd::borrow_raw(STDIN_FILENO) })
|
||||
.is_ok_and(|buf| {
|
||||
// Check if the tty matches /dev/(console|dcons|tty[uv\d])
|
||||
let is_console_tty = match buf.as_os_str().as_bytes() {
|
||||
b"/dev/console" => true,
|
||||
b"/dev/dcons" => true,
|
||||
bytes => bytes.strip_prefix(b"/dev/tty").is_some_and(|rest| {
|
||||
matches!(rest.first(), Some(b'u' | b'v' | b'0'..=b'9'))
|
||||
}),
|
||||
};
|
||||
|
||||
// and that $TERM is simple, e.g. `xterm` or `vt100`, not `xterm-something` or `sun-color`.
|
||||
is_console_tty && env::var_os("TERM").is_none_or(|t| !t.as_bytes().contains(&b'-'))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
22
crates/fallback/Cargo.toml
Normal file
22
crates/fallback/Cargo.toml
Normal file
@@ -0,0 +1,22 @@
|
||||
[package]
|
||||
name = "fish-fallback"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
version = "0.0.0"
|
||||
repository.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
fish-common.workspace = true
|
||||
fish-wchar.workspace = true
|
||||
fish-widecharwidth.workspace = true
|
||||
libc.workspace = true
|
||||
once_cell.workspace = true
|
||||
widestring.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
fish-build-helper.workspace = true
|
||||
rsconf.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
5
crates/fallback/build.rs
Normal file
5
crates/fallback/build.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
use fish_build_helper::target_os_is_cygwin;
|
||||
|
||||
fn main() {
|
||||
rsconf::declare_cfg("cygwin", target_os_is_cygwin())
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
//!
|
||||
//! Many of these functions are more or less broken and incomplete.
|
||||
|
||||
use crate::wchar::prelude::*;
|
||||
use fish_wchar::prelude::*;
|
||||
use fish_widecharwidth::{WcLookupTable, WcWidth};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::cmp;
|
||||
@@ -46,7 +46,7 @@ pub fn fish_wcwidth(c: char) -> isize {
|
||||
// in the console session, but knows nothing about the capabilities of other terminal emulators
|
||||
// or ttys. Use it from the start only if we are logged in to the physical console.
|
||||
#[cfg(not(cygwin))]
|
||||
if crate::common::is_console_session() {
|
||||
if fish_common::is_console_session() {
|
||||
return wcwidth(c);
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ pub fn new(mut chars: std::iter::Map<CharsUtf32<'a>, Canonicalize>) -> Self {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::wcscasecmp;
|
||||
use crate::wchar::prelude::*;
|
||||
use fish_wchar::prelude::*;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
#[test]
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::*;
|
||||
use crate::fallback::fish_wcwidth;
|
||||
use fish_fallback::fish_wcwidth;
|
||||
|
||||
pub struct Pad {
|
||||
char_to_pad: char,
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
use nix::sys::resource::Resource as ResourceEnum;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use crate::fallback::{fish_wcswidth, wcscasecmp};
|
||||
use crate::wutil::perror;
|
||||
use fish_fallback::{fish_wcswidth, wcscasecmp};
|
||||
|
||||
use super::prelude::*;
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
BRACE_BEGIN, BRACE_END, BRACE_SEP, BRACE_SPACE, HOME_DIRECTORY, INTERNAL_SEPARATOR,
|
||||
PROCESS_EXPAND_SELF, PROCESS_EXPAND_SELF_STR, VARIABLE_EXPAND, VARIABLE_EXPAND_SINGLE,
|
||||
};
|
||||
use crate::fallback::fish_wcwidth;
|
||||
use crate::future_feature_flags::{FeatureFlag, feature_test};
|
||||
use crate::global_safety::AtomicRef;
|
||||
use crate::global_safety::RelaxedAtomicBool;
|
||||
@@ -17,7 +16,8 @@
|
||||
use crate::wildcard::{ANY_CHAR, ANY_STRING, ANY_STRING_RECURSIVE};
|
||||
use crate::wutil::fish_iswalnum;
|
||||
use bitflags::bitflags;
|
||||
use fish_common::{ENCODE_DIRECT_END, char_offset, subslice_position};
|
||||
use fish_common::{ENCODE_DIRECT_END, char_offset, is_console_session, subslice_position};
|
||||
use fish_fallback::fish_wcwidth;
|
||||
use fish_wchar::{decode_byte_from_char, encode_byte_to_char};
|
||||
use libc::{SIG_IGN, SIGTTOU, STDIN_FILENO};
|
||||
use once_cell::sync::OnceCell;
|
||||
@@ -1796,33 +1796,6 @@ impl<T, F: FnOnce(T)> ScopeGuarding for ScopeGuard<T, F> {}
|
||||
pub const fn assert_send<T: Send>() {}
|
||||
pub const fn assert_sync<T: Sync>() {}
|
||||
|
||||
/// This function attempts to distinguish between a console session (at the actual login vty) and a
|
||||
/// session within a terminal emulator inside a desktop environment or over SSH. Unfortunately
|
||||
/// there are few values of $TERM that we can interpret as being exclusively console sessions, and
|
||||
/// most common operating systems do not use them. The value is cached for the duration of the fish
|
||||
/// session. We err on the side of assuming it's not a console session. This approach isn't
|
||||
/// bullet-proof and that's OK.
|
||||
pub fn is_console_session() -> bool {
|
||||
static IS_CONSOLE_SESSION: OnceCell<bool> = OnceCell::new();
|
||||
// TODO(terminal-workaround)
|
||||
*IS_CONSOLE_SESSION.get_or_init(|| {
|
||||
nix::unistd::ttyname(unsafe { std::os::fd::BorrowedFd::borrow_raw(STDIN_FILENO) })
|
||||
.is_ok_and(|buf| {
|
||||
// Check if the tty matches /dev/(console|dcons|tty[uv\d])
|
||||
let is_console_tty = match buf.as_os_str().as_bytes() {
|
||||
b"/dev/console" => true,
|
||||
b"/dev/dcons" => true,
|
||||
bytes => bytes.strip_prefix(b"/dev/tty").is_some_and(|rest| {
|
||||
matches!(rest.first(), Some(b'u' | b'v' | b'0'..=b'9'))
|
||||
}),
|
||||
};
|
||||
|
||||
// and that $TERM is simple, e.g. `xterm` or `vt100`, not `xterm-something` or `sun-color`.
|
||||
is_console_tty && env::var_os("TERM").is_none_or(|t| !t.as_bytes().contains(&b'-'))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Asserts that a slice is alphabetically sorted by a <code>&[wstr]</code> `name` field.
|
||||
///
|
||||
/// Mainly useful for static asserts/const eval.
|
||||
|
||||
@@ -155,9 +155,9 @@ fn handle_timezone(var_name: &wstr, vars: &EnvStack) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Update the value of [`FISH_EMOJI_WIDTH`](crate::fallback::FISH_EMOJI_WIDTH).
|
||||
/// Update the value of [`FISH_EMOJI_WIDTH`](fish_fallback::FISH_EMOJI_WIDTH).
|
||||
pub fn guess_emoji_width(vars: &EnvStack) {
|
||||
use crate::fallback::FISH_EMOJI_WIDTH;
|
||||
use fish_fallback::FISH_EMOJI_WIDTH;
|
||||
|
||||
if let Some(width_str) = vars.get(L!("fish_emoji_width")) {
|
||||
// The only valid values are 1 or 2; we default to 1 if it was an invalid int.
|
||||
@@ -199,7 +199,7 @@ pub fn guess_emoji_width(vars: &EnvStack) {
|
||||
// Default to whatever the system's wcwidth gives for U+1F603, but only if it's at least
|
||||
// 1 and at most 2.
|
||||
#[cfg(not(cygwin))]
|
||||
let width = crate::fallback::wcwidth('😃').clamp(1, 2);
|
||||
let width = fish_fallback::wcwidth('😃').clamp(1, 2);
|
||||
#[cfg(cygwin)]
|
||||
let width = 2_isize;
|
||||
FISH_EMOJI_WIDTH.store(width, Ordering::Relaxed);
|
||||
@@ -238,7 +238,7 @@ fn handle_change_ambiguous_width(vars: &EnvStack) {
|
||||
.unwrap_or(1)
|
||||
// Clamp in case of negative values.
|
||||
.max(0) as isize;
|
||||
crate::fallback::FISH_AMBIGUOUS_WIDTH.store(new_width, Ordering::Relaxed);
|
||||
fish_fallback::FISH_AMBIGUOUS_WIDTH.store(new_width, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
fn handle_term_size_change(vars: &EnvStack) {
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
use crate::{
|
||||
common::{EscapeFlags, EscapeStringStyle, escape_string},
|
||||
fallback::fish_wcwidth,
|
||||
flog::FloggableDebug,
|
||||
future_feature_flags::{FeatureFlag, test as feature_test},
|
||||
reader::safe_get_terminal_mode_on_startup,
|
||||
wchar::prelude::*,
|
||||
wutil::fish_wcstoul,
|
||||
};
|
||||
use fish_fallback::fish_wcwidth;
|
||||
use fish_wchar::decode_byte_from_char;
|
||||
|
||||
pub(crate) const Backspace: char = '\u{F500}'; // below ENCODE_DIRECT_BASE
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
pub mod event;
|
||||
pub mod exec;
|
||||
pub mod expand;
|
||||
pub mod fallback;
|
||||
pub mod fd_monitor;
|
||||
pub mod fd_readable_set;
|
||||
pub mod fds;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
//! Constants used in the programmatic representation of fish code.
|
||||
|
||||
use crate::fallback::{fish_wcswidth, fish_wcwidth};
|
||||
use crate::wchar::prelude::*;
|
||||
use bitflags::bitflags;
|
||||
use fish_fallback::{fish_wcswidth, fish_wcwidth};
|
||||
|
||||
pub type SourceOffset = u32;
|
||||
|
||||
|
||||
@@ -71,7 +71,6 @@
|
||||
use crate::exec::exec_subshell;
|
||||
use crate::expand::expand_one;
|
||||
use crate::expand::{ExpandFlags, ExpandResultCode, expand_string, expand_tilde};
|
||||
use crate::fallback::fish_wcwidth;
|
||||
use crate::fd_readable_set::poll_fd_readable;
|
||||
use crate::fds::{AutoCloseFd, make_fd_blocking, wopen_cloexec};
|
||||
use crate::flog::{flog, flogf};
|
||||
@@ -158,6 +157,7 @@
|
||||
use crate::wildcard::wildcard_has;
|
||||
use crate::wutil::{fstat, perror, write_to_fd, wstat};
|
||||
use crate::{abbrs, event, function};
|
||||
use fish_fallback::fish_wcwidth;
|
||||
|
||||
/// A description of where fish is in the process of exiting.
|
||||
#[repr(u8)]
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
has_working_tty_timestamps, shell_modes, wcs2bytes, write_loop,
|
||||
};
|
||||
use crate::env::Environment;
|
||||
use crate::fallback::fish_wcwidth;
|
||||
use crate::flog::{flog, flogf};
|
||||
use crate::global_safety::RelaxedAtomicBool;
|
||||
use crate::highlight::{HighlightColorResolver, HighlightRole, HighlightSpec};
|
||||
@@ -39,6 +38,7 @@
|
||||
use crate::wchar::prelude::*;
|
||||
use crate::wcstringutil::{fish_wcwidth_visible, string_prefixes_string};
|
||||
use crate::wutil::fstat;
|
||||
use fish_fallback::fish_wcwidth;
|
||||
|
||||
#[derive(Copy, Clone, Default)]
|
||||
pub enum CharOffset {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
//! Helper functions for working with wcstring.
|
||||
|
||||
use crate::common::{get_ellipsis_char, get_ellipsis_str};
|
||||
use crate::fallback::{fish_wcwidth, wcscasecmp, wcscasecmp_fuzzy};
|
||||
use crate::wchar::prelude::*;
|
||||
use fish_fallback::{fish_wcwidth, wcscasecmp, wcscasecmp_fuzzy};
|
||||
use fish_wchar::decode_byte_from_char;
|
||||
|
||||
/// Return the number of newlines in a string.
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
};
|
||||
use crate::complete::{CompleteFlags, Completion, CompletionReceiver, PROG_COMPLETE_SEP};
|
||||
use crate::expand::ExpandFlags;
|
||||
use crate::fallback::wcscasecmp;
|
||||
use crate::future_feature_flags::FeatureFlag;
|
||||
use crate::future_feature_flags::feature_test;
|
||||
use crate::wchar::prelude::*;
|
||||
@@ -23,6 +22,7 @@
|
||||
};
|
||||
use crate::wutil::dir_iter::DirEntryType;
|
||||
use crate::wutil::{dir_iter::DirEntry, lwstat, waccess};
|
||||
use fish_fallback::wcscasecmp;
|
||||
|
||||
localizable_consts!(
|
||||
COMPLETE_EXEC_DESC "command"
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
use crate::common::{
|
||||
bytes2wcstring, fish_reserved_codepoint, wcs2bytes, wcs2osstring, wcs2zstring,
|
||||
};
|
||||
use crate::flog;
|
||||
use crate::wcstringutil::{join_strings, wcs2bytes_callback};
|
||||
use crate::{fallback, flog};
|
||||
use errno::errno;
|
||||
use fish_wchar::{L, WExt, WString, wstr};
|
||||
pub use gettext::{
|
||||
@@ -448,7 +448,7 @@ pub fn fish_iswalnum(c: char) -> bool {
|
||||
}
|
||||
|
||||
pub fn fish_wcswidth(s: &wstr) -> isize {
|
||||
fallback::fish_wcswidth(s)
|
||||
fish_fallback::fish_wcswidth(s)
|
||||
}
|
||||
|
||||
/// Given that `cursor` is a pointer into `base`, return the offset in characters.
|
||||
|
||||
Reference in New Issue
Block a user