mirror of
https://github.com/alacritty/alacritty.git
synced 2025-11-06 22:44:18 -05:00
Migrate to 2024 edition
This commit is contained in:
parent
b0304431c4
commit
bb02cb13f1
51 changed files with 121 additions and 153 deletions
|
|
@ -12,7 +12,7 @@ Notable changes to the `alacritty_terminal` crate are documented in its
|
|||
|
||||
### Packaging
|
||||
|
||||
- Minimum Rust version has been bumped to 1.81.0
|
||||
- Minimum Rust version has been bumped to 1.85.0
|
||||
|
||||
### Added
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ members = [
|
|||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
edition = "2021"
|
||||
rust-version = "1.81.0"
|
||||
edition = "2024"
|
||||
rust-version = "1.85.0"
|
||||
|
||||
[profile.release]
|
||||
lto = "thin"
|
||||
|
|
|
|||
|
|
@ -6,15 +6,15 @@ use std::rc::Rc;
|
|||
|
||||
use alacritty_config::SerdeReplace;
|
||||
use clap::{ArgAction, Args, Parser, Subcommand, ValueHint};
|
||||
use log::{error, LevelFilter};
|
||||
use log::{LevelFilter, error};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use toml::Value;
|
||||
|
||||
use alacritty_terminal::tty::Options as PtyOptions;
|
||||
|
||||
use crate::config::UiConfig;
|
||||
use crate::config::ui_config::Program;
|
||||
use crate::config::window::{Class, Identity};
|
||||
use crate::config::UiConfig;
|
||||
use crate::logging::LOG_TARGET_IPC_CONFIG;
|
||||
|
||||
/// CLI options for the main Alacritty executable.
|
||||
|
|
@ -135,7 +135,7 @@ fn parse_class(input: &str) -> Result<Class, String> {
|
|||
let (general, instance) = match input.split_once(',') {
|
||||
// Warn the user if they've passed too many values.
|
||||
Some((_, instance)) if instance.contains(',') => {
|
||||
return Err(String::from("Too many parameters"))
|
||||
return Err(String::from("Too many parameters"));
|
||||
},
|
||||
Some((general, instance)) => (general, instance),
|
||||
None => (input, input),
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@ use winit::raw_window_handle::RawDisplayHandle;
|
|||
|
||||
use alacritty_terminal::term::ClipboardType;
|
||||
|
||||
#[cfg(any(feature = "x11", target_os = "macos", windows))]
|
||||
use copypasta::ClipboardContext;
|
||||
use copypasta::ClipboardProvider;
|
||||
use copypasta::nop_clipboard::NopClipboardContext;
|
||||
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
|
||||
use copypasta::wayland_clipboard;
|
||||
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
|
||||
use copypasta::x11_clipboard::{Primary as X11SelectionClipboard, X11ClipboardContext};
|
||||
#[cfg(any(feature = "x11", target_os = "macos", windows))]
|
||||
use copypasta::ClipboardContext;
|
||||
use copypasta::ClipboardProvider;
|
||||
|
||||
pub struct Clipboard {
|
||||
clipboard: Box<dyn ClipboardProvider>,
|
||||
|
|
@ -22,8 +22,9 @@ impl Clipboard {
|
|||
match display {
|
||||
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
|
||||
RawDisplayHandle::Wayland(display) => {
|
||||
let (selection, clipboard) =
|
||||
wayland_clipboard::create_clipboards_from_external(display.display.as_ptr());
|
||||
let (selection, clipboard) = unsafe {
|
||||
wayland_clipboard::create_clipboards_from_external(display.display.as_ptr())
|
||||
};
|
||||
Self { clipboard: Box::new(clipboard), selection: Some(Box::new(selection)) }
|
||||
},
|
||||
_ => Self::default(),
|
||||
|
|
|
|||
|
|
@ -400,21 +400,11 @@ macro_rules! bindings {
|
|||
}
|
||||
|
||||
macro_rules! trigger {
|
||||
(KeyBinding, $key:literal, $location:expr) => {{
|
||||
BindingKey::Keycode { key: Key::Character($key.into()), location: $location }
|
||||
}};
|
||||
(KeyBinding, $key:literal,) => {{
|
||||
BindingKey::Keycode { key: Key::Character($key.into()), location: KeyLocation::Any }
|
||||
}};
|
||||
(KeyBinding, $key:ident, $location:expr) => {{
|
||||
BindingKey::Keycode { key: Key::Named(NamedKey::$key), location: $location }
|
||||
}};
|
||||
(KeyBinding, $key:ident,) => {{
|
||||
BindingKey::Keycode { key: Key::Named(NamedKey::$key), location: KeyLocation::Any }
|
||||
}};
|
||||
(MouseBinding, $base:ident::$button:ident,) => {{
|
||||
$base::$button
|
||||
}};
|
||||
(KeyBinding, $key:literal, $location:expr) => {{ BindingKey::Keycode { key: Key::Character($key.into()), location: $location } }};
|
||||
(KeyBinding, $key:literal,) => {{ BindingKey::Keycode { key: Key::Character($key.into()), location: KeyLocation::Any } }};
|
||||
(KeyBinding, $key:ident, $location:expr) => {{ BindingKey::Keycode { key: Key::Named(NamedKey::$key), location: $location } }};
|
||||
(KeyBinding, $key:ident,) => {{ BindingKey::Keycode { key: Key::Named(NamedKey::$key), location: KeyLocation::Any } }};
|
||||
(MouseBinding, $base:ident::$button:ident,) => {{ $base::$button }};
|
||||
}
|
||||
|
||||
pub fn default_mouse_bindings() -> Vec<MouseBinding> {
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ impl ConfigMonitor {
|
|||
/// This checks the supplied list of files against the monitored files to determine if a
|
||||
/// restart is necessary.
|
||||
pub fn needs_restart(&self, files: &[PathBuf]) -> bool {
|
||||
Self::hash_paths(files).map_or(true, |hash| Some(hash) == self.watched_hash)
|
||||
Self::hash_paths(files).is_none_or(|hash| Some(hash) == self.watched_hash)
|
||||
}
|
||||
|
||||
/// Generate the hash for a list of paths.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use serde::{de, Deserialize, Deserializer, Serialize};
|
||||
use serde::{Deserialize, Deserializer, Serialize, de};
|
||||
use toml::Value;
|
||||
|
||||
use alacritty_config_derive::{ConfigDeserialize, SerdeReplace};
|
||||
|
|
|
|||
|
|
@ -14,10 +14,11 @@ use winit::keyboard::{Key, ModifiersState};
|
|||
|
||||
use alacritty_config::SerdeReplace;
|
||||
use alacritty_config_derive::{ConfigDeserialize, SerdeReplace};
|
||||
use alacritty_terminal::term::search::RegexSearch;
|
||||
use alacritty_terminal::term::Config as TermConfig;
|
||||
use alacritty_terminal::term::search::RegexSearch;
|
||||
use alacritty_terminal::tty::{Options as PtyOptions, Shell};
|
||||
|
||||
use crate::config::LOG_TARGET_CONFIG;
|
||||
use crate::config::bell::BellConfig;
|
||||
use crate::config::bindings::{
|
||||
self, Action, Binding, BindingKey, KeyBinding, KeyLocation, ModeWrapper, ModsWrapper,
|
||||
|
|
@ -33,7 +34,6 @@ use crate::config::scrolling::Scrolling;
|
|||
use crate::config::selection::Selection;
|
||||
use crate::config::terminal::Terminal;
|
||||
use crate::config::window::WindowConfig;
|
||||
use crate::config::LOG_TARGET_CONFIG;
|
||||
|
||||
/// Regex used for the default URL hint.
|
||||
#[rustfmt::skip]
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ use winit::window::{Fullscreen, Theme as WinitTheme, WindowLevel as WinitWindowL
|
|||
|
||||
use alacritty_config_derive::{ConfigDeserialize, SerdeReplace};
|
||||
|
||||
use crate::config::ui_config::{Delta, Percentage};
|
||||
use crate::config::LOG_TARGET_CONFIG;
|
||||
use crate::config::ui_config::{Delta, Percentage};
|
||||
|
||||
/// Default Alacritty name, used for window title and class.
|
||||
pub const DEFAULT_NAME: &str = "Alacritty";
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use alacritty_terminal::term::{self, RenderableContent as TerminalContent, Term,
|
|||
use alacritty_terminal::vte::ansi::{Color, CursorShape, NamedColor};
|
||||
|
||||
use crate::config::UiConfig;
|
||||
use crate::display::color::{CellRgb, List, Rgb, DIM_FACTOR};
|
||||
use crate::display::color::{CellRgb, DIM_FACTOR, List, Rgb};
|
||||
use crate::display::hint::{self, HintState};
|
||||
use crate::display::{Display, SizeInfo};
|
||||
use crate::event::SearchState;
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
use alacritty_terminal::vte::ansi::CursorShape;
|
||||
|
||||
use crate::display::SizeInfo;
|
||||
use crate::display::color::Rgb;
|
||||
use crate::display::content::RenderableCursor;
|
||||
use crate::display::SizeInfo;
|
||||
use crate::renderer::rects::RenderRect;
|
||||
|
||||
/// Trait for conversion into the iterator.
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ use alacritty_terminal::term::cell::Hyperlink;
|
|||
use alacritty_terminal::term::search::{Match, RegexIter, RegexSearch};
|
||||
use alacritty_terminal::term::{Term, TermMode};
|
||||
|
||||
use crate::config::ui_config::{Hint, HintAction};
|
||||
use crate::config::UiConfig;
|
||||
use crate::config::ui_config::{Hint, HintAction};
|
||||
|
||||
/// Maximum number of linewraps followed outside of the viewport during search highlighting.
|
||||
pub const MAX_SEARCH_LINES: usize = 100;
|
||||
|
|
@ -548,11 +548,7 @@ impl<'a, T> HintPostProcessor<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
if start > iter.point() {
|
||||
None
|
||||
} else {
|
||||
Some(start..=iter.point())
|
||||
}
|
||||
if start > iter.point() { None } else { Some(start..=iter.point()) }
|
||||
}
|
||||
|
||||
/// Loop over submatches until a non-empty post-processed match is found.
|
||||
|
|
|
|||
|
|
@ -32,28 +32,28 @@ use alacritty_terminal::index::{Column, Direction, Line, Point};
|
|||
use alacritty_terminal::selection::Selection;
|
||||
use alacritty_terminal::term::cell::Flags;
|
||||
use alacritty_terminal::term::{
|
||||
self, LineDamageBounds, Term, TermDamage, TermMode, MIN_COLUMNS, MIN_SCREEN_LINES,
|
||||
self, LineDamageBounds, MIN_COLUMNS, MIN_SCREEN_LINES, Term, TermDamage, TermMode,
|
||||
};
|
||||
use alacritty_terminal::vte::ansi::{CursorShape, NamedColor};
|
||||
|
||||
use crate::config::UiConfig;
|
||||
use crate::config::debug::RendererPreference;
|
||||
use crate::config::font::Font;
|
||||
use crate::config::window::Dimensions;
|
||||
#[cfg(not(windows))]
|
||||
use crate::config::window::StartupMode;
|
||||
use crate::config::UiConfig;
|
||||
use crate::display::bell::VisualBell;
|
||||
use crate::display::color::{List, Rgb};
|
||||
use crate::display::content::{RenderableContent, RenderableCursor};
|
||||
use crate::display::cursor::IntoRects;
|
||||
use crate::display::damage::{damage_y_to_viewport_y, DamageTracker};
|
||||
use crate::display::damage::{DamageTracker, damage_y_to_viewport_y};
|
||||
use crate::display::hint::{HintMatch, HintState};
|
||||
use crate::display::meter::Meter;
|
||||
use crate::display::window::Window;
|
||||
use crate::event::{Event, EventType, Mouse, SearchState};
|
||||
use crate::message_bar::{MessageBuffer, MessageType};
|
||||
use crate::renderer::rects::{RenderLine, RenderLines, RenderRect};
|
||||
use crate::renderer::{self, platform, GlyphCache, Renderer};
|
||||
use crate::renderer::{self, GlyphCache, Renderer, platform};
|
||||
use crate::scheduler::{Scheduler, TimerId, Topic};
|
||||
use crate::string::{ShortenDirection, StrShortener};
|
||||
|
||||
|
|
@ -1081,7 +1081,7 @@ impl Display {
|
|||
}
|
||||
|
||||
// Abort if mouse highlighting conditions are not met.
|
||||
if !mouse.inside_text_area || !term.selection.as_ref().map_or(true, Selection::is_empty) {
|
||||
if !mouse.inside_text_area || !term.selection.as_ref().is_none_or(Selection::is_empty) {
|
||||
if self.highlighted_hint.take().is_some() {
|
||||
self.damage_tracker.frame().mark_fully_damaged();
|
||||
dirty = true;
|
||||
|
|
@ -1367,7 +1367,7 @@ impl Display {
|
|||
let bg = colors.line_indicator.background.unwrap_or(colors.primary.foreground);
|
||||
|
||||
// Do not render anything if it would obscure the vi mode cursor.
|
||||
if obstructed_column.map_or(true, |obstructed_column| obstructed_column < column) {
|
||||
if obstructed_column.is_none_or(|obstructed_column| obstructed_column < column) {
|
||||
let glyph_cache = &mut self.glyph_cache;
|
||||
self.renderer.draw_string(point, fg, bg, text.chars(), &self.size_info, glyph_cache);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ use winit::window::{
|
|||
use alacritty_terminal::index::Point;
|
||||
|
||||
use crate::cli::WindowOptions;
|
||||
use crate::config::window::{Decorations, Identity, WindowConfig};
|
||||
use crate::config::UiConfig;
|
||||
use crate::config::window::{Decorations, Identity, WindowConfig};
|
||||
use crate::display::SizeInfo;
|
||||
|
||||
/// Window icon for `_NET_WM_ICON` property.
|
||||
|
|
|
|||
|
|
@ -196,10 +196,9 @@ impl Processor {
|
|||
/// The result is exit code generate from the loop.
|
||||
pub fn run(&mut self, event_loop: EventLoop<Event>) -> Result<(), Box<dyn Error>> {
|
||||
let result = event_loop.run_app(self);
|
||||
if let Some(initial_window_error) = self.initial_window_error.take() {
|
||||
Err(initial_window_error)
|
||||
} else {
|
||||
result.map_err(Into::into)
|
||||
match self.initial_window_error.take() {
|
||||
Some(initial_window_error) => Err(initial_window_error),
|
||||
_ => result.map_err(Into::into),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -746,7 +745,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
|
|||
}
|
||||
|
||||
fn selection_is_empty(&self) -> bool {
|
||||
self.terminal.selection.as_ref().map_or(true, Selection::is_empty)
|
||||
self.terminal.selection.as_ref().is_none_or(Selection::is_empty)
|
||||
}
|
||||
|
||||
fn clear_selection(&mut self) {
|
||||
|
|
@ -937,7 +936,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
|
|||
#[inline]
|
||||
fn start_search(&mut self, direction: Direction) {
|
||||
// Only create new history entry if the previous regex wasn't empty.
|
||||
if self.search_state.history.front().map_or(true, |regex| !regex.is_empty()) {
|
||||
if self.search_state.history.front().is_none_or(|regex| !regex.is_empty()) {
|
||||
self.search_state.history.push_front(String::new());
|
||||
self.search_state.history.truncate(MAX_SEARCH_HISTORY_SIZE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> {
|
|||
| Key::Named(NamedKey::Backspace)
|
||||
if !mode.contains(TermMode::REPORT_ALL_KEYS_AS_ESC) =>
|
||||
{
|
||||
return
|
||||
return;
|
||||
},
|
||||
_ => build_sequence(key, mods, mode),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
//! determine what to do when a non-modifier key is pressed.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::{max, min, Ordering};
|
||||
use std::cmp::{Ordering, max, min};
|
||||
use std::collections::HashSet;
|
||||
use std::ffi::OsStr;
|
||||
use std::fmt::Debug;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ pub fn spawn_ipc_socket(
|
|||
|
||||
let listener = UnixListener::bind(&socket_path)?;
|
||||
|
||||
env::set_var(ALACRITTY_SOCKET_ENV, socket_path.as_os_str());
|
||||
unsafe { env::set_var(ALACRITTY_SOCKET_ENV, socket_path.as_os_str()) };
|
||||
if options.daemon {
|
||||
println!("ALACRITTY_SOCKET={}; export ALACRITTY_SOCKET", socket_path.display());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,11 +87,8 @@ impl Logger {
|
|||
}
|
||||
|
||||
fn file_path(&self) -> Option<PathBuf> {
|
||||
if let Ok(logfile) = self.logfile.lock() {
|
||||
Some(logfile.path().clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
let logfile_lock = self.logfile.lock().ok()?;
|
||||
Some(logfile_lock.path().clone())
|
||||
}
|
||||
|
||||
/// Log a record to the message bar.
|
||||
|
|
@ -204,7 +201,7 @@ impl OnDemandLogFile {
|
|||
path.push(format!("Alacritty-{}.log", process::id()));
|
||||
|
||||
// Set log path as an environment variable.
|
||||
env::set_var(ALACRITTY_LOG_ENV, path.as_os_str());
|
||||
unsafe { env::set_var(ALACRITTY_LOG_ENV, path.as_os_str()) };
|
||||
|
||||
OnDemandLogFile { path, file: None, created: Arc::new(AtomicBool::new(false)) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
use std::ffi::{CStr, CString};
|
||||
use std::{env, str};
|
||||
|
||||
use libc::{setlocale, LC_ALL, LC_CTYPE};
|
||||
use libc::{LC_ALL, LC_CTYPE, setlocale};
|
||||
use log::debug;
|
||||
use objc2::sel;
|
||||
use objc2_foundation::{NSLocale, NSObjectProtocol};
|
||||
|
|
@ -37,12 +37,12 @@ pub fn set_locale_environment() {
|
|||
let fallback_locale_c = CString::new(FALLBACK_LOCALE).unwrap();
|
||||
unsafe { setlocale(LC_CTYPE, fallback_locale_c.as_ptr()) };
|
||||
|
||||
env::set_var("LC_CTYPE", FALLBACK_LOCALE);
|
||||
unsafe { env::set_var("LC_CTYPE", FALLBACK_LOCALE) };
|
||||
} else {
|
||||
// Use system locale.
|
||||
debug!("Using system locale: {}", system_locale);
|
||||
|
||||
env::set_var("LC_ALL", system_locale);
|
||||
unsafe { env::set_var("LC_ALL", system_locale) };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ mod sys {
|
|||
pub pvi_rdir: vnode_info_path,
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
unsafe extern "C" {
|
||||
pub fn proc_pidinfo(
|
||||
pid: c_int,
|
||||
flavor: c_int,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use std::{env, fs};
|
|||
|
||||
use log::info;
|
||||
#[cfg(windows)]
|
||||
use windows_sys::Win32::System::Console::{AttachConsole, FreeConsole, ATTACH_PARENT_PROCESS};
|
||||
use windows_sys::Win32::System::Console::{ATTACH_PARENT_PROCESS, AttachConsole, FreeConsole};
|
||||
use winit::event_loop::EventLoop;
|
||||
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
|
||||
use winit::raw_window_handle::{HasDisplayHandle, RawDisplayHandle};
|
||||
|
|
@ -49,7 +49,7 @@ mod string;
|
|||
mod window_context;
|
||||
|
||||
mod gl {
|
||||
#![allow(clippy::all)]
|
||||
#![allow(clippy::all, unsafe_op_in_unsafe_fn)]
|
||||
include!(concat!(env!("OUT_DIR"), "/gl_bindings.rs"));
|
||||
}
|
||||
|
||||
|
|
@ -58,8 +58,8 @@ use crate::cli::MessageOptions;
|
|||
#[cfg(not(any(target_os = "macos", windows)))]
|
||||
use crate::cli::SocketMessage;
|
||||
use crate::cli::{Options, Subcommands};
|
||||
use crate::config::monitor::ConfigMonitor;
|
||||
use crate::config::UiConfig;
|
||||
use crate::config::monitor::ConfigMonitor;
|
||||
use crate::event::{Event, Processor};
|
||||
#[cfg(target_os = "macos")]
|
||||
use crate::macos::locale;
|
||||
|
|
@ -169,7 +169,7 @@ fn alacritty(mut options: Options) -> Result<(), Box<dyn Error>> {
|
|||
|
||||
// Set env vars from config.
|
||||
for (key, value) in config.env.iter() {
|
||||
env::set_var(key, value);
|
||||
unsafe { env::set_var(key, value) };
|
||||
}
|
||||
|
||||
// Switch to home directory.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::io::Write;
|
|||
use std::{io, panic, ptr};
|
||||
|
||||
use windows_sys::Win32::UI::WindowsAndMessaging::{
|
||||
MessageBoxW, MB_ICONERROR, MB_OK, MB_SETFOREGROUND, MB_TASKMODAL,
|
||||
MB_ICONERROR, MB_OK, MB_SETFOREGROUND, MB_TASKMODAL, MessageBoxW,
|
||||
};
|
||||
|
||||
use alacritty_terminal::tty::windows::win32_string;
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
use std::borrow::Cow;
|
||||
use std::collections::HashSet;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::OnceLock;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::{fmt, ptr};
|
||||
|
||||
use ahash::RandomState;
|
||||
use crossfont::Metrics;
|
||||
use glutin::context::{ContextApi, GlContext, PossiblyCurrentContext};
|
||||
use glutin::display::{GetGlDisplay, GlDisplay};
|
||||
use log::{debug, info, LevelFilter};
|
||||
use log::{LevelFilter, debug, info};
|
||||
use unicode_width::UnicodeWidthChar;
|
||||
|
||||
use alacritty_terminal::index::Point;
|
||||
use alacritty_terminal::term::cell::Flags;
|
||||
|
||||
use crate::config::debug::RendererPreference;
|
||||
use crate::display::SizeInfo;
|
||||
use crate::display::color::Rgb;
|
||||
use crate::display::content::RenderableCell;
|
||||
use crate::display::SizeInfo;
|
||||
use crate::gl;
|
||||
use crate::renderer::rects::{RectRenderer, RenderRect};
|
||||
use crate::renderer::shader::ShaderError;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use glutin::display::{Display, DisplayApiPreference, DisplayFeatures, GetGlDispl
|
|||
use glutin::error::Result as GlutinResult;
|
||||
use glutin::prelude::*;
|
||||
use glutin::surface::{Surface, SurfaceAttributesBuilder, WindowSurface};
|
||||
use log::{debug, LevelFilter};
|
||||
use log::{LevelFilter, debug};
|
||||
|
||||
use winit::dpi::PhysicalSize;
|
||||
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ use alacritty_terminal::grid::Dimensions;
|
|||
use alacritty_terminal::index::{Column, Point};
|
||||
use alacritty_terminal::term::cell::Flags;
|
||||
|
||||
use crate::display::SizeInfo;
|
||||
use crate::display::color::Rgb;
|
||||
use crate::display::content::RenderableCell;
|
||||
use crate::display::SizeInfo;
|
||||
use crate::gl::types::*;
|
||||
use crate::renderer::shader::{ShaderError, ShaderProgram, ShaderVersion};
|
||||
use crate::{gl, renderer};
|
||||
|
|
|
|||
|
|
@ -6,17 +6,17 @@ use log::info;
|
|||
|
||||
use alacritty_terminal::term::cell::Flags;
|
||||
|
||||
use crate::display::content::RenderableCell;
|
||||
use crate::display::SizeInfo;
|
||||
use crate::display::content::RenderableCell;
|
||||
use crate::gl;
|
||||
use crate::gl::types::*;
|
||||
use crate::renderer::shader::{ShaderProgram, ShaderVersion};
|
||||
use crate::renderer::{Error, GlExtensions};
|
||||
|
||||
use super::atlas::{Atlas, ATLAS_SIZE};
|
||||
use super::atlas::{ATLAS_SIZE, Atlas};
|
||||
use super::{
|
||||
glsl3, Glyph, LoadGlyph, LoaderApi, RenderingGlyphFlags, RenderingPass, TextRenderApi,
|
||||
TextRenderBatch, TextRenderer, TextShader,
|
||||
Glyph, LoadGlyph, LoaderApi, RenderingGlyphFlags, RenderingPass, TextRenderApi,
|
||||
TextRenderBatch, TextRenderer, TextShader, glsl3,
|
||||
};
|
||||
|
||||
// Shader source.
|
||||
|
|
|
|||
|
|
@ -6,14 +6,14 @@ use log::info;
|
|||
|
||||
use alacritty_terminal::term::cell::Flags;
|
||||
|
||||
use crate::display::content::RenderableCell;
|
||||
use crate::display::SizeInfo;
|
||||
use crate::display::content::RenderableCell;
|
||||
use crate::gl;
|
||||
use crate::gl::types::*;
|
||||
use crate::renderer::shader::{ShaderProgram, ShaderVersion};
|
||||
use crate::renderer::Error;
|
||||
use crate::renderer::shader::{ShaderProgram, ShaderVersion};
|
||||
|
||||
use super::atlas::{Atlas, ATLAS_SIZE};
|
||||
use super::atlas::{ATLAS_SIZE, Atlas};
|
||||
use super::{
|
||||
Glyph, LoadGlyph, LoaderApi, RenderingGlyphFlags, RenderingPass, TextRenderApi,
|
||||
TextRenderBatch, TextRenderer, TextShader,
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ use crossfont::{GlyphKey, RasterizedGlyph};
|
|||
|
||||
use alacritty_terminal::term::cell::Flags;
|
||||
|
||||
use crate::display::content::RenderableCell;
|
||||
use crate::display::SizeInfo;
|
||||
use crate::display::content::RenderableCell;
|
||||
use crate::gl;
|
||||
use crate::gl::types::*;
|
||||
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ use alacritty_terminal::tty;
|
|||
use crate::cli::{ParsedOptions, WindowOptions};
|
||||
use crate::clipboard::Clipboard;
|
||||
use crate::config::UiConfig;
|
||||
use crate::display::window::Window;
|
||||
use crate::display::Display;
|
||||
use crate::display::window::Window;
|
||||
use crate::event::{
|
||||
ActionContext, Event, EventProxy, InlineSearchState, Mouse, SearchState, TouchPurpose,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,11 +16,7 @@ pub fn derive_deserialize(ident: Ident, generics: Generics, data_enum: DataEnum)
|
|||
// Skip deserialization for `#[config(skip)]` fields.
|
||||
variant.attrs.iter().all(|attr| {
|
||||
let is_skip = |meta: ParseNestedMeta| {
|
||||
if meta.path.is_ident("skip") {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(meta.error("not skip"))
|
||||
}
|
||||
if meta.path.is_ident("skip") { Ok(()) } else { Err(meta.error("not skip")) }
|
||||
};
|
||||
!attr.path().is_ident("config") || attr.parse_nested_meta(is_skip).is_err()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use syn::punctuated::Punctuated;
|
|||
use syn::spanned::Spanned;
|
||||
use syn::{Error, Field, Generics, Ident, Type};
|
||||
|
||||
use crate::{serde_replace, Attr, GenericsStreams, MULTIPLE_FLATTEN_ERROR};
|
||||
use crate::{Attr, GenericsStreams, MULTIPLE_FLATTEN_ERROR, serde_replace};
|
||||
|
||||
/// Use this crate's name as log target.
|
||||
const LOG_TARGET: &str = env!("CARGO_PKG_NAME");
|
||||
|
|
@ -176,7 +176,7 @@ fn field_deserializer(field_streams: &mut FieldStreams, field: &Field) -> Result
|
|||
if let Type::Path(type_path) = &field.ty {
|
||||
if type_path.path.segments.iter().next_back().is_some_and(|s| s.ident == "Option") {
|
||||
match_assignment_stream = quote! {
|
||||
if value.as_str().map_or(false, |s| s.eq_ignore_ascii_case("none")) {
|
||||
if value.as_str().is_some_and(|s| s.eq_ignore_ascii_case("none")) {
|
||||
config.#ident = None;
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use proc_macro::TokenStream;
|
||||
use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Error, Fields};
|
||||
use syn::{Data, DataStruct, DeriveInput, Error, Fields, parse_macro_input};
|
||||
|
||||
/// Error if the derive was used on an unsupported type.
|
||||
const UNSUPPORTED_ERROR: &str = "ConfigDeserialize must be used on an enum or struct with fields";
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use proc_macro2::TokenStream as TokenStream2;
|
|||
use quote::quote;
|
||||
use syn::punctuated::Punctuated;
|
||||
use syn::{
|
||||
parse_macro_input, Data, DataStruct, DeriveInput, Error, Field, Fields, Generics, Ident,
|
||||
Data, DataStruct, DeriveInput, Error, Field, Fields, Generics, Ident, parse_macro_input,
|
||||
};
|
||||
|
||||
use crate::{Attr, GenericsStreams, MULTIPLE_FLATTEN_ERROR};
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ use std::fmt::{self, Display, Formatter};
|
|||
use std::fs::File;
|
||||
use std::io::{self, ErrorKind, Read, Write};
|
||||
use std::num::NonZeroUsize;
|
||||
use std::sync::mpsc::{self, Receiver, Sender, TryRecvError};
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc::{self, Receiver, Sender, TryRecvError};
|
||||
use std::thread::JoinHandle;
|
||||
use std::time::Instant;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//! Grid resize and reflow.
|
||||
|
||||
use std::cmp::{max, min, Ordering};
|
||||
use std::cmp::{Ordering, max, min};
|
||||
use std::mem;
|
||||
|
||||
use crate::index::{Boundary, Column, Line};
|
||||
|
|
|
|||
|
|
@ -83,11 +83,7 @@ impl<T: Default> Row<T> {
|
|||
|
||||
self.occ = min(self.occ, columns);
|
||||
|
||||
if new_row.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(new_row)
|
||||
}
|
||||
if new_row.is_empty() { None } else { Some(new_row) }
|
||||
}
|
||||
|
||||
/// Reset all cells in the row to the `template` cell.
|
||||
|
|
|
|||
|
|
@ -230,11 +230,7 @@ impl<T> Storage<T> {
|
|||
//
|
||||
// Requires `zeroed` to be smaller than `self.inner.len() * 2`,
|
||||
// but both `self.zero` and `requested` are always smaller than `self.inner.len()`.
|
||||
if zeroed >= self.inner.len() {
|
||||
zeroed - self.inner.len()
|
||||
} else {
|
||||
zeroed
|
||||
}
|
||||
if zeroed >= self.inner.len() { zeroed - self.inner.len() } else { zeroed }
|
||||
}
|
||||
|
||||
/// Rotate the ringbuffer to reset `self.zero` back to index `0`.
|
||||
|
|
@ -269,9 +265,9 @@ impl<T> IndexMut<Line> for Storage<T> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::grid::row::Row;
|
||||
use crate::grid::storage::{Storage, MAX_CACHE_SIZE};
|
||||
use crate::grid::GridCell;
|
||||
use crate::grid::row::Row;
|
||||
use crate::grid::storage::{MAX_CACHE_SIZE, Storage};
|
||||
use crate::index::{Column, Line};
|
||||
use crate::term::cell::Flags;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! Line and Column newtypes for strongly typed tty/grid/terminal APIs.
|
||||
|
||||
/// Indexing types and implementations for Grid and Line.
|
||||
use std::cmp::{max, min, Ord, Ordering};
|
||||
use std::cmp::{Ord, Ordering, max, min};
|
||||
use std::fmt;
|
||||
use std::ops::{Add, AddAssign, Deref, Sub, SubAssign};
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ use std::ops::{Bound, Range, RangeBounds};
|
|||
|
||||
use crate::grid::{Dimensions, GridCell, Indexed};
|
||||
use crate::index::{Boundary, Column, Line, Point, Side};
|
||||
use crate::term::cell::{Cell, Flags};
|
||||
use crate::term::Term;
|
||||
use crate::term::cell::{Cell, Flags};
|
||||
use crate::vte::ansi::CursorShape;
|
||||
|
||||
/// A Point and side within that point.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use std::sync::atomic::{AtomicU32, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicU32, Ordering};
|
||||
|
||||
use bitflags::bitflags;
|
||||
#[cfg(feature = "serde")]
|
||||
|
|
@ -183,7 +183,7 @@ impl Cell {
|
|||
&& self
|
||||
.extra
|
||||
.as_ref()
|
||||
.map_or(true, |extra| extra.zerowidth.is_empty() && extra.hyperlink.is_none())
|
||||
.is_none_or(|extra| extra.zerowidth.is_empty() && extra.hyperlink.is_none())
|
||||
{
|
||||
self.extra = None;
|
||||
} else {
|
||||
|
|
@ -201,9 +201,10 @@ impl Cell {
|
|||
/// Set hyperlink.
|
||||
pub fn set_hyperlink(&mut self, hyperlink: Option<Hyperlink>) {
|
||||
let should_drop = hyperlink.is_none()
|
||||
&& self.extra.as_ref().map_or(true, |extra| {
|
||||
extra.zerowidth.is_empty() && extra.underline_color.is_none()
|
||||
});
|
||||
&& self
|
||||
.extra
|
||||
.as_ref()
|
||||
.is_none_or(|extra| extra.zerowidth.is_empty() && extra.underline_color.is_none());
|
||||
|
||||
if should_drop {
|
||||
self.extra = None;
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ use std::{cmp, mem, ptr, slice, str};
|
|||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use base64::engine::general_purpose::STANDARD as Base64;
|
||||
use base64::Engine;
|
||||
use base64::engine::general_purpose::STANDARD as Base64;
|
||||
use bitflags::bitflags;
|
||||
use log::{debug, trace};
|
||||
use unicode_width::UnicodeWidthChar;
|
||||
|
|
@ -2282,11 +2282,7 @@ enum ModeState {
|
|||
|
||||
impl From<bool> for ModeState {
|
||||
fn from(value: bool) -> Self {
|
||||
if value {
|
||||
Self::Set
|
||||
} else {
|
||||
Self::Reset
|
||||
}
|
||||
if value { Self::Set } else { Self::Reset }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,16 +4,16 @@ use std::mem;
|
|||
use std::ops::RangeInclusive;
|
||||
|
||||
use log::{debug, warn};
|
||||
use regex_automata::hybrid::dfa::{Builder, Cache, Config, DFA};
|
||||
pub use regex_automata::hybrid::BuildError;
|
||||
use regex_automata::hybrid::dfa::{Builder, Cache, Config, DFA};
|
||||
use regex_automata::nfa::thompson::Config as ThompsonConfig;
|
||||
use regex_automata::util::syntax::Config as SyntaxConfig;
|
||||
use regex_automata::{Anchored, Input, MatchKind};
|
||||
|
||||
use crate::grid::{BidirectionalIterator, Dimensions, GridIterator, Indexed};
|
||||
use crate::index::{Boundary, Column, Direction, Point, Side};
|
||||
use crate::term::cell::{Cell, Flags};
|
||||
use crate::term::Term;
|
||||
use crate::term::cell::{Cell, Flags};
|
||||
|
||||
/// Used to match equal brackets, when performing a bracket-pair selection.
|
||||
const BRACKET_PAIRS: [(char, char); 4] = [('(', ')'), ('[', ']'), ('{', '}'), ('<', '>')];
|
||||
|
|
@ -689,8 +689,8 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
use crate::index::{Column, Line};
|
||||
use crate::term::test::{mock_term, TermSize};
|
||||
use crate::term::Config;
|
||||
use crate::term::test::{TermSize, mock_term};
|
||||
|
||||
#[test]
|
||||
fn regex_right() {
|
||||
|
|
|
|||
|
|
@ -94,10 +94,10 @@ pub fn setup_env() {
|
|||
// default to 'xterm-256color'. May be overridden by user's config
|
||||
// below.
|
||||
let terminfo = if terminfo_exists("alacritty") { "alacritty" } else { "xterm-256color" };
|
||||
env::set_var("TERM", terminfo);
|
||||
unsafe { env::set_var("TERM", terminfo) };
|
||||
|
||||
// Advertise 24-bit color support.
|
||||
env::set_var("COLORTERM", "truecolor");
|
||||
unsafe { env::set_var("COLORTERM", "truecolor") };
|
||||
}
|
||||
|
||||
/// Check if a terminfo entry exists on the system.
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use std::process::{Child, Command};
|
|||
use std::sync::Arc;
|
||||
use std::{env, ptr};
|
||||
|
||||
use libc::{c_int, TIOCSCTTY};
|
||||
use libc::{F_GETFL, F_SETFL, O_NONBLOCK, TIOCSCTTY, c_int, fcntl};
|
||||
use log::error;
|
||||
use polling::{Event, PollMode, Poller};
|
||||
use rustix_openpty::openpty;
|
||||
|
|
@ -22,7 +22,7 @@ use rustix_openpty::rustix::termios::Winsize;
|
|||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
use rustix_openpty::rustix::termios::{self, InputModes, OptionalActions};
|
||||
use signal_hook::low_level::{pipe as signal_pipe, unregister as unregister_signal};
|
||||
use signal_hook::{consts as sigconsts, SigId};
|
||||
use signal_hook::{SigId, consts as sigconsts};
|
||||
|
||||
use crate::event::{OnResize, WindowSize};
|
||||
use crate::tty::{ChildEvent, EventedPty, EventedReadWrite, Options};
|
||||
|
|
@ -37,7 +37,7 @@ macro_rules! die {
|
|||
($($arg:tt)*) => {{
|
||||
error!($($arg)*);
|
||||
std::process::exit(1);
|
||||
}}
|
||||
}};
|
||||
}
|
||||
|
||||
/// Really only needed on BSD, but should be fine elsewhere.
|
||||
|
|
@ -434,9 +434,7 @@ impl ToWinsize for WindowSize {
|
|||
}
|
||||
|
||||
unsafe fn set_nonblocking(fd: c_int) {
|
||||
use libc::{fcntl, F_GETFL, F_SETFL, O_NONBLOCK};
|
||||
|
||||
let res = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
|
||||
let res = unsafe { fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK) };
|
||||
assert_eq!(res, 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use std::sync::{Arc, Mutex};
|
|||
use std::task::{Context, Poll, Wake, Waker};
|
||||
use std::{io, thread};
|
||||
|
||||
use piper::{pipe, Reader, Writer};
|
||||
use piper::{Reader, Writer, pipe};
|
||||
use polling::os::iocp::{CompletionPacket, PollerIocpExt};
|
||||
use polling::{Event, PollMode, Poller};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@ use std::io::Error;
|
|||
use std::num::NonZeroU32;
|
||||
use std::ptr;
|
||||
use std::sync::atomic::{AtomicPtr, Ordering};
|
||||
use std::sync::{mpsc, Arc, Mutex};
|
||||
use std::sync::{Arc, Mutex, mpsc};
|
||||
|
||||
use polling::os::iocp::{CompletionPacket, PollerIocpExt};
|
||||
use polling::{Event, Poller};
|
||||
|
||||
use windows_sys::Win32::Foundation::{BOOLEAN, FALSE, HANDLE};
|
||||
use windows_sys::Win32::System::Threading::{
|
||||
GetExitCodeProcess, GetProcessId, RegisterWaitForSingleObject, UnregisterWait, INFINITE,
|
||||
GetExitCodeProcess, GetProcessId, INFINITE, RegisterWaitForSingleObject, UnregisterWait,
|
||||
WT_EXECUTEINWAITTHREAD, WT_EXECUTEONLYONCE,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -6,25 +6,25 @@ use std::os::windows::ffi::OsStrExt;
|
|||
use std::os::windows::io::IntoRawHandle;
|
||||
use std::{mem, ptr};
|
||||
|
||||
use windows_sys::core::{HRESULT, PWSTR};
|
||||
use windows_sys::Win32::Foundation::{HANDLE, S_OK};
|
||||
use windows_sys::Win32::System::Console::{
|
||||
ClosePseudoConsole, CreatePseudoConsole, ResizePseudoConsole, COORD, HPCON,
|
||||
COORD, ClosePseudoConsole, CreatePseudoConsole, HPCON, ResizePseudoConsole,
|
||||
};
|
||||
use windows_sys::Win32::System::LibraryLoader::{GetProcAddress, LoadLibraryW};
|
||||
use windows_sys::core::{HRESULT, PWSTR};
|
||||
use windows_sys::{s, w};
|
||||
|
||||
use windows_sys::Win32::System::Threading::{
|
||||
CreateProcessW, InitializeProcThreadAttributeList, UpdateProcThreadAttribute,
|
||||
CREATE_UNICODE_ENVIRONMENT, EXTENDED_STARTUPINFO_PRESENT, PROCESS_INFORMATION,
|
||||
PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, STARTF_USESTDHANDLES, STARTUPINFOEXW, STARTUPINFOW,
|
||||
CREATE_UNICODE_ENVIRONMENT, CreateProcessW, EXTENDED_STARTUPINFO_PRESENT,
|
||||
InitializeProcThreadAttributeList, PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, PROCESS_INFORMATION,
|
||||
STARTF_USESTDHANDLES, STARTUPINFOEXW, STARTUPINFOW, UpdateProcThreadAttribute,
|
||||
};
|
||||
|
||||
use crate::event::{OnResize, WindowSize};
|
||||
use crate::tty::Options;
|
||||
use crate::tty::windows::blocking::{UnblockedReader, UnblockedWriter};
|
||||
use crate::tty::windows::child::ChildExitWatcher;
|
||||
use crate::tty::windows::{cmdline, win32_string, Pty};
|
||||
use crate::tty::Options;
|
||||
use crate::tty::windows::{Pty, cmdline, win32_string};
|
||||
|
||||
const PIPE_CAPACITY: usize = crate::event_loop::READ_BUFFER_SIZE;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ use std::ffi::OsStr;
|
|||
use std::io::{self, Result};
|
||||
use std::iter::once;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
use std::sync::mpsc::TryRecvError;
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc::TryRecvError;
|
||||
|
||||
use crate::event::{OnResize, WindowSize};
|
||||
use crate::tty::windows::child::ChildExitWatcher;
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ use serde::{Deserialize, Serialize};
|
|||
use crate::event::EventListener;
|
||||
use crate::grid::{Dimensions, GridCell};
|
||||
use crate::index::{Boundary, Column, Direction, Line, Point, Side};
|
||||
use crate::term::cell::Flags;
|
||||
use crate::term::Term;
|
||||
use crate::term::cell::Flags;
|
||||
|
||||
/// Possible vi mode motion movements.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
|
|
@ -251,17 +251,19 @@ fn first_occupied<T>(term: &Term<T>, mut point: Point) -> Point {
|
|||
|
||||
// Fallback to the next non-empty cell.
|
||||
let mut line = point.line;
|
||||
occupied.unwrap_or_else(|| loop {
|
||||
if let Some(occupied) = first_occupied_in_line(term, line) {
|
||||
break occupied;
|
||||
}
|
||||
occupied.unwrap_or_else(|| {
|
||||
loop {
|
||||
if let Some(occupied) = first_occupied_in_line(term, line) {
|
||||
break occupied;
|
||||
}
|
||||
|
||||
let last_cell = Point::new(line, last_column);
|
||||
if !is_wrap(term, last_cell) {
|
||||
break last_cell;
|
||||
}
|
||||
let last_cell = Point::new(line, last_column);
|
||||
if !is_wrap(term, last_cell) {
|
||||
break last_cell;
|
||||
}
|
||||
|
||||
line += 1;
|
||||
line += 1;
|
||||
}
|
||||
})
|
||||
} else {
|
||||
occupied
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ macro_rules! ref_tests {
|
|||
ref_test(&test_path);
|
||||
}
|
||||
)*
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ref_tests! {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue