aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBlaž Hrastnik2021-02-21 10:47:21 +0000
committerBlaž Hrastnik2021-02-21 10:47:21 +0000
commit9132c6a591fc4515cdddfd16cc382fc3368ed27c (patch)
treea98facaaaf7ae2c71f8a85a2cac650427c7126b9
parent7da6bd6a71531713c4de58b04810e32e16eb349a (diff)
Make some Document fields read-only.
-rw-r--r--helix-core/src/state.rs4
-rw-r--r--helix-term/src/application.rs2
-rw-r--r--helix-term/src/commands.rs42
-rw-r--r--helix-view/src/document.rs89
-rw-r--r--helix-view/src/editor.rs7
5 files changed, 74 insertions, 70 deletions
diff --git a/helix-core/src/state.rs b/helix-core/src/state.rs
index 65194b38..d597fcbb 100644
--- a/helix-core/src/state.rs
+++ b/helix-core/src/state.rs
@@ -198,9 +198,6 @@ impl State {
granularity: Granularity,
count: usize,
) -> Selection {
- // move all selections according to normal cursor move semantics by collapsing it
- // into cursors and moving them vertically
-
self.selection
.transform(|range| self.move_range(range, dir, granularity, count, false))
}
@@ -255,7 +252,6 @@ fn move_vertically(
let pos = pos_at_coords(text, Position::new(new_line, new_col));
let mut range = Range::new(if extend { range.anchor } else { pos }, pos);
- use std::convert::TryInto;
range.horiz = Some(horiz);
range
}
diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs
index c82724a5..dfa819db 100644
--- a/helix-term/src/application.rs
+++ b/helix-term/src/application.rs
@@ -137,7 +137,7 @@ impl Application {
.tree
.views()
.map(|(view, _key)| view)
- .find(|view| view.doc.path == path);
+ .find(|view| view.doc.path() == path.as_ref());
if let Some(view) = view {
let doc = view.doc.text().slice(..);
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 104b86b7..bf6f0c88 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -442,7 +442,7 @@ pub fn delete_selection(cx: &mut Context) {
let doc = cx.doc();
_delete_selection(doc);
- append_changes_to_history(doc);
+ doc.append_changes_to_history();
}
pub fn change_selection(cx: &mut Context) {
@@ -492,7 +492,6 @@ pub fn append_mode(cx: &mut Context) {
enter_insert_mode(doc);
doc.restore_cursor = true;
- // TODO: as transaction
let text = doc.text().slice(..);
let selection = doc.selection().transform(|range| {
// TODO: to() + next char
@@ -510,7 +509,6 @@ pub fn command_mode(cx: &mut Context) {
let prompt = Prompt::new(
":".to_owned(),
|_input: &str| {
- // TODO: i need this duplicate list right now to avoid borrow checker issues
let command_list = vec![
"q".to_string(),
"o".to_string(),
@@ -650,40 +648,12 @@ pub fn open_below(cx: &mut Context) {
// O inserts a new line before each line with a selection
-fn append_changes_to_history(doc: &mut Document) {
- if doc.changes.is_empty() {
- return;
- }
-
- // TODO: change -> change -> undo -> change -> change fails, probably old_state needs reset
-
- let new_changeset = ChangeSet::new(doc.text());
- let changes = std::mem::replace(&mut doc.changes, new_changeset);
- // Instead of doing this messy merge we could always commit, and based on transaction
- // annotations either add a new layer or compose into the previous one.
- let transaction = Transaction::from(changes).with_selection(doc.selection().clone());
-
- // increment document version
- // TODO: needs to happen on undo/redo too
- doc.version += 1;
-
- // TODO: trigger lsp/documentDidChange with changes
-
- // HAXX: we need to reconstruct the state as it was before the changes..
- let old_state = doc.old_state.take().expect("no old_state available");
-
- // TODO: take transaction by value?
- doc.history.commit_revision(&transaction, &old_state);
-
- // TODO: notify LSP of changes
-}
-
pub fn normal_mode(cx: &mut Context) {
let doc = cx.doc();
doc.mode = Mode::Normal;
- append_changes_to_history(doc);
+ doc.append_changes_to_history();
// if leaving append mode, move cursor back by 1
if doc.restore_cursor {
@@ -848,7 +818,7 @@ pub fn paste(cx: &mut Context) {
};
doc.apply(&transaction);
- append_changes_to_history(doc);
+ doc.append_changes_to_history();
}
}
@@ -884,7 +854,7 @@ pub fn indent(cx: &mut Context) {
}),
);
doc.apply(&transaction);
- append_changes_to_history(doc);
+ doc.append_changes_to_history();
}
pub fn unindent(cx: &mut Context) {
@@ -917,7 +887,7 @@ pub fn unindent(cx: &mut Context) {
let transaction = Transaction::change(&doc.state, changes.into_iter());
doc.apply(&transaction);
- append_changes_to_history(doc);
+ doc.append_changes_to_history();
}
//
@@ -1010,7 +980,7 @@ pub fn completion(cx: &mut Context) {
let transaction =
util::generate_transaction_from_edits(&doc.state, vec![edit]);
doc.apply(&transaction);
- // TODO: append_changes_to_history(doc); if not in insert mode?
+ // TODO: doc.append_changes_to_history(); if not in insert mode?
}
_ => (),
};
diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs
index 72a2710d..dd7b14fc 100644
--- a/helix-view/src/document.rs
+++ b/helix-view/src/document.rs
@@ -17,7 +17,7 @@ pub enum Mode {
pub struct Document {
pub state: State, // rope + selection
/// File path on disk.
- pub path: Option<PathBuf>,
+ path: Option<PathBuf>,
/// Current editing mode.
pub mode: Mode,
@@ -26,13 +26,16 @@ pub struct Document {
/// Tree-sitter AST tree
pub syntax: Option<Syntax>,
/// Corresponding language scope name. Usually `source.<lang>`.
- pub language: Option<String>,
+ language: Option<String>,
/// Pending changes since last history commit.
- pub changes: ChangeSet,
- pub old_state: Option<State>,
- pub history: History,
- pub version: i32, // should be usize?
+ changes: ChangeSet,
+ /// State at last commit. Used for calculating reverts.
+ old_state: Option<State>,
+ /// Undo tree.
+ history: History,
+ /// Current document version, incremented at each change.
+ version: i32, // should be usize?
pub diagnostics: Vec<Diagnostic>,
pub language_server: Option<Arc<helix_lsp::Client>>,
@@ -90,23 +93,8 @@ impl Document {
let mut doc = Self::new(State::new(doc));
- if let Some(language_config) = LOADER.language_config_for_file_name(path.as_path()) {
- let highlight_config = language_config.highlight_config(scopes).unwrap().unwrap();
- // TODO: config.configure(scopes) is now delayed, is that ok?
-
- let syntax = Syntax::new(&doc.state.doc, highlight_config.clone());
-
- doc.syntax = Some(syntax);
- // TODO: maybe just keep an Arc<> pointer to the language_config?
- doc.language = Some(language_config.scope().to_string());
-
- // TODO: this ties lsp support to tree-sitter enabled languages for now. Language
- // config should use Option<HighlightConfig> to let us have non-tree-sitter configs.
-
- // TODO: circular dep: view <-> lsp
- // helix_lsp::REGISTRY;
- // view should probably depend on lsp
- };
+ let language_config = LOADER.language_config_for_file_name(path.as_path());
+ doc.set_language(language_config, scopes);
// canonicalize path to absolute value
doc.path = Some(std::fs::canonicalize(path)?);
@@ -140,17 +128,35 @@ impl Document {
} // and_then notify save
}
- pub fn set_language(&mut self, scope: &str, scopes: &[String]) {
- if let Some(language_config) = LOADER.language_config_for_scope(scope) {
+ pub fn set_language(
+ &mut self,
+ language_config: Option<Arc<helix_core::syntax::LanguageConfiguration>>,
+ scopes: &[String],
+ ) {
+ if let Some(language_config) = language_config {
+ // TODO: maybe just keep an Arc<> pointer to the language_config?
+ self.language = Some(language_config.scope().to_string());
+
+ // TODO: this ties lsp support to tree-sitter enabled languages for now. Language
+ // config should use Option<HighlightConfig> to let us have non-tree-sitter configs.
+
let highlight_config = language_config.highlight_config(scopes).unwrap().unwrap();
// TODO: config.configure(scopes) is now delayed, is that ok?
let syntax = Syntax::new(&self.state.doc, highlight_config.clone());
self.syntax = Some(syntax);
+ } else {
+ self.syntax = None;
+ self.language = None;
};
}
+ pub fn set_language2(&mut self, scope: &str, scopes: &[String]) {
+ let language_config = LOADER.language_config_for_scope(scope);
+ self.set_language(language_config, scopes);
+ }
+
pub fn set_language_server(&mut self, language_server: Option<Arc<helix_lsp::Client>>) {
self.language_server = language_server;
}
@@ -238,12 +244,45 @@ impl Document {
false
}
+ pub fn append_changes_to_history(&mut self) {
+ if self.changes.is_empty() {
+ return;
+ }
+
+ // TODO: change -> change -> undo -> change -> change fails, probably old_state needs reset
+
+ let new_changeset = ChangeSet::new(self.text());
+ let changes = std::mem::replace(&mut self.changes, new_changeset);
+ // Instead of doing this messy merge we could always commit, and based on transaction
+ // annotations either add a new layer or compose into the previous one.
+ let transaction = Transaction::from(changes).with_selection(self.selection().clone());
+
+ // increment document version
+ self.version += 1;
+
+ // HAXX: we need to reconstruct the state as it was before the changes..
+ let old_state = self.old_state.take().expect("no old_state available");
+
+ self.history.commit_revision(&transaction, &old_state);
+ }
+
#[inline]
pub fn mode(&self) -> Mode {
self.mode
}
#[inline]
+ /// Corresponding language scope name. Usually `source.<lang>`.
+ pub fn language(&self) -> Option<&str> {
+ self.language.as_ref().map(String::as_str)
+ }
+
+ #[inline]
+ pub fn version(&self) -> i32 {
+ self.version
+ }
+
+ #[inline]
pub fn path(&self) -> Option<&PathBuf> {
self.path.as_ref()
}
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index 24cd8ef9..b70a6abd 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -37,9 +37,8 @@ impl Editor {
// try to find a language server based on the language name
let language_server = doc
- .language
- .as_ref()
- .and_then(|language| self.language_servers.get(&language, &executor));
+ .language()
+ .and_then(|language| self.language_servers.get(language, &executor));
if let Some(language_server) = language_server {
// TODO: do this everywhere
@@ -47,7 +46,7 @@ impl Editor {
smol::block_on(language_server.text_document_did_open(
doc.url().unwrap(),
- doc.version,
+ doc.version(),
doc.text(),
))
.unwrap();