Skip to content

Commit

Permalink
Add the ability to monitor file paths for changes
Browse files Browse the repository at this point in the history
Add a file watcher to monitor open files and update the associated
zee buffer as the content changes. Event notification is done by the
`notify` crate using the recommended notification API (inotify,
fsevent, etc.) of the host platform.

Much of the watcher module code is taken from the xi-editor project
which is licensed under the Apache 2.0 license.
  • Loading branch information
iainh committed Jul 30, 2022
1 parent 2053b21 commit a123b8a
Show file tree
Hide file tree
Showing 5 changed files with 420 additions and 3 deletions.
80 changes: 80 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions zee/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ ignore = "0.4.18"
include_dir = "0.7.2"
log = "0.4.17"
maplit = "1.0.2"
notify = { version = "=5.0.0-pre.15" }
once_cell = { version = "1.13.0", features = ["parking_lot"] }
palette = "0.5.0"
parking_lot = "0.12.1"
Expand Down
53 changes: 50 additions & 3 deletions zee/src/editor/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use ropey::Rope;
use std::{
fmt::Display,
fs::File,
io::{self, BufWriter},
io::{self, BufReader, BufWriter},
path::{Path, PathBuf},
rc::Rc,
};
Expand All @@ -20,6 +20,7 @@ use crate::{
error::Result,
syntax::parse::{ParseTree, ParserPool, ParserStatus},
versioned::{Versioned, WeakHandle},
watcher::{FileWatcher, WatchToken},
};

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -47,7 +48,7 @@ pub struct BuffersMessage {
}

impl BuffersMessage {
fn new(buffer_id: BufferId, message: BufferMessage) -> Self {
pub fn new(buffer_id: BufferId, message: BufferMessage) -> Self {
Self {
buffer_id,
inner: message,
Expand All @@ -59,14 +60,18 @@ pub struct Buffers {
context: ContextHandle,
buffers: Vec<Buffer>,
next_buffer_id: usize,
watcher: FileWatcher,
}

impl Buffers {
pub fn new(context: ContextHandle) -> Self {
let watcher = FileWatcher::new(context.link.clone());

Self {
context,
buffers: Vec::new(),
next_buffer_id: 0,
watcher,
}
}

Expand All @@ -83,13 +88,34 @@ impl Buffers {
self.context.clone(),
buffer_id,
text,
file_path,
file_path.clone(),
repo,
));

if let Some(file_path) = file_path.as_ref() {
log::debug!("Watching {}", &file_path.display());
self.watcher.watch(file_path, false, WatchToken(buffer_id));
}

buffer_id
}

pub fn remove(&mut self, id: BufferId) -> Option<Buffer> {
let file_path = self
.buffers
.iter()
.find(|buffer| buffer.id == id)
.and_then(|buffer| buffer.file_path.as_ref());

if let Some(file_path) = file_path {
log::debug!(
"Unwatching buffer_id: {}, file_path: {}",
id,
&file_path.display()
);
self.watcher.unwatch(file_path, WatchToken(id));
}

self.buffers
.iter()
.position(|buffer| buffer.id == id)
Expand Down Expand Up @@ -312,6 +338,26 @@ impl Buffer {
}
BufferMessage::PreviousChildRevision => self.content.previous_child(),
BufferMessage::NextChildRevision => self.content.next_child(),
BufferMessage::Refresh => {
// only refresh the buffer if the modification status is 'unchanged'.
if self.modified_status() == ModifiedStatus::Unchanged {
let new_content = Rope::from_reader(BufReader::new(
File::open(&self.file_path.as_ref().unwrap()).unwrap(),
))
.unwrap();

for cursor in self.cursors.iter_mut() {
cursor.sync(&self.content, &new_content);
}

// Create a new revision, update the content.
self.content
.create_revision(OpaqueDiff::empty(), self.cursors[0].clone());
*self.content.staged_mut() = new_content;

self.update_parse_tree(&OpaqueDiff::empty(), true);
}
}
};
}

Expand Down Expand Up @@ -767,6 +813,7 @@ pub enum BufferMessage {
cursor_id: CursorId,
message: CursorMessage,
},
Refresh,
}

#[derive(Debug)]
Expand Down
1 change: 1 addition & 0 deletions zee/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod syntax;
mod task;
mod utils;
mod versioned;
mod watcher;

use clap::Parser;
use std::{env, path::PathBuf};
Expand Down
Loading

0 comments on commit a123b8a

Please sign in to comment.