mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-10 10:35:16 +03:00
Add the :new command, don't crash if saving without filename.
This commit is contained in:
parent
f8844c6811
commit
7c915dc065
@ -1,3 +1,4 @@
|
||||
#[derive(Eq, PartialEq)]
|
||||
pub enum Severity {
|
||||
Error,
|
||||
Warning,
|
||||
|
@ -42,7 +42,6 @@ pub struct Context<'a> {
|
||||
pub callback: Option<crate::compositor::Callback>,
|
||||
pub on_next_key_callback: Option<Box<dyn FnOnce(&mut Context, KeyEvent)>>,
|
||||
pub callbacks: &'a mut LspCallbacks,
|
||||
pub status_msg: Option<String>,
|
||||
}
|
||||
|
||||
impl<'a> Context<'a> {
|
||||
@ -97,11 +96,6 @@ impl<'a> Context<'a> {
|
||||
});
|
||||
self.callbacks.push(callback);
|
||||
}
|
||||
|
||||
// TODO: allow &'static str?
|
||||
pub fn set_status(&mut self, msg: String) {
|
||||
self.status_msg = Some(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/// A command is a function that takes the current state and a count, and does a side-effect on the
|
||||
@ -852,6 +846,8 @@ pub fn command_mode(cx: &mut Context) {
|
||||
}
|
||||
}, // completion
|
||||
move |editor: &mut Editor, input: &str, event: PromptEvent| {
|
||||
use helix_view::editor::Action;
|
||||
|
||||
if event != PromptEvent::Validate {
|
||||
return;
|
||||
}
|
||||
@ -863,16 +859,20 @@ pub fn command_mode(cx: &mut Context) {
|
||||
editor.close(editor.view().id);
|
||||
}
|
||||
["o", path] | ["open", path] => {
|
||||
use helix_view::editor::Action;
|
||||
editor.open(path.into(), Action::Replace);
|
||||
}
|
||||
["w"] | ["write"] => {
|
||||
// TODO: non-blocking via save() command
|
||||
let id = editor.view().doc;
|
||||
let doc = &mut editor.documents[id];
|
||||
if doc.path().is_none() {
|
||||
editor.set_error("cannot write a buffer without a filename".to_string());
|
||||
return;
|
||||
}
|
||||
tokio::spawn(doc.save());
|
||||
}
|
||||
|
||||
["new"] => {
|
||||
editor.new_file(Action::Replace);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
},
|
||||
@ -1585,7 +1585,7 @@ pub fn yank(cx: &mut Context) {
|
||||
|
||||
register::set(reg, values);
|
||||
|
||||
cx.set_status(msg)
|
||||
cx.editor.set_status(msg)
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
@ -28,7 +28,6 @@ use tui::{
|
||||
pub struct EditorView {
|
||||
keymap: Keymaps,
|
||||
on_next_key: Option<Box<dyn FnOnce(&mut commands::Context, KeyEvent)>>,
|
||||
status_msg: Option<String>,
|
||||
last_insert: (commands::Command, Vec<KeyEvent>),
|
||||
completion: Option<Completion>,
|
||||
}
|
||||
@ -40,7 +39,6 @@ impl EditorView {
|
||||
Self {
|
||||
keymap: keymap::default(),
|
||||
on_next_key: None,
|
||||
status_msg: None,
|
||||
last_insert: (commands::normal_mode, Vec::new()),
|
||||
completion: None,
|
||||
}
|
||||
@ -86,17 +84,6 @@ impl EditorView {
|
||||
1,
|
||||
);
|
||||
self.render_statusline(doc, view, area, surface, theme, is_focused);
|
||||
|
||||
// render status
|
||||
if let Some(status_msg) = &self.status_msg {
|
||||
let style = Style::default().fg(Color::Rgb(164, 160, 232)); // lavender
|
||||
surface.set_string(
|
||||
view.area.x,
|
||||
view.area.y + view.area.height,
|
||||
status_msg,
|
||||
style,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_buffer(
|
||||
@ -537,6 +524,9 @@ impl Component for EditorView {
|
||||
EventResult::Consumed(None)
|
||||
}
|
||||
Event::Key(key) => {
|
||||
// clear status
|
||||
cx.editor.status_msg = None;
|
||||
|
||||
let (view, doc) = cx.editor.current();
|
||||
let mode = doc.mode();
|
||||
|
||||
@ -547,12 +537,8 @@ impl Component for EditorView {
|
||||
callback: None,
|
||||
callbacks: cx.callbacks,
|
||||
on_next_key_callback: None,
|
||||
status_msg: None,
|
||||
};
|
||||
|
||||
// clear status
|
||||
self.status_msg = None;
|
||||
|
||||
if let Some(on_next_key) = self.on_next_key.take() {
|
||||
// if there's a command waiting input, do that first
|
||||
on_next_key(&mut cxt, key);
|
||||
@ -602,7 +588,6 @@ impl Component for EditorView {
|
||||
}
|
||||
|
||||
self.on_next_key = cxt.on_next_key_callback.take();
|
||||
self.status_msg = cxt.status_msg.take();
|
||||
// appease borrowck
|
||||
let callback = cxt.callback.take();
|
||||
|
||||
@ -641,6 +626,23 @@ impl Component for EditorView {
|
||||
self.render_view(doc, view, area, surface, &cx.editor.theme, is_focused);
|
||||
}
|
||||
|
||||
// render status msg
|
||||
if let Some((status_msg, severity)) = &cx.editor.status_msg {
|
||||
use helix_view::editor::Severity;
|
||||
let style = if *severity == Severity::Error {
|
||||
cx.editor.theme.get("error")
|
||||
} else {
|
||||
Style::default().fg(Color::Rgb(164, 160, 232)) // lavender
|
||||
};
|
||||
|
||||
surface.set_string(
|
||||
area.x,
|
||||
area.y + area.height.saturating_sub(1),
|
||||
status_msg,
|
||||
style,
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(completion) = &self.completion {
|
||||
completion.render(area, surface, cx)
|
||||
// render completion here
|
||||
|
@ -7,12 +7,16 @@ use slotmap::SlotMap;
|
||||
|
||||
use anyhow::Error;
|
||||
|
||||
pub use helix_core::diagnostic::Severity;
|
||||
|
||||
pub struct Editor {
|
||||
pub tree: Tree,
|
||||
pub documents: SlotMap<DocumentId, Document>,
|
||||
pub count: Option<usize>,
|
||||
pub theme: Theme,
|
||||
pub language_servers: helix_lsp::Registry,
|
||||
|
||||
pub status_msg: Option<(String, Severity)>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
@ -43,9 +47,18 @@ impl Editor {
|
||||
count: None,
|
||||
theme,
|
||||
language_servers,
|
||||
status_msg: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_status(&mut self, status: String) {
|
||||
self.status_msg = Some((status, Severity::Info));
|
||||
}
|
||||
|
||||
pub fn set_error(&mut self, error: String) {
|
||||
self.status_msg = Some((error, Severity::Error));
|
||||
}
|
||||
|
||||
fn _refresh(&mut self) {
|
||||
for (view, _) in self.tree.views_mut() {
|
||||
let doc = &self.documents[view.doc];
|
||||
|
Loading…
Reference in New Issue
Block a user