Compare commits
7 Commits
fix-vim-se
...
revert-opt
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
151926af56 | ||
|
|
6750de3830 | ||
|
|
0c9992c5e9 | ||
|
|
cec46079fe | ||
|
|
f9b69aeff0 | ||
|
|
f00cb371f4 | ||
|
|
25e1e2ecdd |
@@ -15,6 +15,7 @@ use askpass::AskPassDelegate;
|
||||
use cloud_llm_client::CompletionIntent;
|
||||
use collections::{BTreeMap, HashMap, HashSet};
|
||||
use db::kvp::KEY_VALUE_STORE;
|
||||
use editor::RewrapOptions;
|
||||
use editor::{
|
||||
Direction, Editor, EditorElement, EditorMode, MultiBuffer, MultiBufferOffset,
|
||||
actions::ExpandAllDiffHunks,
|
||||
@@ -2180,7 +2181,13 @@ impl GitPanel {
|
||||
let editor = cx.new(|cx| Editor::for_buffer(buffer, None, window, cx));
|
||||
let wrapped_message = editor.update(cx, |editor, cx| {
|
||||
editor.select_all(&Default::default(), window, cx);
|
||||
editor.rewrap(&Default::default(), window, cx);
|
||||
editor.rewrap_impl(
|
||||
RewrapOptions {
|
||||
override_language_settings: false,
|
||||
preserve_existing_whitespace: true,
|
||||
},
|
||||
cx,
|
||||
);
|
||||
editor.text(cx)
|
||||
});
|
||||
if wrapped_message.trim().is_empty() {
|
||||
|
||||
@@ -1025,13 +1025,26 @@ impl PlatformWindow for WaylandWindow {
|
||||
fn resize(&mut self, size: Size<Pixels>) {
|
||||
let state = self.borrow();
|
||||
let state_ptr = self.0.clone();
|
||||
let dp_size = size.to_device_pixels(self.scale_factor());
|
||||
|
||||
// Keep window geometry consistent with configure handling. On Wayland, window geometry is
|
||||
// surface-local: resizing should not attempt to translate the window; the compositor
|
||||
// controls placement. We also account for client-side decoration insets and tiling.
|
||||
let window_geometry = inset_by_tiling(
|
||||
Bounds {
|
||||
origin: Point::default(),
|
||||
size,
|
||||
},
|
||||
state.inset(),
|
||||
state.tiling,
|
||||
)
|
||||
.map(|v| v.0 as i32)
|
||||
.map_size(|v| if v <= 0 { 1 } else { v });
|
||||
|
||||
state.surface_state.set_geometry(
|
||||
state.bounds.origin.x.0 as i32,
|
||||
state.bounds.origin.y.0 as i32,
|
||||
dp_size.width.0,
|
||||
dp_size.height.0,
|
||||
window_geometry.origin.x,
|
||||
window_geometry.origin.y,
|
||||
window_geometry.size.width,
|
||||
window_geometry.size.height,
|
||||
);
|
||||
|
||||
state
|
||||
|
||||
@@ -1672,59 +1672,6 @@ impl GitStore {
|
||||
}
|
||||
}
|
||||
|
||||
fn mark_entries_pending_by_project_paths(
|
||||
&mut self,
|
||||
project_paths: &[ProjectPath],
|
||||
stage: bool,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let buffer_store = &self.buffer_store;
|
||||
|
||||
for project_path in project_paths {
|
||||
let Some(buffer) = buffer_store.read(cx).get_by_path(project_path) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let buffer_id = buffer.read(cx).remote_id();
|
||||
let Some(diff_state) = self.diffs.get(&buffer_id) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
diff_state.update(cx, |diff_state, cx| {
|
||||
let Some(uncommitted_diff) = diff_state.uncommitted_diff() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let buffer_snapshot = buffer.read(cx).text_snapshot();
|
||||
let file_exists = buffer
|
||||
.read(cx)
|
||||
.file()
|
||||
.is_some_and(|file| file.disk_state().exists());
|
||||
|
||||
let all_hunks: Vec<_> = uncommitted_diff
|
||||
.read(cx)
|
||||
.hunks_intersecting_range(
|
||||
text::Anchor::MIN..text::Anchor::MAX,
|
||||
&buffer_snapshot,
|
||||
cx,
|
||||
)
|
||||
.collect();
|
||||
|
||||
if !all_hunks.is_empty() {
|
||||
uncommitted_diff.update(cx, |diff, cx| {
|
||||
diff.stage_or_unstage_hunks(
|
||||
stage,
|
||||
&all_hunks,
|
||||
&buffer_snapshot,
|
||||
file_exists,
|
||||
cx,
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn git_clone(
|
||||
&self,
|
||||
repo: String,
|
||||
@@ -4253,28 +4200,6 @@ impl Repository {
|
||||
save_futures
|
||||
}
|
||||
|
||||
fn mark_entries_pending_for_stage(
|
||||
&self,
|
||||
entries: &[RepoPath],
|
||||
stage: bool,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let Some(git_store) = self.git_store() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut project_paths = Vec::new();
|
||||
for repo_path in entries {
|
||||
if let Some(project_path) = self.repo_path_to_project_path(repo_path, cx) {
|
||||
project_paths.push(project_path);
|
||||
}
|
||||
}
|
||||
|
||||
git_store.update(cx, move |git_store, cx| {
|
||||
git_store.mark_entries_pending_by_project_paths(&project_paths, stage, cx);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn stage_entries(
|
||||
&mut self,
|
||||
entries: Vec<RepoPath>,
|
||||
@@ -4283,9 +4208,6 @@ impl Repository {
|
||||
if entries.is_empty() {
|
||||
return Task::ready(Ok(()));
|
||||
}
|
||||
|
||||
self.mark_entries_pending_for_stage(&entries, true, cx);
|
||||
|
||||
let id = self.id;
|
||||
let save_tasks = self.save_buffers(&entries, cx);
|
||||
let paths = entries
|
||||
@@ -4351,9 +4273,6 @@ impl Repository {
|
||||
if entries.is_empty() {
|
||||
return Task::ready(Ok(()));
|
||||
}
|
||||
|
||||
self.mark_entries_pending_for_stage(&entries, false, cx);
|
||||
|
||||
let id = self.id;
|
||||
let save_tasks = self.save_buffers(&entries, cx);
|
||||
let paths = entries
|
||||
|
||||
@@ -8,8 +8,8 @@ mod terminal_slash_command;
|
||||
use assistant_slash_command::SlashCommandRegistry;
|
||||
use editor::{EditorSettings, actions::SelectAll, blink_manager::BlinkManager};
|
||||
use gpui::{
|
||||
Action, AnyElement, App, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable,
|
||||
KeyContext, KeyDownEvent, Keystroke, MouseButton, MouseDownEvent, Pixels, Render,
|
||||
Action, AnyElement, App, ClipboardEntry, DismissEvent, Entity, EventEmitter, FocusHandle,
|
||||
Focusable, KeyContext, KeyDownEvent, Keystroke, MouseButton, MouseDownEvent, Pixels, Render,
|
||||
ScrollWheelEvent, Styled, Subscription, Task, WeakEntity, actions, anchored, deferred, div,
|
||||
};
|
||||
use persistence::TERMINAL_DB;
|
||||
@@ -687,10 +687,30 @@ impl TerminalView {
|
||||
|
||||
///Attempt to paste the clipboard into the terminal
|
||||
fn paste(&mut self, _: &Paste, _: &mut Window, cx: &mut Context<Self>) {
|
||||
if let Some(clipboard_string) = cx.read_from_clipboard().and_then(|item| item.text()) {
|
||||
self.terminal
|
||||
.update(cx, |terminal, _cx| terminal.paste(&clipboard_string));
|
||||
let Some(clipboard) = cx.read_from_clipboard() else {
|
||||
return;
|
||||
};
|
||||
|
||||
if clipboard.entries().iter().any(|entry| match entry {
|
||||
ClipboardEntry::Image(image) => !image.bytes.is_empty(),
|
||||
_ => false,
|
||||
}) {
|
||||
self.forward_ctrl_v(cx);
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(text) = clipboard.text() {
|
||||
self.terminal
|
||||
.update(cx, |terminal, _cx| terminal.paste(&text));
|
||||
}
|
||||
}
|
||||
|
||||
/// Emits a raw Ctrl+V so TUI agents can read the OS clipboard directly
|
||||
/// and attach images using their native workflows.
|
||||
fn forward_ctrl_v(&self, cx: &mut Context<Self>) {
|
||||
self.terminal.update(cx, |term, _| {
|
||||
term.input(vec![0x16]);
|
||||
});
|
||||
}
|
||||
|
||||
fn send_text(&mut self, text: &SendText, _: &mut Window, cx: &mut Context<Self>) {
|
||||
|
||||
@@ -886,8 +886,12 @@ impl<T: Item> ItemHandle for Entity<T> {
|
||||
// Only trigger autosave if focus has truly left the item.
|
||||
// If focus is still within the item's hierarchy (e.g., moved to a context menu),
|
||||
// don't trigger autosave to avoid unwanted formatting and cursor jumps.
|
||||
// Also skip autosave if focus moved to a modal (e.g., command palette),
|
||||
// since the user is still interacting with the workspace.
|
||||
let focus_handle = item.item_focus_handle(cx);
|
||||
if !focus_handle.contains_focused(window, cx) {
|
||||
if !focus_handle.contains_focused(window, cx)
|
||||
&& !workspace.has_active_modal(window, cx)
|
||||
{
|
||||
Pane::autosave_item(&item, workspace.project.clone(), window, cx)
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
BIN
crates/zed/resources/Document.icns
Normal file
BIN
crates/zed/resources/Document.icns
Normal file
Binary file not shown.
@@ -1,7 +1,4 @@
|
||||
mod app_menus;
|
||||
pub mod component_preview;
|
||||
pub mod edit_prediction_registry;
|
||||
#[cfg(target_os = "macos")]
|
||||
pub(crate) mod mac_only_instance;
|
||||
mod migrate;
|
||||
mod open_listener;
|
||||
|
||||
@@ -106,6 +106,17 @@ mv Cargo.toml.backup Cargo.toml
|
||||
popd
|
||||
echo "Bundled ${app_path}"
|
||||
|
||||
# DocumentTypes.plist references CFBundleTypeIconFile "Document", so the bundle must contain Document.icns.
|
||||
# We use the app icon as a placeholder document icon for now.
|
||||
document_icon_source="crates/zed/resources/Document.icns"
|
||||
document_icon_target="${app_path}/Contents/Resources/Document.icns"
|
||||
if [[ -f "${document_icon_source}" ]]; then
|
||||
mkdir -p "$(dirname "${document_icon_target}")"
|
||||
cp "${document_icon_source}" "${document_icon_target}"
|
||||
else
|
||||
echo "cargo::warning=Missing ${document_icon_source}; macOS document icons may not appear in Finder."
|
||||
fi
|
||||
|
||||
if [[ -n "${MACOS_CERTIFICATE:-}" && -n "${MACOS_CERTIFICATE_PASSWORD:-}" && -n "${APPLE_NOTARIZATION_KEY:-}" && -n "${APPLE_NOTARIZATION_KEY_ID:-}" && -n "${APPLE_NOTARIZATION_ISSUER_ID:-}" ]]; then
|
||||
can_code_sign=true
|
||||
|
||||
|
||||
81
script/verify-macos-document-icon
Executable file
81
script/verify-macos-document-icon
Executable file
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage:
|
||||
script/verify-macos-document-icon /path/to/Zed.app
|
||||
|
||||
Verifies that the given macOS app bundle's Info.plist references a document icon
|
||||
named "Document" and that the corresponding icon file exists in the bundle.
|
||||
|
||||
Specifically checks:
|
||||
- CFBundleDocumentTypes[*].CFBundleTypeIconFile includes "Document"
|
||||
- Contents/Resources/Document.icns exists
|
||||
|
||||
Exit codes:
|
||||
0 - success
|
||||
1 - verification failed
|
||||
2 - invalid usage / missing prerequisites
|
||||
USAGE
|
||||
}
|
||||
|
||||
fail() {
|
||||
echo "error: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [[ $# -ne 1 ]]; then
|
||||
usage >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
app_path="$1"
|
||||
|
||||
if [[ ! -d "${app_path}" ]]; then
|
||||
fail "app bundle not found: ${app_path}"
|
||||
fi
|
||||
|
||||
info_plist="${app_path}/Contents/Info.plist"
|
||||
if [[ ! -f "${info_plist}" ]]; then
|
||||
fail "missing Info.plist: ${info_plist}"
|
||||
fi
|
||||
|
||||
if ! command -v plutil >/dev/null 2>&1; then
|
||||
fail "plutil not found (required on macOS to read Info.plist)"
|
||||
fi
|
||||
|
||||
# Convert to JSON for robust parsing. plutil outputs JSON to stdout in this mode.
|
||||
info_json="$(plutil -convert json -o - "${info_plist}")"
|
||||
|
||||
# Check that CFBundleDocumentTypes exists and that at least one entry references "Document".
|
||||
# We use Python for JSON parsing; macOS ships with Python 3 on many setups, but not all.
|
||||
# If python3 isn't available, fall back to a simpler grep-based check.
|
||||
has_document_icon_ref="false"
|
||||
if command -v python3 >/dev/null 2>&1; then
|
||||
has_document_icon_ref="$(python3 -c "import json,sys; d=json.load(sys.stdin); types=d.get('CFBundleDocumentTypes', []); vals=[t.get('CFBundleTypeIconFile') for t in types if isinstance(t, dict)]; print('true' if 'Document' in vals else 'false')" <<<"${info_json}")"
|
||||
else
|
||||
# This is a best-effort fallback. It may produce false negatives if the JSON formatting differs.
|
||||
if echo "${info_json}" | grep -q '"CFBundleTypeIconFile"[[:space:]]*:[[:space:]]*"Document"'; then
|
||||
has_document_icon_ref="true"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${has_document_icon_ref}" != "true" ]]; then
|
||||
echo "Verification failed for: ${app_path}" >&2
|
||||
echo "Expected Info.plist to reference CFBundleTypeIconFile \"Document\" in CFBundleDocumentTypes." >&2
|
||||
echo "Tip: This bundle may be missing DocumentTypes.plist extensions or may have different icon naming." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
document_icon_path="${app_path}/Contents/Resources/Document.icns"
|
||||
if [[ ! -f "${document_icon_path}" ]]; then
|
||||
echo "Verification failed for: ${app_path}" >&2
|
||||
echo "Expected document icon to exist: ${document_icon_path}" >&2
|
||||
echo "Tip: The bundle script should copy crates/zed/resources/Document.icns into Contents/Resources/Document.icns." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "OK: ${app_path}"
|
||||
echo " - Info.plist references CFBundleTypeIconFile \"Document\""
|
||||
echo " - Found ${document_icon_path}"
|
||||
Reference in New Issue
Block a user