Compare commits

...

20 Commits

Author SHA1 Message Date
Joseph T. Lyons
707da9bbbf v0.97.x stable 2023-08-02 13:50:08 -04:00
Mikayla Maki
c826010008 Halve opacity on wrap guides (#2815)
Wrap guides are a little too bright as is
2023-08-02 12:52:33 -04:00
Mikayla Maki
e928e1db4e disable wrap guides in the assitant panel (#2814)
Wrap guides do not look correct in the assistant due to it's current
header styling. Disable them in that context now.

Release Notes:

- Fix a visual bug displaying when enabling wrap guides in the
assistant.
2023-08-02 12:51:34 -04:00
Joseph T. Lyons
f5b1962b0e zed 0.97.5 2023-07-28 18:13:24 -04:00
Mikayla Maki
0b13c6bc84 Make wrap guides respect scroll position (#2810)
Release Notes:

- Fixed a visual bug when scrolling with wrap guides active
2023-07-28 18:11:23 -04:00
Joseph T. Lyons
75365249cc Update release action to choose between preview and stable URL in Discord announcements
This is what ChatGPT told me, so we'll see.
2023-07-28 15:12:46 -04:00
Conrad Irwin
1c2f5162bc Don't highlight project search matches either (#2807)
@JosephTLyons this is probably worth merging alongside #2803

- vim: Fix a bug where focusing project search results unexpectedly
entered visual mode
2023-07-28 14:31:22 -04:00
Conrad Irwin
209c68c85e Fix jumping to definition in a new file (#2803)
This is broken because vim currently sets settings only on the active
editor. Fix this by correcting the range on the currently active editor.

It would be nice (at some point) to refactor how vim sets settings, but
that's for another day.

Release Notes:

- vim: Fix bug when jumping to definition in new file accidentally
entered visual mode.
2023-07-28 14:30:58 -04:00
Mikayla Maki
023a617b30 zed 0.97.4 2023-07-27 16:36:49 -07:00
Mikayla Maki
286d302273 Make mode indicator follow vim enabled state (#2802)
There was a minor visual bug introduced in
https://github.com/zed-industries/zed/pull/2801, this PR corrects it.

Release Notes:

- N/A
2023-07-27 16:32:28 -07:00
Julia
4091a2004e Avoid panic by accessing view handle by global in wrong window
View handles are window specific but this global will be doing things
in all windows, that would cause a panic when it attempted to update
a status bar mode indicator in a background window

Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2023-07-27 16:32:20 -07:00
Joseph T. Lyons
9d4a2bfb58 Publish preview releases to discord (#2800)
Release Notes:

- N/A
2023-07-27 15:26:36 -04:00
Joseph T. Lyons
33e58d47ac zed 0.97.3 2023-07-27 14:30:24 -04:00
Mikayla Maki
056282f59b Downgrade our dependency on treesitter-cpp (#2799)
Our dependency on `tree-sitter-cpp` got upgraded to an incompatible
version despite semver 'guarantees'. This pins the dependency onto the
commit of version 0.20.0

Release Notes:

- Restored language detection for C++ (preview-only)
2023-07-27 14:21:16 -04:00
Antonio Scandurra
553b9601d1 zed 0.97.2 2023-07-27 14:47:09 +02:00
Antonio Scandurra
a166f0b56a Maintain cursor stack's position correctly when ascending the tree (#2795)
This fixes a bug that could cause the cursor to incorrectly report its
start when using `slice` or `seek_forward`, and then calling `prev`. We
didn't notice this because we were not testing those three methods
together.

I suppose this could explain some of the panics we've observed because
we do use `slice`/`seek_forward` followed by `prev` calls in production.
2023-07-27 14:45:38 +02:00
Joseph T. Lyons
badc2ec0e9 zed 0.97.1 2023-07-26 18:57:44 -04:00
Mikayla Maki
9c3c719ce0 Downgrade tree sitter elm to 5.6.4 (#2794)
The tree sitter elm parser contains a c symbol which collides with other
linked symbols. This PR downgrades the tree sitter elm parser to a
version which doesn't have this problem.

Release Notes:
- Fixed crash when parsing elm files
2023-07-26 18:55:24 -04:00
Mikayla Maki
3594b5e2a8 Block extra drag events in original drag handlers (#2793)
In https://github.com/zed-industries/zed/pull/2790 I added an extra drag
event on mouse_up which signaled the end of a drag event, as mouse_up
event themselves wouldn't reliably fire if users moved their mouse too
quickly. This broke the assumptions of the terminal element. This PR
adds filters to all current on_drag handlers which removes this new
event.

Release Notes:

- Fixed a bug causing terminal links to never open (preview only)
- Fixed a bug in terminal link detection causing it to miss files with a
`-` in it
2023-07-26 18:20:50 -04:00
Joseph T. Lyons
99d0ed4a76 v0.97.x preview 2023-07-26 13:27:34 -04:00
21 changed files with 193 additions and 96 deletions

View File

@@ -6,14 +6,23 @@ jobs:
discord_release:
runs-on: ubuntu-latest
steps:
- name: Get appropriate URL
id: get-appropriate-url
run: |
if [ "${{ github.event.release.prerelease }}" == "true" ]; then
URL="https://zed.dev/releases/preview/latest"
else
URL="https://zed.dev/releases/stable/latest"
fi
echo "::set-output name=URL::$URL"
- name: Discord Webhook Action
uses: tsickert/discord-webhook@v5.3.0
if: ${{ ! github.event.release.prerelease }}
with:
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
content: |
📣 Zed ${{ github.event.release.tag_name }} was just released!
Restart your Zed or head to https://zed.dev/releases/stable/latest to grab it.
Restart your Zed or head to ${{ steps.get-appropriate-url.outputs.URL }} to grab it.
${{ github.event.release.body }}

24
Cargo.lock generated
View File

@@ -6513,7 +6513,7 @@ dependencies = [
"theme",
"tiktoken-rs 0.5.0",
"tree-sitter",
"tree-sitter-cpp",
"tree-sitter-cpp 0.20.2",
"tree-sitter-elixir 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tree-sitter-json 0.19.0",
"tree-sitter-rust",
@@ -8032,9 +8032,18 @@ dependencies = [
[[package]]
name = "tree-sitter-cpp"
version = "0.20.1"
version = "0.20.0"
source = "git+https://github.com/tree-sitter/tree-sitter-cpp?rev=f44509141e7e483323d2ec178f2d2e6c0fc041c1#f44509141e7e483323d2ec178f2d2e6c0fc041c1"
dependencies = [
"cc",
"tree-sitter",
]
[[package]]
name = "tree-sitter-cpp"
version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dbedbf4066bfab725b3f9e2a21530507419a7d2f98621d3c13213502b734ec0"
checksum = "1c88fd925d0333e63ac64e521f5bd79c53019e569ffbbccfeef346a326f459e9"
dependencies = [
"cc",
"tree-sitter",
@@ -8070,9 +8079,8 @@ dependencies = [
[[package]]
name = "tree-sitter-elm"
version = "5.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95236155fa1cd5fcf92123e7e6aa7b6e8c6756b54b5d39afd792a23bd6c9eb7b"
version = "5.6.4"
source = "git+https://github.com/elm-tooling/tree-sitter-elm?rev=692c50c0b961364c40299e73c1306aecb5d20f40#692c50c0b961364c40299e73c1306aecb5d20f40"
dependencies = [
"cc",
"tree-sitter",
@@ -9536,7 +9544,7 @@ dependencies = [
[[package]]
name = "zed"
version = "0.97.0"
version = "0.97.5"
dependencies = [
"activity_indicator",
"ai",
@@ -9623,7 +9631,7 @@ dependencies = [
"tree-sitter",
"tree-sitter-bash",
"tree-sitter-c",
"tree-sitter-cpp",
"tree-sitter-cpp 0.20.0",
"tree-sitter-css",
"tree-sitter-elixir 0.1.0 (git+https://github.com/elixir-lang/tree-sitter-elixir?rev=4ba9dab6e2602960d95b2b625f3386c27e08084e)",
"tree-sitter-elm",

View File

@@ -109,10 +109,10 @@ pretty_assertions = "1.3.0"
tree-sitter-bash = { git = "https://github.com/tree-sitter/tree-sitter-bash", rev = "1b0321ee85701d5036c334a6f04761cdc672e64c" }
tree-sitter-c = "0.20.1"
tree-sitter-cpp = "0.20.0"
tree-sitter-cpp = { git = "https://github.com/tree-sitter/tree-sitter-cpp", rev="f44509141e7e483323d2ec178f2d2e6c0fc041c1" }
tree-sitter-css = { git = "https://github.com/tree-sitter/tree-sitter-css", rev = "769203d0f9abe1a9a691ac2b9fe4bb4397a73c51" }
tree-sitter-elixir = { git = "https://github.com/elixir-lang/tree-sitter-elixir", rev = "4ba9dab6e2602960d95b2b625f3386c27e08084e" }
tree-sitter-elm = "5.6.4"
tree-sitter-elm = { git = "https://github.com/elm-tooling/tree-sitter-elm", rev = "692c50c0b961364c40299e73c1306aecb5d20f40"}
tree-sitter-embedded-template = "0.20.0"
tree-sitter-glsl = { git = "https://github.com/theHamsta/tree-sitter-glsl", rev = "2a56fb7bc8bb03a1892b4741279dd0a8758b7fb3" }
tree-sitter-go = { git = "https://github.com/tree-sitter/tree-sitter-go", rev = "aeb2f33b366fd78d5789ff104956ce23508b85db" }

View File

@@ -1637,6 +1637,7 @@ impl ConversationEditor {
let mut editor = Editor::for_buffer(conversation.read(cx).buffer.clone(), None, cx);
editor.set_soft_wrap_mode(SoftWrap::EditorWidth, cx);
editor.set_show_gutter(false, cx);
editor.set_show_wrap_guides(false, cx);
editor
});

View File

@@ -543,6 +543,7 @@ pub struct Editor {
show_local_selections: bool,
mode: EditorMode,
show_gutter: bool,
show_wrap_guides: Option<bool>,
placeholder_text: Option<Arc<str>>,
highlighted_rows: Option<Range<u32>>,
#[allow(clippy::type_complexity)]
@@ -1375,6 +1376,7 @@ impl Editor {
show_local_selections: true,
mode,
show_gutter: mode == EditorMode::Full,
show_wrap_guides: None,
placeholder_text: None,
highlighted_rows: None,
background_highlights: Default::default(),
@@ -1537,7 +1539,7 @@ impl Editor {
self.collapse_matches = collapse_matches;
}
fn range_for_match<T: std::marker::Copy>(&self, range: &Range<T>) -> Range<T> {
pub fn range_for_match<T: std::marker::Copy>(&self, range: &Range<T>) -> Range<T> {
if self.collapse_matches {
return range.start..range.start;
}
@@ -6374,8 +6376,8 @@ impl Editor {
.range
.to_offset(definition.target.buffer.read(cx));
let range = self.range_for_match(&range);
if Some(&definition.target.buffer) == self.buffer.read(cx).as_singleton().as_ref() {
let range = self.range_for_match(&range);
self.change_selections(Some(Autoscroll::fit()), cx, |s| {
s.select_ranges([range]);
});
@@ -6392,7 +6394,6 @@ impl Editor {
// When selecting a definition in a different buffer, disable the nav history
// to avoid creating a history entry at the previous cursor location.
pane.update(cx, |pane, _| pane.disable_history());
let range = target_editor.range_for_match(&range);
target_editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
s.select_ranges([range]);
});
@@ -7188,6 +7189,10 @@ impl Editor {
pub fn wrap_guides(&self, cx: &AppContext) -> SmallVec<[(usize, bool); 2]> {
let mut wrap_guides = smallvec::smallvec![];
if self.show_wrap_guides == Some(false) {
return wrap_guides;
}
let settings = self.buffer.read(cx).settings_at(0, cx);
if settings.show_wrap_guides {
if let SoftWrap::Column(soft_wrap) = self.soft_wrap_mode(cx) {
@@ -7245,6 +7250,11 @@ impl Editor {
cx.notify();
}
pub fn set_show_wrap_guides(&mut self, show_gutter: bool, cx: &mut ViewContext<Self>) {
self.show_wrap_guides = Some(show_gutter);
cx.notify();
}
pub fn reveal_in_finder(&mut self, _: &RevealInFinder, cx: &mut ViewContext<Self>) {
if let Some(buffer) = self.buffer().read(cx).as_singleton() {
if let Some(file) = buffer.read(cx).file().and_then(|f| f.as_local()) {

View File

@@ -172,6 +172,10 @@ impl EditorElement {
.on_drag(MouseButton::Left, {
let position_map = position_map.clone();
move |event, editor, cx| {
if event.end {
return;
}
if !Self::mouse_dragged(
editor,
event.platform_event,
@@ -542,8 +546,20 @@ impl EditorElement {
});
}
let scroll_left =
layout.position_map.snapshot.scroll_position().x() * layout.position_map.em_width;
for (wrap_position, active) in layout.wrap_guides.iter() {
let x = text_bounds.origin_x() + wrap_position + layout.position_map.em_width / 2.;
let x =
(text_bounds.origin_x() + wrap_position + layout.position_map.em_width / 2.)
- scroll_left;
if x < text_bounds.origin_x()
|| (layout.show_scrollbars && x > self.scrollbar_left(&bounds))
{
continue;
}
let color = if *active {
self.style.active_wrap_guide
} else {
@@ -1032,6 +1048,10 @@ impl EditorElement {
scene.pop_layer();
}
fn scrollbar_left(&self, bounds: &RectF) -> f32 {
bounds.max_x() - self.style.theme.scrollbar.width
}
fn paint_scrollbar(
&mut self,
scene: &mut SceneBuilder,
@@ -1050,7 +1070,7 @@ impl EditorElement {
let top = bounds.min_y();
let bottom = bounds.max_y();
let right = bounds.max_x();
let left = right - style.width;
let left = self.scrollbar_left(&bounds);
let row_range = &layout.scrollbar_row_range;
let max_row = layout.max_row as f32 + (row_range.end - row_range.start);
@@ -1235,6 +1255,10 @@ impl EditorElement {
})
.on_drag(MouseButton::Left, {
move |event, editor: &mut Editor, cx| {
if event.end {
return;
}
let y = event.prev_mouse_position.y();
let new_y = event.position.y();
if thumb_top < y && y < thumb_bottom {

View File

@@ -147,6 +147,9 @@ impl<V: View> Element<V> for Resizable<V> {
let max_size = side.relevant_component(constraint.max);
let on_resize = self.on_resize.clone();
move |event, view: &mut V, cx| {
if event.end {
return;
}
let new_size = min_size
.max(prev_size + side.compute_delta(event))
.min(max_size)

View File

@@ -844,8 +844,8 @@ impl LanguageRegistry {
}
}
}
Err(err) => {
log::error!("failed to load language {name} - {err}");
Err(e) => {
log::error!("failed to load language {name}:\n{:?}", e);
let mut state = this.state.write();
state.mark_language_loaded(id);
if let Some(mut txs) = state.loading_languages.remove(&id) {
@@ -853,7 +853,7 @@ impl LanguageRegistry {
let _ = tx.send(Err(anyhow!(
"failed to load language {}: {}",
name,
err
e
)));
}
}
@@ -1188,25 +1188,39 @@ impl Language {
pub fn with_queries(mut self, queries: LanguageQueries) -> Result<Self> {
if let Some(query) = queries.highlights {
self = self.with_highlights_query(query.as_ref())?;
self = self
.with_highlights_query(query.as_ref())
.context("Error loading highlights query")?;
}
if let Some(query) = queries.brackets {
self = self.with_brackets_query(query.as_ref())?;
self = self
.with_brackets_query(query.as_ref())
.context("Error loading brackets query")?;
}
if let Some(query) = queries.indents {
self = self.with_indents_query(query.as_ref())?;
self = self
.with_indents_query(query.as_ref())
.context("Error loading indents query")?;
}
if let Some(query) = queries.outline {
self = self.with_outline_query(query.as_ref())?;
self = self
.with_outline_query(query.as_ref())
.context("Error loading outline query")?;
}
if let Some(query) = queries.embedding {
self = self.with_embedding_query(query.as_ref())?;
self = self
.with_embedding_query(query.as_ref())
.context("Error loading embedding query")?;
}
if let Some(query) = queries.injections {
self = self.with_injection_query(query.as_ref())?;
self = self
.with_injection_query(query.as_ref())
.context("Error loading injection query")?;
}
if let Some(query) = queries.overrides {
self = self.with_override_query(query.as_ref())?;
self = self
.with_override_query(query.as_ref())
.context("Error loading override query")?;
}
Ok(self)
}

View File

@@ -783,6 +783,7 @@ impl ProjectSearchView {
let range_to_select = match_ranges[new_index].clone();
self.results_editor.update(cx, |editor, cx| {
let range_to_select = editor.range_for_match(&range_to_select);
editor.unfold_ranges([range_to_select.clone()], false, true, cx);
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
s.select_ranges([range_to_select])
@@ -824,8 +825,12 @@ impl ProjectSearchView {
let is_new_search = self.search_id != prev_search_id;
self.results_editor.update(cx, |editor, cx| {
if is_new_search {
let range_to_select = match_ranges
.first()
.clone()
.map(|range| editor.range_for_match(range));
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
s.select_ranges(match_ranges.first().cloned())
s.select_ranges(range_to_select)
});
}
editor.highlight_background::<Self>(

View File

@@ -438,6 +438,7 @@ where
} => {
if ascending {
entry.index += 1;
entry.position = self.position.clone();
}
for (child_tree, child_summary) in child_trees[entry.index..]

View File

@@ -738,7 +738,7 @@ mod tests {
for _ in 0..num_operations {
let splice_end = rng.gen_range(0..tree.extent::<Count>(&()).0 + 1);
let splice_start = rng.gen_range(0..splice_end + 1);
let count = rng.gen_range(0..3);
let count = rng.gen_range(0..10);
let tree_end = tree.extent::<Count>(&());
let new_items = rng
.sample_iter(distributions::Standard)
@@ -805,10 +805,12 @@ mod tests {
}
assert_eq!(filter_cursor.item(), None);
let mut pos = rng.gen_range(0..tree.extent::<Count>(&()).0 + 1);
let mut before_start = false;
let mut cursor = tree.cursor::<Count>();
cursor.seek(&Count(pos), Bias::Right, &());
let start_pos = rng.gen_range(0..=reference_items.len());
cursor.seek(&Count(start_pos), Bias::Right, &());
let mut pos = rng.gen_range(start_pos..=reference_items.len());
cursor.seek_forward(&Count(pos), Bias::Right, &());
for i in 0..10 {
assert_eq!(cursor.start().0, pos);

View File

@@ -78,7 +78,7 @@ lazy_static! {
// * use more strict regex for `file://` protocol matching: original regex has `file:` inside, but we want to avoid matching `some::file::module` strings.
static ref URL_REGEX: RegexSearch = RegexSearch::new(r#"(ipfs:|ipns:|magnet:|mailto:|gemini://|gopher://|https://|http://|news:|file://|git://|ssh:|ftp://)[^\u{0000}-\u{001F}\u{007F}-\u{009F}<>"\s{-}\^⟨⟩`]+"#).unwrap();
static ref WORD_REGEX: RegexSearch = RegexSearch::new("[\\w.:/@-~]+").unwrap();
static ref WORD_REGEX: RegexSearch = RegexSearch::new(r#"[\w.:/@\-~]+"#).unwrap();
}
///Upward flowing events, for changing the title and such

View File

@@ -411,6 +411,10 @@ impl TerminalElement {
})
// Update drag selections
.on_drag(MouseButton::Left, move |event, _: &mut TerminalView, cx| {
if event.end {
return;
}
if cx.is_self_focused() {
if let Some(conn_handle) = connection.upgrade(cx) {
conn_handle.update(cx, |terminal, cx| {

View File

@@ -1,20 +1,64 @@
use gpui::{elements::Label, AnyElement, Element, Entity, View, ViewContext};
use gpui::{
elements::{Empty, Label},
AnyElement, Element, Entity, Subscription, View, ViewContext,
};
use settings::SettingsStore;
use workspace::{item::ItemHandle, StatusItemView};
use crate::state::Mode;
use crate::{state::Mode, Vim, VimEvent, VimModeSetting};
pub struct ModeIndicator {
pub mode: Mode,
pub mode: Option<Mode>,
_subscription: Subscription,
}
impl ModeIndicator {
pub fn new(mode: Mode) -> Self {
Self { mode }
pub fn new(cx: &mut ViewContext<Self>) -> Self {
let handle = cx.handle().downgrade();
let _subscription = cx.subscribe_global::<VimEvent, _>(move |&event, cx| {
if let Some(mode_indicator) = handle.upgrade(cx) {
match event {
VimEvent::ModeChanged { mode } => {
cx.update_window(mode_indicator.window_id(), |cx| {
mode_indicator.update(cx, move |mode_indicator, cx| {
mode_indicator.set_mode(mode, cx);
})
});
}
}
}
});
cx.observe_global::<SettingsStore, _>(move |mode_indicator, cx| {
if settings::get::<VimModeSetting>(cx).0 {
mode_indicator.mode = cx
.has_global::<Vim>()
.then(|| cx.global::<Vim>().state.mode);
} else {
mode_indicator.mode.take();
}
})
.detach();
// Vim doesn't exist in some tests
let mode = cx
.has_global::<Vim>()
.then(|| {
let vim = cx.global::<Vim>();
vim.enabled.then(|| vim.state.mode)
})
.flatten();
Self {
mode,
_subscription,
}
}
pub fn set_mode(&mut self, mode: Mode, cx: &mut ViewContext<Self>) {
if mode != self.mode {
self.mode = mode;
if self.mode != Some(mode) {
self.mode = Some(mode);
cx.notify();
}
}
@@ -30,11 +74,16 @@ impl View for ModeIndicator {
}
fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
let Some(mode) = self.mode.as_ref() else {
return Empty::new().into_any();
};
let theme = &theme::current(cx).workspace.status_bar;
// we always choose text to be 12 monospace characters
// so that as the mode indicator changes, the rest of the
// UI stays still.
let text = match self.mode {
let text = match mode {
Mode::Normal => "-- NORMAL --",
Mode::Insert => "-- INSERT --",
Mode::Visual { line: false } => "-- VISUAL --",

View File

@@ -215,7 +215,7 @@ async fn test_status_indicator(
assert_eq!(
cx.workspace(|_, cx| mode_indicator.read(cx).mode),
Mode::Normal
Some(Mode::Normal)
);
// shows the correct mode
@@ -223,7 +223,7 @@ async fn test_status_indicator(
deterministic.run_until_parked();
assert_eq!(
cx.workspace(|_, cx| mode_indicator.read(cx).mode),
Mode::Insert
Some(Mode::Insert)
);
// shows even in search
@@ -231,7 +231,7 @@ async fn test_status_indicator(
deterministic.run_until_parked();
assert_eq!(
cx.workspace(|_, cx| mode_indicator.read(cx).mode),
Mode::Visual { line: false }
Some(Mode::Visual { line: false })
);
// hides if vim mode is disabled
@@ -239,15 +239,15 @@ async fn test_status_indicator(
deterministic.run_until_parked();
cx.workspace(|workspace, cx| {
let status_bar = workspace.status_bar().read(cx);
let mode_indicator = status_bar.item_of_type::<ModeIndicator>();
assert!(mode_indicator.is_none());
let mode_indicator = status_bar.item_of_type::<ModeIndicator>().unwrap();
assert!(mode_indicator.read(cx).mode.is_none());
});
cx.enable_vim();
deterministic.run_until_parked();
cx.workspace(|workspace, cx| {
let status_bar = workspace.status_bar().read(cx);
let mode_indicator = status_bar.item_of_type::<ModeIndicator>();
assert!(mode_indicator.is_some());
let mode_indicator = status_bar.item_of_type::<ModeIndicator>().unwrap();
assert!(mode_indicator.read(cx).mode.is_some());
});
}

View File

@@ -43,6 +43,10 @@ impl<'a> VimTestContext<'a> {
toolbar.add_item(project_search_bar, cx);
})
});
workspace.status_bar().update(cx, |status_bar, cx| {
let vim_mode_indicator = cx.add_view(ModeIndicator::new);
status_bar.add_right_item(vim_mode_indicator, cx);
});
});
Self { cx }

View File

@@ -43,6 +43,11 @@ struct Number(u8);
actions!(vim, [Tab, Enter]);
impl_actions!(vim, [Number, SwitchMode, PushOperator]);
#[derive(Copy, Clone, Debug)]
enum VimEvent {
ModeChanged { mode: Mode },
}
pub fn init(cx: &mut AppContext) {
settings::register::<VimModeSetting>(cx);
@@ -121,8 +126,6 @@ pub fn observe_keystrokes(cx: &mut WindowContext) {
pub struct Vim {
active_editor: Option<WeakViewHandle<Editor>>,
editor_subscription: Option<Subscription>,
mode_indicator: Option<ViewHandle<ModeIndicator>>,
enabled: bool,
state: VimState,
}
@@ -181,9 +184,7 @@ impl Vim {
self.state.mode = mode;
self.state.operator_stack.clear();
if let Some(mode_indicator) = &self.mode_indicator {
mode_indicator.update(cx, |mode_indicator, cx| mode_indicator.set_mode(mode, cx))
}
cx.emit_global(VimEvent::ModeChanged { mode });
// Sync editor settings like clip mode
self.sync_vim_settings(cx);
@@ -271,44 +272,6 @@ impl Vim {
}
}
fn sync_mode_indicator(cx: &mut WindowContext) {
let Some(workspace) = cx.root_view()
.downcast_ref::<Workspace>()
.map(|workspace| workspace.downgrade()) else {
return;
};
cx.spawn(|mut cx| async move {
workspace.update(&mut cx, |workspace, cx| {
Vim::update(cx, |vim, cx| {
workspace.status_bar().update(cx, |status_bar, cx| {
let current_position = status_bar.position_of_item::<ModeIndicator>();
if vim.enabled && current_position.is_none() {
if vim.mode_indicator.is_none() {
vim.mode_indicator =
Some(cx.add_view(|_| ModeIndicator::new(vim.state.mode)));
};
let mode_indicator = vim.mode_indicator.as_ref().unwrap();
let position = status_bar
.position_of_item::<language_selector::ActiveBufferLanguage>();
if let Some(position) = position {
status_bar.insert_item_after(position, mode_indicator.clone(), cx)
} else {
status_bar.add_left_item(mode_indicator.clone(), cx)
}
} else if !vim.enabled {
if let Some(position) = current_position {
status_bar.remove_item_at(position, cx)
}
}
})
})
})
})
.detach_and_log_err(cx);
}
fn set_enabled(&mut self, enabled: bool, cx: &mut AppContext) {
if self.enabled != enabled {
self.enabled = enabled;
@@ -359,8 +322,6 @@ impl Vim {
self.unhook_vim_settings(editor, cx);
}
});
Vim::sync_mode_indicator(cx);
}
fn unhook_vim_settings(&self, editor: &mut Editor, cx: &mut ViewContext<Editor>) {

View File

@@ -3,7 +3,7 @@ authors = ["Nathan Sobo <nathansobo@gmail.com>"]
description = "The fast, collaborative code editor."
edition = "2021"
name = "zed"
version = "0.97.0"
version = "0.97.5"
publish = false
[lib]

View File

@@ -1 +1 @@
dev
stable

View File

@@ -308,6 +308,7 @@ pub fn initialize_workspace(
);
let active_buffer_language =
cx.add_view(|_| language_selector::ActiveBufferLanguage::new(workspace));
let vim_mode_indicator = cx.add_view(|cx| vim::ModeIndicator::new(cx));
let feedback_button = cx.add_view(|_| {
feedback::deploy_feedback_button::DeployFeedbackButton::new(workspace)
});
@@ -319,6 +320,7 @@ pub fn initialize_workspace(
status_bar.add_right_item(feedback_button, cx);
status_bar.add_right_item(copilot, cx);
status_bar.add_right_item(active_buffer_language, cx);
status_bar.add_right_item(vim_mode_indicator, cx);
status_bar.add_right_item(cursor_position, cx);
});

View File

@@ -170,8 +170,8 @@ export default function editor(): any {
line_number: with_opacity(foreground(layer), 0.35),
line_number_active: foreground(layer),
rename_fade: 0.6,
wrap_guide: with_opacity(foreground(layer), 0.1),
active_wrap_guide: with_opacity(foreground(layer), 0.2),
wrap_guide: with_opacity(foreground(layer), 0.05),
active_wrap_guide: with_opacity(foreground(layer), 0.1),
unnecessary_code_fade: 0.5,
selection: theme.players[0],
whitespace: theme.ramps.neutral(0.5).hex(),