mirror of https://github.com/helix-editor/helix
adding hooks
parent
72949830ee
commit
374389e9d1
|
@ -17,7 +17,7 @@ use helix_view::{
|
||||||
GutterConfig, IndentGuidesConfig, LineEndingConfig, LineNumber, LspConfig, SearchConfig,
|
GutterConfig, IndentGuidesConfig, LineEndingConfig, LineNumber, LspConfig, SearchConfig,
|
||||||
SmartTabConfig, StatusLineConfig, TerminalConfig, WhitespaceConfig,
|
SmartTabConfig, StatusLineConfig, TerminalConfig, WhitespaceConfig,
|
||||||
},
|
},
|
||||||
events::{DocumentFocusLost, SelectionDidChange},
|
events::{DocumentFocusLost, DocumentOpened, SelectionDidChange},
|
||||||
extension::document_id_to_usize,
|
extension::document_id_to_usize,
|
||||||
input::KeyEvent,
|
input::KeyEvent,
|
||||||
theme::Color,
|
theme::Color,
|
||||||
|
@ -590,6 +590,22 @@ fn load_configuration_api(engine: &mut Engine, generate_sources: bool) {
|
||||||
|
|
||||||
module.register_fn("get-config-option-value", get_option_value);
|
module.register_fn("get-config-option-value", get_option_value);
|
||||||
|
|
||||||
|
module.register_fn("set-configuration-for-file!", set_configuration_for_file);
|
||||||
|
|
||||||
|
module
|
||||||
|
.register_fn(
|
||||||
|
"get-language-config",
|
||||||
|
HelixConfiguration::get_language_config,
|
||||||
|
)
|
||||||
|
.register_fn(
|
||||||
|
"get-language-config-by-filename",
|
||||||
|
HelixConfiguration::get_individual_language_config_for_filename,
|
||||||
|
)
|
||||||
|
.register_fn(
|
||||||
|
"set-language-config!",
|
||||||
|
HelixConfiguration::update_individual_language_config,
|
||||||
|
);
|
||||||
|
|
||||||
module
|
module
|
||||||
.register_fn("raw-file-picker", || FilePickerConfig::default())
|
.register_fn("raw-file-picker", || FilePickerConfig::default())
|
||||||
.register_fn("register-file-picker", HelixConfiguration::file_picker)
|
.register_fn("register-file-picker", HelixConfiguration::file_picker)
|
||||||
|
@ -713,6 +729,14 @@ fn load_configuration_api(engine: &mut Engine, generate_sources: bool) {
|
||||||
"#,
|
"#,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
builtin_configuration_module.push_str(&format!(
|
||||||
|
r#"
|
||||||
|
(provide set-configuration-for-file!)
|
||||||
|
(define (set-configuration-for-file! path config)
|
||||||
|
(helix.set-configuration-for-file! *helix.cx* path config))
|
||||||
|
"#,
|
||||||
|
));
|
||||||
|
|
||||||
// Register the get keybindings function
|
// Register the get keybindings function
|
||||||
builtin_configuration_module.push_str(&format!(
|
builtin_configuration_module.push_str(&format!(
|
||||||
r#"
|
r#"
|
||||||
|
@ -847,6 +871,10 @@ fn load_configuration_api(engine: &mut Engine, generate_sources: bool) {
|
||||||
"keybindings",
|
"keybindings",
|
||||||
"inline-diagnostics-cursor-line-enable",
|
"inline-diagnostics-cursor-line-enable",
|
||||||
"inline-diagnostics-end-of-line-enable",
|
"inline-diagnostics-end-of-line-enable",
|
||||||
|
// language configuration functions
|
||||||
|
"get-language-config",
|
||||||
|
"get-language-config-by-filename",
|
||||||
|
"set-language-config!",
|
||||||
];
|
];
|
||||||
|
|
||||||
for func in functions {
|
for func in functions {
|
||||||
|
@ -1449,26 +1477,60 @@ impl IndividualLanguageConfiguration {
|
||||||
|
|
||||||
// Apply end of line configuration on doc open?
|
// Apply end of line configuration on doc open?
|
||||||
// pub fn set_end_of_line(&mut self) {
|
// pub fn set_end_of_line(&mut self) {
|
||||||
// self.
|
// self.config.end
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Custom for HelixConfiguration {}
|
impl Custom for HelixConfiguration {}
|
||||||
|
|
||||||
// impl Custom for LineNumber {}
|
// Set the configuration for an individual file.
|
||||||
|
fn update_configuration_for_file(ctx: &mut Context, doc: DocumentId) {
|
||||||
|
if let Some(document) = ctx.editor.documents.get_mut(&doc) {
|
||||||
|
let path = document.path().unwrap();
|
||||||
|
let config_for_file = ctx
|
||||||
|
.editor
|
||||||
|
.syn_loader
|
||||||
|
.load()
|
||||||
|
.language_config_for_file_name(path);
|
||||||
|
|
||||||
|
document.language = config_for_file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_configuration_for_file(
|
||||||
|
ctx: &mut Context,
|
||||||
|
file_name: SteelString,
|
||||||
|
configuration: IndividualLanguageConfiguration,
|
||||||
|
) {
|
||||||
|
if let Some(document) = ctx.editor.document_by_path_mut(file_name.as_str()) {
|
||||||
|
document.language = Some(Arc::new(configuration.config));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl HelixConfiguration {
|
impl HelixConfiguration {
|
||||||
fn store_language_configuration(&self, language_config: syntax::Loader) {
|
fn store_language_configuration(&self, language_config: syntax::Loader) {
|
||||||
self.language_configuration.store(Arc::new(language_config))
|
self.language_configuration.store(Arc::new(language_config))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_individual_language_config_for_filename(
|
fn get_language_config(
|
||||||
&self,
|
&self,
|
||||||
file_name: &str,
|
language: SteelString,
|
||||||
) -> Option<IndividualLanguageConfiguration> {
|
) -> Option<IndividualLanguageConfiguration> {
|
||||||
self.language_configuration
|
self.language_configuration
|
||||||
.load()
|
.load()
|
||||||
.language_config_for_file_name(std::path::Path::new(file_name))
|
.language_config_for_language_id(language.as_str())
|
||||||
|
.map(|config| IndividualLanguageConfiguration {
|
||||||
|
config: (*config).clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_individual_language_config_for_filename(
|
||||||
|
&self,
|
||||||
|
file_name: SteelString,
|
||||||
|
) -> Option<IndividualLanguageConfiguration> {
|
||||||
|
self.language_configuration
|
||||||
|
.load()
|
||||||
|
.language_config_for_file_name(std::path::Path::new(file_name.as_str()))
|
||||||
.map(|config| IndividualLanguageConfiguration {
|
.map(|config| IndividualLanguageConfiguration {
|
||||||
config: (*config).clone(),
|
config: (*config).clone(),
|
||||||
})
|
})
|
||||||
|
@ -1495,6 +1557,11 @@ impl HelixConfiguration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// // Refresh configuration for a specific file
|
||||||
|
// fn refresh_language_configuration(&mut self) {
|
||||||
|
// todo!()
|
||||||
|
// }
|
||||||
|
|
||||||
fn load_config(&self) -> Config {
|
fn load_config(&self) -> Config {
|
||||||
(*self.configuration.load().clone()).clone()
|
(*self.configuration.load().clone()).clone()
|
||||||
}
|
}
|
||||||
|
@ -2040,6 +2107,7 @@ fn register_hook(event_kind: String, callback_fn: SteelVal) -> steel::UnRecovera
|
||||||
// and act accordingly?
|
// and act accordingly?
|
||||||
register_hook!(move |event: &mut DocumentFocusLost<'_>| {
|
register_hook!(move |event: &mut DocumentFocusLost<'_>| {
|
||||||
let cloned_func = rooted.value().clone();
|
let cloned_func = rooted.value().clone();
|
||||||
|
let doc_id = event.doc;
|
||||||
|
|
||||||
let callback = move |editor: &mut Editor,
|
let callback = move |editor: &mut Editor,
|
||||||
_compositor: &mut Compositor,
|
_compositor: &mut Compositor,
|
||||||
|
@ -2058,8 +2126,13 @@ fn register_hook(event_kind: String, callback_fn: SteelVal) -> steel::UnRecovera
|
||||||
.consume(move |engine, args| {
|
.consume(move |engine, args| {
|
||||||
let context = args[0].clone();
|
let context = args[0].clone();
|
||||||
engine.update_value("*helix.cx*", context);
|
engine.update_value("*helix.cx*", context);
|
||||||
|
let mut args = [doc_id.into_steelval().unwrap()];
|
||||||
|
|
||||||
// TODO: Do something with this error!
|
// TODO: Do something with this error!
|
||||||
engine.call_function_with_args(cloned_func.clone(), Vec::new())
|
engine.call_function_with_args_from_mut_slice(
|
||||||
|
cloned_func.clone(),
|
||||||
|
&mut args,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
present_error_inside_engine_context(&mut ctx, guard, e);
|
present_error_inside_engine_context(&mut ctx, guard, e);
|
||||||
|
@ -2079,34 +2152,83 @@ fn register_hook(event_kind: String, callback_fn: SteelVal) -> steel::UnRecovera
|
||||||
// is probably the most helpful so that way we can look the document up
|
// is probably the most helpful so that way we can look the document up
|
||||||
// and act accordingly?
|
// and act accordingly?
|
||||||
register_hook!(move |event: &mut SelectionDidChange<'_>| {
|
register_hook!(move |event: &mut SelectionDidChange<'_>| {
|
||||||
// let cloned_func = rooted.value().clone();
|
let cloned_func = rooted.value().clone();
|
||||||
|
let view_id = event.view;
|
||||||
|
|
||||||
// let callback = move |editor: &mut Editor,
|
let callback = move |editor: &mut Editor,
|
||||||
// _compositor: &mut Compositor,
|
_compositor: &mut Compositor,
|
||||||
// jobs: &mut job::Jobs| {
|
jobs: &mut job::Jobs| {
|
||||||
// let mut ctx = Context {
|
let mut ctx = Context {
|
||||||
// register: None,
|
register: None,
|
||||||
// count: None,
|
count: None,
|
||||||
// editor,
|
editor,
|
||||||
// callback: Vec::new(),
|
callback: Vec::new(),
|
||||||
// on_next_key_callback: None,
|
on_next_key_callback: None,
|
||||||
// jobs,
|
jobs,
|
||||||
// };
|
};
|
||||||
// enter_engine(|guard| {
|
enter_engine(|guard| {
|
||||||
// if let Err(e) = guard
|
if let Err(e) = guard
|
||||||
// .with_mut_reference::<Context, Context>(&mut ctx)
|
.with_mut_reference::<Context, Context>(&mut ctx)
|
||||||
// .consume(move |engine, args| {
|
.consume(move |engine, args| {
|
||||||
// let context = args[0].clone();
|
let context = args[0].clone();
|
||||||
// engine.update_value("*helix.cx*", context);
|
engine.update_value("*helix.cx*", context);
|
||||||
// // TODO: Do something with this error!
|
// TODO: Reuse this allocation
|
||||||
// engine.call_function_with_args(cloned_func.clone(), Vec::new())
|
let mut args = [view_id.into_steelval().unwrap()];
|
||||||
// })
|
engine.call_function_with_args_from_mut_slice(
|
||||||
// {
|
cloned_func.clone(),
|
||||||
// present_error_inside_engine_context(&mut ctx, guard, e);
|
&mut args,
|
||||||
// }
|
)
|
||||||
// })
|
})
|
||||||
// };
|
{
|
||||||
// job::dispatch_blocking_jobs(callback);
|
present_error_inside_engine_context(&mut ctx, guard, e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
job::dispatch_blocking_jobs(callback);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(SteelVal::Void).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
"document-opened" => {
|
||||||
|
// TODO: Share this code with the above since most of it is
|
||||||
|
// exactly the same
|
||||||
|
register_hook!(move |event: &mut DocumentOpened<'_>| {
|
||||||
|
let cloned_func = rooted.value().clone();
|
||||||
|
let doc_id = event.doc;
|
||||||
|
|
||||||
|
let callback = move |editor: &mut Editor,
|
||||||
|
_compositor: &mut Compositor,
|
||||||
|
jobs: &mut job::Jobs| {
|
||||||
|
let mut ctx = Context {
|
||||||
|
register: None,
|
||||||
|
count: None,
|
||||||
|
editor,
|
||||||
|
callback: Vec::new(),
|
||||||
|
on_next_key_callback: None,
|
||||||
|
jobs,
|
||||||
|
};
|
||||||
|
enter_engine(|guard| {
|
||||||
|
if let Err(e) = guard
|
||||||
|
.with_mut_reference::<Context, Context>(&mut ctx)
|
||||||
|
.consume(move |engine, args| {
|
||||||
|
let context = args[0].clone();
|
||||||
|
engine.update_value("*helix.cx*", context);
|
||||||
|
// TODO: Reuse this allocation if possible
|
||||||
|
let mut args = [doc_id.into_steelval().unwrap()];
|
||||||
|
engine.call_function_with_args_from_mut_slice(
|
||||||
|
cloned_func.clone(),
|
||||||
|
&mut args,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
{
|
||||||
|
present_error_inside_engine_context(&mut ctx, guard, e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
job::dispatch_blocking_jobs(callback);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
@ -2114,13 +2236,6 @@ fn register_hook(event_kind: String, callback_fn: SteelVal) -> steel::UnRecovera
|
||||||
Ok(SteelVal::Void).into()
|
Ok(SteelVal::Void).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unimplemented!
|
|
||||||
// "document-did-change" => {
|
|
||||||
// todo!()
|
|
||||||
// }
|
|
||||||
// "selection-did-change" => {
|
|
||||||
// todo!()
|
|
||||||
// }
|
|
||||||
_ => steelerr!(Generic => "Unable to register hook: Unknown event type: {}", event_kind)
|
_ => steelerr!(Generic => "Unable to register hook: Unknown event type: {}", event_kind)
|
||||||
.into(),
|
.into(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use helix_event::{events, register_event};
|
use helix_event::{events, register_event};
|
||||||
use helix_view::document::Mode;
|
use helix_view::document::Mode;
|
||||||
use helix_view::events::{
|
use helix_view::events::{
|
||||||
DiagnosticsDidChange, DocumentDidChange, DocumentFocusLost, SelectionDidChange,
|
DiagnosticsDidChange, DocumentDidChange, DocumentFocusLost, DocumentOpened, SelectionDidChange,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::commands;
|
use crate::commands;
|
||||||
|
@ -21,4 +21,5 @@ pub fn register() {
|
||||||
register_event::<DocumentFocusLost>();
|
register_event::<DocumentFocusLost>();
|
||||||
register_event::<SelectionDidChange>();
|
register_event::<SelectionDidChange>();
|
||||||
register_event::<DiagnosticsDidChange>();
|
register_event::<DiagnosticsDidChange>();
|
||||||
|
register_event::<DocumentOpened>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,10 @@ use crate::{
|
||||||
annotations::diagnostics::{DiagnosticFilter, InlineDiagnosticsConfig},
|
annotations::diagnostics::{DiagnosticFilter, InlineDiagnosticsConfig},
|
||||||
clipboard::ClipboardProvider,
|
clipboard::ClipboardProvider,
|
||||||
document::{
|
document::{
|
||||||
DocumentOpenError, DocumentSavedEventFuture, DocumentSavedEventResult, Mode, SavePoint,
|
DocumentOpenError, DocumentSavedEvent, DocumentSavedEventFuture, DocumentSavedEventResult,
|
||||||
|
Mode, SavePoint,
|
||||||
},
|
},
|
||||||
events::DocumentFocusLost,
|
events::{DocumentClosed, DocumentFocusLost, DocumentOpened, DocumentSaved},
|
||||||
graphics::{CursorKind, Rect},
|
graphics::{CursorKind, Rect},
|
||||||
handlers::Handlers,
|
handlers::Handlers,
|
||||||
info::Info,
|
info::Info,
|
||||||
|
@ -1784,6 +1785,11 @@ impl Editor {
|
||||||
let id = self.new_document(doc);
|
let id = self.new_document(doc);
|
||||||
self.launch_language_servers(id);
|
self.launch_language_servers(id);
|
||||||
|
|
||||||
|
dispatch(DocumentOpened {
|
||||||
|
editor: self,
|
||||||
|
doc: id,
|
||||||
|
});
|
||||||
|
|
||||||
id
|
id
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1874,6 +1880,11 @@ impl Editor {
|
||||||
|
|
||||||
self._refresh();
|
self._refresh();
|
||||||
|
|
||||||
|
dispatch(DocumentClosed {
|
||||||
|
editor: self,
|
||||||
|
doc: doc_id,
|
||||||
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1911,6 +1922,11 @@ impl Editor {
|
||||||
|
|
||||||
self.write_count += 1;
|
self.write_count += 1;
|
||||||
|
|
||||||
|
dispatch(DocumentSaved {
|
||||||
|
editor: self,
|
||||||
|
doc: doc_id,
|
||||||
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,4 +15,7 @@ events! {
|
||||||
DiagnosticsDidChange<'a> { editor: &'a mut Editor, doc: DocumentId }
|
DiagnosticsDidChange<'a> { editor: &'a mut Editor, doc: DocumentId }
|
||||||
// called **after** a document loses focus (but not when its closed)
|
// called **after** a document loses focus (but not when its closed)
|
||||||
DocumentFocusLost<'a> { editor: &'a mut Editor, doc: DocumentId }
|
DocumentFocusLost<'a> { editor: &'a mut Editor, doc: DocumentId }
|
||||||
|
DocumentOpened<'a> { editor: &'a mut Editor, doc: DocumentId }
|
||||||
|
DocumentClosed<'a> { editor: &'a mut Editor, doc: DocumentId }
|
||||||
|
DocumentSaved<'a> { editor: &'a mut Editor, doc: DocumentId }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue