Compare commits
27 Commits
git-open-d
...
v0.133.7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
622f0884d6 | ||
|
|
a9c9ae784f | ||
|
|
63e3d7d5ea | ||
|
|
78841c658e | ||
|
|
0f825b8cfd | ||
|
|
3304200594 | ||
|
|
816417254b | ||
|
|
71aa3255e6 | ||
|
|
07fd6d903f | ||
|
|
6299c62d52 | ||
|
|
6b64abfed8 | ||
|
|
5929bc3a2a | ||
|
|
56e507a7c1 | ||
|
|
ea46e542be | ||
|
|
7b33de30a9 | ||
|
|
f6c7d03357 | ||
|
|
d7e3b79243 | ||
|
|
7a0f039414 | ||
|
|
e8ea7cfc88 | ||
|
|
759c3417d0 | ||
|
|
09c37027ce | ||
|
|
26c5f035c6 | ||
|
|
fedb2aa949 | ||
|
|
de4e77c380 | ||
|
|
99007ab26f | ||
|
|
f9e59f0213 | ||
|
|
0689ef4369 |
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@@ -173,6 +173,11 @@ jobs:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
# We need to fetch more than one commit so that `script/draft-release-notes`
|
||||
# is able to diff between the current and previous tag.
|
||||
#
|
||||
# 25 was chosen arbitrarily.
|
||||
fetch-depth: 25
|
||||
clean: false
|
||||
submodules: "recursive"
|
||||
|
||||
@@ -206,7 +211,8 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
mkdir -p target/
|
||||
script/draft-release-notes "$version" "$channel" > target/release-notes.md
|
||||
# Ignore any errors that occur while drafting release notes to not fail the build.
|
||||
script/draft-release-notes "$version" "$channel" > target/release-notes.md || true
|
||||
|
||||
- name: Generate license file
|
||||
run: script/generate-licenses
|
||||
|
||||
9
Cargo.lock
generated
9
Cargo.lock
generated
@@ -4088,6 +4088,7 @@ name = "fsevent"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"core-foundation",
|
||||
"fsevent-sys 3.1.0",
|
||||
"parking_lot",
|
||||
"tempfile",
|
||||
@@ -5963,9 +5964,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.3"
|
||||
version = "2.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
|
||||
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||
|
||||
[[package]]
|
||||
name = "memfd"
|
||||
@@ -10519,7 +10520,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "tree-sitter"
|
||||
version = "0.20.100"
|
||||
source = "git+https://github.com/tree-sitter/tree-sitter?rev=7f21c3b98c0749ac192da67a0d65dfe3eabc4a63#7f21c3b98c0749ac192da67a0d65dfe3eabc4a63"
|
||||
source = "git+https://github.com/tree-sitter/tree-sitter?rev=7b4894ba2ae81b988846676f54c0988d4027ef4f#7b4894ba2ae81b988846676f54c0988d4027ef4f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"regex",
|
||||
@@ -12607,7 +12608,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zed"
|
||||
version = "0.133.0"
|
||||
version = "0.133.7"
|
||||
dependencies = [
|
||||
"activity_indicator",
|
||||
"anyhow",
|
||||
|
||||
@@ -407,7 +407,7 @@ features = [
|
||||
]
|
||||
|
||||
[patch.crates-io]
|
||||
tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "7f21c3b98c0749ac192da67a0d65dfe3eabc4a63" }
|
||||
tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "7b4894ba2ae81b988846676f54c0988d4027ef4f" }
|
||||
# Workaround for a broken nightly build of gpui: See #7644 and revisit once 0.5.3 is released.
|
||||
pathfinder_simd = { git = "https://github.com/servo/pathfinder.git", rev = "30419d07660dc11a21e42ef4a7fa329600cff152" }
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ use settings::{Settings, SettingsStore};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::io::Write;
|
||||
use std::{env, mem, path::PathBuf, sync::Arc, time::Duration};
|
||||
use sysinfo::{CpuRefreshKind, MemoryRefreshKind, Pid, ProcessRefreshKind, RefreshKind, System};
|
||||
use sysinfo::{CpuRefreshKind, Pid, ProcessRefreshKind, RefreshKind, System};
|
||||
use telemetry_events::{
|
||||
ActionEvent, AppEvent, AssistantEvent, AssistantKind, CallEvent, CopilotEvent, CpuEvent,
|
||||
EditEvent, EditorEvent, Event, EventRequestBody, EventWrapper, ExtensionEvent, MemoryEvent,
|
||||
@@ -171,40 +171,38 @@ impl Telemetry {
|
||||
drop(state);
|
||||
|
||||
let this = self.clone();
|
||||
cx.spawn(|_| async move {
|
||||
// Avoiding calling `System::new_all()`, as there have been crashes related to it
|
||||
let refresh_kind = RefreshKind::new()
|
||||
.with_memory(MemoryRefreshKind::everything()) // For memory usage
|
||||
.with_processes(ProcessRefreshKind::everything()) // For process usage
|
||||
.with_cpu(CpuRefreshKind::everything()); // For core count
|
||||
|
||||
let mut system = System::new_with_specifics(refresh_kind);
|
||||
|
||||
// Avoiding calling `refresh_all()`, just update what we need
|
||||
system.refresh_specifics(refresh_kind);
|
||||
|
||||
// Waiting some amount of time before the first query is important to get a reasonable value
|
||||
// https://docs.rs/sysinfo/0.29.10/sysinfo/trait.ProcessExt.html#tymethod.cpu_usage
|
||||
const DURATION_BETWEEN_SYSTEM_EVENTS: Duration = Duration::from_secs(4 * 60);
|
||||
|
||||
loop {
|
||||
smol::Timer::after(DURATION_BETWEEN_SYSTEM_EVENTS).await;
|
||||
|
||||
system.refresh_specifics(refresh_kind);
|
||||
cx.background_executor()
|
||||
.spawn(async move {
|
||||
let mut system = System::new_with_specifics(
|
||||
RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
|
||||
);
|
||||
|
||||
let refresh_kind = ProcessRefreshKind::new().with_cpu().with_memory();
|
||||
let current_process = Pid::from_u32(std::process::id());
|
||||
let Some(process) = system.processes().get(¤t_process) else {
|
||||
let process = current_process;
|
||||
log::error!("Failed to find own process {process:?} in system process table");
|
||||
// TODO: Fire an error telemetry event
|
||||
return;
|
||||
};
|
||||
system.refresh_process_specifics(current_process, refresh_kind);
|
||||
|
||||
this.report_memory_event(process.memory(), process.virtual_memory());
|
||||
this.report_cpu_event(process.cpu_usage(), system.cpus().len() as u32);
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
// Waiting some amount of time before the first query is important to get a reasonable value
|
||||
// https://docs.rs/sysinfo/0.29.10/sysinfo/trait.ProcessExt.html#tymethod.cpu_usage
|
||||
const DURATION_BETWEEN_SYSTEM_EVENTS: Duration = Duration::from_secs(4 * 60);
|
||||
|
||||
loop {
|
||||
smol::Timer::after(DURATION_BETWEEN_SYSTEM_EVENTS).await;
|
||||
|
||||
let current_process = Pid::from_u32(std::process::id());
|
||||
system.refresh_process_specifics(current_process, refresh_kind);
|
||||
let Some(process) = system.process(current_process) else {
|
||||
log::error!(
|
||||
"Failed to find own process {current_process:?} in system process table"
|
||||
);
|
||||
// TODO: Fire an error telemetry event
|
||||
return;
|
||||
};
|
||||
|
||||
this.report_memory_event(process.memory(), process.virtual_memory());
|
||||
this.report_cpu_event(process.cpu_usage(), system.cpus().len() as u32);
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
pub fn set_authenticated_user_info(
|
||||
|
||||
@@ -887,22 +887,27 @@ fn diagnostic_header_renderer(diagnostic: Diagnostic) -> RenderBlock {
|
||||
})
|
||||
}
|
||||
|
||||
fn compare_diagnostics<L: language::ToOffset, R: language::ToOffset>(
|
||||
lhs: &DiagnosticEntry<L>,
|
||||
rhs: &DiagnosticEntry<R>,
|
||||
fn compare_diagnostics(
|
||||
old: &DiagnosticEntry<language::Anchor>,
|
||||
new: &DiagnosticEntry<language::Anchor>,
|
||||
snapshot: &language::BufferSnapshot,
|
||||
) -> Ordering {
|
||||
lhs.range
|
||||
use language::ToOffset;
|
||||
// The old diagnostics may point to a previously open Buffer for this file.
|
||||
if !old.range.start.is_valid(snapshot) {
|
||||
return Ordering::Greater;
|
||||
}
|
||||
old.range
|
||||
.start
|
||||
.to_offset(snapshot)
|
||||
.cmp(&rhs.range.start.to_offset(snapshot))
|
||||
.cmp(&new.range.start.to_offset(snapshot))
|
||||
.then_with(|| {
|
||||
lhs.range
|
||||
old.range
|
||||
.end
|
||||
.to_offset(snapshot)
|
||||
.cmp(&rhs.range.end.to_offset(snapshot))
|
||||
.cmp(&new.range.end.to_offset(snapshot))
|
||||
})
|
||||
.then_with(|| lhs.diagnostic.message.cmp(&rhs.diagnostic.message))
|
||||
.then_with(|| old.diagnostic.message.cmp(&new.diagnostic.message))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -8200,9 +8200,13 @@ impl Editor {
|
||||
cursor_offset_in_rename_range_end..cursor_offset_in_rename_range
|
||||
}
|
||||
};
|
||||
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.select_ranges([rename_selection_range]);
|
||||
});
|
||||
if rename_selection_range.end > old_name.len() {
|
||||
editor.select_all(&SelectAll, cx);
|
||||
} else {
|
||||
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.select_ranges([rename_selection_range]);
|
||||
});
|
||||
}
|
||||
editor
|
||||
});
|
||||
|
||||
@@ -8982,8 +8986,14 @@ impl Editor {
|
||||
return;
|
||||
};
|
||||
|
||||
if buffer.read(cx).file().is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
let focused = self.focus_handle(cx).contains_focused(cx);
|
||||
let project = project.clone();
|
||||
let blame = cx.new_model(|cx| GitBlame::new(buffer, project, user_triggered, cx));
|
||||
let blame =
|
||||
cx.new_model(|cx| GitBlame::new(buffer, project, user_triggered, focused, cx));
|
||||
self.blame_subscription = Some(cx.observe(&blame, |_, _, cx| cx.notify()));
|
||||
self.blame = Some(blame);
|
||||
}
|
||||
@@ -9971,6 +9981,10 @@ impl Editor {
|
||||
let rename_editor_focus_handle = rename.editor.read(cx).focus_handle.clone();
|
||||
cx.focus(&rename_editor_focus_handle);
|
||||
} else {
|
||||
if let Some(blame) = self.blame.as_ref() {
|
||||
blame.update(cx, GitBlame::focus)
|
||||
}
|
||||
|
||||
self.blink_manager.update(cx, BlinkManager::enable);
|
||||
self.show_cursor_names(cx);
|
||||
self.buffer.update(cx, |buffer, cx| {
|
||||
@@ -9991,6 +10005,10 @@ impl Editor {
|
||||
self.blink_manager.update(cx, BlinkManager::disable);
|
||||
self.buffer
|
||||
.update(cx, |buffer, cx| buffer.remove_active_selections(cx));
|
||||
|
||||
if let Some(blame) = self.blame.as_ref() {
|
||||
blame.update(cx, GitBlame::blur)
|
||||
}
|
||||
self.hide_context_menu(cx);
|
||||
hide_hover(self, cx);
|
||||
cx.emit(EditorEvent::Blurred);
|
||||
@@ -10323,7 +10341,19 @@ impl Render for Editor {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
|
||||
let text_style = match self.mode {
|
||||
EditorMode::SingleLine | EditorMode::AutoHeight { .. } => cx.text_style(),
|
||||
EditorMode::SingleLine | EditorMode::AutoHeight { .. } => TextStyle {
|
||||
color: cx.theme().colors().editor_foreground,
|
||||
font_family: settings.ui_font.family.clone(),
|
||||
font_features: settings.ui_font.features,
|
||||
font_size: rems(0.875).into(),
|
||||
font_weight: FontWeight::NORMAL,
|
||||
font_style: FontStyle::Normal,
|
||||
line_height: relative(settings.buffer_line_height.value()),
|
||||
background_color: None,
|
||||
underline: None,
|
||||
strikethrough: None,
|
||||
white_space: WhiteSpace::Normal,
|
||||
},
|
||||
EditorMode::Full => TextStyle {
|
||||
color: cx.theme().colors().editor_foreground,
|
||||
font_family: settings.buffer_font.family.clone(),
|
||||
|
||||
@@ -1323,7 +1323,7 @@ impl EditorElement {
|
||||
|
||||
fn calculate_relative_line_numbers(
|
||||
&self,
|
||||
buffer_rows: Vec<Option<u32>>,
|
||||
snapshot: &EditorSnapshot,
|
||||
rows: &Range<u32>,
|
||||
relative_to: Option<u32>,
|
||||
) -> HashMap<u32, u32> {
|
||||
@@ -1333,6 +1333,12 @@ impl EditorElement {
|
||||
};
|
||||
|
||||
let start = rows.start.min(relative_to);
|
||||
let end = rows.end.max(relative_to);
|
||||
|
||||
let buffer_rows = snapshot
|
||||
.buffer_rows(start)
|
||||
.take(1 + (end - start) as usize)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let head_idx = relative_to - start;
|
||||
let mut delta = 1;
|
||||
@@ -1407,9 +1413,7 @@ impl EditorElement {
|
||||
None
|
||||
};
|
||||
|
||||
let buffer_rows = buffer_rows.collect::<Vec<_>>();
|
||||
let relative_rows =
|
||||
self.calculate_relative_line_numbers(buffer_rows.clone(), &rows, relative_to);
|
||||
let relative_rows = self.calculate_relative_line_numbers(snapshot, &rows, relative_to);
|
||||
|
||||
for (ix, row) in buffer_rows.into_iter().enumerate() {
|
||||
let display_row = rows.start + ix as u32;
|
||||
@@ -4453,8 +4457,12 @@ mod tests {
|
||||
.unwrap();
|
||||
assert_eq!(layouts.len(), 6);
|
||||
|
||||
let relative_rows =
|
||||
element.calculate_relative_line_numbers((0..6).map(Some).collect(), &(0..6), Some(3));
|
||||
let relative_rows = window
|
||||
.update(cx, |editor, cx| {
|
||||
let snapshot = editor.snapshot(cx);
|
||||
element.calculate_relative_line_numbers(&snapshot, &(0..6), Some(3))
|
||||
})
|
||||
.unwrap();
|
||||
assert_eq!(relative_rows[&0], 3);
|
||||
assert_eq!(relative_rows[&1], 2);
|
||||
assert_eq!(relative_rows[&2], 1);
|
||||
@@ -4463,16 +4471,24 @@ mod tests {
|
||||
assert_eq!(relative_rows[&5], 2);
|
||||
|
||||
// works if cursor is before screen
|
||||
let relative_rows =
|
||||
element.calculate_relative_line_numbers((0..6).map(Some).collect(), &(3..6), Some(1));
|
||||
let relative_rows = window
|
||||
.update(cx, |editor, cx| {
|
||||
let snapshot = editor.snapshot(cx);
|
||||
element.calculate_relative_line_numbers(&snapshot, &(3..6), Some(1))
|
||||
})
|
||||
.unwrap();
|
||||
assert_eq!(relative_rows.len(), 3);
|
||||
assert_eq!(relative_rows[&3], 2);
|
||||
assert_eq!(relative_rows[&4], 3);
|
||||
assert_eq!(relative_rows[&5], 4);
|
||||
|
||||
// works if cursor is after screen
|
||||
let relative_rows =
|
||||
element.calculate_relative_line_numbers((0..6).map(Some).collect(), &(0..3), Some(6));
|
||||
let relative_rows = window
|
||||
.update(cx, |editor, cx| {
|
||||
let snapshot = editor.snapshot(cx);
|
||||
element.calculate_relative_line_numbers(&snapshot, &(0..3), Some(6))
|
||||
})
|
||||
.unwrap();
|
||||
assert_eq!(relative_rows.len(), 3);
|
||||
assert_eq!(relative_rows[&0], 5);
|
||||
assert_eq!(relative_rows[&1], 4);
|
||||
|
||||
@@ -88,7 +88,9 @@ pub struct GitBlame {
|
||||
buffer_snapshot: BufferSnapshot,
|
||||
buffer_edits: text::Subscription,
|
||||
task: Task<Result<()>>,
|
||||
focused: bool,
|
||||
generated: bool,
|
||||
changed_while_blurred: bool,
|
||||
user_triggered: bool,
|
||||
regenerate_on_edit_task: Task<Result<()>>,
|
||||
_regenerate_subscriptions: Vec<Subscription>,
|
||||
@@ -99,6 +101,7 @@ impl GitBlame {
|
||||
buffer: Model<Buffer>,
|
||||
project: Model<Project>,
|
||||
user_triggered: bool,
|
||||
focused: bool,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Self {
|
||||
let entries = SumTree::from_item(
|
||||
@@ -153,6 +156,8 @@ impl GitBlame {
|
||||
entries,
|
||||
buffer_edits,
|
||||
user_triggered,
|
||||
focused,
|
||||
changed_while_blurred: false,
|
||||
commit_details: HashMap::default(),
|
||||
task: Task::ready(Ok(())),
|
||||
generated: false,
|
||||
@@ -186,6 +191,18 @@ impl GitBlame {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn blur(&mut self, _: &mut ModelContext<Self>) {
|
||||
self.focused = false;
|
||||
}
|
||||
|
||||
pub fn focus(&mut self, cx: &mut ModelContext<Self>) {
|
||||
self.focused = true;
|
||||
if self.changed_while_blurred {
|
||||
self.changed_while_blurred = false;
|
||||
self.generate(cx);
|
||||
}
|
||||
}
|
||||
|
||||
fn sync(&mut self, cx: &mut ModelContext<Self>) {
|
||||
let edits = self.buffer_edits.consume();
|
||||
let new_snapshot = self.buffer.read(cx).snapshot();
|
||||
@@ -298,6 +315,10 @@ impl GitBlame {
|
||||
}
|
||||
|
||||
fn generate(&mut self, cx: &mut ModelContext<Self>) {
|
||||
if !self.focused {
|
||||
self.changed_while_blurred = true;
|
||||
return;
|
||||
}
|
||||
let buffer_edits = self.buffer.update(cx, |buffer, _| buffer.subscribe());
|
||||
let snapshot = self.buffer.read(cx).snapshot();
|
||||
let blame = self.project.read(cx).blame_buffer(&self.buffer, None, cx);
|
||||
@@ -544,7 +565,8 @@ mod tests {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let blame = cx.new_model(|cx| GitBlame::new(buffer.clone(), project.clone(), true, cx));
|
||||
let blame =
|
||||
cx.new_model(|cx| GitBlame::new(buffer.clone(), project.clone(), true, true, cx));
|
||||
|
||||
let event = project.next_event(cx).await;
|
||||
assert_eq!(
|
||||
@@ -613,7 +635,7 @@ mod tests {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let git_blame = cx.new_model(|cx| GitBlame::new(buffer.clone(), project, false, cx));
|
||||
let git_blame = cx.new_model(|cx| GitBlame::new(buffer.clone(), project, false, true, cx));
|
||||
|
||||
cx.executor().run_until_parked();
|
||||
|
||||
@@ -693,7 +715,7 @@ mod tests {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let git_blame = cx.new_model(|cx| GitBlame::new(buffer.clone(), project, false, cx));
|
||||
let git_blame = cx.new_model(|cx| GitBlame::new(buffer.clone(), project, false, true, cx));
|
||||
|
||||
cx.executor().run_until_parked();
|
||||
|
||||
@@ -842,7 +864,7 @@ mod tests {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let git_blame = cx.new_model(|cx| GitBlame::new(buffer.clone(), project, false, cx));
|
||||
let git_blame = cx.new_model(|cx| GitBlame::new(buffer.clone(), project, false, true, cx));
|
||||
cx.executor().run_until_parked();
|
||||
git_blame.update(cx, |blame, cx| blame.check_invariants(cx));
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ bitflags.workspace = true
|
||||
parking_lot.workspace = true
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
core-foundation.workspace = true
|
||||
fsevent-sys = "3.0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -120,7 +120,8 @@ impl EventStream {
|
||||
{
|
||||
self.state.callback = Some(Box::new(f));
|
||||
unsafe {
|
||||
let run_loop = cf::CFRunLoopGetCurrent();
|
||||
let run_loop =
|
||||
core_foundation::base::CFRetain(cf::CFRunLoopGetCurrent()) as *mut c_void;
|
||||
{
|
||||
let mut state = self.lifecycle.lock();
|
||||
match *state {
|
||||
@@ -248,6 +249,7 @@ impl Drop for Handle {
|
||||
if let Lifecycle::Running(run_loop) = *state {
|
||||
unsafe {
|
||||
cf::CFRunLoopStop(run_loop);
|
||||
cf::CFRelease(run_loop)
|
||||
}
|
||||
}
|
||||
*state = Lifecycle::Stopped;
|
||||
|
||||
@@ -38,7 +38,6 @@ mod macos {
|
||||
.header("src/platform/mac/dispatch.h")
|
||||
.allowlist_var("_dispatch_main_q")
|
||||
.allowlist_var("_dispatch_source_type_data_add")
|
||||
.allowlist_var("DISPATCH_QUEUE_PRIORITY_DEFAULT")
|
||||
.allowlist_var("DISPATCH_QUEUE_PRIORITY_HIGH")
|
||||
.allowlist_var("DISPATCH_TIME_NOW")
|
||||
.allowlist_function("dispatch_get_global_queue")
|
||||
|
||||
@@ -76,7 +76,7 @@ impl PlatformDispatcher for MacDispatcher {
|
||||
fn dispatch_after(&self, duration: Duration, runnable: Runnable) {
|
||||
unsafe {
|
||||
let queue =
|
||||
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT.try_into().unwrap(), 0);
|
||||
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH.try_into().unwrap(), 0);
|
||||
let when = dispatch_time(DISPATCH_TIME_NOW as u64, duration.as_nanos() as i64);
|
||||
dispatch_after_f(
|
||||
when,
|
||||
|
||||
@@ -55,11 +55,12 @@ impl SvgRenderer {
|
||||
};
|
||||
|
||||
// Render the SVG to a pixmap with the specified width and height.
|
||||
let mut pixmap =
|
||||
resvg::tiny_skia::Pixmap::new(size.width.into(), size.height.into()).unwrap();
|
||||
let mut pixmap = resvg::tiny_skia::Pixmap::new(size.width.into(), size.height.into())
|
||||
.ok_or(usvg::Error::InvalidSize)?;
|
||||
|
||||
let transform = tree.view_box().to_transform(
|
||||
resvg::tiny_skia::Size::from_wh(size.width.0 as f32, size.height.0 as f32).unwrap(),
|
||||
resvg::tiny_skia::Size::from_wh(size.width.0 as f32, size.height.0 as f32)
|
||||
.ok_or(usvg::Error::InvalidSize)?,
|
||||
);
|
||||
|
||||
resvg::render(&tree, transform, &mut pixmap.as_mut());
|
||||
|
||||
@@ -606,13 +606,21 @@ impl SyntaxSnapshot {
|
||||
LogIncludedRanges(&included_ranges),
|
||||
);
|
||||
|
||||
tree = parse_text(
|
||||
let result = parse_text(
|
||||
grammar,
|
||||
text.as_rope(),
|
||||
step_start_byte,
|
||||
included_ranges,
|
||||
Some(old_tree.clone()),
|
||||
);
|
||||
match result {
|
||||
Ok(t) => tree = t,
|
||||
Err(e) => {
|
||||
log::error!("error parsing text: {:?}", e);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
changed_ranges = join_ranges(
|
||||
invalidated_ranges
|
||||
.iter()
|
||||
@@ -651,13 +659,20 @@ impl SyntaxSnapshot {
|
||||
LogIncludedRanges(&included_ranges),
|
||||
);
|
||||
|
||||
tree = parse_text(
|
||||
let result = parse_text(
|
||||
grammar,
|
||||
text.as_rope(),
|
||||
step_start_byte,
|
||||
included_ranges,
|
||||
None,
|
||||
);
|
||||
match result {
|
||||
Ok(t) => tree = t,
|
||||
Err(e) => {
|
||||
log::error!("error parsing text: {:?}", e);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
changed_ranges = vec![step_start_byte..step_end_byte];
|
||||
}
|
||||
|
||||
@@ -1161,16 +1176,12 @@ fn parse_text(
|
||||
start_byte: usize,
|
||||
ranges: Vec<tree_sitter::Range>,
|
||||
old_tree: Option<Tree>,
|
||||
) -> Tree {
|
||||
) -> anyhow::Result<Tree> {
|
||||
PARSER.with(|parser| {
|
||||
let mut parser = parser.borrow_mut();
|
||||
let mut chunks = text.chunks_in_range(start_byte..text.len());
|
||||
parser
|
||||
.set_included_ranges(&ranges)
|
||||
.expect("overlapping ranges");
|
||||
parser
|
||||
.set_language(&grammar.ts_language)
|
||||
.expect("incompatible grammar");
|
||||
parser.set_included_ranges(&ranges)?;
|
||||
parser.set_language(&grammar.ts_language)?;
|
||||
parser
|
||||
.parse_with(
|
||||
&mut move |offset, _| {
|
||||
@@ -1179,7 +1190,7 @@ fn parse_text(
|
||||
},
|
||||
old_tree.as_ref(),
|
||||
)
|
||||
.expect("invalid language")
|
||||
.ok_or_else(|| anyhow::anyhow!("failed to parse"))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -8457,11 +8457,13 @@ impl Project {
|
||||
OpenBuffer::Weak(_) => {}
|
||||
},
|
||||
hash_map::Entry::Vacant(e) => {
|
||||
assert!(
|
||||
is_remote,
|
||||
"received buffer update from {:?}",
|
||||
envelope.original_sender_id
|
||||
);
|
||||
if !is_remote {
|
||||
debug_panic!(
|
||||
"received buffer update from {:?}",
|
||||
envelope.original_sender_id
|
||||
);
|
||||
return Err(anyhow!("received buffer update for non-remote project"));
|
||||
}
|
||||
e.insert(OpenBuffer::Operations(ops));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,8 +98,14 @@ impl PtyProcessInfo {
|
||||
|
||||
fn refresh(&mut self) -> Option<&Process> {
|
||||
let pid = self.pid_getter.pid()?;
|
||||
self.system.refresh_processes_specifics(self.refresh_kind);
|
||||
self.system.process(pid)
|
||||
if self
|
||||
.system
|
||||
.refresh_process_specifics(pid, self.refresh_kind)
|
||||
{
|
||||
self.system.process(pid)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn load(&mut self) -> Option<ProcessInfo> {
|
||||
|
||||
@@ -97,6 +97,8 @@ impl Anchor {
|
||||
pub fn is_valid(&self, buffer: &BufferSnapshot) -> bool {
|
||||
if *self == Anchor::MIN || *self == Anchor::MAX {
|
||||
true
|
||||
} else if self.buffer_id != Some(buffer.remote_id) {
|
||||
false
|
||||
} else {
|
||||
let fragment_id = buffer.fragment_id_for_anchor(self);
|
||||
let mut fragment_cursor = buffer.fragments.cursor::<(Option<&Locator>, usize)>();
|
||||
|
||||
@@ -159,11 +159,21 @@ fn search_submit(workspace: &mut Workspace, _: &SearchSubmit, cx: &mut ViewConte
|
||||
search_bar.select_match(direction, count, cx);
|
||||
search_bar.focus_editor(&Default::default(), cx);
|
||||
|
||||
let prior_selections = state.prior_selections.drain(..).collect();
|
||||
let mut prior_selections: Vec<_> = state.prior_selections.drain(..).collect();
|
||||
let prior_mode = state.prior_mode;
|
||||
let prior_operator = state.prior_operator.take();
|
||||
let new_selections = vim.editor_selections(cx);
|
||||
|
||||
// If the active editor has changed during a search, don't panic.
|
||||
if prior_selections.iter().any(|s| {
|
||||
vim.update_active_editor(cx, |_vim, editor, cx| {
|
||||
!s.start.is_valid(&editor.snapshot(cx).buffer_snapshot)
|
||||
})
|
||||
.unwrap_or(true)
|
||||
}) {
|
||||
prior_selections.clear();
|
||||
}
|
||||
|
||||
if prior_mode != vim.state().mode {
|
||||
vim.switch_mode(prior_mode, true, cx);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::{
|
||||
},
|
||||
toolbar::Toolbar,
|
||||
workspace_settings::{AutosaveSetting, TabBarSettings, WorkspaceSettings},
|
||||
CloseWindow, NewCenterTerminal, NewFile, NewSearch, OpenInTerminal, OpenTerminal, OpenVisible,
|
||||
NewCenterTerminal, NewFile, NewSearch, OpenInTerminal, OpenTerminal, OpenVisible,
|
||||
SplitDirection, ToggleZoom, Workspace,
|
||||
};
|
||||
use anyhow::Result;
|
||||
@@ -879,8 +879,6 @@ impl Pane {
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<Task<Result<()>>> {
|
||||
if self.items.is_empty() {
|
||||
// Close the window when there's no active items to close.
|
||||
cx.dispatch_action(Box::new(CloseWindow));
|
||||
return None;
|
||||
}
|
||||
let active_item_id = self.items[self.active_item_index].item_id();
|
||||
@@ -1889,6 +1887,24 @@ impl Pane {
|
||||
let mut to_pane = cx.view().clone();
|
||||
let mut split_direction = self.drag_split_direction;
|
||||
let paths = paths.paths().to_vec();
|
||||
let is_remote = self
|
||||
.workspace
|
||||
.update(cx, |workspace, cx| {
|
||||
if workspace.project().read(cx).is_remote() {
|
||||
workspace.show_error(
|
||||
&anyhow::anyhow!("Cannot drop files on a remote project"),
|
||||
cx,
|
||||
);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.unwrap_or(true);
|
||||
if is_remote {
|
||||
return;
|
||||
}
|
||||
|
||||
self.workspace
|
||||
.update(cx, |workspace, cx| {
|
||||
let fs = Arc::clone(workspace.project().read(cx).fs());
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
description = "The fast, collaborative code editor."
|
||||
edition = "2021"
|
||||
name = "zed"
|
||||
version = "0.133.0"
|
||||
version = "0.133.7"
|
||||
publish = false
|
||||
license = "GPL-3.0-or-later"
|
||||
authors = ["Zed Team <hi@zed.dev>"]
|
||||
|
||||
@@ -1 +1 @@
|
||||
dev
|
||||
stable
|
||||
@@ -27,13 +27,18 @@ async function main() {
|
||||
if (parts[2] == 0) {
|
||||
priorVersion = [parts[0], parts[1] - 1, 0].join(".");
|
||||
}
|
||||
} else if (!tagExists("v${priorVersion}")) {
|
||||
} else if (!ensureTag(`v${priorVersion}`)) {
|
||||
console.log("Copy the release notes from preview.");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
let [tag, priorTag] = [`v${version}${suffix}`, `v${priorVersion}${suffix}`];
|
||||
|
||||
if (!ensureTag(tag) || !ensureTag(priorTag)) {
|
||||
console.log("Could not draft release notes, missing a tag:", tag, priorTag);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const newCommits = getCommits(priorTag, tag);
|
||||
|
||||
let releaseNotes = [];
|
||||
@@ -99,11 +104,17 @@ function getCommits(oldTag, newTag) {
|
||||
return pullRequestNumbers;
|
||||
}
|
||||
|
||||
function tagExists(tag) {
|
||||
function ensureTag(tag) {
|
||||
try {
|
||||
execFileSync("git", ["rev-parse", "--verify", tag]);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
try {
|
||||
execFileSync("git"[("fetch", "origin", "--shallow-exclude", tag)]);
|
||||
execFileSync("git"[("fetch", "origin", "--deepen", "1")]);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user