aboutsummaryrefslogtreecommitdiff
path: root/helix-view/src/document.rs
diff options
context:
space:
mode:
Diffstat (limited to 'helix-view/src/document.rs')
-rw-r--r--helix-view/src/document.rs106
1 files changed, 51 insertions, 55 deletions
diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs
index 3e38c24d..9326fb79 100644
--- a/helix-view/src/document.rs
+++ b/helix-view/src/document.rs
@@ -1,7 +1,5 @@
use anyhow::{anyhow, Context, Error};
-use serde::de::{self, Deserialize, Deserializer};
use std::cell::Cell;
-use std::collections::HashMap;
use std::fmt::Display;
use std::future::Future;
use std::path::{Component, Path, PathBuf};
@@ -12,12 +10,14 @@ use helix_core::{
auto_detect_line_ending,
chars::{char_is_line_ending, char_is_whitespace},
history::History,
- syntax::{LanguageConfiguration, LOADER},
+ syntax::{self, LanguageConfiguration},
ChangeSet, Diagnostic, LineEnding, Rope, Selection, State, Syntax, Transaction,
DEFAULT_LINE_ENDING,
};
-use crate::{DocumentId, ViewId};
+use crate::{DocumentId, Theme, ViewId};
+
+use std::collections::HashMap;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Mode {
@@ -26,40 +26,6 @@ pub enum Mode {
Insert,
}
-impl Display for Mode {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Mode::Normal => f.write_str("normal"),
- Mode::Select => f.write_str("select"),
- Mode::Insert => f.write_str("insert"),
- }
- }
-}
-
-impl FromStr for Mode {
- type Err = Error;
-
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- match s {
- "normal" => Ok(Mode::Normal),
- "select" => Ok(Mode::Select),
- "insert" => Ok(Mode::Insert),
- _ => Err(anyhow!("Invalid mode '{}'", s)),
- }
- }
-}
-
-// toml deserializer doesn't seem to recognize string as enum
-impl<'de> Deserialize<'de> for Mode {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: Deserializer<'de>,
- {
- let s = String::deserialize(deserializer)?;
- s.parse().map_err(de::Error::custom)
- }
-}
-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum IndentStyle {
Tabs,
@@ -127,6 +93,29 @@ impl fmt::Debug for Document {
}
}
+impl Display for Mode {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Mode::Normal => f.write_str("normal"),
+ Mode::Select => f.write_str("select"),
+ Mode::Insert => f.write_str("insert"),
+ }
+ }
+}
+
+impl FromStr for Mode {
+ type Err = Error;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ match s {
+ "normal" => Ok(Mode::Normal),
+ "select" => Ok(Mode::Select),
+ "insert" => Ok(Mode::Insert),
+ _ => Err(anyhow!("Invalid mode '{}'", s)),
+ }
+ }
+}
+
/// Like std::mem::replace() except it allows the replacement value to be mapped from the
/// original value.
fn take_with<T, F>(mut_ref: &mut T, closure: F)
@@ -181,7 +170,7 @@ pub fn fold_home_dir(path: &Path) -> PathBuf {
/// [`std::fs::canonicalize`] can be hard to use correctly, since it can often
/// fail, or on Windows returns annoying device paths. This is a problem Cargo
/// needs to improve on.
-/// Copied from cargo: https://github.com/rust-lang/cargo/blob/070e459c2d8b79c5b2ac5218064e7603329c92ae/crates/cargo-util/src/paths.rs#L81
+/// Copied from cargo: <https://github.com/rust-lang/cargo/blob/070e459c2d8b79c5b2ac5218064e7603329c92ae/crates/cargo-util/src/paths.rs#L81>
pub fn normalize_path(path: &Path) -> PathBuf {
let path = expand_tilde(path);
let mut components = path.components().peekable();
@@ -253,7 +242,11 @@ impl Document {
}
// TODO: async fn?
- pub fn load(path: PathBuf) -> Result<Self, Error> {
+ pub fn load(
+ path: PathBuf,
+ theme: Option<&Theme>,
+ config_loader: Option<&syntax::Loader>,
+ ) -> Result<Self, Error> {
use std::{fs::File, io::BufReader};
let mut doc = if !path.exists() {
@@ -277,6 +270,10 @@ impl Document {
doc.detect_indent_style();
doc.set_line_ending(line_ending);
+ if let Some(loader) = config_loader {
+ doc.detect_language(theme, loader);
+ }
+
Ok(doc)
}
@@ -351,12 +348,10 @@ impl Document {
}
}
- fn detect_language(&mut self) {
- if let Some(path) = self.path() {
- let loader = LOADER.get().unwrap();
- let language_config = loader.language_config_for_file_name(path);
- let scopes = loader.scopes();
- self.set_language(language_config, scopes);
+ pub fn detect_language(&mut self, theme: Option<&Theme>, config_loader: &syntax::Loader) {
+ if let Some(path) = &self.path {
+ let language_config = config_loader.language_config_for_file_name(path);
+ self.set_language(theme, language_config);
}
}
@@ -493,18 +488,16 @@ impl Document {
// and error out when document is saved
self.path = Some(path);
- // try detecting the language based on filepath
- self.detect_language();
-
Ok(())
}
pub fn set_language(
&mut self,
+ theme: Option<&Theme>,
language_config: Option<Arc<helix_core::syntax::LanguageConfiguration>>,
- scopes: &[String],
) {
if let Some(language_config) = language_config {
+ let scopes = theme.map(|theme| theme.scopes()).unwrap_or(&[]);
if let Some(highlight_config) = language_config.highlight_config(scopes) {
let syntax = Syntax::new(&self.text, highlight_config);
self.syntax = Some(syntax);
@@ -518,12 +511,15 @@ impl Document {
};
}
- pub fn set_language2(&mut self, scope: &str) {
- let loader = LOADER.get().unwrap();
- let language_config = loader.language_config_for_scope(scope);
- let scopes = loader.scopes();
+ pub fn set_language2(
+ &mut self,
+ scope: &str,
+ theme: Option<&Theme>,
+ config_loader: Arc<syntax::Loader>,
+ ) {
+ let language_config = config_loader.language_config_for_scope(scope);
- self.set_language(language_config, scopes);
+ self.set_language(theme, language_config);
}
pub fn set_language_server(&mut self, language_server: Option<Arc<helix_lsp::Client>>) {