@@ -664,7 +664,7 @@ pub fn _search_next(cx: &mut Context, extend: bool) {
664 let query = query.first().unwrap();
664 let query = query.first().unwrap();
665 let (view, doc) = cx.current();
665 let (view, doc) = cx.current();
666 let contents = doc.text().slice(..).to_string();
666 let contents = doc.text().slice(..).to_string();
667− let regex = Regex::new(&query).unwrap();
667+ let regex = Regex::new(query).unwrap();
668 _search(doc, view, &contents, ®ex, extend);
668 _search(doc, view, &contents, ®ex, extend);
@@ -809,7 +809,7 @@ pub fn append_mode(cx: &mut Context) {
809 doc.set_selection(view.id, selection);
809 doc.set_selection(view.id, selection);
812−const COMMAND_LIST: &[&str] = &["write", "open", "quit"];
812+const COMMAND_LIST: &[&str] = &["write", "open", "quit", "quit!"];
814pub fn command_mode(cx: &mut Context) {
814pub fn command_mode(cx: &mut Context) {
815 let prompt = Prompt::new(
815 let prompt = Prompt::new(
@@ -856,6 +856,31 @@ pub fn command_mode(cx: &mut Context) {
857 match *parts.as_slice() {
857 match *parts.as_slice() {
858 ["q"] | ["quit"] => {
858 ["q"] | ["quit"] => {
859+ // last view and we have unsaved changes
860+ if editor.tree.views().count() == 1 {
861+ let modified: Vec<_> = editor
863+ .filter(|doc| doc.is_modified())
866+ .and_then(|path| path.to_str())
867+ .unwrap_or("[scratch]")
871+ if !modified.is_empty() {
873+ "{} unsaved buffer(s) remaining: {:?}",
877+ editor.set_error(err);
881+ editor.close(editor.view().id, /* close_buffer */ false);
883+ ["q!"] | ["quit!"] => {
859 editor.close(editor.view().id, /* close_buffer */ false);
884 editor.close(editor.view().id, /* close_buffer */ false);
861 ["o", path] | ["open", path] => {
886 ["o", path] | ["open", path] => {