mirror of https://github.com/helix-editor/helix
deprecate old keybinding scheme
parent
baa753176a
commit
0b107d6f41
|
@ -2337,6 +2337,229 @@ fn global_search(cx: &mut Context) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn search_in_directory(cx: &mut Context, search_root: PathBuf) {
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct FileResult {
|
||||||
|
path: PathBuf,
|
||||||
|
/// 0 indexed lines
|
||||||
|
line_num: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FileResult {
|
||||||
|
fn new(path: &Path, line_num: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
path: path.to_path_buf(),
|
||||||
|
line_num,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ui::menu::Item for FileResult {
|
||||||
|
type Data = Option<PathBuf>;
|
||||||
|
|
||||||
|
fn format(&self, current_path: &Self::Data) -> Row {
|
||||||
|
let relative_path = helix_core::path::get_relative_path(&self.path)
|
||||||
|
.to_string_lossy()
|
||||||
|
.into_owned();
|
||||||
|
if current_path
|
||||||
|
.as_ref()
|
||||||
|
.map(|p| p == &self.path)
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
format!("{} (*)", relative_path).into()
|
||||||
|
} else {
|
||||||
|
relative_path.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let config = cx.editor.config();
|
||||||
|
let smart_case = config.search.smart_case;
|
||||||
|
let file_picker_config = config.file_picker.clone();
|
||||||
|
|
||||||
|
let reg = cx.register.unwrap_or('/');
|
||||||
|
let completions = search_completions(cx, Some(reg));
|
||||||
|
ui::regex_prompt(
|
||||||
|
cx,
|
||||||
|
"global-search:".into(),
|
||||||
|
Some(reg),
|
||||||
|
move |_editor: &Editor, input: &str| {
|
||||||
|
completions
|
||||||
|
.iter()
|
||||||
|
.filter(|comp| comp.starts_with(input))
|
||||||
|
.map(|comp| (0.., std::borrow::Cow::Owned(comp.clone())))
|
||||||
|
.collect()
|
||||||
|
},
|
||||||
|
move |cx, regex, event| {
|
||||||
|
if event != PromptEvent::Validate {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cx.editor.registers.last_search_register = reg;
|
||||||
|
|
||||||
|
let current_path = doc_mut!(cx.editor).path().cloned();
|
||||||
|
let documents: Vec<_> = cx
|
||||||
|
.editor
|
||||||
|
.documents()
|
||||||
|
.map(|doc| (doc.path().cloned(), doc.text().to_owned()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if let Ok(matcher) = RegexMatcherBuilder::new()
|
||||||
|
.case_smart(smart_case)
|
||||||
|
.build(regex.as_str())
|
||||||
|
{
|
||||||
|
let search_root = search_root.clone();
|
||||||
|
|
||||||
|
if !search_root.exists() {
|
||||||
|
cx.editor
|
||||||
|
.set_error("Current working directory does not exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (picker, injector) = Picker::stream(current_path);
|
||||||
|
|
||||||
|
let dedup_symlinks = file_picker_config.deduplicate_links;
|
||||||
|
let absolute_root = search_root
|
||||||
|
.canonicalize()
|
||||||
|
.unwrap_or_else(|_| search_root.clone());
|
||||||
|
let injector_ = injector.clone();
|
||||||
|
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
let searcher = SearcherBuilder::new()
|
||||||
|
.binary_detection(BinaryDetection::quit(b'\x00'))
|
||||||
|
.build();
|
||||||
|
WalkBuilder::new(search_root)
|
||||||
|
.hidden(file_picker_config.hidden)
|
||||||
|
.parents(file_picker_config.parents)
|
||||||
|
.ignore(file_picker_config.ignore)
|
||||||
|
.follow_links(file_picker_config.follow_symlinks)
|
||||||
|
.git_ignore(file_picker_config.git_ignore)
|
||||||
|
.git_global(file_picker_config.git_global)
|
||||||
|
.git_exclude(file_picker_config.git_exclude)
|
||||||
|
.max_depth(file_picker_config.max_depth)
|
||||||
|
.filter_entry(move |entry| {
|
||||||
|
filter_picker_entry(entry, &absolute_root, dedup_symlinks)
|
||||||
|
})
|
||||||
|
.build_parallel()
|
||||||
|
.run(|| {
|
||||||
|
let mut searcher = searcher.clone();
|
||||||
|
let matcher = matcher.clone();
|
||||||
|
let injector = injector_.clone();
|
||||||
|
let documents = &documents;
|
||||||
|
Box::new(move |entry: Result<DirEntry, ignore::Error>| -> WalkState {
|
||||||
|
let entry = match entry {
|
||||||
|
Ok(entry) => entry,
|
||||||
|
Err(_) => return WalkState::Continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
match entry.file_type() {
|
||||||
|
Some(entry) if entry.is_file() => {}
|
||||||
|
// skip everything else
|
||||||
|
_ => return WalkState::Continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut stop = false;
|
||||||
|
let sink = sinks::UTF8(|line_num, _| {
|
||||||
|
stop = injector
|
||||||
|
.push(FileResult::new(entry.path(), line_num as usize - 1))
|
||||||
|
.is_err();
|
||||||
|
|
||||||
|
Ok(!stop)
|
||||||
|
});
|
||||||
|
let doc = documents.iter().find(|&(doc_path, _)| {
|
||||||
|
doc_path
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |doc_path| doc_path == entry.path())
|
||||||
|
});
|
||||||
|
|
||||||
|
let result = if let Some((_, doc)) = doc {
|
||||||
|
// there is already a buffer for this file
|
||||||
|
// search the buffer instead of the file because it's faster
|
||||||
|
// and captures new edits without requiring a save
|
||||||
|
if searcher.multi_line_with_matcher(&matcher) {
|
||||||
|
// in this case a continous buffer is required
|
||||||
|
// convert the rope to a string
|
||||||
|
let text = doc.to_string();
|
||||||
|
searcher.search_slice(&matcher, text.as_bytes(), sink)
|
||||||
|
} else {
|
||||||
|
searcher.search_reader(
|
||||||
|
&matcher,
|
||||||
|
RopeReader::new(doc.slice(..)),
|
||||||
|
sink,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
searcher.search_path(&matcher, entry.path(), sink)
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(err) = result {
|
||||||
|
log::error!(
|
||||||
|
"Global search error: {}, {}",
|
||||||
|
entry.path().display(),
|
||||||
|
err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if stop {
|
||||||
|
WalkState::Quit
|
||||||
|
} else {
|
||||||
|
WalkState::Continue
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.jobs.callback(async move {
|
||||||
|
let call = move |_: &mut Editor, compositor: &mut Compositor| {
|
||||||
|
let picker = Picker::with_stream(
|
||||||
|
picker,
|
||||||
|
injector,
|
||||||
|
move |cx, FileResult { path, line_num }, action| {
|
||||||
|
let doc = match cx.editor.open(path, action) {
|
||||||
|
Ok(id) => doc_mut!(cx.editor, &id),
|
||||||
|
Err(e) => {
|
||||||
|
cx.editor.set_error(format!(
|
||||||
|
"Failed to open file '{}': {}",
|
||||||
|
path.display(),
|
||||||
|
e
|
||||||
|
));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let line_num = *line_num;
|
||||||
|
let view = view_mut!(cx.editor);
|
||||||
|
let text = doc.text();
|
||||||
|
if line_num >= text.len_lines() {
|
||||||
|
cx.editor.set_error(
|
||||||
|
"The line you jumped to does not exist anymore because the file has changed.",
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let start = text.line_to_char(line_num);
|
||||||
|
let end = text.line_to_char((line_num + 1).min(text.len_lines()));
|
||||||
|
|
||||||
|
doc.set_selection(view.id, Selection::single(start, end));
|
||||||
|
if action.align_view(view, doc.id()) {
|
||||||
|
align_view(doc, view, Align::Center);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.with_preview(
|
||||||
|
|_editor, FileResult { path, line_num }| {
|
||||||
|
Some((path.clone().into(), Some((*line_num, *line_num))))
|
||||||
|
},
|
||||||
|
);
|
||||||
|
compositor.push(Box::new(overlaid(picker)))
|
||||||
|
};
|
||||||
|
Ok(Callback::EditorCompositor(Box::new(call)))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Otherwise do nothing
|
||||||
|
// log::warn!("Global Search Invalid Pattern")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
enum Extend {
|
enum Extend {
|
||||||
Above,
|
Above,
|
||||||
Below,
|
Below,
|
||||||
|
|
|
@ -64,23 +64,6 @@ impl ScriptingEngine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_keybindings() -> Option<HashMap<Mode, KeyTrie>> {
|
|
||||||
let mut map = HashMap::new();
|
|
||||||
|
|
||||||
// Overlay these in reverse, so the precedence applies correctly
|
|
||||||
for kind in PLUGIN_PRECEDENCE.iter().rev() {
|
|
||||||
if let Some(keybindings) = manual_dispatch!(kind, get_keybindings()) {
|
|
||||||
map.extend(keybindings);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if map.is_empty() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(map)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn handle_keymap_event(
|
pub fn handle_keymap_event(
|
||||||
editor: &mut ui::EditorView,
|
editor: &mut ui::EditorView,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
|
@ -169,12 +152,6 @@ pub trait PluginSystem {
|
||||||
/// run anything here that could modify the context before the main editor is available.
|
/// run anything here that could modify the context before the main editor is available.
|
||||||
fn run_initialization_script(&self, _cx: &mut Context) {}
|
fn run_initialization_script(&self, _cx: &mut Context) {}
|
||||||
|
|
||||||
/// Fetch the keybindings so that these can be loaded in to the keybinding map. These are
|
|
||||||
/// keybindings that overwrite the default ones.
|
|
||||||
fn get_keybindings(&self) -> Option<HashMap<Mode, KeyTrie>> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Allow the engine to directly handle a keymap event. This is some of the tightest integration
|
/// Allow the engine to directly handle a keymap event. This is some of the tightest integration
|
||||||
/// with the engine, directly intercepting any keymap events. By default, this just delegates to the
|
/// with the engine, directly intercepting any keymap events. By default, this just delegates to the
|
||||||
/// editors default keybindings.
|
/// editors default keybindings.
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
use helix_core::{
|
use helix_core::{
|
||||||
extensions::steel_implementations::{rope_module, SteelRopeSlice},
|
extensions::steel_implementations::{rope_module, SteelRopeSlice},
|
||||||
graphemes,
|
graphemes,
|
||||||
|
path::expand_tilde,
|
||||||
shellwords::Shellwords,
|
shellwords::Shellwords,
|
||||||
Range, Selection, Tendril,
|
Range, Selection, Tendril,
|
||||||
};
|
};
|
||||||
|
use helix_loader::{current_working_dir, set_current_working_dir};
|
||||||
use helix_view::{
|
use helix_view::{
|
||||||
document::Mode,
|
document::Mode,
|
||||||
editor::{Action, ConfigEvent},
|
editor::{Action, ConfigEvent},
|
||||||
|
@ -16,7 +18,7 @@ use serde_json::Value;
|
||||||
use steel::{
|
use steel::{
|
||||||
gc::unsafe_erased_pointers::CustomReference,
|
gc::unsafe_erased_pointers::CustomReference,
|
||||||
rerrs::ErrorKind,
|
rerrs::ErrorKind,
|
||||||
rvals::{as_underlying_type, AsRefMutSteelValFromRef, FromSteelVal, IntoSteelVal},
|
rvals::{as_underlying_type, AsRefMutSteelValFromRef, FromSteelVal, IntoSteelVal, SteelString},
|
||||||
steel_vm::{engine::Engine, register_fn::RegisterFn},
|
steel_vm::{engine::Engine, register_fn::RegisterFn},
|
||||||
SteelErr, SteelVal,
|
SteelErr, SteelVal,
|
||||||
};
|
};
|
||||||
|
@ -97,6 +99,8 @@ thread_local! {
|
||||||
|
|
||||||
pub static REVERSE_BUFFER_MAP: SteelVal =
|
pub static REVERSE_BUFFER_MAP: SteelVal =
|
||||||
SteelVal::boxed(SteelVal::empty_hashmap());
|
SteelVal::boxed(SteelVal::empty_hashmap());
|
||||||
|
|
||||||
|
pub static GLOBAL_KEYBINDING_MAP: SteelVal = get_keymap().into_steelval().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_keymap_api(engine: &mut Engine, api: KeyMapApi) {
|
fn load_keymap_api(engine: &mut Engine, api: KeyMapApi) {
|
||||||
|
@ -119,6 +123,11 @@ fn load_keymap_api(engine: &mut Engine, api: KeyMapApi) {
|
||||||
REVERSE_BUFFER_MAP.with(|x| x.clone()),
|
REVERSE_BUFFER_MAP.with(|x| x.clone()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
module.register_value(
|
||||||
|
"*global-keybinding-map*",
|
||||||
|
GLOBAL_KEYBINDING_MAP.with(|x| x.clone()),
|
||||||
|
);
|
||||||
|
|
||||||
engine.register_module(module);
|
engine.register_module(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,10 +207,6 @@ impl super::PluginSystem for SteelScriptingEngine {
|
||||||
run_initialization_script(cx);
|
run_initialization_script(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_keybindings(&self) -> Option<HashMap<Mode, KeyTrie>> {
|
|
||||||
crate::commands::engine::scheme::SharedKeyBindingsEventQueue::get()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_keymap_event(
|
fn handle_keymap_event(
|
||||||
&self,
|
&self,
|
||||||
editor: &mut ui::EditorView,
|
editor: &mut ui::EditorView,
|
||||||
|
@ -423,7 +428,8 @@ impl SteelScriptingEngine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
// Refer to the global keybinding map for the rest
|
||||||
|
Some(GLOBAL_KEYBINDING_MAP.with(|x| x.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,8 +660,8 @@ fn run_initialization_script(cx: &mut Context) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static KEYBINDING_QUEUE: Lazy<SharedKeyBindingsEventQueue> =
|
// pub static KEYBINDING_QUEUE: Lazy<SharedKeyBindingsEventQueue> =
|
||||||
Lazy::new(|| SharedKeyBindingsEventQueue::new());
|
// Lazy::new(|| SharedKeyBindingsEventQueue::new());
|
||||||
|
|
||||||
pub static CALLBACK_QUEUE: Lazy<CallbackQueue> = Lazy::new(|| CallbackQueue::new());
|
pub static CALLBACK_QUEUE: Lazy<CallbackQueue> = Lazy::new(|| CallbackQueue::new());
|
||||||
|
|
||||||
|
@ -725,44 +731,44 @@ impl CallbackQueue {
|
||||||
/// In order to send events from the engine back to the configuration, we can created a shared
|
/// In order to send events from the engine back to the configuration, we can created a shared
|
||||||
/// queue that the engine and the config push and pull from. Alternatively, we could use a channel
|
/// queue that the engine and the config push and pull from. Alternatively, we could use a channel
|
||||||
/// directly, however this was easy enough to set up.
|
/// directly, however this was easy enough to set up.
|
||||||
pub struct SharedKeyBindingsEventQueue {
|
// pub struct SharedKeyBindingsEventQueue {
|
||||||
raw_bindings: Arc<Mutex<Vec<String>>>,
|
// raw_bindings: Arc<Mutex<Vec<String>>>,
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl SharedKeyBindingsEventQueue {
|
// impl SharedKeyBindingsEventQueue {
|
||||||
pub fn new() -> Self {
|
// pub fn new() -> Self {
|
||||||
Self {
|
// Self {
|
||||||
raw_bindings: std::sync::Arc::new(std::sync::Mutex::new(Vec::new())),
|
// raw_bindings: std::sync::Arc::new(std::sync::Mutex::new(Vec::new())),
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn merge(other_as_json: String) {
|
// pub fn merge(other_as_json: String) {
|
||||||
KEYBINDING_QUEUE
|
// KEYBINDING_QUEUE
|
||||||
.raw_bindings
|
// .raw_bindings
|
||||||
.lock()
|
// .lock()
|
||||||
.unwrap()
|
// .unwrap()
|
||||||
.push(other_as_json);
|
// .push(other_as_json);
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn get() -> Option<HashMap<Mode, KeyTrie>> {
|
// pub fn get() -> Option<HashMap<Mode, KeyTrie>> {
|
||||||
let guard = KEYBINDING_QUEUE.raw_bindings.lock().unwrap();
|
// let guard = KEYBINDING_QUEUE.raw_bindings.lock().unwrap();
|
||||||
|
|
||||||
if let Some(first) = guard.get(0).clone() {
|
// if let Some(first) = guard.get(0).clone() {
|
||||||
let mut initial = serde_json::from_str(first).unwrap();
|
// let mut initial = serde_json::from_str(first).unwrap();
|
||||||
|
|
||||||
// while let Some(remaining_event) = guard.pop_front() {
|
// // while let Some(remaining_event) = guard.pop_front() {
|
||||||
for remaining_event in guard.iter() {
|
// for remaining_event in guard.iter() {
|
||||||
let bindings = serde_json::from_str(remaining_event).unwrap();
|
// let bindings = serde_json::from_str(remaining_event).unwrap();
|
||||||
|
|
||||||
merge_keys(&mut initial, bindings);
|
// merge_keys(&mut initial, bindings);
|
||||||
}
|
// }
|
||||||
|
|
||||||
return Some(initial);
|
// return Some(initial);
|
||||||
}
|
// }
|
||||||
|
|
||||||
None
|
// None
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl Custom for PromptEvent {}
|
impl Custom for PromptEvent {}
|
||||||
|
|
||||||
|
@ -1122,7 +1128,7 @@ fn configure_engine() -> std::rc::Rc<std::cell::RefCell<steel::steel_vm::engine:
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut module = BuiltInModule::new("helix/core/keybindings".to_string());
|
let mut module = BuiltInModule::new("helix/core/keybindings".to_string());
|
||||||
module.register_fn("set-keybindings!", SharedKeyBindingsEventQueue::merge);
|
// module.register_fn("set-keybindings!", SharedKeyBindingsEventQueue::merge);
|
||||||
|
|
||||||
RegisterFn::<
|
RegisterFn::<
|
||||||
_,
|
_,
|
||||||
|
@ -1278,6 +1284,11 @@ fn configure_engine() -> std::rc::Rc<std::cell::RefCell<steel::steel_vm::engine:
|
||||||
module.register_fn("run-in-engine!", run_in_engine);
|
module.register_fn("run-in-engine!", run_in_engine);
|
||||||
module.register_fn("get-helix-scm-path", get_helix_scm_path);
|
module.register_fn("get-helix-scm-path", get_helix_scm_path);
|
||||||
module.register_fn("get-init-scm-path", get_init_scm_path);
|
module.register_fn("get-init-scm-path", get_init_scm_path);
|
||||||
|
|
||||||
|
module.register_fn("get-helix-cwd", get_helix_cwd);
|
||||||
|
|
||||||
|
module.register_fn("search-in-directory", search_in_directory);
|
||||||
|
|
||||||
module.register_fn("block-on-shell-command", run_shell_command_text);
|
module.register_fn("block-on-shell-command", run_shell_command_text);
|
||||||
|
|
||||||
module.register_fn("cx->current-file", current_path);
|
module.register_fn("cx->current-file", current_path);
|
||||||
|
@ -1721,6 +1732,13 @@ pub fn cx_pos_within_text(cx: &mut Context) -> usize {
|
||||||
pos
|
pos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_helix_cwd(cx: &mut Context) -> Option<String> {
|
||||||
|
helix_loader::current_working_dir()
|
||||||
|
.as_os_str()
|
||||||
|
.to_str()
|
||||||
|
.map(|x| x.into())
|
||||||
|
}
|
||||||
|
|
||||||
// Special newline...
|
// Special newline...
|
||||||
pub fn custom_insert_newline(cx: &mut Context, indent: String) {
|
pub fn custom_insert_newline(cx: &mut Context, indent: String) {
|
||||||
let (view, doc) = current_ref!(cx.editor);
|
let (view, doc) = current_ref!(cx.editor);
|
||||||
|
@ -1819,3 +1837,8 @@ pub fn custom_insert_newline(cx: &mut Context, indent: String) {
|
||||||
let (view, doc) = current!(cx.editor);
|
let (view, doc) = current!(cx.editor);
|
||||||
doc.apply(&transaction, view.id);
|
doc.apply(&transaction, view.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn search_in_directory(cx: &mut Context, directory: String) {
|
||||||
|
let search_path = expand_tilde(&PathBuf::from(directory));
|
||||||
|
crate::commands::search_in_directory(cx, search_path);
|
||||||
|
}
|
||||||
|
|
|
@ -3111,13 +3111,15 @@ pub(super) fn command_mode(cx: &mut Context) {
|
||||||
// .collect()
|
// .collect()
|
||||||
fuzzy_match(
|
fuzzy_match(
|
||||||
input,
|
input,
|
||||||
TYPABLE_COMMAND_LIST.iter().map(|command| Cow::from(command.name)).chain(crate::commands::engine::ScriptingEngine::available_commands()),
|
TYPABLE_COMMAND_LIST
|
||||||
|
.iter()
|
||||||
|
.map(|command| Cow::from(command.name))
|
||||||
|
.chain(crate::commands::engine::ScriptingEngine::available_commands()),
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(name, _)| (0.., name.into()))
|
.map(|(name, _)| (0.., name.into()))
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, use the command's completer and the last shellword
|
// Otherwise, use the command's completer and the last shellword
|
||||||
// as completion input.
|
// as completion input.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::keymap;
|
use crate::keymap;
|
||||||
use crate::keymap::{merge_keys, KeyTrie, Keymaps};
|
use crate::keymap::{merge_keys, KeyTrie};
|
||||||
use helix_loader::merge_toml_values;
|
use helix_loader::merge_toml_values;
|
||||||
use helix_view::document::Mode;
|
use helix_view::document::Mode;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
@ -59,7 +59,6 @@ impl Config {
|
||||||
pub fn load(
|
pub fn load(
|
||||||
global: Result<String, ConfigLoadError>,
|
global: Result<String, ConfigLoadError>,
|
||||||
local: Result<String, ConfigLoadError>,
|
local: Result<String, ConfigLoadError>,
|
||||||
engine_overlay: Option<HashMap<Mode, KeyTrie>>,
|
|
||||||
) -> Result<Config, ConfigLoadError> {
|
) -> Result<Config, ConfigLoadError> {
|
||||||
let global_config: Result<ConfigRaw, ConfigLoadError> =
|
let global_config: Result<ConfigRaw, ConfigLoadError> =
|
||||||
global.and_then(|file| toml::from_str(&file).map_err(ConfigLoadError::BadConfig));
|
global.and_then(|file| toml::from_str(&file).map_err(ConfigLoadError::BadConfig));
|
||||||
|
@ -76,10 +75,6 @@ impl Config {
|
||||||
merge_keys(&mut keys, local_keys)
|
merge_keys(&mut keys, local_keys)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(overlay) = engine_overlay {
|
|
||||||
merge_keys(&mut keys, overlay);
|
|
||||||
}
|
|
||||||
|
|
||||||
let editor = match (global.editor, local.editor) {
|
let editor = match (global.editor, local.editor) {
|
||||||
(None, None) => helix_view::editor::Config::default(),
|
(None, None) => helix_view::editor::Config::default(),
|
||||||
(None, Some(val)) | (Some(val), None) => {
|
(None, Some(val)) | (Some(val), None) => {
|
||||||
|
@ -107,10 +102,6 @@ impl Config {
|
||||||
merge_keys(&mut keys, keymap);
|
merge_keys(&mut keys, keymap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(overlay) = engine_overlay {
|
|
||||||
merge_keys(&mut keys, overlay);
|
|
||||||
}
|
|
||||||
|
|
||||||
Config {
|
Config {
|
||||||
theme: config.theme,
|
theme: config.theme,
|
||||||
keys,
|
keys,
|
||||||
|
@ -134,9 +125,7 @@ impl Config {
|
||||||
let local_config = fs::read_to_string(helix_loader::workspace_config_file())
|
let local_config = fs::read_to_string(helix_loader::workspace_config_file())
|
||||||
.map_err(ConfigLoadError::Error);
|
.map_err(ConfigLoadError::Error);
|
||||||
|
|
||||||
let bindings = crate::commands::engine::ScriptingEngine::get_keybindings();
|
Config::load(global_config, local_config)
|
||||||
|
|
||||||
Config::load(global_config, local_config, bindings)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +135,7 @@ mod tests {
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
fn load_test(config: &str) -> Config {
|
fn load_test(config: &str) -> Config {
|
||||||
Config::load(Ok(config.to_owned()), Err(ConfigLoadError::default()), None).unwrap()
|
Config::load(Ok(config.to_owned()), Err(ConfigLoadError::default())).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue