Collapse if-let nests into let-chains (MSRV-1.95 collapsible_if sweep)
Root cause of the CI Lint regression: commit 6113c53 bumped
rust-version 1.85 -> 1.95. clippy::collapsible_if is MSRV-gated —
collapsing `if let { if let }` needs let-chains, stabilized in Rust
1.95. At MSRV 1.85 clippy suppressed these; at 1.95 it emits them.
The patterns were pre-existing; the MSRV bump surfaced 47 of them
and turned `Lint (luajit)` / `Lint (lua54)` red at HEAD (was green
through PR #7; red from PR #8 = the release-prep MSRV bump).
Resolution (operator-chosen: autofix into let-chains): applied
`cargo clippy --fix` across the luajit, lua54, and crdt lanes
(--all-targets). The fix only applied with the lint at warn level;
`-- -D warnings` turns it into an error and blocks --fix.
Verified on the pinned 1.95.0, all three lanes:
clippy --all-targets -D warnings clean (luajit / lua54 / crdt);
fmt 0 diffs; lib tests 1223/0.
Note: the prior #6 "quiescent audit, clippy clean" was inaccurate —
clippy was not actually re-run there (build/version/fmt only), so
this MSRV-gated regression went uncaught until the live attach-debug
investigation surfaced it. This commit restores genuine clippy
cleanliness at MSRV 1.95.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
46aed3f393
commit
d3fa63290a
|
|
@ -669,10 +669,10 @@ impl AsyncRuntime {
|
|||
// a time keeps RefCell happy across re-entrant pending
|
||||
// borrows.
|
||||
let prior_id = self.supersede.borrow().get(key).copied();
|
||||
if let Some(prior) = prior_id {
|
||||
if let Some(job) = self.pending.borrow().get(&prior) {
|
||||
job.cancel.cancel();
|
||||
}
|
||||
if let Some(prior) = prior_id
|
||||
&& let Some(job) = self.pending.borrow().get(&prior)
|
||||
{
|
||||
job.cancel.cancel();
|
||||
}
|
||||
self.supersede.borrow_mut().insert(key.to_owned(), id);
|
||||
}
|
||||
|
|
@ -1043,10 +1043,10 @@ impl AsyncRuntime {
|
|||
let now = Instant::now();
|
||||
for id in &newly_settled {
|
||||
if let Some(job) = pending.get(id) {
|
||||
if let Some(key) = &job.supersede_key {
|
||||
if sup.get(key) == Some(id) {
|
||||
sup.remove(key);
|
||||
}
|
||||
if let Some(key) = &job.supersede_key
|
||||
&& sup.get(key) == Some(id)
|
||||
{
|
||||
sup.remove(key);
|
||||
}
|
||||
// T M3.7: record the settle in the completion
|
||||
// ring. We push the front and trim the back so
|
||||
|
|
@ -1548,15 +1548,14 @@ fn walk_dir(root: &Path, tx: &cb_channel::Sender<PathBuf>, cancel: &Cancellation
|
|||
continue;
|
||||
}
|
||||
if file_type.is_dir() {
|
||||
if let Some(name) = path.file_name().and_then(|n| n.to_str()) {
|
||||
if name.starts_with('.')
|
||||
if let Some(name) = path.file_name().and_then(|n| n.to_str())
|
||||
&& (name.starts_with('.')
|
||||
|| matches!(
|
||||
name,
|
||||
"node_modules" | "target" | "build" | "dist" | "__pycache__"
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
stack.push(path);
|
||||
} else if file_type.is_file() && tx.send(path).is_err() {
|
||||
|
|
|
|||
|
|
@ -859,10 +859,10 @@ pub(crate) fn run_attach_pair(
|
|||
// active buffer's cursor stale so subsequent
|
||||
// keystrokes round-trip too until the daemon's
|
||||
// next `CursorByte` re-grounds the mirror cursor.
|
||||
if matches!(frontend_event, FrontendEvent::Key(_)) {
|
||||
if let Some(active_buf) = buffer_mirror.active_buffer() {
|
||||
buffer_mirror.mark_cursor_stale(active_buf);
|
||||
}
|
||||
if matches!(frontend_event, FrontendEvent::Key(_))
|
||||
&& let Some(active_buf) = buffer_mirror.active_buffer()
|
||||
{
|
||||
buffer_mirror.mark_cursor_stale(active_buf);
|
||||
}
|
||||
|
||||
// Visual optimistic paint (Path β). Fires only when
|
||||
|
|
@ -906,27 +906,27 @@ pub(crate) fn run_attach_pair(
|
|||
#[cfg(not(feature = "crdt"))]
|
||||
let optimistic_handled = false;
|
||||
|
||||
if !optimistic_handled {
|
||||
if let Err(e) = forward_event(&mut writer, &ev, assigned_id, frontend.size()) {
|
||||
// Likely a broken pipe — instance went away.
|
||||
eprintln!("pmacs: {e}");
|
||||
return Err(e);
|
||||
}
|
||||
// Post-audit-round-6 F30 — `forward_event` (success
|
||||
// path) may write a Mouse / Paste / Resize /
|
||||
// FocusGained / FocusLost event (or no-op for a Key
|
||||
// Release). Mouse down/drag in particular can move
|
||||
// the daemon's active window cursor, change the
|
||||
// active buffer, or both. Anything except an
|
||||
// optimistic CrdtOp can desync the mirror's cursor
|
||||
// from the daemon's view; conservatively mark the
|
||||
// active buffer's cursor stale so subsequent
|
||||
// keystrokes round-trip until the daemon's next
|
||||
// `CursorByte` re-grounds the mirror.
|
||||
#[cfg(feature = "crdt")]
|
||||
if let Some(active_buf) = buffer_mirror.active_buffer() {
|
||||
buffer_mirror.mark_cursor_stale(active_buf);
|
||||
}
|
||||
if !optimistic_handled
|
||||
&& let Err(e) = forward_event(&mut writer, &ev, assigned_id, frontend.size())
|
||||
{
|
||||
// Likely a broken pipe — instance went away.
|
||||
eprintln!("pmacs: {e}");
|
||||
return Err(e);
|
||||
}
|
||||
// Post-audit-round-6 F30 — `forward_event` (success
|
||||
// path) may write a Mouse / Paste / Resize /
|
||||
// FocusGained / FocusLost event (or no-op for a Key
|
||||
// Release). Mouse down/drag in particular can move
|
||||
// the daemon's active window cursor, change the
|
||||
// active buffer, or both. Anything except an
|
||||
// optimistic CrdtOp can desync the mirror's cursor
|
||||
// from the daemon's view; conservatively mark the
|
||||
// active buffer's cursor stale so subsequent
|
||||
// keystrokes round-trip until the daemon's next
|
||||
// `CursorByte` re-grounds the mirror.
|
||||
#[cfg(feature = "crdt")]
|
||||
if let Some(active_buf) = buffer_mirror.active_buffer() {
|
||||
buffer_mirror.mark_cursor_stale(active_buf);
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -321,10 +321,10 @@ fn read_frame<R: Read>(r: &mut R) -> io::Result<Option<Vec<u8>>> {
|
|||
if line.is_empty() {
|
||||
continue;
|
||||
}
|
||||
if let Some((k, v)) = line.split_once(':') {
|
||||
if k.trim().eq_ignore_ascii_case("content-length") {
|
||||
content_length = v.trim().parse().ok();
|
||||
}
|
||||
if let Some((k, v)) = line.split_once(':')
|
||||
&& k.trim().eq_ignore_ascii_case("content-length")
|
||||
{
|
||||
content_length = v.trim().parse().ok();
|
||||
}
|
||||
}
|
||||
let n = content_length
|
||||
|
|
|
|||
|
|
@ -1034,20 +1034,19 @@ fn main() {
|
|||
// notification by writing a sentinel file. Tests
|
||||
// that drove an `invoke_tool` cancellation poll for
|
||||
// the file as proof the server actually got it.
|
||||
if let Some(dir) = std::env::var_os("PMACS_FAKE_MCP_CANCEL_DIR") {
|
||||
if let Some(req_id) = params.get("requestId") {
|
||||
// requestId is whatever the client sent —
|
||||
// typically a u64, but per the spec it can
|
||||
// be any JSON value. Use its string form.
|
||||
let id_str = match req_id {
|
||||
serde_json::Value::Number(n) => n.to_string(),
|
||||
serde_json::Value::String(s) => s.clone(),
|
||||
other => other.to_string(),
|
||||
};
|
||||
let path =
|
||||
std::path::PathBuf::from(&dir).join(format!("cancelled-{id_str}"));
|
||||
let _ = std::fs::write(&path, b"");
|
||||
}
|
||||
if let Some(dir) = std::env::var_os("PMACS_FAKE_MCP_CANCEL_DIR")
|
||||
&& let Some(req_id) = params.get("requestId")
|
||||
{
|
||||
// requestId is whatever the client sent —
|
||||
// typically a u64, but per the spec it can
|
||||
// be any JSON value. Use its string form.
|
||||
let id_str = match req_id {
|
||||
serde_json::Value::Number(n) => n.to_string(),
|
||||
serde_json::Value::String(s) => s.clone(),
|
||||
other => other.to_string(),
|
||||
};
|
||||
let path = std::path::PathBuf::from(&dir).join(format!("cancelled-{id_str}"));
|
||||
let _ = std::fs::write(&path, b"");
|
||||
}
|
||||
}
|
||||
("prompts/get", Some(idv)) => {
|
||||
|
|
@ -1817,7 +1816,7 @@ fn main() {
|
|||
}
|
||||
if mode == "ignore_eof_sleep" {
|
||||
loop {
|
||||
std::thread::sleep(std::time::Duration::from_secs(60));
|
||||
std::thread::sleep(std::time::Duration::from_mins(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2560,8 +2560,8 @@ mod tests {
|
|||
for op in ops {
|
||||
let op_repr = format!("{op:?}");
|
||||
let edit = apply_capturing(&mut a, op);
|
||||
if let Some(edit) = edit {
|
||||
if let Some(crdt_op) = edit.crdt_op.as_ref() {
|
||||
if let Some(edit) = edit
|
||||
&& let Some(crdt_op) = edit.crdt_op.as_ref() {
|
||||
// Apply the wire-format bytes to the
|
||||
// receiver. Receiver projection must match
|
||||
// A's projection after this.
|
||||
|
|
@ -2580,7 +2580,6 @@ mod tests {
|
|||
op_repr, a_proj, b_proj
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,13 +127,13 @@ impl BufferRegistry {
|
|||
pub fn remove(&mut self, id: BufferId) -> Result<Buffer, RegistryError> {
|
||||
// Peek without taking ownership: if the buffer is mid-edit we
|
||||
// surface a typed error and leave the registry untouched.
|
||||
if let Some(buf) = self.buffers.get(&id) {
|
||||
if buf.editing_in_progress() {
|
||||
return Err(RegistryError::ConcurrentEdit {
|
||||
id,
|
||||
name: buf.name().to_string(),
|
||||
});
|
||||
}
|
||||
if let Some(buf) = self.buffers.get(&id)
|
||||
&& buf.editing_in_progress()
|
||||
{
|
||||
return Err(RegistryError::ConcurrentEdit {
|
||||
id,
|
||||
name: buf.name().to_string(),
|
||||
});
|
||||
}
|
||||
let buf = self
|
||||
.buffers
|
||||
|
|
|
|||
|
|
@ -214,10 +214,10 @@ fn extract_markup_text(v: &Value) -> Option<String> {
|
|||
if let Some(s) = v.as_str() {
|
||||
return Some(s.to_owned());
|
||||
}
|
||||
if let Some(obj) = v.as_object() {
|
||||
if let Some(s) = obj.get("value").and_then(Value::as_str) {
|
||||
return Some(s.to_owned());
|
||||
}
|
||||
if let Some(obj) = v.as_object()
|
||||
&& let Some(s) = obj.get("value").and_then(Value::as_str)
|
||||
{
|
||||
return Some(s.to_owned());
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
@ -431,10 +431,10 @@ impl CompletionTriggers {
|
|||
};
|
||||
let mut chars = Vec::with_capacity(arr.len());
|
||||
for v in arr {
|
||||
if let Some(s) = v.as_str() {
|
||||
if let Some(ch) = s.chars().next() {
|
||||
chars.push(ch);
|
||||
}
|
||||
if let Some(s) = v.as_str()
|
||||
&& let Some(ch) = s.chars().next()
|
||||
{
|
||||
chars.push(ch);
|
||||
}
|
||||
}
|
||||
Self { chars }
|
||||
|
|
|
|||
|
|
@ -58,10 +58,10 @@ pub fn resolve_config_dir(
|
|||
xdg: Option<&std::ffi::OsStr>,
|
||||
home: Option<&std::ffi::OsStr>,
|
||||
) -> Option<PathBuf> {
|
||||
if let Some(xdg) = xdg {
|
||||
if !xdg.is_empty() {
|
||||
return Some(PathBuf::from(xdg).join(CONFIG_SUBDIR));
|
||||
}
|
||||
if let Some(xdg) = xdg
|
||||
&& !xdg.is_empty()
|
||||
{
|
||||
return Some(PathBuf::from(xdg).join(CONFIG_SUBDIR));
|
||||
}
|
||||
let home = home?;
|
||||
Some(PathBuf::from(home).join(".config").join(CONFIG_SUBDIR))
|
||||
|
|
|
|||
|
|
@ -1276,11 +1276,11 @@ fn send_buffer_snapshots(editor: &EditorState, write_stream: &mut UnixStream) {
|
|||
// Upgrade non-CRDT buffers to CRDT-backed in place. The
|
||||
// upgrade preserves the buffer's id, name, and content; only
|
||||
// the CRDT machinery is added.
|
||||
if !buf.is_crdt_backed() {
|
||||
if let Err(e) = buf.upgrade_to_crdt(instance_peer_id) {
|
||||
eprintln!("pmacs: upgrade_to_crdt for {buffer_id:?} failed: {e:?}");
|
||||
continue;
|
||||
}
|
||||
if !buf.is_crdt_backed()
|
||||
&& let Err(e) = buf.upgrade_to_crdt(instance_peer_id)
|
||||
{
|
||||
eprintln!("pmacs: upgrade_to_crdt for {buffer_id:?} failed: {e:?}");
|
||||
continue;
|
||||
}
|
||||
let Some(crdt) = buf.crdt_state() else {
|
||||
// Upgrade succeeded but somehow crdt is still None —
|
||||
|
|
@ -1516,15 +1516,14 @@ fn validate_remote_crdt_op(
|
|||
let expected_peer_id = crate::crdt::peer_id_from_frontend(source);
|
||||
let registry_handle = editor.core.borrow().registry.clone();
|
||||
let registry = registry_handle.borrow();
|
||||
if let Ok(buf) = registry.get(buffer_id) {
|
||||
if buf
|
||||
if let Ok(buf) = registry.get(buffer_id)
|
||||
&& buf
|
||||
.validate_remote_op_peer_ids(expected_peer_id, &op.bytes)
|
||||
.is_err()
|
||||
{
|
||||
return Err(
|
||||
"op.bytes carry CRDT ops attributed to a peer other than the authenticated source",
|
||||
);
|
||||
}
|
||||
{
|
||||
return Err(
|
||||
"op.bytes carry CRDT ops attributed to a peer other than the authenticated source",
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
10
src/help.rs
10
src/help.rs
|
|
@ -307,13 +307,13 @@ fn replace_help_buffer(
|
|||
edits.push(edit);
|
||||
}
|
||||
}
|
||||
if !text.is_empty() {
|
||||
if let Ok(edit) = buf.apply_edit(EditOp::Insert {
|
||||
if !text.is_empty()
|
||||
&& let Ok(edit) = buf.apply_edit(EditOp::Insert {
|
||||
pos: 0,
|
||||
bytes: text.as_bytes(),
|
||||
}) {
|
||||
edits.push(edit);
|
||||
}
|
||||
})
|
||||
{
|
||||
edits.push(edit);
|
||||
}
|
||||
// The help buffer is regenerated content; mark it clean so the
|
||||
// modeline doesn't claim it has unsaved changes.
|
||||
|
|
|
|||
|
|
@ -94,10 +94,10 @@ fn collapse_contents(v: &Value) -> Option<String> {
|
|||
}
|
||||
return Some(out);
|
||||
}
|
||||
if let Some(obj) = v.as_object() {
|
||||
if let Some(s) = obj.get("value").and_then(Value::as_str) {
|
||||
return Some(s.to_owned());
|
||||
}
|
||||
if let Some(obj) = v.as_object()
|
||||
&& let Some(s) = obj.get("value").and_then(Value::as_str)
|
||||
{
|
||||
return Some(s.to_owned());
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,13 +103,13 @@ pub fn render(
|
|||
edits.push(edit);
|
||||
}
|
||||
}
|
||||
if !text.is_empty() {
|
||||
if let Ok(edit) = buf.apply_edit(EditOp::Insert {
|
||||
if !text.is_empty()
|
||||
&& let Ok(edit) = buf.apply_edit(EditOp::Insert {
|
||||
pos: 0,
|
||||
bytes: text.as_bytes(),
|
||||
}) {
|
||||
edits.push(edit);
|
||||
}
|
||||
})
|
||||
{
|
||||
edits.push(edit);
|
||||
}
|
||||
buf.mark_clean();
|
||||
(id, edits)
|
||||
|
|
|
|||
|
|
@ -245,18 +245,18 @@ impl KeymapStack {
|
|||
let mut any_pending = false;
|
||||
|
||||
// 1) Buffer-local --- highest priority.
|
||||
if let Some(id) = active_buffer {
|
||||
if let Some(map) = self.buffers.get(&id) {
|
||||
match map.lookup(sequence) {
|
||||
Resolution::Bound(b) => {
|
||||
return StackResolution::Bound(ResolvedBinding {
|
||||
binding: b,
|
||||
scope: Scope::Buffer(id),
|
||||
});
|
||||
}
|
||||
Resolution::Pending => any_pending = true,
|
||||
Resolution::Unbound => {}
|
||||
if let Some(id) = active_buffer
|
||||
&& let Some(map) = self.buffers.get(&id)
|
||||
{
|
||||
match map.lookup(sequence) {
|
||||
Resolution::Bound(b) => {
|
||||
return StackResolution::Bound(ResolvedBinding {
|
||||
binding: b,
|
||||
scope: Scope::Buffer(id),
|
||||
});
|
||||
}
|
||||
Resolution::Pending => any_pending = true,
|
||||
Resolution::Unbound => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -282,10 +282,10 @@ fn bind_recursive(map: &mut Keymap, sequence: &[Chord], command: String, source:
|
|||
fn unbind_recursive(map: &mut Keymap, sequence: &[Chord]) -> Option<Binding> {
|
||||
let (head, tail) = sequence.split_first()?;
|
||||
if tail.is_empty() {
|
||||
if let Some(Branch::Leaf(_)) = map.branches.get(head) {
|
||||
if let Some(Branch::Leaf(b)) = map.branches.remove(head) {
|
||||
return Some(b);
|
||||
}
|
||||
if let Some(Branch::Leaf(_)) = map.branches.get(head)
|
||||
&& let Some(Branch::Leaf(b)) = map.branches.remove(head)
|
||||
{
|
||||
return Some(b);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
|
@ -294,10 +294,10 @@ fn unbind_recursive(map: &mut Keymap, sequence: &[Chord]) -> Option<Binding> {
|
|||
_ => return None,
|
||||
};
|
||||
// Prune empty submaps so the tree doesn't grow stalactites.
|
||||
if let Some(Branch::Submap(sub)) = map.branches.get(head) {
|
||||
if sub.is_empty() {
|
||||
map.branches.remove(head);
|
||||
}
|
||||
if let Some(Branch::Submap(sub)) = map.branches.get(head)
|
||||
&& sub.is_empty()
|
||||
{
|
||||
map.branches.remove(head);
|
||||
}
|
||||
Some(removed)
|
||||
}
|
||||
|
|
|
|||
45
src/lsp.rs
45
src/lsp.rs
|
|
@ -1137,16 +1137,16 @@ impl LspManager {
|
|||
};
|
||||
// Build the initialize request payload.
|
||||
let body = self.build_initialize(sid, init_request_id);
|
||||
if let Some(client) = self.clients.get(&sid) {
|
||||
if let Err(e) = send_frame_to(&self.supervisor, client, &body) {
|
||||
self.push_event(
|
||||
sid,
|
||||
at,
|
||||
LspEventKind::ProtocolError {
|
||||
message: format!("failed to send initialize: {e}"),
|
||||
},
|
||||
);
|
||||
}
|
||||
if let Some(client) = self.clients.get(&sid)
|
||||
&& let Err(e) = send_frame_to(&self.supervisor, client, &body)
|
||||
{
|
||||
self.push_event(
|
||||
sid,
|
||||
at,
|
||||
LspEventKind::ProtocolError {
|
||||
message: format!("failed to send initialize: {e}"),
|
||||
},
|
||||
);
|
||||
}
|
||||
self.push_event(sid, at, LspEventKind::Started { pid });
|
||||
}
|
||||
|
|
@ -1233,10 +1233,8 @@ impl LspManager {
|
|||
} else {
|
||||
self.push_event(sid, at, LspEventKind::Crashed { reason });
|
||||
}
|
||||
if restart {
|
||||
if let Some(client) = self.clients.get_mut(&sid) {
|
||||
client.next_restart_at = Some(at + self.restart_backoff);
|
||||
}
|
||||
if restart && let Some(client) = self.clients.get_mut(&sid) {
|
||||
client.next_restart_at = Some(at + self.restart_backoff);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1263,10 +1261,10 @@ impl LspManager {
|
|||
// Frame violations are unrecoverable on the same
|
||||
// byte stream; terminate and let the restart
|
||||
// policy bring things back if configured.
|
||||
if let Some(client) = self.clients.get_mut(&sid) {
|
||||
if let Some(pid) = client.process {
|
||||
let _ = self.supervisor.borrow_mut().terminate(pid);
|
||||
}
|
||||
if let Some(client) = self.clients.get_mut(&sid)
|
||||
&& let Some(pid) = client.process
|
||||
{
|
||||
let _ = self.supervisor.borrow_mut().terminate(pid);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -1419,12 +1417,11 @@ impl LspManager {
|
|||
// help) get absorbed into the matching shared store before
|
||||
// surfacing as a generic `Response` event. Consumers
|
||||
// observing the event in the same tick see the fresh data.
|
||||
if let Some(route) = self.pending_routes.remove(&(sid, rid)) {
|
||||
if error.is_none() {
|
||||
if let Some(value) = result.as_ref() {
|
||||
self.absorb_routed_response(sid, &route, value);
|
||||
}
|
||||
}
|
||||
if let Some(route) = self.pending_routes.remove(&(sid, rid))
|
||||
&& error.is_none()
|
||||
&& let Some(value) = result.as_ref()
|
||||
{
|
||||
self.absorb_routed_response(sid, &route, value);
|
||||
}
|
||||
// Generic response.
|
||||
self.push_event(
|
||||
|
|
|
|||
34
src/mcp.rs
34
src/mcp.rs
|
|
@ -1524,16 +1524,16 @@ impl McpManager {
|
|||
req_id
|
||||
};
|
||||
let body = build_initialize(init_request_id);
|
||||
if let Some(client) = self.clients.get(&sid) {
|
||||
if let Err(e) = send_frame_to(&self.supervisor, client, &body) {
|
||||
self.push_event(
|
||||
sid,
|
||||
at,
|
||||
McpEventKind::ProtocolError {
|
||||
message: format!("failed to send initialize: {e}"),
|
||||
},
|
||||
);
|
||||
}
|
||||
if let Some(client) = self.clients.get(&sid)
|
||||
&& let Err(e) = send_frame_to(&self.supervisor, client, &body)
|
||||
{
|
||||
self.push_event(
|
||||
sid,
|
||||
at,
|
||||
McpEventKind::ProtocolError {
|
||||
message: format!("failed to send initialize: {e}"),
|
||||
},
|
||||
);
|
||||
}
|
||||
self.push_event(sid, at, McpEventKind::Started { pid });
|
||||
}
|
||||
|
|
@ -1597,10 +1597,8 @@ impl McpManager {
|
|||
TerminalKind::Stopped => self.push_event(sid, at, McpEventKind::Stopped),
|
||||
TerminalKind::Crashed => self.push_event(sid, at, McpEventKind::Crashed { reason }),
|
||||
}
|
||||
if restart {
|
||||
if let Some(client) = self.clients.get_mut(&sid) {
|
||||
client.next_restart_at = Some(at + self.restart_backoff);
|
||||
}
|
||||
if restart && let Some(client) = self.clients.get_mut(&sid) {
|
||||
client.next_restart_at = Some(at + self.restart_backoff);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1911,10 +1909,10 @@ impl McpManager {
|
|||
/// of the LSP layer's "frame violations are unrecoverable on the
|
||||
/// same byte stream" path.
|
||||
fn terminate_after_protocol_error(&mut self, sid: McpServerId) {
|
||||
if let Some(client) = self.clients.get(&sid) {
|
||||
if let Some(pid) = client.process {
|
||||
let _ = self.supervisor.borrow_mut().terminate(pid);
|
||||
}
|
||||
if let Some(client) = self.clients.get(&sid)
|
||||
&& let Some(pid) = client.process
|
||||
{
|
||||
let _ = self.supervisor.borrow_mut().terminate(pid);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -494,14 +494,15 @@ impl MinibufferAction {
|
|||
}
|
||||
return Self::Ignore;
|
||||
}
|
||||
if alt && !ctrl {
|
||||
if let KeyCode::Char(c) = chord.code {
|
||||
return match c {
|
||||
'n' => Self::ScrollNext,
|
||||
'p' => Self::ScrollPrev,
|
||||
_ => Self::Ignore,
|
||||
};
|
||||
}
|
||||
if alt
|
||||
&& !ctrl
|
||||
&& let KeyCode::Char(c) = chord.code
|
||||
{
|
||||
return match c {
|
||||
'n' => Self::ScrollNext,
|
||||
'p' => Self::ScrollPrev,
|
||||
_ => Self::Ignore,
|
||||
};
|
||||
}
|
||||
Self::Ignore
|
||||
}
|
||||
|
|
@ -631,10 +632,10 @@ pub fn fuzzy_score(needle: &str, haystack: &str) -> Option<i32> {
|
|||
if n[i] == hc {
|
||||
if j == 0 {
|
||||
score += 10;
|
||||
} else if let Some(prev_h) = h.get(j - 1) {
|
||||
if matches!(*prev_h, '.' | '-' | '_' | ' ') {
|
||||
score += 5;
|
||||
}
|
||||
} else if let Some(prev_h) = h.get(j - 1)
|
||||
&& matches!(*prev_h, '.' | '-' | '_' | ' ')
|
||||
{
|
||||
score += 5;
|
||||
}
|
||||
if let Some(p) = prev_match {
|
||||
if p + 1 == j {
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ pub struct Fetcher {
|
|||
timeout: Duration,
|
||||
}
|
||||
|
||||
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(60);
|
||||
const DEFAULT_TIMEOUT: Duration = Duration::from_mins(1);
|
||||
|
||||
impl Fetcher {
|
||||
/// Construct a fetcher with an explicit cache directory. The
|
||||
|
|
@ -472,10 +472,10 @@ fn xdg_cache_root() -> Result<PathBuf, FetchError> {
|
|||
#[must_use]
|
||||
pub fn normalize_url(url: &str) -> String {
|
||||
let mut u = url.trim_end_matches('/').to_string();
|
||||
if dot_git_strip_applies(&u) {
|
||||
if let Some(s) = u.strip_suffix(".git") {
|
||||
u = s.to_string();
|
||||
}
|
||||
if dot_git_strip_applies(&u)
|
||||
&& let Some(s) = u.strip_suffix(".git")
|
||||
{
|
||||
u = s.to_string();
|
||||
}
|
||||
if let Some(scheme_end) = u.find("://") {
|
||||
let host_start = scheme_end + 3;
|
||||
|
|
@ -497,14 +497,12 @@ fn dot_git_strip_applies(u: &str) -> bool {
|
|||
}
|
||||
// SSH shorthand: `user@host:path`. Distinguished from URL forms
|
||||
// by the `@` appearing before any `:` and no `://` prefix.
|
||||
if !u.contains("://") {
|
||||
if let Some(at) = u.find('@') {
|
||||
if let Some(colon) = u.find(':') {
|
||||
if at < colon {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if !u.contains("://")
|
||||
&& let Some(at) = u.find('@')
|
||||
&& let Some(colon) = u.find(':')
|
||||
&& at < colon
|
||||
{
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -657,13 +657,13 @@ impl Installer {
|
|||
let staging_path = plan
|
||||
.install_path
|
||||
.with_file_name(format!(".{}.swap.tmp", plan.basename));
|
||||
if let Err(e) = std::fs::remove_file(&staging_path) {
|
||||
if e.kind() != io::ErrorKind::NotFound {
|
||||
return Err(InstallError::Io {
|
||||
path: staging_path,
|
||||
source: e,
|
||||
});
|
||||
}
|
||||
if let Err(e) = std::fs::remove_file(&staging_path)
|
||||
&& e.kind() != io::ErrorKind::NotFound
|
||||
{
|
||||
return Err(InstallError::Io {
|
||||
path: staging_path,
|
||||
source: e,
|
||||
});
|
||||
}
|
||||
symlink_create(&plan.canonical_source, &staging_path)?;
|
||||
|
||||
|
|
@ -846,15 +846,15 @@ impl Installer {
|
|||
// and pmacs.toml version disagree. Branch and commit pins
|
||||
// skip this check --- the user explicitly asked for that
|
||||
// revision regardless of what the manifest says.
|
||||
if let InstallPin::Version(req) = &spec.pin {
|
||||
if !req.matches(&manifest.version) {
|
||||
return Err(InstallError::ManifestVersionMismatch {
|
||||
address: url.clone(),
|
||||
tag: tag_descriptor.clone(),
|
||||
manifest_version: manifest.version.to_string(),
|
||||
req: req.to_string(),
|
||||
});
|
||||
}
|
||||
if let InstallPin::Version(req) = &spec.pin
|
||||
&& !req.matches(&manifest.version)
|
||||
{
|
||||
return Err(InstallError::ManifestVersionMismatch {
|
||||
address: url.clone(),
|
||||
tag: tag_descriptor.clone(),
|
||||
manifest_version: manifest.version.to_string(),
|
||||
req: req.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
// Archive + extract.
|
||||
|
|
|
|||
|
|
@ -408,13 +408,13 @@ impl Lockfile {
|
|||
|
||||
/// Write pre-serialized lockfile bytes to disk atomically.
|
||||
pub fn write_bytes_to(path: &Path, bytes: &[u8]) -> Result<(), LockfileError> {
|
||||
if let Some(parent) = path.parent() {
|
||||
if !parent.as_os_str().is_empty() {
|
||||
fs::create_dir_all(parent).map_err(|source| LockfileError::Io {
|
||||
path: parent.to_path_buf(),
|
||||
source,
|
||||
})?;
|
||||
}
|
||||
if let Some(parent) = path.parent()
|
||||
&& !parent.as_os_str().is_empty()
|
||||
{
|
||||
fs::create_dir_all(parent).map_err(|source| LockfileError::Io {
|
||||
path: parent.to_path_buf(),
|
||||
source,
|
||||
})?;
|
||||
}
|
||||
crate::file_io::save_atomic(path, bytes)
|
||||
.map(|_| ())
|
||||
|
|
|
|||
|
|
@ -890,23 +890,23 @@ impl<'a> ResolverState<'a> {
|
|||
// selection. This is the `UpdatePolicy::UpdateOne` cascade
|
||||
// brake — non-target packages stay at lockfile versions
|
||||
// unless current constraints force them to move.
|
||||
if let Some(hint) = self.prefer_versions.get(url).cloned() {
|
||||
if let Some(cand) = after_user.iter().find(|c| c.version == hint) {
|
||||
let manifest = self
|
||||
.read_manifest(url, repo, &cand.commit_for_tag())?
|
||||
.clone();
|
||||
if manifest.pmacs_required.matches(self.pmacs_version) {
|
||||
return Ok(ChosenTag {
|
||||
tag: cand.tag.clone(),
|
||||
commit: cand.commit_for_tag(),
|
||||
version: cand.version.clone(),
|
||||
});
|
||||
}
|
||||
// Hinted version is no longer pmacs-compatible (e.g.
|
||||
// user upgraded pmacs and the locked version requires
|
||||
// an older one). Fall through to highest-version
|
||||
// selection.
|
||||
if let Some(hint) = self.prefer_versions.get(url).cloned()
|
||||
&& let Some(cand) = after_user.iter().find(|c| c.version == hint)
|
||||
{
|
||||
let manifest = self
|
||||
.read_manifest(url, repo, &cand.commit_for_tag())?
|
||||
.clone();
|
||||
if manifest.pmacs_required.matches(self.pmacs_version) {
|
||||
return Ok(ChosenTag {
|
||||
tag: cand.tag.clone(),
|
||||
commit: cand.commit_for_tag(),
|
||||
version: cand.version.clone(),
|
||||
});
|
||||
}
|
||||
// Hinted version is no longer pmacs-compatible (e.g.
|
||||
// user upgraded pmacs and the locked version requires
|
||||
// an older one). Fall through to highest-version
|
||||
// selection.
|
||||
}
|
||||
|
||||
// Phase 2b: walk highest-first, fetch manifest lazily, return
|
||||
|
|
|
|||
|
|
@ -945,13 +945,12 @@ impl ProcessSupervisor {
|
|||
} else {
|
||||
// Schedule a restart attempt for `restart_backoff` from
|
||||
// now if not yet scheduled.
|
||||
if let Some(proc) = self.processes.get_mut(&id) {
|
||||
if matches!(proc.state, ProcessState::Terminated(_))
|
||||
&& !matches!(proc.spec.restart, RestartPolicy::Never)
|
||||
&& proc.next_restart_at.is_none()
|
||||
{
|
||||
proc.next_restart_at = Some(now + self.restart_backoff);
|
||||
}
|
||||
if let Some(proc) = self.processes.get_mut(&id)
|
||||
&& matches!(proc.state, ProcessState::Terminated(_))
|
||||
&& !matches!(proc.spec.restart, RestartPolicy::Never)
|
||||
&& proc.next_restart_at.is_none()
|
||||
{
|
||||
proc.next_restart_at = Some(now + self.restart_backoff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1032,13 +1031,13 @@ impl ProcessSupervisor {
|
|||
}
|
||||
// SIGKILL anything left.
|
||||
for id in &ids {
|
||||
if let Some(proc) = self.processes.get(id) {
|
||||
if matches!(
|
||||
if let Some(proc) = self.processes.get(id)
|
||||
&& matches!(
|
||||
proc.state,
|
||||
ProcessState::Running { .. } | ProcessState::Exiting { .. }
|
||||
) {
|
||||
let _ = self.signal(*id, Signal::SIGKILL);
|
||||
}
|
||||
)
|
||||
{
|
||||
let _ = self.signal(*id, Signal::SIGKILL);
|
||||
}
|
||||
}
|
||||
// Final reap loop. SIGKILL is delivered immediately by the
|
||||
|
|
|
|||
|
|
@ -232,10 +232,10 @@ fn walk_for_marker(
|
|||
if let Some(kind) = match_marker(ancestor, markers) {
|
||||
return Some((ancestor.to_path_buf(), kind));
|
||||
}
|
||||
if let Some(stop) = stop_root {
|
||||
if ancestor == stop {
|
||||
break;
|
||||
}
|
||||
if let Some(stop) = stop_root
|
||||
&& ancestor == stop
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
None
|
||||
|
|
|
|||
|
|
@ -344,10 +344,10 @@ impl ProjectIndex {
|
|||
/// Save the index to `dest` as JSON, creating parent directories
|
||||
/// as needed.
|
||||
pub fn save(&self, dest: &Path) -> io::Result<()> {
|
||||
if let Some(parent) = dest.parent() {
|
||||
if !parent.as_os_str().is_empty() {
|
||||
fs::create_dir_all(parent)?;
|
||||
}
|
||||
if let Some(parent) = dest.parent()
|
||||
&& !parent.as_os_str().is_empty()
|
||||
{
|
||||
fs::create_dir_all(parent)?;
|
||||
}
|
||||
let bytes = serde_json::to_vec(self).map_err(io::Error::other)?;
|
||||
fs::write(dest, bytes)
|
||||
|
|
@ -729,10 +729,10 @@ fn extract_rust_heuristic(source: &str) -> Vec<Symbol> {
|
|||
|
||||
fn strip_rust_visibility(s: &str) -> &str {
|
||||
let trimmed = s.trim_start();
|
||||
if let Some(rest) = trimmed.strip_prefix("pub(") {
|
||||
if let Some(close) = rest.find(')') {
|
||||
return rest[close + 1..].trim_start();
|
||||
}
|
||||
if let Some(rest) = trimmed.strip_prefix("pub(")
|
||||
&& let Some(close) = rest.find(')')
|
||||
{
|
||||
return rest[close + 1..].trim_start();
|
||||
}
|
||||
if let Some(rest) = trimmed.strip_prefix("pub ") {
|
||||
return rest.trim_start();
|
||||
|
|
@ -771,18 +771,18 @@ fn extract_lua_heuristic(source: &str) -> Vec<Symbol> {
|
|||
}
|
||||
}
|
||||
// local NAME = function(...
|
||||
if let Some(rest) = line.strip_prefix("local ") {
|
||||
if let Some(eq) = rest.find('=') {
|
||||
let name = rest[..eq].trim();
|
||||
let value = rest[eq + 1..].trim_start();
|
||||
if is_identifier(name) {
|
||||
let kind = if value.starts_with("function") {
|
||||
SymbolKind::Function
|
||||
} else {
|
||||
SymbolKind::Variable
|
||||
};
|
||||
push_sym(&mut out, name, kind, line_idx, col);
|
||||
}
|
||||
if let Some(rest) = line.strip_prefix("local ")
|
||||
&& let Some(eq) = rest.find('=')
|
||||
{
|
||||
let name = rest[..eq].trim();
|
||||
let value = rest[eq + 1..].trim_start();
|
||||
if is_identifier(name) {
|
||||
let kind = if value.starts_with("function") {
|
||||
SymbolKind::Function
|
||||
} else {
|
||||
SymbolKind::Variable
|
||||
};
|
||||
push_sym(&mut out, name, kind, line_idx, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -917,21 +917,21 @@ pub fn extract_treesitter(
|
|||
|
||||
fn walk_treesitter(node: tree_sitter::Node<'_>, bytes: &[u8], out: &mut Vec<Symbol>) {
|
||||
let kind_name = node.kind();
|
||||
if let Some(sym_kind) = treesitter_kind(kind_name) {
|
||||
if let Some(name_node) = node.child_by_field_name("name") {
|
||||
let start = name_node.start_byte();
|
||||
let end = name_node.end_byte();
|
||||
if let Ok(name) = std::str::from_utf8(&bytes[start..end]) {
|
||||
let pos = node.start_position();
|
||||
out.push(Symbol {
|
||||
name: name.to_owned(),
|
||||
kind: sym_kind,
|
||||
line: pos.row as u32,
|
||||
col: pos.column as u32,
|
||||
source: SymbolSource::TreeSitter,
|
||||
container: None,
|
||||
});
|
||||
}
|
||||
if let Some(sym_kind) = treesitter_kind(kind_name)
|
||||
&& let Some(name_node) = node.child_by_field_name("name")
|
||||
{
|
||||
let start = name_node.start_byte();
|
||||
let end = name_node.end_byte();
|
||||
if let Ok(name) = std::str::from_utf8(&bytes[start..end]) {
|
||||
let pos = node.start_position();
|
||||
out.push(Symbol {
|
||||
name: name.to_owned(),
|
||||
kind: sym_kind,
|
||||
line: pos.row as u32,
|
||||
col: pos.column as u32,
|
||||
source: SymbolSource::TreeSitter,
|
||||
container: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
let mut cursor = node.walk();
|
||||
|
|
@ -1027,26 +1027,25 @@ fn ingest_lsp_one(
|
|||
(parent_uri.map(str::to_owned), 0, 0)
|
||||
};
|
||||
|
||||
if !name.is_empty() {
|
||||
if let Some(uri) = uri.as_deref() {
|
||||
if let Some(path) = uri_to_path(uri) {
|
||||
let kind = kind_code.map_or(SymbolKind::Other("unknown".into()), |code| {
|
||||
SymbolKind::from_lsp_code(code)
|
||||
});
|
||||
out.push(LspSymbolInbound {
|
||||
path,
|
||||
language: None,
|
||||
symbol: Symbol {
|
||||
name: name.to_owned(),
|
||||
kind,
|
||||
line,
|
||||
col,
|
||||
source: SymbolSource::Lsp,
|
||||
container: container.clone(),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
if !name.is_empty()
|
||||
&& let Some(uri) = uri.as_deref()
|
||||
&& let Some(path) = uri_to_path(uri)
|
||||
{
|
||||
let kind = kind_code.map_or(SymbolKind::Other("unknown".into()), |code| {
|
||||
SymbolKind::from_lsp_code(code)
|
||||
});
|
||||
out.push(LspSymbolInbound {
|
||||
path,
|
||||
language: None,
|
||||
symbol: Symbol {
|
||||
name: name.to_owned(),
|
||||
kind,
|
||||
line,
|
||||
col,
|
||||
source: SymbolSource::Lsp,
|
||||
container: container.clone(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// DocumentSymbol form: recurse into children with the same uri.
|
||||
|
|
@ -1089,12 +1088,13 @@ fn percent_decode(s: &str) -> String {
|
|||
let mut out = Vec::with_capacity(bytes.len());
|
||||
let mut i = 0;
|
||||
while i < bytes.len() {
|
||||
if bytes[i] == b'%' && i + 2 < bytes.len() {
|
||||
if let (Some(h), Some(l)) = (hex_val(bytes[i + 1]), hex_val(bytes[i + 2])) {
|
||||
out.push((h << 4) | l);
|
||||
i += 3;
|
||||
continue;
|
||||
}
|
||||
if bytes[i] == b'%'
|
||||
&& i + 2 < bytes.len()
|
||||
&& let (Some(h), Some(l)) = (hex_val(bytes[i + 1]), hex_val(bytes[i + 2]))
|
||||
{
|
||||
out.push((h << 4) | l);
|
||||
i += 3;
|
||||
continue;
|
||||
}
|
||||
out.push(bytes[i]);
|
||||
i += 1;
|
||||
|
|
|
|||
|
|
@ -149,20 +149,20 @@ fn parse_parameter(v: &Value, parent_label: &str) -> Option<SignatureParameter>
|
|||
documentation,
|
||||
});
|
||||
}
|
||||
if let Some(arr) = label_field.as_array() {
|
||||
if arr.len() == 2 {
|
||||
let start = arr[0].as_u64()? as u32;
|
||||
let end = arr[1].as_u64()? as u32;
|
||||
let s = parent_label
|
||||
.get(start as usize..end as usize)
|
||||
.unwrap_or("")
|
||||
.to_owned();
|
||||
return Some(SignatureParameter {
|
||||
label: s,
|
||||
span: Some((start, end)),
|
||||
documentation,
|
||||
});
|
||||
}
|
||||
if let Some(arr) = label_field.as_array()
|
||||
&& arr.len() == 2
|
||||
{
|
||||
let start = arr[0].as_u64()? as u32;
|
||||
let end = arr[1].as_u64()? as u32;
|
||||
let s = parent_label
|
||||
.get(start as usize..end as usize)
|
||||
.unwrap_or("")
|
||||
.to_owned();
|
||||
return Some(SignatureParameter {
|
||||
label: s,
|
||||
span: Some((start, end)),
|
||||
documentation,
|
||||
});
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
@ -171,10 +171,10 @@ fn extract_markup_text(v: &Value) -> Option<String> {
|
|||
if let Some(s) = v.as_str() {
|
||||
return Some(s.to_owned());
|
||||
}
|
||||
if let Some(obj) = v.as_object() {
|
||||
if let Some(s) = obj.get("value").and_then(Value::as_str) {
|
||||
return Some(s.to_owned());
|
||||
}
|
||||
if let Some(obj) = v.as_object()
|
||||
&& let Some(s) = obj.get("value").and_then(Value::as_str)
|
||||
{
|
||||
return Some(s.to_owned());
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
@ -383,35 +383,34 @@ impl View for SignatureView {
|
|||
}
|
||||
}
|
||||
|
||||
if max_rows > 1 {
|
||||
if let Some(doc) = snap.documentation.as_deref() {
|
||||
for (i, line) in doc.lines().enumerate() {
|
||||
let row_idx = i as u32 + 1;
|
||||
if row_idx >= max_rows {
|
||||
if max_rows > 1
|
||||
&& let Some(doc) = snap.documentation.as_deref()
|
||||
{
|
||||
for (i, line) in doc.lines().enumerate() {
|
||||
let row_idx = i as u32 + 1;
|
||||
if row_idx >= max_rows {
|
||||
break;
|
||||
}
|
||||
let mut col: u32 = 0;
|
||||
for ch in line.chars() {
|
||||
if col >= max_cols {
|
||||
break;
|
||||
}
|
||||
let mut col: u32 = 0;
|
||||
for ch in line.chars() {
|
||||
if col >= max_cols {
|
||||
break;
|
||||
}
|
||||
let width = char_display_width(ch);
|
||||
if width == 0 {
|
||||
continue;
|
||||
}
|
||||
let cell = cells.at(CellCoord::new(origin.row + row_idx, origin.col + col));
|
||||
cell.glyph = Glyph::Char(ch);
|
||||
cell.style = Style::default();
|
||||
cell.attachment = None;
|
||||
let width = char_display_width(ch);
|
||||
if width == 0 {
|
||||
continue;
|
||||
}
|
||||
let cell = cells.at(CellCoord::new(origin.row + row_idx, origin.col + col));
|
||||
cell.glyph = Glyph::Char(ch);
|
||||
cell.style = Style::default();
|
||||
cell.attachment = None;
|
||||
col += 1;
|
||||
if width == 2 && col < max_cols {
|
||||
let cont = cells.at(CellCoord::new(origin.row + row_idx, origin.col + col));
|
||||
cont.glyph = Glyph::Continuation;
|
||||
cont.style = Style::default();
|
||||
cont.attachment = None;
|
||||
col += 1;
|
||||
if width == 2 && col < max_cols {
|
||||
let cont =
|
||||
cells.at(CellCoord::new(origin.row + row_idx, origin.col + col));
|
||||
cont.glyph = Glyph::Continuation;
|
||||
cont.style = Style::default();
|
||||
cont.attachment = None;
|
||||
col += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,10 +102,10 @@ pub fn resolve_socket_path_with_runtime(arg: Option<&str>, runtime: &Path) -> Pa
|
|||
/// non-empty, else `/tmp/pmacs-<uid>`.
|
||||
#[must_use]
|
||||
pub fn runtime_dir() -> PathBuf {
|
||||
if let Some(xdg) = env::var_os("XDG_RUNTIME_DIR") {
|
||||
if !xdg.is_empty() {
|
||||
return PathBuf::from(xdg);
|
||||
}
|
||||
if let Some(xdg) = env::var_os("XDG_RUNTIME_DIR")
|
||||
&& !xdg.is_empty()
|
||||
{
|
||||
return PathBuf::from(xdg);
|
||||
}
|
||||
PathBuf::from(format!("/tmp/pmacs-{}", current_uid()))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,13 +84,13 @@ pub fn render(
|
|||
edits.push(edit);
|
||||
}
|
||||
}
|
||||
if !text.is_empty() {
|
||||
if let Ok(edit) = buf.apply_edit(EditOp::Insert {
|
||||
if !text.is_empty()
|
||||
&& let Ok(edit) = buf.apply_edit(EditOp::Insert {
|
||||
pos: 0,
|
||||
bytes: text.as_bytes(),
|
||||
}) {
|
||||
edits.push(edit);
|
||||
}
|
||||
})
|
||||
{
|
||||
edits.push(edit);
|
||||
}
|
||||
buf.mark_clean();
|
||||
(id, edits)
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ mod soak_helpers {
|
|||
1 => rt.dispatch_compute_sum((u64::from(rng()) % 1_000) + 1, None),
|
||||
_ => rt.dispatch_emit_n((u64::from(rng()) % 32) + 1, None, Some(8)),
|
||||
};
|
||||
if rng() % 4 == 0 {
|
||||
if rng().is_multiple_of(4) {
|
||||
rt.cancel(id);
|
||||
}
|
||||
let inner_deadline = Instant::now() + Duration::from_secs(2);
|
||||
|
|
|
|||
|
|
@ -269,12 +269,12 @@ impl Observer {
|
|||
// reconstruct here. In M10.11's smoke / scenario
|
||||
// tests, the observer attaches before any edit
|
||||
// activity, so this branch shouldn't fire.
|
||||
if let Some(r) = self.replicas.get(&buffer_id) {
|
||||
if let Err(e) = r.import_updates(&op.bytes) {
|
||||
self.import_errors
|
||||
.entry(buffer_id)
|
||||
.or_insert_with(|| format!("{e:?}"));
|
||||
}
|
||||
if let Some(r) = self.replicas.get(&buffer_id)
|
||||
&& let Err(e) = r.import_updates(&op.bytes)
|
||||
{
|
||||
self.import_errors
|
||||
.entry(buffer_id)
|
||||
.or_insert_with(|| format!("{e:?}"));
|
||||
}
|
||||
}
|
||||
InstanceMessage::PresenceUpdate { frontend_id, .. }
|
||||
|
|
@ -349,10 +349,10 @@ impl Observer {
|
|||
let deadline = Instant::now() + timeout;
|
||||
loop {
|
||||
self.pump(Duration::from_millis(100));
|
||||
if let Some(text) = self.materialized(buffer_id) {
|
||||
if text == expected {
|
||||
return Ok(());
|
||||
}
|
||||
if let Some(text) = self.materialized(buffer_id)
|
||||
&& text == expected
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
if Instant::now() >= deadline {
|
||||
let observed = self
|
||||
|
|
@ -375,10 +375,10 @@ impl Observer {
|
|||
let deadline = Instant::now() + timeout;
|
||||
loop {
|
||||
self.pump(Duration::from_millis(100));
|
||||
if let Some(text) = self.materialized(buffer_id) {
|
||||
if substrings.iter().all(|s| text.contains(s)) {
|
||||
return Ok(());
|
||||
}
|
||||
if let Some(text) = self.materialized(buffer_id)
|
||||
&& substrings.iter().all(|s| text.contains(s))
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
if Instant::now() >= deadline {
|
||||
let observed = self
|
||||
|
|
|
|||
|
|
@ -3002,11 +3002,11 @@ fn m4_12_definition_response_lands_in_store() {
|
|||
mgr.borrow_mut().tick();
|
||||
let store = mgr.borrow().definition_store();
|
||||
let guard = store.lock().expect("lock");
|
||||
if let Some(r) = guard.get(&key) {
|
||||
if let Some(loc) = r.locations.first() {
|
||||
got = Some((loc.line, loc.col));
|
||||
break;
|
||||
}
|
||||
if let Some(r) = guard.get(&key)
|
||||
&& let Some(loc) = r.locations.first()
|
||||
{
|
||||
got = Some((loc.line, loc.col));
|
||||
break;
|
||||
}
|
||||
drop(guard);
|
||||
std::thread::sleep(Duration::from_millis(15));
|
||||
|
|
@ -3043,11 +3043,11 @@ fn m4_12_formatting_response_lands_in_store() {
|
|||
mgr.borrow_mut().tick();
|
||||
let store = mgr.borrow().formatting_store();
|
||||
let guard = store.lock().expect("lock");
|
||||
if let Some(r) = guard.get(&key) {
|
||||
if !r.edits.is_empty() {
|
||||
got = r.edits.clone();
|
||||
break;
|
||||
}
|
||||
if let Some(r) = guard.get(&key)
|
||||
&& !r.edits.is_empty()
|
||||
{
|
||||
got = r.edits.clone();
|
||||
break;
|
||||
}
|
||||
drop(guard);
|
||||
std::thread::sleep(Duration::from_millis(15));
|
||||
|
|
|
|||
|
|
@ -142,14 +142,14 @@ fn attach_send_key_receive_cell_response() {
|
|||
stream
|
||||
.set_read_timeout(Some(Duration::from_millis(200)))
|
||||
.unwrap();
|
||||
if let Ok(msg) = read_message::<InstanceMessage>(&mut stream) {
|
||||
if matches!(
|
||||
if let Ok(msg) = read_message::<InstanceMessage>(&mut stream)
|
||||
&& matches!(
|
||||
msg,
|
||||
InstanceMessage::CellDelta { .. } | InstanceMessage::Cursor(_)
|
||||
) {
|
||||
got_response = true;
|
||||
break;
|
||||
}
|
||||
)
|
||||
{
|
||||
got_response = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert!(got_response, "expected render response after key");
|
||||
|
|
@ -830,11 +830,11 @@ fn m10_9_other_frontend_cursor_appears_in_recipient_cell_delta_with_color() {
|
|||
for cell in &span.cells {
|
||||
// The palette uses Color::Rgb(...). Any cell whose
|
||||
// fg is a palette entry is an overlay cell.
|
||||
if let Color::Rgb(_, _, _) = cell.style.fg {
|
||||
if is_palette_color(cell.style.fg) {
|
||||
saw_palette_cell = true;
|
||||
break;
|
||||
}
|
||||
if let Color::Rgb(_, _, _) = cell.style.fg
|
||||
&& is_palette_color(cell.style.fg)
|
||||
{
|
||||
saw_palette_cell = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if saw_palette_cell {
|
||||
|
|
@ -937,10 +937,10 @@ fn wait_for_palette_color_in_b(stream: &mut UnixStream, timeout: Duration) -> Op
|
|||
{
|
||||
for span in &spans {
|
||||
for cell in &span.cells {
|
||||
if let Color::Rgb(_, _, _) = cell.style.fg {
|
||||
if is_palette_color(cell.style.fg) {
|
||||
return Some(cell.style.fg);
|
||||
}
|
||||
if let Color::Rgb(_, _, _) = cell.style.fg
|
||||
&& is_palette_color(cell.style.fg)
|
||||
{
|
||||
return Some(cell.style.fg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1554,29 +1554,25 @@ fn m10_10_criterion_3_two_frontend_conflict_converges() {
|
|||
let mut a_received_b_op = false;
|
||||
let mut b_received_a_op = false;
|
||||
while Instant::now() < deadline && !(a_received_b_op && b_received_a_op) {
|
||||
if !a_received_b_op {
|
||||
if let Ok(InstanceMessage::CrdtOp { op, .. }) =
|
||||
if !a_received_b_op
|
||||
&& let Ok(InstanceMessage::CrdtOp { op, .. }) =
|
||||
read_message::<InstanceMessage>(&mut stream_a)
|
||||
{
|
||||
if op.peer_id == hello_b.assigned_frontend_id.0 {
|
||||
replica_a
|
||||
.import_updates(&op.bytes)
|
||||
.expect("a import B's op");
|
||||
a_received_b_op = true;
|
||||
}
|
||||
}
|
||||
&& op.peer_id == hello_b.assigned_frontend_id.0
|
||||
{
|
||||
replica_a
|
||||
.import_updates(&op.bytes)
|
||||
.expect("a import B's op");
|
||||
a_received_b_op = true;
|
||||
}
|
||||
if !b_received_a_op {
|
||||
if let Ok(InstanceMessage::CrdtOp { op, .. }) =
|
||||
if !b_received_a_op
|
||||
&& let Ok(InstanceMessage::CrdtOp { op, .. }) =
|
||||
read_message::<InstanceMessage>(&mut stream_b)
|
||||
{
|
||||
if op.peer_id == hello_a.assigned_frontend_id.0 {
|
||||
replica_b
|
||||
.import_updates(&op.bytes)
|
||||
.expect("b import A's op");
|
||||
b_received_a_op = true;
|
||||
}
|
||||
}
|
||||
&& op.peer_id == hello_a.assigned_frontend_id.0
|
||||
{
|
||||
replica_b
|
||||
.import_updates(&op.bytes)
|
||||
.expect("b import A's op");
|
||||
b_received_a_op = true;
|
||||
}
|
||||
}
|
||||
assert!(
|
||||
|
|
@ -2008,11 +2004,10 @@ fn m10_10_f26_spoofed_loro_internal_peer_id_is_rejected() {
|
|||
while Instant::now() < deadline {
|
||||
if let Ok(InstanceMessage::CrdtOp { op, .. }) =
|
||||
read_message::<InstanceMessage>(&mut stream_b)
|
||||
&& op.bytes == spoofed_bytes
|
||||
{
|
||||
if op.bytes == spoofed_bytes {
|
||||
saw_spoofed_broadcast = true;
|
||||
break;
|
||||
}
|
||||
saw_spoofed_broadcast = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert!(
|
||||
|
|
|
|||
|
|
@ -84,14 +84,13 @@ fn locate_lua() -> Option<PathBuf> {
|
|||
return Some(p);
|
||||
}
|
||||
}
|
||||
if let Ok(out) = std::process::Command::new("which").arg(name).output() {
|
||||
if out.status.success() {
|
||||
if let Ok(path) = String::from_utf8(out.stdout) {
|
||||
let path = path.trim();
|
||||
if !path.is_empty() {
|
||||
return Some(PathBuf::from(path));
|
||||
}
|
||||
}
|
||||
if let Ok(out) = std::process::Command::new("which").arg(name).output()
|
||||
&& out.status.success()
|
||||
&& let Ok(path) = String::from_utf8(out.stdout)
|
||||
{
|
||||
let path = path.trim();
|
||||
if !path.is_empty() {
|
||||
return Some(PathBuf::from(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,7 +396,7 @@ fn m6_6_buffer_memory_stays_under_200mb_during_run() {
|
|||
let reached_target = pump_until(
|
||||
&mut editor,
|
||||
|e| history_bytes(e) >= TARGET_HISTORY_BYTES,
|
||||
Duration::from_secs(60),
|
||||
Duration::from_mins(1),
|
||||
);
|
||||
assert!(
|
||||
reached_target,
|
||||
|
|
|
|||
|
|
@ -1012,13 +1012,13 @@ fn dired_sort_mtime_orders_newest_first() {
|
|||
.write(true)
|
||||
.open(&oldest)
|
||||
.unwrap()
|
||||
.set_modified(now - Duration::from_secs(120))
|
||||
.set_modified(now - Duration::from_mins(2))
|
||||
.expect("set mtime oldest");
|
||||
std::fs::File::options()
|
||||
.write(true)
|
||||
.open(&middle)
|
||||
.unwrap()
|
||||
.set_modified(now - Duration::from_secs(60))
|
||||
.set_modified(now - Duration::from_mins(1))
|
||||
.expect("set mtime middle");
|
||||
std::fs::File::options()
|
||||
.write(true)
|
||||
|
|
|
|||
|
|
@ -288,11 +288,11 @@ fn m9_3_cancellation_reaches_server() {
|
|||
// file.
|
||||
if let Ok(entries) = std::fs::read_dir(&cancel_dir) {
|
||||
for entry in entries.flatten() {
|
||||
if let Some(name) = entry.file_name().to_str() {
|
||||
if name.starts_with("cancelled-") {
|
||||
sentinel_seen = true;
|
||||
break;
|
||||
}
|
||||
if let Some(name) = entry.file_name().to_str()
|
||||
&& name.starts_with("cancelled-")
|
||||
{
|
||||
sentinel_seen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue