mirror of https://github.com/helix-editor/helix
Compare commits
3 Commits
cbe5e0fc1b
...
c950db2057
Author | SHA1 | Date |
---|---|---|
|
c950db2057 | |
|
4281228da3 | |
|
32dfc1647b |
|
@ -37,6 +37,12 @@ impl From<PathBuf> for Uri {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<&Path> for Uri {
|
||||||
|
fn from(path: &Path) -> Self {
|
||||||
|
Self::File(path.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for Uri {
|
impl fmt::Display for Uri {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
@ -69,7 +69,7 @@ impl Client {
|
||||||
self: &Arc<Self>,
|
self: &Arc<Self>,
|
||||||
root_markers: &[String],
|
root_markers: &[String],
|
||||||
manual_roots: &[PathBuf],
|
manual_roots: &[PathBuf],
|
||||||
doc_path: Option<&std::path::PathBuf>,
|
doc_path: Option<&std::path::Path>,
|
||||||
may_support_workspace: bool,
|
may_support_workspace: bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let (workspace, workspace_is_cwd) = find_workspace();
|
let (workspace, workspace_is_cwd) = find_workspace();
|
||||||
|
|
|
@ -591,7 +591,7 @@ impl Registry {
|
||||||
&mut self,
|
&mut self,
|
||||||
name: String,
|
name: String,
|
||||||
ls_config: &LanguageConfiguration,
|
ls_config: &LanguageConfiguration,
|
||||||
doc_path: Option<&std::path::PathBuf>,
|
doc_path: Option<&std::path::Path>,
|
||||||
root_dirs: &[PathBuf],
|
root_dirs: &[PathBuf],
|
||||||
enable_snippets: bool,
|
enable_snippets: bool,
|
||||||
) -> Result<Arc<Client>, StartupError> {
|
) -> Result<Arc<Client>, StartupError> {
|
||||||
|
@ -624,7 +624,7 @@ impl Registry {
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
language_config: &LanguageConfiguration,
|
language_config: &LanguageConfiguration,
|
||||||
doc_path: Option<&std::path::PathBuf>,
|
doc_path: Option<&std::path::Path>,
|
||||||
root_dirs: &[PathBuf],
|
root_dirs: &[PathBuf],
|
||||||
enable_snippets: bool,
|
enable_snippets: bool,
|
||||||
) -> Option<Result<Arc<Client>>> {
|
) -> Option<Result<Arc<Client>>> {
|
||||||
|
@ -679,7 +679,7 @@ impl Registry {
|
||||||
pub fn get<'a>(
|
pub fn get<'a>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
language_config: &'a LanguageConfiguration,
|
language_config: &'a LanguageConfiguration,
|
||||||
doc_path: Option<&'a std::path::PathBuf>,
|
doc_path: Option<&'a std::path::Path>,
|
||||||
root_dirs: &'a [PathBuf],
|
root_dirs: &'a [PathBuf],
|
||||||
enable_snippets: bool,
|
enable_snippets: bool,
|
||||||
) -> impl Iterator<Item = (LanguageServerName, Result<Arc<Client>>)> + 'a {
|
) -> impl Iterator<Item = (LanguageServerName, Result<Arc<Client>>)> + 'a {
|
||||||
|
@ -867,7 +867,7 @@ fn start_client(
|
||||||
name: String,
|
name: String,
|
||||||
config: &LanguageConfiguration,
|
config: &LanguageConfiguration,
|
||||||
ls_config: &LanguageServerConfiguration,
|
ls_config: &LanguageServerConfiguration,
|
||||||
doc_path: Option<&std::path::PathBuf>,
|
doc_path: Option<&std::path::Path>,
|
||||||
root_dirs: &[PathBuf],
|
root_dirs: &[PathBuf],
|
||||||
enable_snippets: bool,
|
enable_snippets: bool,
|
||||||
) -> Result<NewClient, StartupError> {
|
) -> Result<NewClient, StartupError> {
|
||||||
|
|
|
@ -2522,7 +2522,7 @@ fn global_search(cx: &mut Context) {
|
||||||
|
|
||||||
let documents: Vec<_> = editor
|
let documents: Vec<_> = editor
|
||||||
.documents()
|
.documents()
|
||||||
.map(|doc| (doc.path().cloned(), doc.text().to_owned()))
|
.map(|doc| (doc.pathbuf(), doc.text().to_owned()))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let matcher = match RegexMatcherBuilder::new()
|
let matcher = match RegexMatcherBuilder::new()
|
||||||
|
@ -3157,7 +3157,7 @@ fn buffer_picker(cx: &mut Context) {
|
||||||
|
|
||||||
let new_meta = |doc: &Document| BufferMeta {
|
let new_meta = |doc: &Document| BufferMeta {
|
||||||
id: doc.id(),
|
id: doc.id(),
|
||||||
path: doc.path().cloned(),
|
path: doc.pathbuf(),
|
||||||
is_modified: doc.is_modified(),
|
is_modified: doc.is_modified(),
|
||||||
is_current: doc.id() == current,
|
is_current: doc.id() == current,
|
||||||
focused_at: doc.focused_at,
|
focused_at: doc.focused_at,
|
||||||
|
@ -3239,7 +3239,7 @@ fn jumplist_picker(cx: &mut Context) {
|
||||||
|
|
||||||
JumpMeta {
|
JumpMeta {
|
||||||
id: doc_id,
|
id: doc_id,
|
||||||
path: doc.and_then(|d| d.path().cloned()),
|
path: doc.and_then(|doc| doc.pathbuf()),
|
||||||
selection,
|
selection,
|
||||||
text,
|
text,
|
||||||
is_current: view.doc == doc_id,
|
is_current: view.doc == doc_id,
|
||||||
|
|
|
@ -376,14 +376,13 @@ fn debug_parameter_prompt(
|
||||||
|
|
||||||
pub fn dap_toggle_breakpoint(cx: &mut Context) {
|
pub fn dap_toggle_breakpoint(cx: &mut Context) {
|
||||||
let (view, doc) = current!(cx.editor);
|
let (view, doc) = current!(cx.editor);
|
||||||
let path = match doc.path() {
|
|
||||||
Some(path) => path.clone(),
|
let Some(path) = doc.pathbuf() else {
|
||||||
None => {
|
|
||||||
cx.editor
|
cx.editor
|
||||||
.set_error("Can't set breakpoint: document has no path");
|
.set_error("Can't set breakpoint: document has no path");
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let text = doc.text().slice(..);
|
let text = doc.text().slice(..);
|
||||||
let line = doc.selection(view.id).primary().cursor_line(text);
|
let line = doc.selection(view.id).primary().cursor_line(text);
|
||||||
dap_toggle_breakpoint_impl(cx, path, line);
|
dap_toggle_breakpoint_impl(cx, path, line);
|
||||||
|
@ -623,9 +622,8 @@ pub fn dap_disable_exceptions(cx: &mut Context) {
|
||||||
// TODO: both edit condition and edit log need to be stable: we might get new breakpoints from the debugger which can change offsets
|
// TODO: both edit condition and edit log need to be stable: we might get new breakpoints from the debugger which can change offsets
|
||||||
pub fn dap_edit_condition(cx: &mut Context) {
|
pub fn dap_edit_condition(cx: &mut Context) {
|
||||||
if let Some((pos, breakpoint)) = get_breakpoint_at_current_line(cx.editor) {
|
if let Some((pos, breakpoint)) = get_breakpoint_at_current_line(cx.editor) {
|
||||||
let path = match doc!(cx.editor).path() {
|
let Some(path) = doc!(cx.editor).pathbuf() else {
|
||||||
Some(path) => path.clone(),
|
return;
|
||||||
None => return,
|
|
||||||
};
|
};
|
||||||
let callback = Box::pin(async move {
|
let callback = Box::pin(async move {
|
||||||
let call: Callback = Callback::EditorCompositor(Box::new(move |editor, compositor| {
|
let call: Callback = Callback::EditorCompositor(Box::new(move |editor, compositor| {
|
||||||
|
@ -665,9 +663,8 @@ pub fn dap_edit_condition(cx: &mut Context) {
|
||||||
|
|
||||||
pub fn dap_edit_log(cx: &mut Context) {
|
pub fn dap_edit_log(cx: &mut Context) {
|
||||||
if let Some((pos, breakpoint)) = get_breakpoint_at_current_line(cx.editor) {
|
if let Some((pos, breakpoint)) = get_breakpoint_at_current_line(cx.editor) {
|
||||||
let path = match doc!(cx.editor).path() {
|
let Some(path) = doc!(cx.editor).pathbuf() else {
|
||||||
Some(path) => path.clone(),
|
return;
|
||||||
None => return,
|
|
||||||
};
|
};
|
||||||
let callback = Box::pin(async move {
|
let callback = Box::pin(async move {
|
||||||
let call: Callback = Callback::EditorCompositor(Box::new(move |editor, compositor| {
|
let call: Callback = Callback::EditorCompositor(Box::new(move |editor, compositor| {
|
||||||
|
|
|
@ -315,11 +315,9 @@ pub fn syntax_workspace_symbol_picker(cx: &mut Context) {
|
||||||
let pattern = Arc::new(pattern);
|
let pattern = Arc::new(pattern);
|
||||||
let injector = injector.clone();
|
let injector = injector.clone();
|
||||||
let loader = editor.syn_loader.load();
|
let loader = editor.syn_loader.load();
|
||||||
let documents: HashSet<_> = editor
|
|
||||||
.documents()
|
let documents: HashSet<_> = editor.documents().filter_map(Document::pathbuf).collect();
|
||||||
.filter_map(Document::path)
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
async move {
|
async move {
|
||||||
let searcher = state.searcher_builder.build();
|
let searcher = state.searcher_builder.build();
|
||||||
state.walk_builder.build_parallel().run(|| {
|
state.walk_builder.build_parallel().run(|| {
|
||||||
|
|
|
@ -181,7 +181,7 @@ fn buffer_gather_paths_impl(editor: &mut Editor, args: Args) -> Vec<DocumentId>
|
||||||
for arg in args {
|
for arg in args {
|
||||||
let doc_id = editor.documents().find_map(|doc| {
|
let doc_id = editor.documents().find_map(|doc| {
|
||||||
let arg_path = Some(Path::new(arg.as_ref()));
|
let arg_path = Some(Path::new(arg.as_ref()));
|
||||||
if doc.path().map(|p| p.as_path()) == arg_path || doc.relative_path() == arg_path {
|
if doc.path() == arg_path || doc.relative_path() == arg_path {
|
||||||
Some(doc.id())
|
Some(doc.id())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -1397,11 +1397,11 @@ fn reload(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> anyh
|
||||||
doc.reload(view, &cx.editor.diff_providers).map(|_| {
|
doc.reload(view, &cx.editor.diff_providers).map(|_| {
|
||||||
view.ensure_cursor_in_view(doc, scrolloff);
|
view.ensure_cursor_in_view(doc, scrolloff);
|
||||||
})?;
|
})?;
|
||||||
if let Some(path) = doc.path() {
|
if let Some(path) = doc.pathbuf() {
|
||||||
cx.editor
|
cx.editor
|
||||||
.language_servers
|
.language_servers
|
||||||
.file_event_handler
|
.file_event_handler
|
||||||
.file_changed(path.clone());
|
.file_changed(path);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1443,11 +1443,11 @@ fn reload_all(cx: &mut compositor::Context, _args: Args, event: PromptEvent) ->
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(path) = doc.path() {
|
if let Some(path) = doc.pathbuf() {
|
||||||
cx.editor
|
cx.editor
|
||||||
.language_servers
|
.language_servers
|
||||||
.file_event_handler
|
.file_event_handler
|
||||||
.file_changed(path.clone());
|
.file_changed(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
for view_id in view_ids {
|
for view_id in view_ids {
|
||||||
|
@ -2525,9 +2525,8 @@ fn move_buffer(cx: &mut compositor::Context, args: Args, event: PromptEvent) ->
|
||||||
|
|
||||||
let doc = doc!(cx.editor);
|
let doc = doc!(cx.editor);
|
||||||
let old_path = doc
|
let old_path = doc
|
||||||
.path()
|
.pathbuf()
|
||||||
.context("Scratch buffer cannot be moved. Use :write instead")?
|
.context("Scratch buffer cannot be moved. Use :write instead")?;
|
||||||
.clone();
|
|
||||||
let new_path: PathBuf = args.first().unwrap().into();
|
let new_path: PathBuf = args.first().unwrap().into();
|
||||||
|
|
||||||
// if new_path is a directory, append the original file name
|
// if new_path is a directory, append the original file name
|
||||||
|
|
|
@ -1160,9 +1160,8 @@ impl EditorView {
|
||||||
|
|
||||||
let (view, doc) = current!(cxt.editor);
|
let (view, doc) = current!(cxt.editor);
|
||||||
|
|
||||||
let path = match doc.path() {
|
let Some(path) = doc.pathbuf() else {
|
||||||
Some(path) => path.clone(),
|
return EventResult::Ignored(None);
|
||||||
None => return EventResult::Ignored(None),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(char_idx) =
|
if let Some(char_idx) =
|
||||||
|
|
|
@ -466,11 +466,11 @@ where
|
||||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||||
{
|
{
|
||||||
let title = {
|
let title = {
|
||||||
let path = context.doc.path();
|
let path = context
|
||||||
let path = path
|
.doc
|
||||||
|
.path()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|p| p.to_string_lossy())
|
.map_or_else(|| SCRATCH_BUFFER_NAME.into(), |p| p.to_string_lossy());
|
||||||
.unwrap_or_else(|| SCRATCH_BUFFER_NAME.into());
|
|
||||||
format!(" {} ", path)
|
format!(" {} ", path)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ async fn test_write_quit_fail() -> anyhow::Result<()> {
|
||||||
assert_eq!(1, docs.len());
|
assert_eq!(1, docs.len());
|
||||||
|
|
||||||
let doc = docs.pop().unwrap();
|
let doc = docs.pop().unwrap();
|
||||||
assert_eq!(Some(&path::normalize(file.path())), doc.path());
|
assert_eq!(Some(path::normalize(file.path())), doc.pathbuf());
|
||||||
assert_eq!(&Severity::Error, app.editor.get_status().unwrap().1);
|
assert_eq!(&Severity::Error, app.editor.get_status().unwrap().1);
|
||||||
}),
|
}),
|
||||||
false,
|
false,
|
||||||
|
@ -265,7 +265,7 @@ async fn test_write_scratch_to_new_path() -> anyhow::Result<()> {
|
||||||
assert_eq!(1, docs.len());
|
assert_eq!(1, docs.len());
|
||||||
|
|
||||||
let doc = docs.pop().unwrap();
|
let doc = docs.pop().unwrap();
|
||||||
assert_eq!(Some(&path::normalize(file.path())), doc.path());
|
assert_eq!(Some(path::normalize(file.path())), doc.pathbuf());
|
||||||
}),
|
}),
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
@ -651,7 +651,7 @@ async fn test_symlink_write_fail() -> anyhow::Result<()> {
|
||||||
assert_eq!(1, docs.len());
|
assert_eq!(1, docs.len());
|
||||||
|
|
||||||
let doc = docs.pop().unwrap();
|
let doc = docs.pop().unwrap();
|
||||||
assert_eq!(Some(&path::normalize(&symlink_path)), doc.path());
|
assert_eq!(Some(path::normalize(&symlink_path)), doc.pathbuf());
|
||||||
assert_eq!(&Severity::Error, app.editor.get_status().unwrap().1);
|
assert_eq!(&Severity::Error, app.editor.get_status().unwrap().1);
|
||||||
}),
|
}),
|
||||||
false,
|
false,
|
||||||
|
|
|
@ -1934,8 +1934,14 @@ impl Document {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
/// File path on disk.
|
/// File path on disk.
|
||||||
pub fn path(&self) -> Option<&PathBuf> {
|
pub fn path(&self) -> Option<&Path> {
|
||||||
self.path.as_ref()
|
self.path.as_deref()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
/// Owned file path on disk.
|
||||||
|
pub fn pathbuf(&self) -> Option<PathBuf> {
|
||||||
|
self.path.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// File path as a URL.
|
/// File path as a URL.
|
||||||
|
@ -1944,7 +1950,7 @@ impl Document {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uri(&self) -> Option<helix_core::Uri> {
|
pub fn uri(&self) -> Option<helix_core::Uri> {
|
||||||
Some(self.path()?.clone().into())
|
Some(self.path()?.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -1540,14 +1540,14 @@ impl Editor {
|
||||||
let Some(doc_url) = doc.url() else {
|
let Some(doc_url) = doc.url() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let (lang, path) = (doc.language.clone(), doc.path().cloned());
|
let (lang, path) = (doc.language.clone(), doc.path());
|
||||||
let config = doc.config.load();
|
let config = doc.config.load();
|
||||||
let root_dirs = &config.workspace_lsp_roots;
|
let root_dirs = &config.workspace_lsp_roots;
|
||||||
|
|
||||||
// store only successfully started language servers
|
// store only successfully started language servers
|
||||||
let language_servers = lang.as_ref().map_or_else(HashMap::default, |language| {
|
let language_servers = lang.as_ref().map_or_else(HashMap::default, |language| {
|
||||||
self.language_servers
|
self.language_servers
|
||||||
.get(language, path.as_ref(), root_dirs, config.lsp.snippets)
|
.get(language, path, root_dirs, config.lsp.snippets)
|
||||||
.filter_map(|(lang, client)| match client {
|
.filter_map(|(lang, client)| match client {
|
||||||
Ok(client) => Some((lang, client)),
|
Ok(client) => Some((lang, client)),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -2061,12 +2061,12 @@ impl Editor {
|
||||||
|
|
||||||
pub fn document_by_path<P: AsRef<Path>>(&self, path: P) -> Option<&Document> {
|
pub fn document_by_path<P: AsRef<Path>>(&self, path: P) -> Option<&Document> {
|
||||||
self.documents()
|
self.documents()
|
||||||
.find(|doc| doc.path().map(|p| p == path.as_ref()).unwrap_or(false))
|
.find(|doc| doc.path().is_some_and(|p| p == path.as_ref()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn document_by_path_mut<P: AsRef<Path>>(&mut self, path: P) -> Option<&mut Document> {
|
pub fn document_by_path_mut<P: AsRef<Path>>(&mut self, path: P) -> Option<&mut Document> {
|
||||||
self.documents_mut()
|
self.documents_mut()
|
||||||
.find(|doc| doc.path().map(|p| p == path.as_ref()).unwrap_or(false))
|
.find(|doc| doc.path().is_some_and(|p| p == path.as_ref()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns all supported diagnostics for the document
|
/// Returns all supported diagnostics for the document
|
||||||
|
|
|
@ -284,8 +284,9 @@ fn execution_pause_indicator<'doc>(
|
||||||
frame
|
frame
|
||||||
.source
|
.source
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|source| source.path.as_ref())
|
.and_then(|source| source.path.as_deref())
|
||||||
});
|
});
|
||||||
|
|
||||||
let should_display_for_current_doc =
|
let should_display_for_current_doc =
|
||||||
doc.path().is_some() && frame_source_path.unwrap_or(None) == doc.path();
|
doc.path().is_some() && frame_source_path.unwrap_or(None) == doc.path();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue