Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--helix-core/src/uri.rs35
-rw-r--r--helix-term/src/commands/lsp.rs13
-rw-r--r--helix-view/src/document.rs7
-rw-r--r--helix-view/src/editor.rs11
-rw-r--r--helix-view/src/handlers/diagnostics.rs3
-rw-r--r--helix-view/src/handlers/lsp.rs5
-rw-r--r--helix-view/src/lib.rs20
7 files changed, 49 insertions, 45 deletions
diff --git a/helix-core/src/uri.rs b/helix-core/src/uri.rs
index cbe0fadd..c9d39ea6 100644
--- a/helix-core/src/uri.rs
+++ b/helix-core/src/uri.rs
@@ -1,18 +1,44 @@
use std::{
fmt,
+ num::NonZeroUsize,
path::{Path, PathBuf},
sync::Arc,
};
+// uses NonZeroUsize so Option<DocumentId> takes the same space
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub struct DocumentId(NonZeroUsize);
+
+impl DocumentId {
+ pub const MAX: Self = Self(unsafe { NonZeroUsize::new_unchecked(usize::MAX) });
+
+ pub fn next(&self) -> Self {
+ // Safety: adding 1 from 1 is fine, probably impossible to reach usize max
+ Self(unsafe { NonZeroUsize::new_unchecked(self.0.get() + 1) })
+ }
+}
+
+impl Default for DocumentId {
+ fn default() -> DocumentId {
+ // Safety: 1 is non-zero
+ DocumentId(unsafe { NonZeroUsize::new_unchecked(1) })
+ }
+}
+
+impl std::fmt::Display for DocumentId {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{}", self.0)
+ }
+}
+
/// A generic pointer to a file location.
///
-/// Currently this type only supports paths to local files.
-///
-/// Cloning this type is cheap: the internal representation uses an Arc.
+/// Cloning this type is cheap: the internal representation uses an Arc or data which is Copy.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[non_exhaustive]
pub enum Uri {
File(Arc<Path>),
+ Scratch(DocumentId),
}
impl Uri {
@@ -21,12 +47,14 @@ impl Uri {
pub fn to_url(&self) -> Result<url::Url, ()> {
match self {
Uri::File(path) => url::Url::from_file_path(path),
+ Uri::Scratch(_) => Err(()),
}
}
pub fn as_path(&self) -> Option<&Path> {
match self {
Self::File(path) => Some(path),
+ Self::Scratch(_) => None,
}
}
}
@@ -41,6 +69,7 @@ impl fmt::Display for Uri {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::File(path) => write!(f, "{}", path.display()),
+ Self::Scratch(id) => write!(f, "[scratch {id}]"),
}
}
}
diff --git a/helix-term/src/commands/lsp.rs b/helix-term/src/commands/lsp.rs
index 78c420c6..d6ce4c1c 100644
--- a/helix-term/src/commands/lsp.rs
+++ b/helix-term/src/commands/lsp.rs
@@ -338,9 +338,7 @@ pub fn symbol_picker(cx: &mut Context) {
let request = language_server.document_symbols(doc.identifier()).unwrap();
let offset_encoding = language_server.offset_encoding();
let doc_id = doc.identifier();
- let doc_uri = doc
- .uri()
- .expect("docs with active language servers must be backed by paths");
+ let doc_uri = doc.uri();
async move {
let symbols = match request.await? {
@@ -558,11 +556,10 @@ pub fn workspace_symbol_picker(cx: &mut Context) {
pub fn diagnostics_picker(cx: &mut Context) {
let doc = doc!(cx.editor);
- if let Some(uri) = doc.uri() {
- let diagnostics = cx.editor.diagnostics.get(&uri).cloned().unwrap_or_default();
- let picker = diag_picker(cx, [(uri, diagnostics)], DiagnosticsFormat::HideSourcePath);
- cx.push_layer(Box::new(overlaid(picker)));
- }
+ let uri = doc.uri();
+ let diagnostics = cx.editor.diagnostics.get(&uri).cloned().unwrap_or_default();
+ let picker = diag_picker(cx, [(uri, diagnostics)], DiagnosticsFormat::HideSourcePath);
+ cx.push_layer(Box::new(overlaid(picker)));
}
pub fn workspace_diagnostics_picker(cx: &mut Context) {
diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs
index fb89e2e0..e7d83ab0 100644
--- a/helix-view/src/document.rs
+++ b/helix-view/src/document.rs
@@ -1936,8 +1936,11 @@ impl Document {
Url::from_file_path(self.path()?).ok()
}
- pub fn uri(&self) -> Option<helix_core::Uri> {
- Some(self.path()?.clone().into())
+ pub fn uri(&self) -> helix_core::Uri {
+ self.path
+ .clone()
+ .map(|path| path.into())
+ .unwrap_or(helix_core::Uri::Scratch(self.id))
}
#[inline]
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index 89f05374..194285a8 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -29,7 +29,7 @@ use std::{
collections::{BTreeMap, HashMap, HashSet},
fs,
io::{self, stdin},
- num::{NonZeroU8, NonZeroUsize},
+ num::NonZeroU8,
path::{Path, PathBuf},
pin::Pin,
sync::Arc,
@@ -1729,9 +1729,7 @@ impl Editor {
/// Generate an id for a new document and register it.
fn new_document(&mut self, mut doc: Document) -> DocumentId {
let id = self.next_document_id;
- // Safety: adding 1 from 1 is fine, probably impossible to reach usize max
- self.next_document_id =
- DocumentId(unsafe { NonZeroUsize::new_unchecked(self.next_document_id.0.get() + 1) });
+ self.next_document_id = self.next_document_id.next();
doc.id = id;
self.documents.insert(id, doc);
@@ -2061,9 +2059,8 @@ impl Editor {
) -> impl Iterator<Item = helix_core::Diagnostic> + 'a {
let text = document.text().clone();
let language_config = document.language.clone();
- document
- .uri()
- .and_then(|uri| diagnostics.get(&uri))
+ diagnostics
+ .get(&document.uri())
.map(|diags| {
diags.iter().filter_map(move |(diagnostic, provider)| {
let server_id = provider.language_server_id()?;
diff --git a/helix-view/src/handlers/diagnostics.rs b/helix-view/src/handlers/diagnostics.rs
index 2b8ff632..9ce595e5 100644
--- a/helix-view/src/handlers/diagnostics.rs
+++ b/helix-view/src/handlers/diagnostics.rs
@@ -1,5 +1,4 @@
use std::cell::Cell;
-use std::num::NonZeroUsize;
use std::sync::atomic::{self, AtomicUsize};
use std::sync::Arc;
use std::time::Duration;
@@ -86,7 +85,7 @@ impl DiagnosticsHandler {
active_generation,
generation: Cell::new(0),
events,
- last_doc: Cell::new(DocumentId(NonZeroUsize::new(usize::MAX).unwrap())),
+ last_doc: Cell::new(DocumentId::MAX),
last_cursor_line: Cell::new(usize::MAX),
active: true,
}
diff --git a/helix-view/src/handlers/lsp.rs b/helix-view/src/handlers/lsp.rs
index c1041b2a..e9a9c654 100644
--- a/helix-view/src/handlers/lsp.rs
+++ b/helix-view/src/handlers/lsp.rs
@@ -289,10 +289,7 @@ impl Editor {
version: Option<i32>,
mut diagnostics: Vec<lsp::Diagnostic>,
) {
- let doc = self
- .documents
- .values_mut()
- .find(|doc| doc.uri().is_some_and(|u| u == uri));
+ let doc = self.documents.values_mut().find(|doc| doc.uri() == uri);
if let Some((version, doc)) = version.zip(doc.as_ref()) {
if version != doc.version() {
diff --git a/helix-view/src/lib.rs b/helix-view/src/lib.rs
index 6d0903b1..46bcf7e6 100644
--- a/helix-view/src/lib.rs
+++ b/helix-view/src/lib.rs
@@ -20,25 +20,6 @@ pub mod theme;
pub mod tree;
pub mod view;
-use std::num::NonZeroUsize;
-
-// uses NonZeroUsize so Option<DocumentId> use a byte rather than two
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
-pub struct DocumentId(NonZeroUsize);
-
-impl Default for DocumentId {
- fn default() -> DocumentId {
- // Safety: 1 is non-zero
- DocumentId(unsafe { NonZeroUsize::new_unchecked(1) })
- }
-}
-
-impl std::fmt::Display for DocumentId {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.write_fmt(format_args!("{}", self.0))
- }
-}
-
slotmap::new_key_type! {
pub struct ViewId;
}
@@ -78,5 +59,6 @@ pub use action::Action;
pub use document::Document;
pub use editor::Editor;
use helix_core::char_idx_at_visual_offset;
+pub use helix_core::uri::DocumentId;
pub use theme::Theme;
pub use view::View;