mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-21 16:02:20 +00:00
style: run rustfmt over the branch
CI runs `cargo fmt --check` and I had not run it once across this branch, while making most edits by inserting text rather than writing it. 27 files were non-conformant; `origin/main` is clean, so all of it is mine and CI would have failed on the first push. No behaviour change — the suite is identical either side of it. Also checked clippy the way CI does, `--locked --workspace --all-targets -D warnings`, which is stricter than the invocation I had been using.
This commit is contained in:
@@ -65,8 +65,9 @@ pub fn parse_tab(s: &str) -> Result<TabAddress> {
|
||||
// handed back has to address the tab it created. Demanding the sigil made
|
||||
// the one id you are certain of the one shape the CLI refused.
|
||||
let body = s.strip_prefix('@').unwrap_or(s);
|
||||
let not_an_address =
|
||||
|| anyhow!("'{s}' is not a tab address — @7 as numbered by `tty7 tab ls`, or a full tab id");
|
||||
let not_an_address = || {
|
||||
anyhow!("'{s}' is not a tab address — @7 as numbered by `tty7 tab ls`, or a full tab id")
|
||||
};
|
||||
if body.is_empty() {
|
||||
return Err(not_an_address());
|
||||
}
|
||||
@@ -165,14 +166,19 @@ mod tests {
|
||||
);
|
||||
}
|
||||
if file == "cli.rs" {
|
||||
assert!(found >= 3, "{file}: expected the three tab-address helps, found {found}");
|
||||
assert!(
|
||||
found >= 3,
|
||||
"{file}: expected the three tab-address helps, found {found}"
|
||||
);
|
||||
} else {
|
||||
assert!(found >= 1, "{file}: expected a message about @ numbers, found {found}");
|
||||
assert!(
|
||||
found >= 1,
|
||||
"{file}: expected a message about @ numbers, found {found}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
use super::*;
|
||||
|
||||
fn shell_context() -> Context {
|
||||
|
||||
@@ -1144,10 +1144,7 @@ fn pane_close(
|
||||
/// listing counts it, and the doctor's row names it and points at the reaper —
|
||||
/// so they cannot be allowed to drift. A row that says seven and a reaper that
|
||||
/// ends none is a worse answer than either alone.
|
||||
fn is_stray(
|
||||
info: &tty7_core::daemon::protocol::PaneInfo,
|
||||
held: impl Fn(u64) -> bool,
|
||||
) -> bool {
|
||||
fn is_stray(info: &tty7_core::daemon::protocol::PaneInfo, held: impl Fn(u64) -> bool) -> bool {
|
||||
!info.attached && !held(info.pane_id)
|
||||
}
|
||||
|
||||
@@ -1809,7 +1806,9 @@ fn doctor(ctx: &Context, backend: &mut dyn Backend) -> Result<Outcome> {
|
||||
let loaded = tty7_core::core::config::Config::load_with_outcome();
|
||||
let (config_state, config_ok) = match loaded.1 {
|
||||
tty7_core::core::config::LoadOutcome::Parsed => ("ok".to_string(), true),
|
||||
tty7_core::core::config::LoadOutcome::Absent => ("none yet — the defaults are the config".to_string(), true),
|
||||
tty7_core::core::config::LoadOutcome::Absent => {
|
||||
("none yet — the defaults are the config".to_string(), true)
|
||||
}
|
||||
tty7_core::core::config::LoadOutcome::Quarantined => {
|
||||
// What failed and where, not just that something did. serde
|
||||
// already names the field, the type it wanted and the line and
|
||||
@@ -1832,8 +1831,7 @@ fn doctor(ctx: &Context, backend: &mut dyn Backend) -> Result<Outcome> {
|
||||
)
|
||||
}
|
||||
tty7_core::core::config::LoadOutcome::Unreadable => (
|
||||
"UNREADABLE — running on defaults and not saving"
|
||||
.to_string(),
|
||||
"UNREADABLE — running on defaults and not saving".to_string(),
|
||||
false,
|
||||
),
|
||||
};
|
||||
@@ -4922,7 +4920,11 @@ mod tests {
|
||||
.filter(|p| p["orphan"] == serde_json::json!(true))
|
||||
.map(|p| p["pane"].as_u64().expect("an id"))
|
||||
.collect();
|
||||
assert_eq!(flagged, vec![78], "only the pane nobody is watching is flagged");
|
||||
assert_eq!(
|
||||
flagged,
|
||||
vec![78],
|
||||
"only the pane nobody is watching is flagged"
|
||||
);
|
||||
assert_eq!(
|
||||
listed["orphans"].as_u64(),
|
||||
Some(flagged.len() as u64),
|
||||
@@ -5080,7 +5082,9 @@ mod tests {
|
||||
const DOC: &str = include_str!("../../../docs/cli/reference.mdx");
|
||||
|
||||
let lead = "JSON: `{\"context\":";
|
||||
let at = DOC.find(lead).expect("the reference documents doctor's JSON");
|
||||
let at = DOC
|
||||
.find(lead)
|
||||
.expect("the reference documents doctor's JSON");
|
||||
let line = &DOC[at..at + DOC[at..].find('\n').expect("the line ends")];
|
||||
let documented: Vec<&str> = line
|
||||
.split('"')
|
||||
|
||||
@@ -491,11 +491,7 @@ impl<'a> HookTarget<'a> {
|
||||
if let Some(exe) = self.hook_command_exe() {
|
||||
return format!("{exe} agent-hook {} {event}", agent.slug());
|
||||
}
|
||||
format!(
|
||||
"{} agent-hook {} {event}",
|
||||
self.quoted_exe(),
|
||||
agent.slug()
|
||||
)
|
||||
format!("{} agent-hook {} {event}", self.quoted_exe(), agent.slug())
|
||||
}
|
||||
|
||||
/// The executable path, quoted for whichever shell is going to re-read it.
|
||||
@@ -1822,9 +1818,9 @@ mod tests {
|
||||
let end = body.find("\n}\n").expect("the entry point ends");
|
||||
let body = &body[..end];
|
||||
|
||||
let gate = body
|
||||
.find("TTY7_ENV_MARKER")
|
||||
.unwrap_or_else(|| panic!("`run_agent_hook` no longer checks {TTY7_ENV_MARKER}: {body}"));
|
||||
let gate = body.find("TTY7_ENV_MARKER").unwrap_or_else(|| {
|
||||
panic!("`run_agent_hook` no longer checks {TTY7_ENV_MARKER}: {body}")
|
||||
});
|
||||
assert!(
|
||||
body[gate..].contains("return"),
|
||||
"the marker is named but nothing returns on it: {body}"
|
||||
@@ -1872,10 +1868,16 @@ mod tests {
|
||||
}
|
||||
|
||||
fn walk(d: &Path, out: &mut Vec<PathBuf>) {
|
||||
let Ok(entries) = std::fs::read_dir(d) else { return };
|
||||
let Ok(entries) = std::fs::read_dir(d) else {
|
||||
return;
|
||||
};
|
||||
for e in entries.flatten() {
|
||||
let p = e.path();
|
||||
if p.is_dir() { walk(&p, out) } else { out.push(p) }
|
||||
if p.is_dir() {
|
||||
walk(&p, out)
|
||||
} else {
|
||||
out.push(p)
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut files = Vec::new();
|
||||
@@ -1891,13 +1893,21 @@ mod tests {
|
||||
.to_string()
|
||||
};
|
||||
for file in &files {
|
||||
let Ok(text) = std::fs::read_to_string(file) else { continue };
|
||||
let name = file.file_name().unwrap_or_default().to_string_lossy().into_owned();
|
||||
let Ok(text) = std::fs::read_to_string(file) else {
|
||||
continue;
|
||||
};
|
||||
let name = file
|
||||
.file_name()
|
||||
.unwrap_or_default()
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
for line in text.lines() {
|
||||
// Every bridge explains itself in comments that spell the
|
||||
// command out; that is prose, not a command line.
|
||||
let trimmed = line.trim_start();
|
||||
if trimmed.starts_with("//") || trimmed.starts_with("/*") || trimmed.starts_with('#')
|
||||
if trimmed.starts_with("//")
|
||||
|| trimmed.starts_with("/*")
|
||||
|| trimmed.starts_with('#')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -2113,8 +2123,7 @@ mod tests {
|
||||
format!("{command_exe} agent-hook claude stop")
|
||||
);
|
||||
assert!(
|
||||
command_exe.contains(&exe.display().to_string())
|
||||
|| here.hook_command_exe().is_some(),
|
||||
command_exe.contains(&exe.display().to_string()) || here.hook_command_exe().is_some(),
|
||||
"the full path is in there unless it resolved by name"
|
||||
);
|
||||
}
|
||||
@@ -2689,5 +2698,3 @@ mod tests {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1138,8 +1138,16 @@ mod tests {
|
||||
// naive rule, and a recent leap day.
|
||||
assert_eq!(days_from_civil(1970, 1, 1), 0, "the epoch is day zero");
|
||||
assert_eq!(days_from_civil(1969, 12, 31), -1, "and the day before it");
|
||||
assert_eq!(days_in_month(2000, 2), 29, "2000 is a leap year: divisible by 400");
|
||||
assert_eq!(days_in_month(1900, 2), 28, "1900 is not: divisible by 100, not 400");
|
||||
assert_eq!(
|
||||
days_in_month(2000, 2),
|
||||
29,
|
||||
"2000 is a leap year: divisible by 400"
|
||||
);
|
||||
assert_eq!(
|
||||
days_in_month(1900, 2),
|
||||
28,
|
||||
"1900 is not: divisible by 100, not 400"
|
||||
);
|
||||
assert_eq!(days_in_month(2024, 2), 29);
|
||||
assert_eq!(days_in_month(2023, 2), 28);
|
||||
|
||||
@@ -1172,7 +1180,11 @@ mod tests {
|
||||
// leap year, so 200 years hold 49 + 1 = 48 ordinary leap years plus
|
||||
// 2000 itself.
|
||||
assert_eq!(leap_days, 49, "two centuries hold 49 leap days here");
|
||||
assert_eq!(days_in_month(2024, 13), 0, "a month out of range has no days");
|
||||
assert_eq!(
|
||||
days_in_month(2024, 13),
|
||||
0,
|
||||
"a month out of range has no days"
|
||||
);
|
||||
assert_eq!(days_in_month(2024, 0), 0);
|
||||
}
|
||||
|
||||
@@ -1195,7 +1207,10 @@ mod tests {
|
||||
|
||||
let (mut y, mut m, mut d) = (1900i64, 1u32, 1u32);
|
||||
let mut days = days_from_civil(1900, 1, 1);
|
||||
assert!(days < 0, "the walk has to start before the epoch to exercise it");
|
||||
assert!(
|
||||
days < 0,
|
||||
"the walk has to start before the epoch to exercise it"
|
||||
);
|
||||
let mut checked = 0usize;
|
||||
while y < 2100 {
|
||||
assert_eq!(
|
||||
@@ -1223,7 +1238,10 @@ mod tests {
|
||||
}
|
||||
// 200 x 365 + 49 leap days: every fourth year from 1904 to 2096, less
|
||||
// 1900, plus 2000. The same 49 the walk above counts.
|
||||
assert_eq!(checked, 73_049, "two centuries of days, 1900-01-01 to 2099-12-31");
|
||||
assert_eq!(
|
||||
checked, 73_049,
|
||||
"two centuries of days, 1900-01-01 to 2099-12-31"
|
||||
);
|
||||
}
|
||||
|
||||
fn commit(sha: &str, parents: &[&str]) -> (Oid, SmallVec<[Oid; 2]>) {
|
||||
@@ -1306,7 +1324,10 @@ mod tests {
|
||||
struct Lcg(u64);
|
||||
impl Lcg {
|
||||
fn n(&mut self, m: usize) -> usize {
|
||||
self.0 = self.0.wrapping_mul(6364136223846793005).wrapping_add(1442695040888963407);
|
||||
self.0 = self
|
||||
.0
|
||||
.wrapping_mul(6364136223846793005)
|
||||
.wrapping_add(1442695040888963407);
|
||||
((self.0 >> 33) as usize) % m.max(1)
|
||||
}
|
||||
}
|
||||
@@ -1318,7 +1339,11 @@ mod tests {
|
||||
let mut page = Vec::with_capacity(n);
|
||||
for i in 0..n {
|
||||
let remaining = n - i - 1;
|
||||
let want = if remaining == 0 { 0 } else { 1 + r.n(max_parents) };
|
||||
let want = if remaining == 0 {
|
||||
0
|
||||
} else {
|
||||
1 + r.n(max_parents)
|
||||
};
|
||||
let mut ps: SmallVec<[Oid; 2]> = SmallVec::new();
|
||||
for _ in 0..want.min(remaining) {
|
||||
let p = i + 1 + r.n(remaining);
|
||||
@@ -1350,12 +1375,18 @@ mod tests {
|
||||
parents.len().min(u8::MAX as usize),
|
||||
"seed {seed} row {i}: parent count"
|
||||
);
|
||||
let outs = row.edges.iter().filter(|e| matches!(e, Edge::Out { .. })).count();
|
||||
let outs = row
|
||||
.edges
|
||||
.iter()
|
||||
.filter(|e| matches!(e, Edge::Out { .. }))
|
||||
.count();
|
||||
if parents.is_empty() {
|
||||
assert_eq!(outs, 0, "seed {seed} row {i}: a root must not send an Out");
|
||||
}
|
||||
assert!(
|
||||
!row.edges.iter().any(|e| matches!(*e, Edge::Pass { lane, .. } if lane == row.node)),
|
||||
!row.edges
|
||||
.iter()
|
||||
.any(|e| matches!(*e, Edge::Pass { lane, .. } if lane == row.node)),
|
||||
"seed {seed} row {i}: a Pass crosses the row's own node lane: {row:?}"
|
||||
);
|
||||
}
|
||||
@@ -1376,7 +1407,10 @@ mod tests {
|
||||
let mut alloc = LaneAlloc::new();
|
||||
alloc.push(&page[..cut], &mut split);
|
||||
alloc.push(&page[cut..], &mut split);
|
||||
assert_eq!(whole, split, "seed {seed}: page boundary at {cut} changed the layout");
|
||||
assert_eq!(
|
||||
whole, split,
|
||||
"seed {seed}: page boundary at {cut} changed the layout"
|
||||
);
|
||||
assert_lanes_line_up(&split);
|
||||
}
|
||||
}
|
||||
@@ -2273,4 +2307,3 @@ mod tests {
|
||||
assert!(!page.complete, "five of the seven is not the whole history");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -123,10 +123,13 @@ impl GitignoreChain {
|
||||
/// in the ignore file is not worth an answer that cannot have moved.
|
||||
fn folds_case(&mut self, root: &Path) -> bool {
|
||||
*self.fold_case.entry(root.to_path_buf()).or_insert_with(|| {
|
||||
crate::core::git::git_output(root, &["config", "--type=bool", "--get", "core.ignorecase"])
|
||||
.ok()
|
||||
.filter(|out| out.success())
|
||||
.is_some_and(|out| String::from_utf8_lossy(&out.stdout).trim() == "true")
|
||||
crate::core::git::git_output(
|
||||
root,
|
||||
&["config", "--type=bool", "--get", "core.ignorecase"],
|
||||
)
|
||||
.ok()
|
||||
.filter(|out| out.success())
|
||||
.is_some_and(|out| String::from_utf8_lossy(&out.stdout).trim() == "true")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -356,5 +359,3 @@ mod tests {
|
||||
let _ = std::fs::remove_dir_all(&root);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1796,7 +1796,10 @@ mod tests {
|
||||
|
||||
// The fifo is not in the sender's gift to delete either — the temp-dir
|
||||
// check allows it here, but a refused read must not have unlinked it.
|
||||
assert!(fifo.exists(), "a refused transfer should leave the path alone");
|
||||
assert!(
|
||||
fifo.exists(),
|
||||
"a refused transfer should leave the path alone"
|
||||
);
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
@@ -1850,7 +1853,9 @@ mod tests {
|
||||
|
||||
let precious = dir.join("id_ed25519");
|
||||
std::fs::write(&precious, [0u8, 1, 2, 3, 4, 5, 6, 7]).unwrap();
|
||||
let img = temp_file_transfer(&precious).resolve().expect("still reads");
|
||||
let img = temp_file_transfer(&precious)
|
||||
.resolve()
|
||||
.expect("still reads");
|
||||
assert_eq!(img.data.len(), 8);
|
||||
assert!(
|
||||
precious.exists(),
|
||||
|
||||
@@ -1832,7 +1832,10 @@ mod tests {
|
||||
let lead = "`delta` is externally tagged the same way. The kinds are";
|
||||
// From *after* the lead, so the sentence's own `delta` is not read as
|
||||
// one of the kinds it introduces.
|
||||
let at = DOC.find(lead).expect("the reference still enumerates the kinds") + lead.len();
|
||||
let at = DOC
|
||||
.find(lead)
|
||||
.expect("the reference still enumerates the kinds")
|
||||
+ lead.len();
|
||||
let listed = &DOC[at..at + DOC[at..].find(".\n\n").expect("the sentence ends")];
|
||||
let named: Vec<&str> = listed
|
||||
.split('`')
|
||||
@@ -1841,7 +1844,10 @@ mod tests {
|
||||
.filter(|t| t.chars().all(|c| c.is_ascii_lowercase() || c == '_'))
|
||||
.collect();
|
||||
|
||||
let missing: Vec<&String> = variants.iter().filter(|v| !named.contains(&v.as_str())).collect();
|
||||
let missing: Vec<&String> = variants
|
||||
.iter()
|
||||
.filter(|v| !named.contains(&v.as_str()))
|
||||
.collect();
|
||||
assert!(
|
||||
missing.is_empty(),
|
||||
"these layout deltas reach `tty7 events` with nothing in \
|
||||
@@ -2387,10 +2393,10 @@ mod tests {
|
||||
#[test]
|
||||
fn emptying_a_tab_moves_the_active_mark_and_announces_it() {
|
||||
let (store, _dir, ws, first) = store_with_tab();
|
||||
let second = store.tab_create(ws, None, seed(9, "/b"), None, None).unwrap();
|
||||
store
|
||||
.workspace_set_active_tab(ws, second.id, None)
|
||||
let second = store
|
||||
.tab_create(ws, None, seed(9, "/b"), None, None)
|
||||
.unwrap();
|
||||
store.workspace_set_active_tab(ws, second.id, None).unwrap();
|
||||
assert_eq!(store.workspace(ws).unwrap().active_tab, Some(second.id));
|
||||
|
||||
// Closing the second tab's only pane takes the tab with it.
|
||||
@@ -2431,7 +2437,12 @@ mod tests {
|
||||
let dropped = store.pane_close(ws, 2, None).unwrap();
|
||||
assert_eq!(dropped, vec![2], "the caller is told to hang it up");
|
||||
assert_eq!(
|
||||
store.machine().panes.iter().map(|p| p.id).collect::<Vec<_>>(),
|
||||
store
|
||||
.machine()
|
||||
.panes
|
||||
.iter()
|
||||
.map(|p| p.id)
|
||||
.collect::<Vec<_>>(),
|
||||
vec![1],
|
||||
"and the record goes with it, or it is an orphan on every later look"
|
||||
);
|
||||
|
||||
@@ -1467,7 +1467,9 @@ mod tests {
|
||||
loop {
|
||||
let e = rest.find("\npub enum ");
|
||||
let t = rest.find("\npub struct ");
|
||||
let Some(at) = [e, t].into_iter().flatten().min() else { break };
|
||||
let Some(at) = [e, t].into_iter().flatten().min() else {
|
||||
break;
|
||||
};
|
||||
rest = &rest[at + 1..];
|
||||
let Some(open) = rest.find('{') else { break };
|
||||
let name: String = rest[..open]
|
||||
@@ -3146,5 +3148,3 @@ mod tests {
|
||||
assert!(!client.is_connected());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -353,7 +353,10 @@ mod tests {
|
||||
"cd /\n",
|
||||
"the window's own history file is not the daemon's to move"
|
||||
);
|
||||
assert!(!dir.exists(), "and nothing should have appeared at the new name");
|
||||
assert!(
|
||||
!dir.exists(),
|
||||
"and nothing should have appeared at the new name"
|
||||
);
|
||||
|
||||
let (displaced, dir) = case("both");
|
||||
std::fs::create_dir_all(&displaced).unwrap();
|
||||
|
||||
@@ -12,12 +12,12 @@ use portable_pty::{Child, CommandBuilder, MasterPty, PtySize, native_pty_system}
|
||||
use crate::core::kitty_graphics::{GraphicsSniffer, Segment, Sniffed};
|
||||
use crate::core::osc::OscTokenizer;
|
||||
use crate::core::shells::program_problem as shell_program_problem;
|
||||
use crate::core::threads::Locked as _;
|
||||
use crate::daemon::protocol::{
|
||||
AuthResponse, DaemonMsg, MAX_FRAME, NativeSshSpec, PaneInfo, RemoteContext, RemoteKind,
|
||||
ShellSpec, WinSize,
|
||||
};
|
||||
use crate::daemon::shell_integration;
|
||||
use crate::core::threads::Locked as _;
|
||||
|
||||
#[cfg(windows)]
|
||||
fn default_prog() -> CommandBuilder {
|
||||
|
||||
@@ -1576,7 +1576,10 @@ mod tests {
|
||||
let mut rest = &body[..end];
|
||||
while let Some(at) = rest.find(&needle) {
|
||||
rest = &rest[at + needle.len()..];
|
||||
let name: String = rest.chars().take_while(|c| c.is_ascii_alphanumeric()).collect();
|
||||
let name: String = rest
|
||||
.chars()
|
||||
.take_while(|c| c.is_ascii_alphanumeric())
|
||||
.collect();
|
||||
if !name.is_empty() {
|
||||
out.push(name);
|
||||
}
|
||||
|
||||
@@ -4,11 +4,11 @@ use std::sync::atomic::{AtomicU64, Ordering};
|
||||
use std::sync::mpsc::{self, Receiver};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use crate::core::threads::Locked as _;
|
||||
use crate::daemon::pane::DaemonPane;
|
||||
use crate::daemon::protocol::{ClientMsg, DaemonMsg, DaemonVersion, RemoteKind};
|
||||
use crate::daemon::ssh::SshConnection;
|
||||
use crate::daemon::transport::{self, Stream};
|
||||
use crate::core::threads::Locked as _;
|
||||
|
||||
struct Registry {
|
||||
panes: Mutex<HashMap<u64, Arc<DaemonPane>>>,
|
||||
@@ -697,10 +697,7 @@ fn raise_open_file_limit() {
|
||||
rlim_max: limit.rlim_max,
|
||||
};
|
||||
if unsafe { libc::setrlimit(libc::RLIMIT_NOFILE, &raised) } == 0 {
|
||||
log::debug!(
|
||||
"open-file limit raised from {} to {want}",
|
||||
limit.rlim_cur
|
||||
);
|
||||
log::debug!("open-file limit raised from {} to {want}", limit.rlim_cur);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3441,4 +3441,3 @@ mod tests {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ use std::time::Duration;
|
||||
|
||||
use tokio::sync::oneshot;
|
||||
|
||||
use crate::daemon::protocol::{AuthPromptKind, AuthResponse, DaemonMsg, SshPhase};
|
||||
use crate::core::threads::Locked as _;
|
||||
use crate::daemon::protocol::{AuthPromptKind, AuthResponse, DaemonMsg, SshPhase};
|
||||
|
||||
const PROMPT_TIMEOUT: Duration = Duration::from_secs(120);
|
||||
const DELIVERY_WINDOW: Duration = Duration::from_secs(15);
|
||||
|
||||
@@ -108,9 +108,7 @@ impl ClientHandler {
|
||||
// `record_trusted` drops the line this key supersedes before adding it,
|
||||
// and adds nothing if that drop fails — see its comment for why the
|
||||
// order is not optional.
|
||||
if remember
|
||||
&& let Err(e) = known_hosts::record_trusted(&self.host, self.port, key)
|
||||
{
|
||||
if remember && let Err(e) = known_hosts::record_trusted(&self.host, self.port, key) {
|
||||
log::warn!("not recording host key in known_hosts: {e}");
|
||||
}
|
||||
true
|
||||
|
||||
@@ -31,10 +31,10 @@ use crate::daemon::remote_link::{self, RemoteEntry, RemoteLink};
|
||||
use crate::daemon::router::{RouteChannel, RouteSetup};
|
||||
use crate::daemon::shell_integration::remote;
|
||||
|
||||
use crate::core::threads::Locked as _;
|
||||
use forward::RemoteForwardTable;
|
||||
use handler::ClientHandler;
|
||||
use session::drive_channel;
|
||||
use crate::core::threads::Locked as _;
|
||||
|
||||
const DEFAULT_CONNECT_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
|
||||
@@ -955,7 +955,11 @@ mod tests {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
assert_eq!(said.trim(), "tty7-live-check", "the far side ran it and answered");
|
||||
assert_eq!(
|
||||
said.trim(),
|
||||
"tty7-live-check",
|
||||
"the far side ran it and answered"
|
||||
);
|
||||
assert_eq!(code, Some(0), "and said how it went");
|
||||
|
||||
// The second ask has to come back on the same connection: sharing
|
||||
@@ -964,7 +968,10 @@ mod tests {
|
||||
.open_connection(&spec, &broker)
|
||||
.await
|
||||
.expect("a second connection to the same host");
|
||||
assert!(reused, "the second ask should have been given the first one");
|
||||
assert!(
|
||||
reused,
|
||||
"the second ask should have been given the first one"
|
||||
);
|
||||
assert_eq!(again.key(), conn.key());
|
||||
|
||||
conn.mark_dead();
|
||||
|
||||
@@ -315,8 +315,14 @@ fn awkward_text_survives_the_pty_and_the_ring_unchanged() {
|
||||
("a CJK pair", &b"cjk:\xe4\xbd\xa0\xe5\xa5\xbd|"[..]),
|
||||
("a decomposed accent", &b"dec:e\xcc\x81|"[..]),
|
||||
("a precomposed accent", &b"pre:\xc3\xa9|"[..]),
|
||||
("a regional-indicator flag", &b"flag:\xf0\x9f\x87\xaf\xf0\x9f\x87\xb5|"[..]),
|
||||
("a ZWJ sequence", &b"zwj:\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x92\xbb|"[..]),
|
||||
(
|
||||
"a regional-indicator flag",
|
||||
&b"flag:\xf0\x9f\x87\xaf\xf0\x9f\x87\xb5|"[..],
|
||||
),
|
||||
(
|
||||
"a ZWJ sequence",
|
||||
&b"zwj:\xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x92\xbb|"[..],
|
||||
),
|
||||
] {
|
||||
assert!(
|
||||
windows_contain(&seen, bytes),
|
||||
|
||||
@@ -1094,15 +1094,14 @@ mod tests {
|
||||
.collect();
|
||||
assert_eq!(
|
||||
kept,
|
||||
vec![(9000, "localhost".to_string(), 90), (1080, String::new(), 0)],
|
||||
vec![
|
||||
(9000, "localhost".to_string(), 90),
|
||||
(1080, String::new(), 0)
|
||||
],
|
||||
"the forwards that fit a host and a port still come across whole"
|
||||
);
|
||||
|
||||
let named: Vec<&str> = report
|
||||
.ignored
|
||||
.iter()
|
||||
.map(|i| i.option.as_str())
|
||||
.collect();
|
||||
let named: Vec<&str> = report.ignored.iter().map(|i| i.option.as_str()).collect();
|
||||
assert!(
|
||||
named.contains(&"LocalForward") && named.contains(&"RemoteForward"),
|
||||
"the four that were dropped have to appear in the report, spelled as \
|
||||
@@ -1707,4 +1706,3 @@ mod tests {
|
||||
crate::testutil::temp_root(&format!("ssh-config-test-{name}"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -1437,7 +1437,9 @@ impl Tty7App {
|
||||
if let Some(app) = weak_app.upgrade()
|
||||
&& let Some((tab, name)) = app.read(cx).unsaved_edit_to_confirm()
|
||||
{
|
||||
app.update(cx, |app, cx| app.confirm_window_close(tab, name, window, cx));
|
||||
app.update(cx, |app, cx| {
|
||||
app.confirm_window_close(tab, name, window, cx)
|
||||
});
|
||||
return false;
|
||||
}
|
||||
let last_window = crate::ui::windows::WindowRegistry::count(cx) <= 1;
|
||||
|
||||
+21
-10
@@ -1807,10 +1807,14 @@ mod unsaved_close_gpui_tests {
|
||||
input.update(cx, |state, cx| state.insert("three\n", window, cx));
|
||||
let saved = to_crlf(&input.read(cx).text().to_string());
|
||||
assert!(
|
||||
!saved.contains("\n") || saved.split("\n").count() - 1 == saved.matches("\r\n").count(),
|
||||
!saved.contains("\n")
|
||||
|| saved.split("\n").count() - 1 == saved.matches("\r\n").count(),
|
||||
"a bare newline survived into a CRLF file: {saved:?}"
|
||||
);
|
||||
assert!(saved.contains("three\r\n"), "the added line is there: {saved:?}");
|
||||
assert!(
|
||||
saved.contains("three\r\n"),
|
||||
"the added line is there: {saved:?}"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1822,7 +1826,10 @@ mod unsaved_close_gpui_tests {
|
||||
let input = new_buffer("one\ntwo\n", window, cx);
|
||||
input.update(cx, |state, cx| state.insert("three\n", window, cx));
|
||||
let text = input.read(cx).text().to_string();
|
||||
assert!(!uniformly_crlf("one\ntwo\n"), "a unix file is not a crlf one");
|
||||
assert!(
|
||||
!uniformly_crlf("one\ntwo\n"),
|
||||
"a unix file is not a crlf one"
|
||||
);
|
||||
assert!(!text.contains('\r'), "a carriage return appeared: {text:?}");
|
||||
});
|
||||
}
|
||||
@@ -1832,7 +1839,10 @@ mod unsaved_close_gpui_tests {
|
||||
fn a_mixed_file_is_not_given_a_winner() {
|
||||
assert!(!uniformly_crlf("a\r\nb\n"), "mixed endings are not CRLF");
|
||||
assert!(!uniformly_crlf("a\nb\r\n"), "in either order");
|
||||
assert!(!uniformly_crlf("no newline at all"), "and neither is a single line");
|
||||
assert!(
|
||||
!uniformly_crlf("no newline at all"),
|
||||
"and neither is a single line"
|
||||
);
|
||||
assert!(uniformly_crlf("a\r\n"), "one CRLF line is a CRLF file");
|
||||
}
|
||||
|
||||
@@ -1918,7 +1928,10 @@ mod unsaved_close_gpui_tests {
|
||||
let (tab, name) = app
|
||||
.unsaved_edit_to_confirm()
|
||||
.expect("the window is holding an unwritten buffer");
|
||||
assert_eq!(tab, 1, "and it names the tab holding it, not the active one");
|
||||
assert_eq!(
|
||||
tab, 1,
|
||||
"and it names the tab holding it, not the active one"
|
||||
);
|
||||
assert_eq!(name, "notes.md");
|
||||
});
|
||||
}
|
||||
@@ -1931,9 +1944,7 @@ mod unsaved_close_gpui_tests {
|
||||
/// is the same as no guard — and one wired wrongly is worse: a window
|
||||
/// that will not shut.
|
||||
#[gpui::test]
|
||||
fn the_window_close_callback_refuses_only_when_something_is_unwritten(
|
||||
cx: &mut TestAppContext,
|
||||
) {
|
||||
fn the_window_close_callback_refuses_only_when_something_is_unwritten(cx: &mut TestAppContext) {
|
||||
cx.update(crate::ui::windows::WindowRegistry::init);
|
||||
|
||||
let (app, mut vcx, _streams) = harness_with_tabs(cx, 2);
|
||||
@@ -2022,8 +2033,8 @@ mod unsaved_close_gpui_tests {
|
||||
});
|
||||
|
||||
cx.update(|cx| {
|
||||
let (found_ws, tab, name) =
|
||||
crate::ui::app::Tty7App::quit_loses_unwritten_work(cx).expect("quitting would lose it");
|
||||
let (found_ws, tab, name) = crate::ui::app::Tty7App::quit_loses_unwritten_work(cx)
|
||||
.expect("quitting would lose it");
|
||||
assert_eq!(found_ws, ws, "the window holding it, not the one in front");
|
||||
assert_eq!(tab, 1, "and the tab holding it");
|
||||
assert_eq!(name, "notes.md");
|
||||
|
||||
+1
-3
@@ -963,9 +963,7 @@ pub fn translate_zh(key: L10nKey) -> Option<&'static str> {
|
||||
L10nKey::FileTreeDeleteFolderBody => {
|
||||
"该文件夹及其中的所有内容都将被删除。不会放入回收站,且无法撤销。"
|
||||
}
|
||||
L10nKey::FileTreeDeleteFileBody => {
|
||||
"该文件将被删除。不会放入回收站,且无法撤销。"
|
||||
}
|
||||
L10nKey::FileTreeDeleteFileBody => "该文件将被删除。不会放入回收站,且无法撤销。",
|
||||
L10nKey::SftpDeleteFolderBody => {
|
||||
"该文件夹及其中所有内容将在 {host} 上被删除。远端没有回收站。"
|
||||
}
|
||||
|
||||
+6
-4
@@ -40,8 +40,7 @@ pub fn init(cx: &mut App) {
|
||||
/// has no business knowing what a window is.
|
||||
pub(crate) fn install_relaunch_guard() {
|
||||
crate::core::update::set_relaunch_guard(Box::new(|cx, proceed| {
|
||||
let Some((workspace, tab, name)) =
|
||||
crate::ui::app::Tty7App::quit_loses_unwritten_work(cx)
|
||||
let Some((workspace, tab, name)) = crate::ui::app::Tty7App::quit_loses_unwritten_work(cx)
|
||||
else {
|
||||
proceed(cx);
|
||||
return;
|
||||
@@ -94,7 +93,8 @@ pub(crate) fn install_relaunch_guard() {
|
||||
/// more than one window is not the frontmost one. Answering it quits
|
||||
/// everything, which is what was asked for.
|
||||
fn quit_or_ask(cx: &mut App) {
|
||||
let Some((workspace, tab, name)) = crate::ui::app::Tty7App::quit_loses_unwritten_work(cx) else {
|
||||
let Some((workspace, tab, name)) = crate::ui::app::Tty7App::quit_loses_unwritten_work(cx)
|
||||
else {
|
||||
cx.quit();
|
||||
return;
|
||||
};
|
||||
@@ -1648,7 +1648,9 @@ mod tests {
|
||||
let body = &SRC[start..];
|
||||
let body = &body[..body.find("\n}\n").expect("the function ends")];
|
||||
|
||||
let fixed = body.find("bindings.extend(fixed_bindings())").expect("fixed");
|
||||
let fixed = body
|
||||
.find("bindings.extend(fixed_bindings())")
|
||||
.expect("fixed");
|
||||
let config = body
|
||||
.find("bindings.extend(action_bindings(")
|
||||
.expect("the config's own bindings");
|
||||
|
||||
@@ -558,7 +558,6 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
use tty7_core::core::machine::{Axis, PaneNode, PaneSeed, Tab, TabId};
|
||||
|
||||
use super::*;
|
||||
@@ -986,11 +985,14 @@ mod tests {
|
||||
let (first, second, third) = (leaf_tab(1), leaf_tab(2), leaf_tab(3));
|
||||
let (a, b, c) = (first.id, second.id, third.id);
|
||||
for (at, tab) in [(0, first), (1, second), (0, third)] {
|
||||
assert!(apply(&mut machine, id, &LayoutDelta::TabCreated { at, tab }));
|
||||
assert!(apply(
|
||||
&mut machine,
|
||||
id,
|
||||
&LayoutDelta::TabCreated { at, tab }
|
||||
));
|
||||
}
|
||||
let order = |m: &Machine| -> Vec<TabId> {
|
||||
m.workspaces[0].tabs.iter().map(|t| t.id).collect()
|
||||
};
|
||||
let order =
|
||||
|m: &Machine| -> Vec<TabId> { m.workspaces[0].tabs.iter().map(|t| t.id).collect() };
|
||||
assert_eq!(
|
||||
order(&machine),
|
||||
vec![c, a, b],
|
||||
@@ -1068,11 +1070,18 @@ mod tests {
|
||||
},
|
||||
};
|
||||
let tab_id = tab.id;
|
||||
assert!(apply(&mut machine, id, &LayoutDelta::TabCreated { at: 0, tab }));
|
||||
assert!(apply(
|
||||
&mut machine,
|
||||
id,
|
||||
&LayoutDelta::TabCreated { at: 0, tab }
|
||||
));
|
||||
|
||||
let ratios = |m: &Machine| -> (f32, f32) {
|
||||
let root = &m.workspaces[0].tabs[0].root;
|
||||
let PaneNode::Split { ratio: outer, b, .. } = root else {
|
||||
let PaneNode::Split {
|
||||
ratio: outer, b, ..
|
||||
} = root
|
||||
else {
|
||||
panic!("the root is a split")
|
||||
};
|
||||
let PaneNode::Split { ratio: inner, .. } = &**b else {
|
||||
@@ -1154,7 +1163,11 @@ mod tests {
|
||||
|
||||
let tab = leaf_tab(1);
|
||||
let only = tab.id;
|
||||
assert!(apply(&mut machine, id, &LayoutDelta::TabCreated { at: 0, tab }));
|
||||
assert!(apply(
|
||||
&mut machine,
|
||||
id,
|
||||
&LayoutDelta::TabCreated { at: 0, tab }
|
||||
));
|
||||
assert!(apply(
|
||||
&mut machine,
|
||||
id,
|
||||
@@ -1162,7 +1175,11 @@ mod tests {
|
||||
));
|
||||
assert_eq!(machine.workspaces[0].active_tab, Some(only));
|
||||
|
||||
assert!(apply(&mut machine, id, &LayoutDelta::TabClosed { tab: only }));
|
||||
assert!(apply(
|
||||
&mut machine,
|
||||
id,
|
||||
&LayoutDelta::TabClosed { tab: only }
|
||||
));
|
||||
assert!(machine.workspaces[0].tabs.is_empty());
|
||||
assert_eq!(
|
||||
machine.workspaces[0].active_tab, None,
|
||||
|
||||
+8
-3
@@ -1683,7 +1683,10 @@ mod tests {
|
||||
/// the stored one. After folding, both halves are on the row.
|
||||
#[test]
|
||||
fn a_commit_subject_carrying_control_characters_draws_on_one_row() {
|
||||
assert_eq!(row_subject("fix: something\rHIDDEN"), "fix: something HIDDEN");
|
||||
assert_eq!(
|
||||
row_subject("fix: something\rHIDDEN"),
|
||||
"fix: something HIDDEN"
|
||||
);
|
||||
assert_eq!(row_subject("feat:\tindented"), "feat: indented");
|
||||
assert_eq!(row_subject("chore: a\u{b}b\u{c}c"), "chore: a b c");
|
||||
assert_eq!(
|
||||
@@ -1696,11 +1699,13 @@ mod tests {
|
||||
// reason the fold happens before it rather than after.
|
||||
let folded = row_subject("fix: something\rHIDDEN");
|
||||
let (prefix, subject) = split_conventional(&folded);
|
||||
assert_eq!(prefix.map(|(p, breaking)| (p.to_string(), breaking)), Some(("fix".to_string(), false)));
|
||||
assert_eq!(
|
||||
prefix.map(|(p, breaking)| (p.to_string(), breaking)),
|
||||
Some(("fix".to_string(), false))
|
||||
);
|
||||
assert_eq!(subject, "something HIDDEN");
|
||||
}
|
||||
|
||||
|
||||
use super::*;
|
||||
use crate::ui::app::test_window::harness;
|
||||
use crate::ui::host_ops::HostId;
|
||||
|
||||
+24
-6
@@ -146,19 +146,37 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn split_display_path_separates_the_name_from_its_directory() {
|
||||
assert_eq!(split_display_path("src/ui/app.rs"), ("app.rs".to_string(), "src/ui".to_string()));
|
||||
assert_eq!(split_display_path("README.md"), ("README.md".to_string(), "".to_string()));
|
||||
assert_eq!(split_display_path("a/b"), ("b".to_string(), "a".to_string()));
|
||||
assert_eq!(
|
||||
split_display_path("src/ui/app.rs"),
|
||||
("app.rs".to_string(), "src/ui".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
split_display_path("README.md"),
|
||||
("README.md".to_string(), "".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
split_display_path("a/b"),
|
||||
("b".to_string(), "a".to_string())
|
||||
);
|
||||
assert_eq!(split_display_path(""), ("".to_string(), "".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn split_display_path_ignores_a_trailing_slash() {
|
||||
assert_eq!(split_display_path("src/ui/"), ("ui".to_string(), "src".to_string()));
|
||||
assert_eq!(split_display_path("src/"), ("src".to_string(), "".to_string()));
|
||||
assert_eq!(
|
||||
split_display_path("src/ui/"),
|
||||
("ui".to_string(), "src".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
split_display_path("src/"),
|
||||
("src".to_string(), "".to_string())
|
||||
);
|
||||
// A leading slash leaves an empty directory half rather than dropping
|
||||
// the root — the caller decides how to render that.
|
||||
assert_eq!(split_display_path("/etc"), ("etc".to_string(), "".to_string()));
|
||||
assert_eq!(
|
||||
split_display_path("/etc"),
|
||||
("etc".to_string(), "".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
+8
-2
@@ -216,7 +216,11 @@ pub(crate) struct OrphanPane {
|
||||
/// not empty itself when a window is busy.
|
||||
fn vouched_for_pane_ids(cx: &mut App) -> HashSet<u64> {
|
||||
let mut held = held_local_pane_ids(cx);
|
||||
held.extend(crate::ui::tree_sync::shown_pane_ids(cx).into_iter().flatten());
|
||||
held.extend(
|
||||
crate::ui::tree_sync::shown_pane_ids(cx)
|
||||
.into_iter()
|
||||
.flatten(),
|
||||
);
|
||||
held
|
||||
}
|
||||
|
||||
@@ -3456,7 +3460,9 @@ mod tests {
|
||||
});
|
||||
|
||||
// Whatever the harness put on screen is live and must not be offered.
|
||||
let shown = cx.update(crate::ui::tree_sync::shown_pane_ids).unwrap_or_default();
|
||||
let shown = cx
|
||||
.update(crate::ui::tree_sync::shown_pane_ids)
|
||||
.unwrap_or_default();
|
||||
assert!(!shown.is_empty(), "the harness window is showing panes");
|
||||
|
||||
let listed: Vec<PaneInfo> = shown
|
||||
|
||||
+7
-5
@@ -2583,8 +2583,8 @@ fn settle_hydration(
|
||||
state.said_why_empty = false;
|
||||
dirty
|
||||
};
|
||||
let Some(app) =
|
||||
crate::ui::windows::WindowRegistry::app_for(cx, client_ws).and_then(|app| app.upgrade())
|
||||
let Some(app) = crate::ui::windows::WindowRegistry::app_for(cx, client_ws)
|
||||
.and_then(|app| app.upgrade())
|
||||
else {
|
||||
break 'landed false;
|
||||
};
|
||||
@@ -2608,8 +2608,8 @@ fn settle_hydration(
|
||||
}
|
||||
if session.tabs.is_empty() && adopt == Adopt::IfEmpty {
|
||||
if was_dirty
|
||||
&& let Some(app) =
|
||||
crate::ui::windows::WindowRegistry::app_for(cx, client_ws).and_then(|a| a.upgrade())
|
||||
&& let Some(app) = crate::ui::windows::WindowRegistry::app_for(cx, client_ws)
|
||||
.and_then(|a| a.upgrade())
|
||||
{
|
||||
app.update(cx, |app, cx| sync_window(app, cx));
|
||||
}
|
||||
@@ -3268,7 +3268,9 @@ mod tests {
|
||||
.unwrap_or_default();
|
||||
assert_eq!(
|
||||
census,
|
||||
[7, 9].into_iter().collect::<std::collections::HashSet<u64>>(),
|
||||
[7, 9]
|
||||
.into_iter()
|
||||
.collect::<std::collections::HashSet<u64>>(),
|
||||
"every pane the window made, counted once"
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user