Compare commits
6 Commits
on-app-qui
...
agent-chec
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b38b6ff12c | ||
|
|
52a9101970 | ||
|
|
1a798830cb | ||
|
|
481e3e5092 | ||
|
|
b35e69692d | ||
|
|
add67bde43 |
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -18025,6 +18025,7 @@ dependencies = [
|
||||
"command_palette_hooks",
|
||||
"db",
|
||||
"editor",
|
||||
"env_logger 0.11.8",
|
||||
"futures 0.3.31",
|
||||
"git_ui",
|
||||
"gpui",
|
||||
|
||||
@@ -333,10 +333,14 @@
|
||||
"ctrl-x ctrl-c": "editor::ShowEditPrediction", // zed specific
|
||||
"ctrl-x ctrl-l": "editor::ToggleCodeActions", // zed specific
|
||||
"ctrl-x ctrl-z": "editor::Cancel",
|
||||
"ctrl-x ctrl-e": "vim::LineDown",
|
||||
"ctrl-x ctrl-y": "vim::LineUp",
|
||||
"ctrl-w": "editor::DeleteToPreviousWordStart",
|
||||
"ctrl-u": "editor::DeleteToBeginningOfLine",
|
||||
"ctrl-t": "vim::Indent",
|
||||
"ctrl-d": "vim::Outdent",
|
||||
"ctrl-y": "vim::InsertFromAbove",
|
||||
"ctrl-e": "vim::InsertFromBelow",
|
||||
"ctrl-k": ["vim::PushDigraph", {}],
|
||||
"ctrl-v": ["vim::PushLiteral", {}],
|
||||
"ctrl-shift-v": "editor::Paste", // note: this is *very* similar to ctrl-v in vim, but ctrl-shift-v on linux is the typical shortcut for paste when ctrl-v is already in use.
|
||||
|
||||
@@ -813,6 +813,7 @@ impl Thread {
|
||||
}
|
||||
|
||||
fn finalize_pending_checkpoint(&mut self, cx: &mut Context<Self>) {
|
||||
dbg!("finalize_pending_checkpoint");
|
||||
let pending_checkpoint = if self.is_generating() {
|
||||
return;
|
||||
} else if let Some(checkpoint) = self.pending_checkpoint.take() {
|
||||
@@ -829,10 +830,13 @@ impl Thread {
|
||||
pending_checkpoint: ThreadCheckpoint,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
dbg!("finalize_checkpoint");
|
||||
let git_store = self.project.read(cx).git_store().clone();
|
||||
let final_checkpoint = git_store.update(cx, |git_store, cx| git_store.checkpoint(cx));
|
||||
cx.spawn(async move |this, cx| match final_checkpoint.await {
|
||||
Ok(final_checkpoint) => {
|
||||
dbg!(&pending_checkpoint.git_checkpoint);
|
||||
dbg!(&final_checkpoint);
|
||||
let equal = git_store
|
||||
.update(cx, |store, cx| {
|
||||
store.compare_checkpoints(
|
||||
@@ -844,7 +848,7 @@ impl Thread {
|
||||
.await
|
||||
.unwrap_or(false);
|
||||
|
||||
if !equal {
|
||||
if dbg!(!equal) {
|
||||
this.update(cx, |this, cx| {
|
||||
this.insert_checkpoint(pending_checkpoint, cx)
|
||||
})?;
|
||||
@@ -860,6 +864,7 @@ impl Thread {
|
||||
}
|
||||
|
||||
fn insert_checkpoint(&mut self, checkpoint: ThreadCheckpoint, cx: &mut Context<Self>) {
|
||||
dbg!("insert_checkpoint");
|
||||
self.checkpoints_by_message
|
||||
.insert(checkpoint.message_id, checkpoint);
|
||||
cx.emit(ThreadEvent::CheckpointChanged);
|
||||
@@ -867,6 +872,7 @@ impl Thread {
|
||||
}
|
||||
|
||||
pub fn last_restore_checkpoint(&self) -> Option<&LastRestoreCheckpoint> {
|
||||
dbg!();
|
||||
self.last_restore_checkpoint.as_ref()
|
||||
}
|
||||
|
||||
|
||||
@@ -1492,13 +1492,19 @@ impl GitRepository for RealGitRepository {
|
||||
let mut excludes = exclude_files(git).await?;
|
||||
|
||||
git.run(&["add", "--all"]).await?;
|
||||
let tree = git.run(&["write-tree"]).await?;
|
||||
dbg!("added all files");
|
||||
let tree = git.run(&["write-tree"]).await;
|
||||
dbg!(&tree);
|
||||
let tree = tree?;
|
||||
let checkpoint_sha = if let Some(head_sha) = head_sha.as_deref() {
|
||||
dbg!(&["git", "commit-tree", &tree, "-p", head_sha, "-m", "Checkpoint"]));
|
||||
git.run(&["commit-tree", &tree, "-p", head_sha, "-m", "Checkpoint"])
|
||||
.await?
|
||||
} else {
|
||||
dbg!(&["git", "commit-tree", &tree, "-m", "Checkpoint"]);
|
||||
git.run(&["commit-tree", &tree, "-m", "Checkpoint"]).await?
|
||||
};
|
||||
dbg!(&checkpoint_sha);
|
||||
|
||||
excludes.restore_original().await?;
|
||||
|
||||
@@ -1551,6 +1557,8 @@ impl GitRepository for RealGitRepository {
|
||||
left: GitRepositoryCheckpoint,
|
||||
right: GitRepositoryCheckpoint,
|
||||
) -> BoxFuture<'_, Result<bool>> {
|
||||
// todo! fail or short circuit
|
||||
|
||||
let working_directory = self.working_directory();
|
||||
let git_binary_path = self.git_binary_path.clone();
|
||||
|
||||
@@ -1559,6 +1567,11 @@ impl GitRepository for RealGitRepository {
|
||||
.spawn(async move {
|
||||
let working_directory = working_directory?;
|
||||
let git = GitBinary::new(git_binary_path, working_directory, executor);
|
||||
log::error!(
|
||||
"git diff-tree --quiet {} {}",
|
||||
left.commit_sha,
|
||||
right.commit_sha
|
||||
);
|
||||
let result = git
|
||||
.run(&[
|
||||
"diff-tree",
|
||||
@@ -1567,6 +1580,7 @@ impl GitRepository for RealGitRepository {
|
||||
&right.commit_sha.to_string(),
|
||||
])
|
||||
.await;
|
||||
dbg!(&result);
|
||||
match result {
|
||||
Ok(_) => Ok(true),
|
||||
Err(error) => {
|
||||
|
||||
@@ -7,7 +7,6 @@ use std::{
|
||||
path::{Path, PathBuf},
|
||||
rc::{Rc, Weak},
|
||||
sync::{Arc, atomic::Ordering::SeqCst},
|
||||
task::{Poll, Waker},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
@@ -92,36 +91,6 @@ impl AppCell {
|
||||
}
|
||||
Ok(AppRefMut(self.app.try_borrow_mut()?))
|
||||
}
|
||||
|
||||
pub fn shutdown(self: &Rc<AppCell>) {
|
||||
let mut futures = Vec::new();
|
||||
|
||||
let mut cx = self.borrow_mut();
|
||||
|
||||
for observer in cx.quit_observers.remove(&()) {
|
||||
futures.push(observer(&mut cx));
|
||||
}
|
||||
|
||||
cx.windows.clear();
|
||||
cx.window_handles.clear();
|
||||
cx.flush_effects();
|
||||
let executor = cx.background_executor.clone();
|
||||
drop(cx);
|
||||
|
||||
let waker = Waker::noop();
|
||||
let mut future_cx = std::task::Context::from_waker(waker);
|
||||
let futures = futures::future::join_all(futures);
|
||||
futures::pin_mut!(futures);
|
||||
let mut start = std::time::Instant::now();
|
||||
while start.elapsed() < SHUTDOWN_TIMEOUT {
|
||||
match futures.as_mut().poll(&mut future_cx) {
|
||||
Poll::Pending => {
|
||||
executor.tick();
|
||||
}
|
||||
Poll::Ready(_) => break,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
@@ -413,13 +382,39 @@ impl App {
|
||||
platform.on_quit(Box::new({
|
||||
let cx = app.clone();
|
||||
move || {
|
||||
cx.shutdown();
|
||||
cx.borrow_mut().shutdown();
|
||||
}
|
||||
}));
|
||||
|
||||
app
|
||||
}
|
||||
|
||||
/// Quit the application gracefully. Handlers registered with [`Context::on_app_quit`]
|
||||
/// will be given 100ms to complete before exiting.
|
||||
pub fn shutdown(&mut self) {
|
||||
let mut futures = Vec::new();
|
||||
|
||||
for observer in self.quit_observers.remove(&()) {
|
||||
futures.push(observer(self));
|
||||
}
|
||||
|
||||
self.windows.clear();
|
||||
self.window_handles.clear();
|
||||
self.flush_effects();
|
||||
self.quitting = true;
|
||||
|
||||
let futures = futures::future::join_all(futures);
|
||||
if self
|
||||
.background_executor
|
||||
.block_with_timeout(SHUTDOWN_TIMEOUT, futures)
|
||||
.is_err()
|
||||
{
|
||||
log::error!("timed out waiting on app_will_quit");
|
||||
}
|
||||
|
||||
self.quitting = false;
|
||||
}
|
||||
|
||||
/// Get the id of the current keyboard layout
|
||||
pub fn keyboard_layout(&self) -> &dyn PlatformKeyboardLayout {
|
||||
self.keyboard_layout.as_ref()
|
||||
|
||||
@@ -167,7 +167,7 @@ impl TestAppContext {
|
||||
/// public so the macro can call it.
|
||||
pub fn quit(&self) {
|
||||
self.on_quit.borrow_mut().drain(..).for_each(|f| f());
|
||||
self.app.shutdown();
|
||||
self.app.borrow_mut().shutdown();
|
||||
}
|
||||
|
||||
/// Register cleanup to run when the test ends.
|
||||
|
||||
@@ -384,9 +384,10 @@ impl BackgroundExecutor {
|
||||
self.dispatcher.as_test().unwrap().advance_clock(duration)
|
||||
}
|
||||
|
||||
/// docs
|
||||
/// in tests, run one task.
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn tick(&self) -> bool {
|
||||
self.dispatcher.tick(true)
|
||||
self.dispatcher.as_test().unwrap().tick(false)
|
||||
}
|
||||
|
||||
/// in tests, run all tasks that are ready to run. If after doing so
|
||||
|
||||
@@ -545,7 +545,6 @@ pub trait PlatformDispatcher: Send + Sync {
|
||||
fn now(&self) -> Instant {
|
||||
Instant::now()
|
||||
}
|
||||
fn tick(&self, _: bool) -> bool;
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
fn as_test(&self) -> Option<&TestDispatcher> {
|
||||
|
||||
@@ -4,14 +4,6 @@
|
||||
|
||||
use crate::{PlatformDispatcher, TaskLabel};
|
||||
use async_task::Runnable;
|
||||
use block::{Block, ConcreteBlock, RcBlock};
|
||||
use core_foundation::{
|
||||
base::CFTypeRef,
|
||||
runloop::{
|
||||
CFRunLoopRef, CFRunLoopRunInMode, CFRunLoopWakeUp, kCFRunLoopCommonModes,
|
||||
kCFRunLoopDefaultMode,
|
||||
},
|
||||
};
|
||||
use objc::{
|
||||
class, msg_send,
|
||||
runtime::{BOOL, YES},
|
||||
@@ -19,9 +11,7 @@ use objc::{
|
||||
};
|
||||
use parking::{Parker, Unparker};
|
||||
use parking_lot::Mutex;
|
||||
use smol::io::BlockOn;
|
||||
use std::{
|
||||
cell::Cell,
|
||||
ffi::c_void,
|
||||
ptr::{NonNull, addr_of},
|
||||
sync::Arc,
|
||||
@@ -74,21 +64,11 @@ impl PlatformDispatcher for MacDispatcher {
|
||||
}
|
||||
|
||||
fn dispatch_on_main_thread(&self, runnable: Runnable) {
|
||||
use core_foundation::runloop::CFRunLoopGetMain;
|
||||
|
||||
unsafe {
|
||||
let mut runnable = Cell::new(Some(runnable));
|
||||
let main_run_loop = CFRunLoopGetMain();
|
||||
let block = ConcreteBlock::new(move || {
|
||||
if let Some(runnable) = runnable.take() {
|
||||
runnable.run();
|
||||
}
|
||||
})
|
||||
.copy();
|
||||
CFRunLoopPerformBlock(
|
||||
main_run_loop,
|
||||
kCFRunLoopDefaultMode as _,
|
||||
&*block as *const Block<_, _> as _,
|
||||
dispatch_async_f(
|
||||
dispatch_get_main_queue(),
|
||||
runnable.into_raw().as_ptr() as *mut c_void,
|
||||
Some(trampoline),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -107,13 +87,6 @@ impl PlatformDispatcher for MacDispatcher {
|
||||
}
|
||||
}
|
||||
|
||||
fn tick(&self, background_only: bool) -> bool {
|
||||
unsafe {
|
||||
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0., 0);
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn park(&self, timeout: Option<Duration>) -> bool {
|
||||
if let Some(timeout) = timeout {
|
||||
self.parker.lock().park_timeout(timeout)
|
||||
@@ -132,7 +105,3 @@ extern "C" fn trampoline(runnable: *mut c_void) {
|
||||
let task = unsafe { Runnable::<()>::from_raw(NonNull::new_unchecked(runnable as *mut ())) };
|
||||
task.run();
|
||||
}
|
||||
|
||||
unsafe extern "C" {
|
||||
fn CFRunLoopPerformBlock(rl: CFRunLoopRef, mode: CFTypeRef, block: *const c_void);
|
||||
}
|
||||
|
||||
@@ -122,6 +122,68 @@ impl TestDispatcher {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tick(&self, background_only: bool) -> bool {
|
||||
let mut state = self.state.lock();
|
||||
|
||||
while let Some((deadline, _)) = state.delayed.first() {
|
||||
if *deadline > state.time {
|
||||
break;
|
||||
}
|
||||
let (_, runnable) = state.delayed.remove(0);
|
||||
state.background.push(runnable);
|
||||
}
|
||||
|
||||
let foreground_len: usize = if background_only {
|
||||
0
|
||||
} else {
|
||||
state
|
||||
.foreground
|
||||
.values()
|
||||
.map(|runnables| runnables.len())
|
||||
.sum()
|
||||
};
|
||||
let background_len = state.background.len();
|
||||
|
||||
let runnable;
|
||||
let main_thread;
|
||||
if foreground_len == 0 && background_len == 0 {
|
||||
let deprioritized_background_len = state.deprioritized_background.len();
|
||||
if deprioritized_background_len == 0 {
|
||||
return false;
|
||||
}
|
||||
let ix = state.random.gen_range(0..deprioritized_background_len);
|
||||
main_thread = false;
|
||||
runnable = state.deprioritized_background.swap_remove(ix);
|
||||
} else {
|
||||
main_thread = state.random.gen_ratio(
|
||||
foreground_len as u32,
|
||||
(foreground_len + background_len) as u32,
|
||||
);
|
||||
if main_thread {
|
||||
let state = &mut *state;
|
||||
runnable = state
|
||||
.foreground
|
||||
.values_mut()
|
||||
.filter(|runnables| !runnables.is_empty())
|
||||
.choose(&mut state.random)
|
||||
.unwrap()
|
||||
.pop_front()
|
||||
.unwrap();
|
||||
} else {
|
||||
let ix = state.random.gen_range(0..background_len);
|
||||
runnable = state.background.swap_remove(ix);
|
||||
};
|
||||
};
|
||||
|
||||
let was_main_thread = state.is_main_thread;
|
||||
state.is_main_thread = main_thread;
|
||||
drop(state);
|
||||
runnable.run();
|
||||
self.state.lock().is_main_thread = was_main_thread;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn deprioritize(&self, task_label: TaskLabel) {
|
||||
self.state
|
||||
.lock()
|
||||
@@ -205,68 +267,6 @@ impl PlatformDispatcher for TestDispatcher {
|
||||
state.start_time + state.time
|
||||
}
|
||||
|
||||
fn tick(&self, background_only: bool) -> bool {
|
||||
let mut state = self.state.lock();
|
||||
|
||||
while let Some((deadline, _)) = state.delayed.first() {
|
||||
if *deadline > state.time {
|
||||
break;
|
||||
}
|
||||
let (_, runnable) = state.delayed.remove(0);
|
||||
state.background.push(runnable);
|
||||
}
|
||||
|
||||
let foreground_len: usize = if background_only {
|
||||
0
|
||||
} else {
|
||||
state
|
||||
.foreground
|
||||
.values()
|
||||
.map(|runnables| runnables.len())
|
||||
.sum()
|
||||
};
|
||||
let background_len = state.background.len();
|
||||
|
||||
let runnable;
|
||||
let main_thread;
|
||||
if foreground_len == 0 && background_len == 0 {
|
||||
let deprioritized_background_len = state.deprioritized_background.len();
|
||||
if deprioritized_background_len == 0 {
|
||||
return false;
|
||||
}
|
||||
let ix = state.random.gen_range(0..deprioritized_background_len);
|
||||
main_thread = false;
|
||||
runnable = state.deprioritized_background.swap_remove(ix);
|
||||
} else {
|
||||
main_thread = state.random.gen_ratio(
|
||||
foreground_len as u32,
|
||||
(foreground_len + background_len) as u32,
|
||||
);
|
||||
if main_thread {
|
||||
let state = &mut *state;
|
||||
runnable = state
|
||||
.foreground
|
||||
.values_mut()
|
||||
.filter(|runnables| !runnables.is_empty())
|
||||
.choose(&mut state.random)
|
||||
.unwrap()
|
||||
.pop_front()
|
||||
.unwrap();
|
||||
} else {
|
||||
let ix = state.random.gen_range(0..background_len);
|
||||
runnable = state.background.swap_remove(ix);
|
||||
};
|
||||
};
|
||||
|
||||
let was_main_thread = state.is_main_thread;
|
||||
state.is_main_thread = main_thread;
|
||||
drop(state);
|
||||
runnable.run();
|
||||
self.state.lock().is_main_thread = was_main_thread;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn dispatch(&self, runnable: Runnable, label: Option<TaskLabel>) {
|
||||
{
|
||||
let mut state = self.state.lock();
|
||||
|
||||
@@ -167,6 +167,7 @@ fn generate_test_function(
|
||||
));
|
||||
cx_teardowns.extend(quote!(
|
||||
dispatcher.run_until_parked();
|
||||
#cx_varname.executor().forbid_parking();
|
||||
#cx_varname.quit();
|
||||
dispatcher.run_until_parked();
|
||||
));
|
||||
@@ -232,7 +233,7 @@ fn generate_test_function(
|
||||
cx_teardowns.extend(quote!(
|
||||
drop(#cx_varname_lock);
|
||||
dispatcher.run_until_parked();
|
||||
#cx_varname.update(|cx| { cx.quit() });
|
||||
#cx_varname.update(|cx| { cx.background_executor().forbid_parking(); cx.quit(); });
|
||||
dispatcher.run_until_parked();
|
||||
));
|
||||
continue;
|
||||
@@ -247,6 +248,7 @@ fn generate_test_function(
|
||||
));
|
||||
cx_teardowns.extend(quote!(
|
||||
dispatcher.run_until_parked();
|
||||
#cx_varname.executor().forbid_parking();
|
||||
#cx_varname.quit();
|
||||
dispatcher.run_until_parked();
|
||||
));
|
||||
|
||||
@@ -136,7 +136,6 @@ impl DapStore {
|
||||
breakpoint_store: Entity<BreakpointStore>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
cx.on_app_quit(Self::shutdown_sessions).detach();
|
||||
let mode = DapStoreMode::Local(LocalDapStore {
|
||||
fs,
|
||||
environment,
|
||||
|
||||
@@ -3367,20 +3367,6 @@ impl LocalLspStore {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
|
||||
reg: lsp::Registration,
|
||||
) -> anyhow::Result<OneOf<bool, T>> {
|
||||
let caps = match reg
|
||||
.register_options
|
||||
.map(|options| serde_json::from_value::<T>(options))
|
||||
.transpose()?
|
||||
{
|
||||
None => OneOf::Left(true),
|
||||
Some(options) => OneOf::Right(options),
|
||||
};
|
||||
Ok(caps)
|
||||
}
|
||||
|
||||
fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
|
||||
if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
|
||||
cx.emit(LspStoreEvent::LanguageServerUpdate {
|
||||
@@ -11690,190 +11676,190 @@ impl LspStore {
|
||||
// Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
|
||||
}
|
||||
"workspace/symbol" => {
|
||||
let options = parse_register_capabilities(reg)?;
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.workspace_symbol_provider = Some(options);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
if let Some(options) = parse_register_capabilities(reg)? {
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.workspace_symbol_provider = Some(options);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
"workspace/fileOperations" => {
|
||||
let caps = reg
|
||||
.register_options
|
||||
.map(serde_json::from_value)
|
||||
.transpose()?
|
||||
.unwrap_or_default();
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities
|
||||
.workspace
|
||||
.get_or_insert_default()
|
||||
.file_operations = Some(caps);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
if let Some(options) = reg.register_options {
|
||||
let caps = serde_json::from_value(options)?;
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities
|
||||
.workspace
|
||||
.get_or_insert_default()
|
||||
.file_operations = Some(caps);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
"workspace/executeCommand" => {
|
||||
let options = reg
|
||||
.register_options
|
||||
.map(serde_json::from_value)
|
||||
.transpose()?
|
||||
.unwrap_or_default();
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.execute_command_provider = Some(options);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
if let Some(options) = reg.register_options {
|
||||
let options = serde_json::from_value(options)?;
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.execute_command_provider = Some(options);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
"textDocument/rangeFormatting" => {
|
||||
let options = parse_register_capabilities(reg)?;
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.document_range_formatting_provider = Some(options);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
if let Some(options) = parse_register_capabilities(reg)? {
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.document_range_formatting_provider = Some(options);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
"textDocument/onTypeFormatting" => {
|
||||
let options = reg
|
||||
if let Some(options) = reg
|
||||
.register_options
|
||||
.map(serde_json::from_value)
|
||||
.transpose()?
|
||||
.unwrap_or_default();
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.document_on_type_formatting_provider = Some(options);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
{
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.document_on_type_formatting_provider = Some(options);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
"textDocument/formatting" => {
|
||||
let options = parse_register_capabilities(reg)?;
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.document_formatting_provider = Some(options);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
if let Some(options) = parse_register_capabilities(reg)? {
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.document_formatting_provider = Some(options);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
"textDocument/rename" => {
|
||||
let options = parse_register_capabilities(reg)?;
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.rename_provider = Some(options);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
if let Some(options) = parse_register_capabilities(reg)? {
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.rename_provider = Some(options);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
"textDocument/inlayHint" => {
|
||||
let options = parse_register_capabilities(reg)?;
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.inlay_hint_provider = Some(options);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
if let Some(options) = parse_register_capabilities(reg)? {
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.inlay_hint_provider = Some(options);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
"textDocument/documentSymbol" => {
|
||||
let options = parse_register_capabilities(reg)?;
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.document_symbol_provider = Some(options);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
if let Some(options) = parse_register_capabilities(reg)? {
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.document_symbol_provider = Some(options);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
"textDocument/codeAction" => {
|
||||
let options = reg
|
||||
if let Some(options) = reg
|
||||
.register_options
|
||||
.map(serde_json::from_value)
|
||||
.transpose()?;
|
||||
let provider_capability = match options {
|
||||
None => lsp::CodeActionProviderCapability::Simple(true),
|
||||
Some(options) => lsp::CodeActionProviderCapability::Options(options),
|
||||
};
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.code_action_provider = Some(provider_capability);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
.transpose()?
|
||||
{
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.code_action_provider =
|
||||
Some(lsp::CodeActionProviderCapability::Options(options));
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
"textDocument/definition" => {
|
||||
let caps = parse_register_capabilities(reg)?;
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.definition_provider = Some(caps);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
if let Some(options) = parse_register_capabilities(reg)? {
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.definition_provider = Some(options);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
"textDocument/completion" => {
|
||||
let caps = reg
|
||||
if let Some(caps) = reg
|
||||
.register_options
|
||||
.map(serde_json::from_value)
|
||||
.transpose()?
|
||||
.unwrap_or_default();
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.completion_provider = Some(caps);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
{
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.completion_provider = Some(caps);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
"textDocument/hover" => {
|
||||
let caps = reg
|
||||
if let Some(caps) = reg
|
||||
.register_options
|
||||
.map(serde_json::from_value)
|
||||
.transpose()?
|
||||
.unwrap_or_else(|| lsp::HoverProviderCapability::Simple(true));
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.hover_provider = Some(caps);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
{
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.hover_provider = Some(caps);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
"textDocument/signatureHelp" => {
|
||||
let caps = reg
|
||||
if let Some(caps) = reg
|
||||
.register_options
|
||||
.map(serde_json::from_value)
|
||||
.transpose()?
|
||||
.unwrap_or_default();
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.signature_help_provider = Some(caps);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
{
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.signature_help_provider = Some(caps);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
"textDocument/synchronization" => {
|
||||
let caps = reg
|
||||
if let Some(caps) = reg
|
||||
.register_options
|
||||
.map(serde_json::from_value)
|
||||
.transpose()?
|
||||
.unwrap_or_else(|| {
|
||||
lsp::TextDocumentSyncCapability::Options(
|
||||
lsp::TextDocumentSyncOptions::default(),
|
||||
)
|
||||
{
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.text_document_sync = Some(caps);
|
||||
});
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.text_document_sync = Some(caps);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
"textDocument/codeLens" => {
|
||||
let caps = reg
|
||||
if let Some(caps) = reg
|
||||
.register_options
|
||||
.map(serde_json::from_value)
|
||||
.transpose()?
|
||||
.unwrap_or_else(|| lsp::CodeLensOptions {
|
||||
resolve_provider: None,
|
||||
{
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.code_lens_provider = Some(caps);
|
||||
});
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.code_lens_provider = Some(caps);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
"textDocument/diagnostic" => {
|
||||
let caps = reg
|
||||
if let Some(caps) = reg
|
||||
.register_options
|
||||
.map(serde_json::from_value)
|
||||
.transpose()?
|
||||
.unwrap_or_else(|| {
|
||||
lsp::DiagnosticServerCapabilities::RegistrationOptions(
|
||||
lsp::DiagnosticRegistrationOptions::default(),
|
||||
)
|
||||
{
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.diagnostic_provider = Some(caps);
|
||||
});
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.diagnostic_provider = Some(caps);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
"textDocument/colorProvider" => {
|
||||
let caps = reg
|
||||
if let Some(caps) = reg
|
||||
.register_options
|
||||
.map(serde_json::from_value)
|
||||
.transpose()?
|
||||
.unwrap_or_else(|| lsp::ColorProviderCapability::Simple(true));
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.color_provider = Some(caps);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
{
|
||||
server.update_capabilities(|capabilities| {
|
||||
capabilities.color_provider = Some(caps);
|
||||
});
|
||||
notify_server_capabilities_updated(&server, cx);
|
||||
}
|
||||
}
|
||||
_ => log::warn!("unhandled capability registration: {reg:?}"),
|
||||
}
|
||||
@@ -12016,6 +12002,18 @@ impl LspStore {
|
||||
}
|
||||
}
|
||||
|
||||
// Registration with empty capabilities should be ignored.
|
||||
// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/formatting.ts#L67-L70
|
||||
fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
|
||||
reg: lsp::Registration,
|
||||
) -> anyhow::Result<Option<OneOf<bool, T>>> {
|
||||
Ok(reg
|
||||
.register_options
|
||||
.map(|options| serde_json::from_value::<T>(options))
|
||||
.transpose()?
|
||||
.map(OneOf::Right))
|
||||
}
|
||||
|
||||
fn subscribe_to_binary_statuses(
|
||||
languages: &Arc<LanguageRegistry>,
|
||||
cx: &mut Context<'_, LspStore>,
|
||||
|
||||
@@ -650,13 +650,12 @@ impl HeadlessProject {
|
||||
cx: AsyncApp,
|
||||
) -> Result<proto::Ack> {
|
||||
cx.spawn(async move |cx| {
|
||||
// todo!("come back to this")
|
||||
// cx.update(|cx| {
|
||||
// // TODO: This is a hack, because in a headless project, shutdown isn't executed
|
||||
// // when calling quit, but it should be.
|
||||
// cx.shutdown();
|
||||
// cx.quit();
|
||||
// })
|
||||
cx.update(|cx| {
|
||||
// TODO: This is a hack, because in a headless project, shutdown isn't executed
|
||||
// when calling quit, but it should be.
|
||||
cx.shutdown();
|
||||
cx.quit();
|
||||
})
|
||||
})
|
||||
.detach();
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ command_palette.workspace = true
|
||||
command_palette_hooks.workspace = true
|
||||
db.workspace = true
|
||||
editor.workspace = true
|
||||
env_logger.workspace = true
|
||||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
itertools.workspace = true
|
||||
|
||||
@@ -31,7 +31,7 @@ impl Vim {
|
||||
) {
|
||||
let count = Vim::take_count(cx).unwrap_or(1);
|
||||
Vim::take_forced_motion(cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
if let Some(selections) = editor
|
||||
.change_list
|
||||
.next_change(count, direction)
|
||||
@@ -49,7 +49,7 @@ impl Vim {
|
||||
}
|
||||
|
||||
pub(crate) fn push_to_change_list(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let Some((new_positions, buffer)) = self.update_editor(window, cx, |vim, editor, _, cx| {
|
||||
let Some((new_positions, buffer)) = self.update_editor(cx, |vim, editor, cx| {
|
||||
let (map, selections) = editor.selections.all_adjusted_display(cx);
|
||||
let buffer = editor.buffer().clone();
|
||||
|
||||
|
||||
@@ -241,9 +241,9 @@ impl Deref for WrappedAction {
|
||||
|
||||
pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
// Vim::action(editor, cx, |vim, action: &StartOfLine, window, cx| {
|
||||
Vim::action(editor, cx, |vim, action: &VimSet, window, cx| {
|
||||
Vim::action(editor, cx, |vim, action: &VimSet, _, cx| {
|
||||
for option in action.options.iter() {
|
||||
vim.update_editor(window, cx, |_, editor, _, cx| match option {
|
||||
vim.update_editor(cx, |_, editor, cx| match option {
|
||||
VimOption::Wrap(true) => {
|
||||
editor
|
||||
.set_soft_wrap_mode(language::language_settings::SoftWrap::EditorWidth, cx);
|
||||
@@ -298,7 +298,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
});
|
||||
|
||||
Vim::action(editor, cx, |vim, action: &VimSave, window, cx| {
|
||||
vim.update_editor(window, cx, |_, editor, window, cx| {
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
let Some(project) = editor.project.clone() else {
|
||||
return;
|
||||
};
|
||||
@@ -375,7 +375,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
cx,
|
||||
);
|
||||
}
|
||||
vim.update_editor(window, cx, |vim, editor, window, cx| match action {
|
||||
vim.update_editor(cx, |vim, editor, cx| match action {
|
||||
DeleteMarks::Marks(s) => {
|
||||
if s.starts_with('-') || s.ends_with('-') || s.contains(['\'', '`']) {
|
||||
err(s.clone(), window, cx);
|
||||
@@ -432,7 +432,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
});
|
||||
|
||||
Vim::action(editor, cx, |vim, action: &VimEdit, window, cx| {
|
||||
vim.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
vim.update_editor(cx, |vim, editor, cx| {
|
||||
let Some(workspace) = vim.workspace(window) else {
|
||||
return;
|
||||
};
|
||||
@@ -462,11 +462,10 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
.map(|c| Keystroke::parse(&c.to_string()).unwrap())
|
||||
.collect();
|
||||
vim.switch_mode(Mode::Normal, true, window, cx);
|
||||
let initial_selections = vim.update_editor(window, cx, |_, editor, _, _| {
|
||||
editor.selections.disjoint_anchors()
|
||||
});
|
||||
let initial_selections =
|
||||
vim.update_editor(cx, |_, editor, _| editor.selections.disjoint_anchors());
|
||||
if let Some(range) = &action.range {
|
||||
let result = vim.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
let result = vim.update_editor(cx, |vim, editor, cx| {
|
||||
let range = range.buffer_range(vim, editor, window, cx)?;
|
||||
editor.change_selections(
|
||||
SelectionEffects::no_scroll().nav_history(false),
|
||||
@@ -498,7 +497,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
cx.spawn_in(window, async move |vim, cx| {
|
||||
task.await;
|
||||
vim.update_in(cx, |vim, window, cx| {
|
||||
vim.update_editor(window, cx, |_, editor, window, cx| {
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
if had_range {
|
||||
editor.change_selections(SelectionEffects::default(), window, cx, |s| {
|
||||
s.select_anchor_ranges([s.newest_anchor().range()]);
|
||||
@@ -510,7 +509,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
} else {
|
||||
vim.switch_mode(Mode::Normal, true, window, cx);
|
||||
}
|
||||
vim.update_editor(window, cx, |_, editor, _, cx| {
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
if let Some(first_sel) = initial_selections {
|
||||
if let Some(tx_id) = editor
|
||||
.buffer()
|
||||
@@ -548,7 +547,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
|
||||
Vim::action(editor, cx, |vim, action: &GoToLine, window, cx| {
|
||||
vim.switch_mode(Mode::Normal, false, window, cx);
|
||||
let result = vim.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
let result = vim.update_editor(cx, |vim, editor, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let buffer_row = action.range.head().buffer_row(vim, editor, window, cx)?;
|
||||
let current = editor.selections.newest::<Point>(cx);
|
||||
@@ -573,7 +572,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
});
|
||||
|
||||
Vim::action(editor, cx, |vim, action: &YankCommand, window, cx| {
|
||||
vim.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
vim.update_editor(cx, |vim, editor, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
if let Ok(range) = action.range.buffer_range(vim, editor, window, cx) {
|
||||
let end = if range.end < snapshot.buffer_snapshot.max_row() {
|
||||
@@ -600,7 +599,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
});
|
||||
|
||||
Vim::action(editor, cx, |vim, action: &WithRange, window, cx| {
|
||||
let result = vim.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
let result = vim.update_editor(cx, |vim, editor, cx| {
|
||||
action.range.buffer_range(vim, editor, window, cx)
|
||||
});
|
||||
|
||||
@@ -619,7 +618,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
};
|
||||
|
||||
let previous_selections = vim
|
||||
.update_editor(window, cx, |_, editor, window, cx| {
|
||||
.update_editor(cx, |_, editor, cx| {
|
||||
let selections = action.restore_selection.then(|| {
|
||||
editor
|
||||
.selections
|
||||
@@ -635,7 +634,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
.flatten();
|
||||
window.dispatch_action(action.action.boxed_clone(), cx);
|
||||
cx.defer_in(window, move |vim, window, cx| {
|
||||
vim.update_editor(window, cx, |_, editor, window, cx| {
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
if let Some(previous_selections) = previous_selections {
|
||||
s.select_ranges(previous_selections);
|
||||
@@ -1536,7 +1535,7 @@ impl OnMatchingLines {
|
||||
}
|
||||
|
||||
pub fn run(&self, vim: &mut Vim, window: &mut Window, cx: &mut Context<Vim>) {
|
||||
let result = vim.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
let result = vim.update_editor(cx, |vim, editor, cx| {
|
||||
self.range.buffer_range(vim, editor, window, cx)
|
||||
});
|
||||
|
||||
@@ -1600,7 +1599,7 @@ impl OnMatchingLines {
|
||||
});
|
||||
};
|
||||
|
||||
vim.update_editor(window, cx, |_, editor, window, cx| {
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let mut row = range.start.0;
|
||||
|
||||
@@ -1680,7 +1679,7 @@ pub struct ShellExec {
|
||||
impl Vim {
|
||||
pub fn cancel_running_command(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
if self.running_command.take().is_some() {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, _window, _cx| {
|
||||
editor.clear_row_highlights::<ShellExec>();
|
||||
})
|
||||
@@ -1691,7 +1690,7 @@ impl Vim {
|
||||
fn prepare_shell_command(
|
||||
&mut self,
|
||||
command: &str,
|
||||
window: &mut Window,
|
||||
_: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> String {
|
||||
let mut ret = String::new();
|
||||
@@ -1711,7 +1710,7 @@ impl Vim {
|
||||
}
|
||||
match c {
|
||||
'%' => {
|
||||
self.update_editor(window, cx, |_, editor, _window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
if let Some((_, buffer, _)) = editor.active_excerpt(cx) {
|
||||
if let Some(file) = buffer.read(cx).file() {
|
||||
if let Some(local) = file.as_local() {
|
||||
@@ -1747,7 +1746,7 @@ impl Vim {
|
||||
let Some(workspace) = self.workspace(window) else {
|
||||
return;
|
||||
};
|
||||
let command = self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
let command = self.update_editor(cx, |_, editor, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let start = editor.selections.newest_display(cx);
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
@@ -1794,7 +1793,7 @@ impl Vim {
|
||||
let Some(workspace) = self.workspace(window) else {
|
||||
return;
|
||||
};
|
||||
let command = self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
let command = self.update_editor(cx, |_, editor, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let start = editor.selections.newest_display(cx);
|
||||
let range = object
|
||||
@@ -1896,7 +1895,7 @@ impl ShellExec {
|
||||
let mut input_snapshot = None;
|
||||
let mut input_range = None;
|
||||
let mut needs_newline_prefix = false;
|
||||
vim.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
vim.update_editor(cx, |vim, editor, cx| {
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
let range = if let Some(range) = self.range.clone() {
|
||||
let Some(range) = range.buffer_range(vim, editor, window, cx).log_err() else {
|
||||
@@ -1990,7 +1989,7 @@ impl ShellExec {
|
||||
}
|
||||
|
||||
vim.update_in(cx, |vim, window, cx| {
|
||||
vim.update_editor(window, cx, |_, editor, window, cx| {
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.edit([(range.clone(), text)], cx);
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
|
||||
@@ -56,9 +56,7 @@ impl Vim {
|
||||
|
||||
self.pop_operator(window, cx);
|
||||
if self.editor_input_enabled() {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
editor.insert(&text, window, cx)
|
||||
});
|
||||
self.update_editor(cx, |_, editor, cx| editor.insert(&text, window, cx));
|
||||
} else {
|
||||
self.input_ignored(text, window, cx);
|
||||
}
|
||||
@@ -214,9 +212,7 @@ impl Vim {
|
||||
text.push_str(suffix);
|
||||
|
||||
if self.editor_input_enabled() {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
editor.insert(&text, window, cx)
|
||||
});
|
||||
self.update_editor(cx, |_, editor, cx| editor.insert(&text, window, cx));
|
||||
} else {
|
||||
self.input_ignored(text.into(), window, cx);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
mut is_boundary: impl FnMut(char, char, &CharClassifier) -> bool,
|
||||
) {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
let times = times.unwrap_or(1);
|
||||
@@ -115,7 +115,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
mut is_boundary: impl FnMut(char, char, &CharClassifier) -> bool,
|
||||
) {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
let times = times.unwrap_or(1);
|
||||
@@ -175,7 +175,7 @@ impl Vim {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
@@ -253,7 +253,7 @@ impl Vim {
|
||||
})
|
||||
}
|
||||
Motion::FindForward { .. } => {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
@@ -280,7 +280,7 @@ impl Vim {
|
||||
});
|
||||
}
|
||||
Motion::FindBackward { .. } => {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
@@ -312,7 +312,7 @@ impl Vim {
|
||||
|
||||
fn helix_insert(&mut self, _: &HelixInsert, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.start_recording(cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.move_with(|_map, selection| {
|
||||
// In helix normal mode, move cursor to start of selection and collapse
|
||||
@@ -328,7 +328,7 @@ impl Vim {
|
||||
fn helix_append(&mut self, _: &HelixAppend, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.start_recording(cx);
|
||||
self.switch_mode(Mode::Insert, false, window, cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
let point = if selection.is_empty() {
|
||||
@@ -343,7 +343,7 @@ impl Vim {
|
||||
}
|
||||
|
||||
pub fn helix_replace(&mut self, text: &str, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let (map, selections) = editor.selections.all_display(cx);
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
let count = Vim::take_count(cx).unwrap_or(1);
|
||||
Vim::take_forced_motion(cx);
|
||||
vim.store_visual_marks(window, cx);
|
||||
vim.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
vim.update_editor(cx, |vim, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let original_positions = vim.save_selection_starts(editor, cx);
|
||||
for _ in 0..count {
|
||||
@@ -50,7 +50,7 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
let count = Vim::take_count(cx).unwrap_or(1);
|
||||
Vim::take_forced_motion(cx);
|
||||
vim.store_visual_marks(window, cx);
|
||||
vim.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
vim.update_editor(cx, |vim, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let original_positions = vim.save_selection_starts(editor, cx);
|
||||
for _ in 0..count {
|
||||
@@ -69,7 +69,7 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
let count = Vim::take_count(cx).unwrap_or(1);
|
||||
Vim::take_forced_motion(cx);
|
||||
vim.store_visual_marks(window, cx);
|
||||
vim.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
vim.update_editor(cx, |vim, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let original_positions = vim.save_selection_starts(editor, cx);
|
||||
for _ in 0..count {
|
||||
@@ -95,7 +95,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.stop_recording(cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let mut selection_starts: HashMap<_, _> = Default::default();
|
||||
@@ -137,7 +137,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.stop_recording(cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let mut original_positions: HashMap<_, _> = Default::default();
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
|
||||
@@ -3,7 +3,9 @@ use editor::{Bias, Editor};
|
||||
use gpui::{Action, Context, Window, actions};
|
||||
use language::SelectionGoal;
|
||||
use settings::Settings;
|
||||
use text::Point;
|
||||
use vim_mode_setting::HelixModeSetting;
|
||||
use workspace::searchable::Direction;
|
||||
|
||||
actions!(
|
||||
vim,
|
||||
@@ -11,13 +13,23 @@ actions!(
|
||||
/// Switches to normal mode with cursor positioned before the current character.
|
||||
NormalBefore,
|
||||
/// Temporarily switches to normal mode for one command.
|
||||
TemporaryNormal
|
||||
TemporaryNormal,
|
||||
/// Inserts the next character from the line above into the current line.
|
||||
InsertFromAbove,
|
||||
/// Inserts the next character from the line below into the current line.
|
||||
InsertFromBelow
|
||||
]
|
||||
);
|
||||
|
||||
pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
Vim::action(editor, cx, Vim::normal_before);
|
||||
Vim::action(editor, cx, Vim::temporary_normal);
|
||||
Vim::action(editor, cx, |vim, _: &InsertFromAbove, window, cx| {
|
||||
vim.insert_around(Direction::Prev, window, cx)
|
||||
});
|
||||
Vim::action(editor, cx, |vim, _: &InsertFromBelow, window, cx| {
|
||||
vim.insert_around(Direction::Next, window, cx)
|
||||
})
|
||||
}
|
||||
|
||||
impl Vim {
|
||||
@@ -38,7 +50,7 @@ impl Vim {
|
||||
if count <= 1 || Vim::globals(cx).dot_replaying {
|
||||
self.create_mark("^".into(), window, cx);
|
||||
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.dismiss_menus_and_popups(false, window, cx);
|
||||
|
||||
if !HelixModeSetting::get_global(cx).0 {
|
||||
@@ -71,6 +83,29 @@ impl Vim {
|
||||
self.switch_mode(Mode::Normal, true, window, cx);
|
||||
self.temp_mode = true;
|
||||
}
|
||||
|
||||
fn insert_around(&mut self, direction: Direction, _: &mut Window, cx: &mut Context<Self>) {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
let mut edits = Vec::new();
|
||||
for selection in editor.selections.all::<Point>(cx) {
|
||||
let point = selection.head();
|
||||
let new_row = match direction {
|
||||
Direction::Next => point.row + 1,
|
||||
Direction::Prev if point.row > 0 => point.row - 1,
|
||||
_ => continue,
|
||||
};
|
||||
let source = snapshot.clip_point(Point::new(new_row, point.column), Bias::Left);
|
||||
if let Some(c) = snapshot.chars_at(source).next()
|
||||
&& c != '\n'
|
||||
{
|
||||
edits.push((point..point, c.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
editor.edit(edits, cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -156,4 +191,13 @@ mod test {
|
||||
.await;
|
||||
cx.shared_state().await.assert_eq("hehello\nˇllo\n");
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_insert_ctrl_y(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
|
||||
cx.set_shared_state("hello\nˇ\nworld").await;
|
||||
cx.simulate_shared_keystrokes("i ctrl-y ctrl-e").await;
|
||||
cx.shared_state().await.assert_eq("hello\nhoˇ\nworld");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -679,7 +679,7 @@ impl Vim {
|
||||
match self.mode {
|
||||
Mode::Visual | Mode::VisualLine | Mode::VisualBlock => {
|
||||
if !prior_selections.is_empty() {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.select_ranges(prior_selections.iter().cloned())
|
||||
})
|
||||
|
||||
@@ -132,7 +132,7 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
|
||||
Vim::action(editor, cx, |vim, _: &HelixDelete, window, cx| {
|
||||
vim.record_current_action(cx);
|
||||
vim.update_editor(window, cx, |_, editor, window, cx| {
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
if selection.is_empty() {
|
||||
@@ -146,7 +146,7 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
});
|
||||
|
||||
Vim::action(editor, cx, |vim, _: &HelixCollapseSelection, window, cx| {
|
||||
vim.update_editor(window, cx, |_, editor, window, cx| {
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
let mut point = selection.head();
|
||||
@@ -198,7 +198,7 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
Vim::action(editor, cx, |vim, _: &Undo, window, cx| {
|
||||
let times = Vim::take_count(cx);
|
||||
Vim::take_forced_motion(cx);
|
||||
vim.update_editor(window, cx, |_, editor, window, cx| {
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
for _ in 0..times.unwrap_or(1) {
|
||||
editor.undo(&editor::actions::Undo, window, cx);
|
||||
}
|
||||
@@ -207,7 +207,7 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
Vim::action(editor, cx, |vim, _: &Redo, window, cx| {
|
||||
let times = Vim::take_count(cx);
|
||||
Vim::take_forced_motion(cx);
|
||||
vim.update_editor(window, cx, |_, editor, window, cx| {
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
for _ in 0..times.unwrap_or(1) {
|
||||
editor.redo(&editor::actions::Redo, window, cx);
|
||||
}
|
||||
@@ -215,7 +215,7 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
});
|
||||
Vim::action(editor, cx, |vim, _: &UndoLastLine, window, cx| {
|
||||
Vim::take_forced_motion(cx);
|
||||
vim.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
vim.update_editor(cx, |vim, editor, cx| {
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
let Some(last_change) = editor.change_list.last_before_grouping() else {
|
||||
return;
|
||||
@@ -526,7 +526,7 @@ impl Vim {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
editor.change_selections(
|
||||
SelectionEffects::default().nav_history(motion.push_to_jump_list()),
|
||||
@@ -546,7 +546,7 @@ impl Vim {
|
||||
fn insert_after(&mut self, _: &InsertAfter, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.start_recording(cx);
|
||||
self.switch_mode(Mode::Insert, false, window, cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.move_cursors_with(|map, cursor, _| (right(map, cursor, 1), SelectionGoal::None));
|
||||
});
|
||||
@@ -557,7 +557,7 @@ impl Vim {
|
||||
self.start_recording(cx);
|
||||
if self.mode.is_visual() {
|
||||
let current_mode = self.mode;
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
if current_mode == Mode::VisualLine {
|
||||
@@ -581,7 +581,7 @@ impl Vim {
|
||||
) {
|
||||
self.start_recording(cx);
|
||||
self.switch_mode(Mode::Insert, false, window, cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.move_cursors_with(|map, cursor, _| {
|
||||
(
|
||||
@@ -601,7 +601,7 @@ impl Vim {
|
||||
) {
|
||||
self.start_recording(cx);
|
||||
self.switch_mode(Mode::Insert, false, window, cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.move_cursors_with(|map, cursor, _| {
|
||||
(next_line_end(map, cursor, 1), SelectionGoal::None)
|
||||
@@ -618,7 +618,7 @@ impl Vim {
|
||||
) {
|
||||
self.start_recording(cx);
|
||||
self.switch_mode(Mode::Insert, false, window, cx);
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let Some(Mark::Local(marks)) = vim.get_mark("^", editor, window, cx) else {
|
||||
return;
|
||||
};
|
||||
@@ -637,7 +637,7 @@ impl Vim {
|
||||
) {
|
||||
self.start_recording(cx);
|
||||
self.switch_mode(Mode::Insert, false, window, cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let selections = editor.selections.all::<Point>(cx);
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
@@ -678,7 +678,7 @@ impl Vim {
|
||||
) {
|
||||
self.start_recording(cx);
|
||||
self.switch_mode(Mode::Insert, false, window, cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let selections = editor.selections.all::<Point>(cx);
|
||||
@@ -725,7 +725,7 @@ impl Vim {
|
||||
self.record_current_action(cx);
|
||||
let count = Vim::take_count(cx).unwrap_or(1);
|
||||
Vim::take_forced_motion(cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, _, cx| {
|
||||
let selections = editor.selections.all::<Point>(cx);
|
||||
|
||||
@@ -754,7 +754,7 @@ impl Vim {
|
||||
self.record_current_action(cx);
|
||||
let count = Vim::take_count(cx).unwrap_or(1);
|
||||
Vim::take_forced_motion(cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let selections = editor.selections.all::<Point>(cx);
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
@@ -804,7 +804,7 @@ impl Vim {
|
||||
times -= 1;
|
||||
}
|
||||
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
for _ in 0..times {
|
||||
editor.join_lines_impl(insert_whitespace, window, cx)
|
||||
@@ -828,10 +828,10 @@ impl Vim {
|
||||
)
|
||||
}
|
||||
|
||||
fn show_location(&mut self, _: &ShowLocation, window: &mut Window, cx: &mut Context<Self>) {
|
||||
fn show_location(&mut self, _: &ShowLocation, _: &mut Window, cx: &mut Context<Self>) {
|
||||
let count = Vim::take_count(cx);
|
||||
Vim::take_forced_motion(cx);
|
||||
self.update_editor(window, cx, |vim, editor, _window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let selection = editor.selections.newest_anchor();
|
||||
let Some((buffer, point, _)) = editor
|
||||
.buffer()
|
||||
@@ -875,7 +875,7 @@ impl Vim {
|
||||
fn toggle_comments(&mut self, _: &ToggleComments, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.record_current_action(cx);
|
||||
self.store_visual_marks(window, cx);
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let original_positions = vim.save_selection_starts(editor, cx);
|
||||
editor.toggle_comments(&Default::default(), window, cx);
|
||||
@@ -897,7 +897,7 @@ impl Vim {
|
||||
let count = Vim::take_count(cx).unwrap_or(1);
|
||||
Vim::take_forced_motion(cx);
|
||||
self.stop_recording(cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
let (map, display_selections) = editor.selections.all_display(cx);
|
||||
|
||||
@@ -34,7 +34,7 @@ impl Vim {
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
// We are swapping to insert mode anyway. Just set the line end clipping behavior now
|
||||
@@ -111,7 +111,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let mut objects_found = false;
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
// We are swapping to insert mode anyway. Just set the line end clipping behavior now
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
|
||||
@@ -31,7 +31,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.stop_recording(cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
@@ -87,7 +87,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.stop_recording(cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
let mut original_positions: HashMap<_, _> = Default::default();
|
||||
@@ -195,7 +195,7 @@ impl Vim {
|
||||
let count = Vim::take_count(cx).unwrap_or(1) as u32;
|
||||
Vim::take_forced_motion(cx);
|
||||
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let mut ranges = Vec::new();
|
||||
let mut cursor_positions = Vec::new();
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
|
||||
@@ -22,7 +22,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.stop_recording(cx);
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
@@ -96,7 +96,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.stop_recording(cx);
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
// Emulates behavior in vim where if we expanded backwards to include a newline
|
||||
|
||||
@@ -53,7 +53,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.store_visual_marks(window, cx);
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let mut edits = Vec::new();
|
||||
let mut new_anchors = Vec::new();
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ use crate::{
|
||||
|
||||
impl Vim {
|
||||
pub fn create_mark(&mut self, text: Arc<str>, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let anchors = editor
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
@@ -49,7 +49,7 @@ impl Vim {
|
||||
let mut ends = vec![];
|
||||
let mut reversed = vec![];
|
||||
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let (map, selections) = editor.selections.all_display(cx);
|
||||
for selection in selections {
|
||||
let end = movement::saturating_left(&map, selection.end);
|
||||
@@ -190,7 +190,7 @@ impl Vim {
|
||||
self.pop_operator(window, cx);
|
||||
}
|
||||
let mark = self
|
||||
.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
.update_editor(cx, |vim, editor, cx| {
|
||||
vim.get_mark(&text, editor, window, cx)
|
||||
})
|
||||
.flatten();
|
||||
@@ -209,7 +209,7 @@ impl Vim {
|
||||
|
||||
let Some(mut anchors) = anchors else { return };
|
||||
|
||||
self.update_editor(window, cx, |_, editor, _, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.create_nav_history_entry(cx);
|
||||
});
|
||||
let is_active_operator = self.active_operator().is_some();
|
||||
@@ -231,7 +231,7 @@ impl Vim {
|
||||
|| self.mode == Mode::VisualLine
|
||||
|| self.mode == Mode::VisualBlock;
|
||||
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let map = editor.snapshot(window, cx);
|
||||
let mut ranges: Vec<Range<Anchor>> = Vec::new();
|
||||
for mut anchor in anchors {
|
||||
|
||||
@@ -32,7 +32,7 @@ impl Vim {
|
||||
let count = Vim::take_count(cx).unwrap_or(1);
|
||||
Vim::take_forced_motion(cx);
|
||||
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
@@ -236,7 +236,7 @@ impl Vim {
|
||||
) {
|
||||
self.stop_recording(cx);
|
||||
let selected_register = self.selected_register.take();
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
@@ -273,7 +273,7 @@ impl Vim {
|
||||
) {
|
||||
self.stop_recording(cx);
|
||||
let selected_register = self.selected_register.take();
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
|
||||
@@ -97,7 +97,7 @@ impl Vim {
|
||||
let amount = by(Vim::take_count(cx).map(|c| c as f32));
|
||||
Vim::take_forced_motion(cx);
|
||||
self.exit_temporary_normal(window, cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
scroll_editor(editor, move_cursor, &amount, window, cx)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ impl Vim {
|
||||
|
||||
// If the active editor has changed during a search, don't panic.
|
||||
if prior_selections.iter().any(|s| {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
!s.start
|
||||
.is_valid(&editor.snapshot(window, cx).buffer_snapshot)
|
||||
})
|
||||
@@ -457,7 +457,7 @@ impl Vim {
|
||||
else {
|
||||
return;
|
||||
};
|
||||
if let Some(result) = self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
if let Some(result) = self.update_editor(cx, |vim, editor, cx| {
|
||||
let range = action.range.buffer_range(vim, editor, window, cx)?;
|
||||
let snapshot = &editor.snapshot(window, cx).buffer_snapshot;
|
||||
let end_point = Point::new(range.end.0, snapshot.line_len(range.end));
|
||||
|
||||
@@ -45,7 +45,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.store_visual_marks(window, cx);
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
|
||||
@@ -14,7 +14,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.stop_recording(cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let mut selection_starts: HashMap<_, _> = Default::default();
|
||||
@@ -51,7 +51,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.stop_recording(cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let mut original_positions: HashMap<_, _> = Default::default();
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
|
||||
@@ -25,7 +25,7 @@ impl Vim {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
@@ -70,7 +70,7 @@ impl Vim {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
let mut start_positions: HashMap<_, _> = Default::default();
|
||||
|
||||
@@ -49,7 +49,7 @@ impl Vim {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
let map = editor.snapshot(window, cx);
|
||||
@@ -94,7 +94,7 @@ impl Vim {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
let map = editor.snapshot(window, cx);
|
||||
@@ -148,7 +148,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.stop_recording(cx);
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
let mut selection = editor.selections.newest_display(cx);
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
@@ -167,7 +167,7 @@ impl Vim {
|
||||
|
||||
pub fn exchange_visual(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.stop_recording(cx);
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let selection = editor.selections.newest_anchor();
|
||||
let new_range = selection.start..selection.end;
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
@@ -178,7 +178,7 @@ impl Vim {
|
||||
|
||||
pub fn clear_exchange(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.stop_recording(cx);
|
||||
self.update_editor(window, cx, |_, editor, _, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.clear_background_highlights::<VimExchange>(cx);
|
||||
});
|
||||
self.clear_operator(window, cx);
|
||||
@@ -193,7 +193,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.stop_recording(cx);
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
let mut selection = editor.selections.newest_display(cx);
|
||||
|
||||
@@ -18,7 +18,7 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
Vim::take_count(cx);
|
||||
Vim::take_forced_motion(cx);
|
||||
vim.store_visual_marks(window, cx);
|
||||
vim.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
vim.update_editor(cx, |vim, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let mut positions = vim.save_selection_starts(editor, cx);
|
||||
editor.rewrap_impl(
|
||||
@@ -55,7 +55,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.stop_recording(cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let mut selection_starts: HashMap<_, _> = Default::default();
|
||||
@@ -100,7 +100,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.stop_recording(cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let mut original_positions: HashMap<_, _> = Default::default();
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
|
||||
@@ -29,7 +29,7 @@ impl Vim {
|
||||
let count = Vim::take_count(cx);
|
||||
let forced_motion = Vim::take_forced_motion(cx);
|
||||
let mode = self.mode;
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
@@ -140,7 +140,7 @@ impl Vim {
|
||||
};
|
||||
let surround = pair.end != *text;
|
||||
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
|
||||
@@ -228,7 +228,7 @@ impl Vim {
|
||||
) {
|
||||
if let Some(will_replace_pair) = object_to_bracket_pair(target) {
|
||||
self.stop_recording(cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
|
||||
@@ -344,7 +344,7 @@ impl Vim {
|
||||
) -> bool {
|
||||
let mut valid = false;
|
||||
if let Some(pair) = object_to_bracket_pair(object) {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
let (display_map, selections) = editor.selections.all_adjusted_display(cx);
|
||||
|
||||
@@ -15,6 +15,7 @@ impl VimTestContext {
|
||||
if cx.has_global::<VimGlobals>() {
|
||||
return;
|
||||
}
|
||||
env_logger::try_init().ok();
|
||||
cx.update(|cx| {
|
||||
let settings = SettingsStore::test(cx);
|
||||
cx.set_global(settings);
|
||||
|
||||
@@ -748,7 +748,7 @@ impl Vim {
|
||||
editor,
|
||||
cx,
|
||||
|vim, action: &editor::actions::AcceptEditPrediction, window, cx| {
|
||||
vim.update_editor(window, cx, |_, editor, window, cx| {
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
editor.accept_edit_prediction(action, window, cx);
|
||||
});
|
||||
// In non-insertion modes, predictions will be hidden and instead a jump will be
|
||||
@@ -847,7 +847,7 @@ impl Vim {
|
||||
if let Some(action) = keystroke_event.action.as_ref() {
|
||||
// Keystroke is handled by the vim system, so continue forward
|
||||
if action.name().starts_with("vim::") {
|
||||
self.update_editor(window, cx, |_, editor, _, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx)
|
||||
});
|
||||
return;
|
||||
@@ -909,7 +909,7 @@ impl Vim {
|
||||
anchor,
|
||||
is_deactivate,
|
||||
} => {
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let mark = if *is_deactivate {
|
||||
"\"".to_string()
|
||||
} else {
|
||||
@@ -972,7 +972,7 @@ impl Vim {
|
||||
if mode == Mode::Normal || mode != last_mode {
|
||||
self.current_tx.take();
|
||||
self.current_anchor.take();
|
||||
self.update_editor(window, cx, |_, editor, _, _| {
|
||||
self.update_editor(cx, |_, editor, _| {
|
||||
editor.clear_selection_drag_state();
|
||||
});
|
||||
}
|
||||
@@ -988,7 +988,7 @@ impl Vim {
|
||||
&& self.mode != self.last_mode
|
||||
&& (self.mode == Mode::Insert || self.last_mode == Mode::Insert)
|
||||
{
|
||||
self.update_editor(window, cx, |vim, editor, _, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let is_relative = vim.mode != Mode::Insert;
|
||||
editor.set_relative_line_number(Some(is_relative), cx)
|
||||
});
|
||||
@@ -1003,7 +1003,7 @@ impl Vim {
|
||||
}
|
||||
|
||||
// Adjust selections
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
if last_mode != Mode::VisualBlock && last_mode.is_visual() && mode == Mode::VisualBlock
|
||||
{
|
||||
vim.visual_block_motion(true, editor, window, cx, |_, point, goal| {
|
||||
@@ -1214,7 +1214,7 @@ impl Vim {
|
||||
if preserve_selection {
|
||||
self.switch_mode(Mode::Visual, true, window, cx);
|
||||
} else {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
s.move_with(|_, selection| {
|
||||
@@ -1232,18 +1232,18 @@ impl Vim {
|
||||
if let Some(old_vim) = Vim::globals(cx).focused_vim() {
|
||||
if old_vim.entity_id() != cx.entity().entity_id() {
|
||||
old_vim.update(cx, |vim, cx| {
|
||||
vim.update_editor(window, cx, |_, editor, _, cx| {
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
editor.set_relative_line_number(None, cx)
|
||||
});
|
||||
});
|
||||
|
||||
self.update_editor(window, cx, |vim, editor, _, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let is_relative = vim.mode != Mode::Insert;
|
||||
editor.set_relative_line_number(Some(is_relative), cx)
|
||||
});
|
||||
}
|
||||
} else {
|
||||
self.update_editor(window, cx, |vim, editor, _, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let is_relative = vim.mode != Mode::Insert;
|
||||
editor.set_relative_line_number(Some(is_relative), cx)
|
||||
});
|
||||
@@ -1256,35 +1256,30 @@ impl Vim {
|
||||
self.stop_recording_immediately(NormalBefore.boxed_clone(), cx);
|
||||
self.store_visual_marks(window, cx);
|
||||
self.clear_operator(window, cx);
|
||||
self.update_editor(window, cx, |vim, editor, _, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
if vim.cursor_shape(cx) == CursorShape::Block {
|
||||
editor.set_cursor_shape(CursorShape::Hollow, cx);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn cursor_shape_changed(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.update_editor(window, cx, |vim, editor, _, cx| {
|
||||
fn cursor_shape_changed(&mut self, _: &mut Window, cx: &mut Context<Self>) {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
editor.set_cursor_shape(vim.cursor_shape(cx), cx);
|
||||
});
|
||||
}
|
||||
|
||||
fn update_editor<S>(
|
||||
&mut self,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
update: impl FnOnce(&mut Self, &mut Editor, &mut Window, &mut Context<Editor>) -> S,
|
||||
update: impl FnOnce(&mut Self, &mut Editor, &mut Context<Editor>) -> S,
|
||||
) -> Option<S> {
|
||||
let editor = self.editor.upgrade()?;
|
||||
Some(editor.update(cx, |editor, cx| update(self, editor, window, cx)))
|
||||
Some(editor.update(cx, |editor, cx| update(self, editor, cx)))
|
||||
}
|
||||
|
||||
fn editor_selections(
|
||||
&mut self,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Vec<Range<Anchor>> {
|
||||
self.update_editor(window, cx, |_, editor, _, _| {
|
||||
fn editor_selections(&mut self, _: &mut Window, cx: &mut Context<Self>) -> Vec<Range<Anchor>> {
|
||||
self.update_editor(cx, |_, editor, _| {
|
||||
editor
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
@@ -1300,7 +1295,7 @@ impl Vim {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<String> {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let selection = editor.selections.newest::<usize>(cx);
|
||||
|
||||
let snapshot = &editor.snapshot(window, cx).buffer_snapshot;
|
||||
@@ -1489,7 +1484,7 @@ impl Vim {
|
||||
) {
|
||||
match self.mode {
|
||||
Mode::VisualLine | Mode::VisualBlock | Mode::Visual => {
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let original_mode = vim.undo_modes.get(transaction_id);
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
match original_mode {
|
||||
@@ -1520,7 +1515,7 @@ impl Vim {
|
||||
self.switch_mode(Mode::Normal, true, window, cx)
|
||||
}
|
||||
Mode::Normal => {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
selection
|
||||
@@ -1547,7 +1542,7 @@ impl Vim {
|
||||
self.current_anchor = Some(newest);
|
||||
} else if self.current_anchor.as_ref().unwrap() != &newest {
|
||||
if let Some(tx_id) = self.current_tx.take() {
|
||||
self.update_editor(window, cx, |_, editor, _, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.group_until_transaction(tx_id, cx)
|
||||
});
|
||||
}
|
||||
@@ -1694,7 +1689,7 @@ impl Vim {
|
||||
}
|
||||
Some(Operator::Register) => match self.mode {
|
||||
Mode::Insert => {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
if let Some(register) = Vim::update_globals(cx, |globals, cx| {
|
||||
globals.read_register(text.chars().next(), Some(editor), cx)
|
||||
}) {
|
||||
@@ -1720,7 +1715,7 @@ impl Vim {
|
||||
}
|
||||
|
||||
if self.mode == Mode::Normal {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.accept_edit_prediction(
|
||||
&editor::actions::AcceptEditPrediction {},
|
||||
window,
|
||||
@@ -1733,7 +1728,7 @@ impl Vim {
|
||||
}
|
||||
|
||||
fn sync_vim_settings(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
editor.set_cursor_shape(vim.cursor_shape(cx), cx);
|
||||
editor.set_clip_at_line_ends(vim.clip_at_line_ends(), cx);
|
||||
editor.set_collapse_matches(true);
|
||||
|
||||
@@ -104,7 +104,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
let count = Vim::take_count(cx).unwrap_or(1);
|
||||
Vim::take_forced_motion(cx);
|
||||
for _ in 0..count {
|
||||
vim.update_editor(window, cx, |_, editor, window, cx| {
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
editor.select_larger_syntax_node(&Default::default(), window, cx);
|
||||
});
|
||||
}
|
||||
@@ -117,7 +117,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
let count = Vim::take_count(cx).unwrap_or(1);
|
||||
Vim::take_forced_motion(cx);
|
||||
for _ in 0..count {
|
||||
vim.update_editor(window, cx, |_, editor, window, cx| {
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
editor.select_smaller_syntax_node(&Default::default(), window, cx);
|
||||
});
|
||||
}
|
||||
@@ -129,7 +129,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
return;
|
||||
};
|
||||
let marks = vim
|
||||
.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
.update_editor(cx, |vim, editor, cx| {
|
||||
vim.get_mark("<", editor, window, cx)
|
||||
.zip(vim.get_mark(">", editor, window, cx))
|
||||
})
|
||||
@@ -148,7 +148,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
vim.create_visual_marks(vim.mode, window, cx);
|
||||
}
|
||||
|
||||
vim.update_editor(window, cx, |_, editor, window, cx| {
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
let map = s.display_map();
|
||||
@@ -189,7 +189,7 @@ impl Vim {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
if vim.mode == Mode::VisualBlock
|
||||
&& !matches!(
|
||||
@@ -397,7 +397,7 @@ impl Vim {
|
||||
self.switch_mode(target_mode, true, window, cx);
|
||||
}
|
||||
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
let mut mut_selection = selection.clone();
|
||||
@@ -475,7 +475,7 @@ impl Vim {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.split_selection_into_lines(&Default::default(), window, cx);
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.move_cursors_with(|map, cursor, _| {
|
||||
@@ -493,7 +493,7 @@ impl Vim {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.split_selection_into_lines(&Default::default(), window, cx);
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.move_cursors_with(|map, cursor, _| {
|
||||
@@ -517,7 +517,7 @@ impl Vim {
|
||||
}
|
||||
|
||||
pub fn other_end(&mut self, _: &OtherEnd, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.move_with(|_, selection| {
|
||||
selection.reversed = !selection.reversed;
|
||||
@@ -533,7 +533,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let mode = self.mode;
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.move_with(|_, selection| {
|
||||
selection.reversed = !selection.reversed;
|
||||
@@ -547,7 +547,7 @@ impl Vim {
|
||||
|
||||
pub fn visual_delete(&mut self, line_mode: bool, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.store_visual_marks(window, cx);
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let mut original_columns: HashMap<_, _> = Default::default();
|
||||
let line_mode = line_mode || editor.selections.line_mode;
|
||||
editor.selections.line_mode = false;
|
||||
@@ -631,7 +631,7 @@ impl Vim {
|
||||
|
||||
pub fn visual_yank(&mut self, line_mode: bool, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.store_visual_marks(window, cx);
|
||||
self.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let line_mode = line_mode || editor.selections.line_mode;
|
||||
|
||||
// For visual line mode, adjust selections to avoid yanking the next line when on \n
|
||||
@@ -679,7 +679,7 @@ impl Vim {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.stop_recording(cx);
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let (display_map, selections) = editor.selections.all_adjusted_display(cx);
|
||||
|
||||
@@ -722,7 +722,7 @@ impl Vim {
|
||||
Vim::take_forced_motion(cx);
|
||||
let count =
|
||||
Vim::take_count(cx).unwrap_or_else(|| if self.mode.is_visual() { 1 } else { 2 });
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
for _ in 0..count {
|
||||
if editor
|
||||
@@ -745,7 +745,7 @@ impl Vim {
|
||||
Vim::take_forced_motion(cx);
|
||||
let count =
|
||||
Vim::take_count(cx).unwrap_or_else(|| if self.mode.is_visual() { 1 } else { 2 });
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
for _ in 0..count {
|
||||
if editor
|
||||
.select_previous(&Default::default(), window, cx)
|
||||
@@ -773,7 +773,7 @@ impl Vim {
|
||||
let mut start_selection = 0usize;
|
||||
let mut end_selection = 0usize;
|
||||
|
||||
self.update_editor(window, cx, |_, editor, _, _| {
|
||||
self.update_editor(cx, |_, editor, _| {
|
||||
editor.set_collapse_matches(false);
|
||||
});
|
||||
if vim_is_normal {
|
||||
@@ -791,7 +791,7 @@ impl Vim {
|
||||
}
|
||||
});
|
||||
}
|
||||
self.update_editor(window, cx, |_, editor, _, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let latest = editor.selections.newest::<usize>(cx);
|
||||
start_selection = latest.start;
|
||||
end_selection = latest.end;
|
||||
@@ -812,7 +812,7 @@ impl Vim {
|
||||
self.stop_replaying(cx);
|
||||
return;
|
||||
}
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let latest = editor.selections.newest::<usize>(cx);
|
||||
if vim_is_normal {
|
||||
start_selection = latest.start;
|
||||
|
||||
@@ -326,7 +326,7 @@ When you use `cargo build` or `cargo test` as the build command, Zed can infer t
|
||||
[
|
||||
{
|
||||
"label": "Build & Debug native binary",
|
||||
"adapter": "CodeLLDB"
|
||||
"adapter": "CodeLLDB",
|
||||
"build": {
|
||||
"command": "cargo",
|
||||
"args": ["build"]
|
||||
|
||||
Reference in New Issue
Block a user