-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -207,6 +207,8 @@ pub enum CoreNotification { | |
SaveTrace { destination: PathBuf, frontend_samples: Value }, | ||
/// Tells `xi-core` to set the language id for the view. | ||
SetLanguage { view_id: ViewId, language_id: LanguageId }, | ||
/// Enables/disabled tailing file at file_path. | ||
ToggleTail { view_id: ViewId, file_path: String, enabled: bool }, | ||
This comment has been minimized.
Sorry, something went wrong.
cmyr
|
||
} | ||
|
||
/// The requests which make up the base of the protocol. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,6 +58,7 @@ use crate::WeakXiCore; | |
|
||
#[cfg(feature = "notify")] | ||
use crate::watcher::{FileWatcher, WatchToken}; | ||
use notify::event::Flag::Ongoing; | ||
#[cfg(feature = "notify")] | ||
use notify::Event; | ||
#[cfg(feature = "notify")] | ||
|
@@ -331,6 +332,9 @@ impl CoreState { | |
// handled at the top level | ||
ClientStarted { .. } => (), | ||
SetLanguage { view_id, language_id } => self.do_set_language(view_id, language_id), | ||
ToggleTail { view_id, file_path, enabled } => { | ||
self.do_toggle_tail(view_id, file_path, enabled) | ||
} | ||
} | ||
} | ||
|
||
|
@@ -555,6 +559,32 @@ impl CoreState { | |
fn after_stop_plugin(&mut self, plugin: &Plugin) { | ||
self.iter_groups().for_each(|mut cx| cx.plugin_stopped(plugin)); | ||
} | ||
|
||
#[cfg(feature = "notify")] | ||
fn do_toggle_tail(&mut self, view_id: ViewId, path: P, enabled: bool) | ||
where | ||
P: AsRef<Path>, | ||
{ | ||
let buffer_id = self.views.get(&view_id).map(|v| v.borrow().get_buffer_id()); | ||
let buffer_id = match buffer_id { | ||
Some(id) => id, | ||
None => return, | ||
}; | ||
if enabled { | ||
let path = path.as_ref(); | ||
self.file_manager.update_current_position_in_tail(path, buffer_id); | ||
} else { | ||
self.file_manager.disable_tailing(buffer_id); | ||
} | ||
} | ||
|
||
#[cfg(not(feature = "notify"))] | ||
fn do_toggle_tail(&mut self, view_id: ViewId, path: P, enabled: bool) | ||
where | ||
P: AsRef<Path>, | ||
{ | ||
warn!("do_toggle_tail called without notify feature enabled."); | ||
} | ||
} | ||
|
||
/// Idle, tracing, and file event handling | ||
|
@@ -705,10 +735,36 @@ impl CoreState { | |
#[cfg(feature = "notify")] | ||
fn handle_open_file_fs_event(&mut self, event: Event) { | ||
use notify::event::*; | ||
let mut is_tail_event = false; | ||
let path = match event.kind { | ||
EventKind::Create(CreateKind::Any) | ||
| EventKind::Modify(ModifyKind::Metadata(MetadataKind::Any)) | ||
| EventKind::Modify(ModifyKind::Any) => &event.paths[0], | ||
| EventKind::Modify(ModifyKind::Any) => { | ||
let path = &event.paths[0]; | ||
|
||
is_tail_event = match event.flag().unwrap_or_else(false) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
cmyr
|
||
Ongoing => { | ||
let buffer_id = match self.file_manager.get_editor(path) { | ||
Some(id) => id, | ||
None => return, | ||
}; | ||
let file_info = self.file_manager.get_info(buffer_id); | ||
match file_info { | ||
Some(i) => { | ||
match i.tailing_enabled { | ||
Some(t) => true, | ||
// Ignore tail events for paths which are not tailed. | ||
None => return, | ||
} | ||
} | ||
None => return, | ||
} | ||
} | ||
_ => false, | ||
}; | ||
|
||
path | ||
} | ||
other => { | ||
debug!("Ignoring event in open file {:?}", other); | ||
return; | ||
|
@@ -727,16 +783,21 @@ impl CoreState { | |
// A more robust solution would also hash the file's contents. | ||
|
||
if has_changes && is_pristine { | ||
if let Ok(text) = self.file_manager.open(path, buffer_id) { | ||
// this is ugly; we don't map buffer_id -> view_id anywhere | ||
// but we know we must have a view. | ||
let view_id = self | ||
.views | ||
.values() | ||
.find(|v| v.borrow().get_buffer_id() == buffer_id) | ||
.map(|v| v.borrow().get_view_id()) | ||
.unwrap(); | ||
self.make_context(view_id).unwrap().reload(text); | ||
if is_tail_event { | ||
This comment has been minimized.
Sorry, something went wrong.
sjoshid
Author
Owner
|
||
// Since this is tail event, we need to get delta of changes since the last time we | ||
// read the file. | ||
} else { | ||
if let Ok(text) = self.file_manager.open(path, buffer_id) { | ||
// this is ugly; we don't map buffer_id -> view_id anywhere | ||
// but we know we must have a view. | ||
let view_id = self | ||
.views | ||
.values() | ||
.find(|v| v.borrow().get_buffer_id() == buffer_id) | ||
.map(|v| v.borrow().get_view_id()) | ||
.unwrap(); | ||
self.make_context(view_id).unwrap().reload(text); | ||
} | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,7 +35,7 @@ | |
//! they arrive, and an idle task is scheduled. | ||
|
||
use crossbeam::unbounded; | ||
use notify::{event::*, watcher, RecommendedWatcher, RecursiveMode, Watcher}; | ||
use notify::{event::*, watcher, Config, RecommendedWatcher, RecursiveMode, Watcher}; | ||
use std::collections::VecDeque; | ||
use std::fmt; | ||
use std::mem; | ||
|
@@ -44,7 +44,9 @@ use std::sync::{Arc, Mutex}; | |
use std::thread; | ||
use std::time::Duration; | ||
|
||
use notify::event::DataChange::Content; | ||
use xi_rpc::RpcPeer; | ||
use xi_trace::SampleEventType::DurationBegin; | ||
|
||
/// Delay for aggregating related file system events. | ||
pub const DEBOUNCE_WAIT_MILLIS: u64 = 50; | ||
|
@@ -98,7 +100,9 @@ impl FileWatcher { | |
let state = Arc::new(Mutex::new(WatcherState::default())); | ||
let state_clone = state.clone(); | ||
|
||
let inner = watcher(tx_event, Duration::from_millis(100)).expect("watcher should spawn"); | ||
let mut inner = | ||
watcher(tx_event, Duration::from_millis(100)).expect("watcher should spawn"); | ||
inner.configure(Config::OngoingEvents(Some(Duration::from_millis(50)))); | ||
This comment has been minimized.
Sorry, something went wrong.
sjoshid
Author
Owner
|
||
|
||
thread::spawn(move || { | ||
while let Ok(Ok(event)) = rx_event.recv() { | ||
|
3 comments
on commit 4f437a3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cmyr
Would it be possible to a quick review of this? I'll open a PR if you are ok with the general direction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nothing here seems crazy!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added few more comments.
Some(u64)
will contain cursor location in file which I'll keep updating as I read delta.If
None
, means tailing for that file is disabled.