on master help sign in
Refactor document methods
commit59b5bf31780c937096a3f6bbf99b4b0bb7b35494 authorGokul Soumya <gokulps15@gmail.com> dateMon 7 Feb 2022, 21:04 (5 years ago) parentfa83426
1 file changed+62−103
helix-view/src/document.rs+62−103
helix-view/src/document.rs+62−103
@@ -1,4 +1,4 @@
1−use anyhow::{anyhow, Context, Error};
1+use anyhow::{anyhow, bail, Context, Error};
22use serde::de::{self, Deserialize, Deserializer};
33use serde::Serialize;
44use std::cell::Cell;
@@ -11,7 +11,7 @@ use std::sync::Arc;
1111
1212use helix_core::{
1313 encoding,
14− history::History,
14+ history::{History, UndoKind},
1515 indent::{auto_detect_indent_style, IndentStyle},
1616 line_ending::auto_detect_line_ending,
1717 syntax::{self, LanguageConfiguration},
@@ -54,7 +54,7 @@ impl FromStr for Mode {
5454 "normal" => Ok(Mode::Normal),
5555 "select" => Ok(Mode::Select),
5656 "insert" => Ok(Mode::Insert),
57− _ => Err(anyhow!("Invalid mode '{}'", s)),
57+ _ => bail!("Invalid mode '{}'", s),
5858 }
5959 }
6060}
@@ -396,7 +396,7 @@ impl Document {
396396 /// The same as [`format`], but only returns formatting changes if auto-formatting
397397 /// is configured.
398398 pub fn auto_format(&self) -> Option<impl Future<Output = LspFormatting> + 'static> {
399− if self.language_config().map(|c| c.auto_format) == Some(true) {
399+ if self.language_config()?.auto_format {
400400 self.format()
401401 } else {
402402 None
@@ -406,30 +406,27 @@ impl Document {
406406 /// If supported, returns the changes that should be applied to this document in order
407407 /// to format it nicely.
408408 pub fn format(&self) -> Option<impl Future<Output = LspFormatting> + 'static> {
409− if let Some(language_server) = self.language_server() {
410− let text = self.text.clone();
411− let offset_encoding = language_server.offset_encoding();
412− let request = language_server.text_document_formatting(
413− self.identifier(),
414− lsp::FormattingOptions::default(),
415− None,
416− )?;
417−
418− let fut = async move {
419− let edits = request.await.unwrap_or_else(|e| {
420− log::warn!("LSP formatting failed: {}", e);
421− Default::default()
422− });
423− LspFormatting {
424− doc: text,
425− edits,
426− offset_encoding,
427− }
428− };
429− Some(fut)
430− } else {
431− None
432− }
409+ let language_server = self.language_server()?;
410+ let text = self.text.clone();
411+ let offset_encoding = language_server.offset_encoding();
412+ let request = language_server.text_document_formatting(
413+ self.identifier(),
414+ lsp::FormattingOptions::default(),
415+ None,
416+ )?;
417+
418+ let fut = async move {
419+ let edits = request.await.unwrap_or_else(|e| {
420+ log::warn!("LSP formatting failed: {}", e);
421+ Default::default()
422+ });
423+ LspFormatting {
424+ doc: text,
425+ edits,
426+ offset_encoding,
427+ }
428+ };
429+ Some(fut)
433430 }
434431
435432 pub fn save(&mut self) -> impl Future<Output = Result<(), anyhow::Error>> {
@@ -473,9 +470,7 @@ impl Document {
473470 if let Some(parent) = path.parent() {
474471 // TODO: display a prompt asking the user if the directories should be created
475472 if !parent.exists() {
476− return Err(Error::msg(
477− "can't save file, parent directory does not exist",
478− ));
473+ bail!("can't save file, parent directory does not exist");
479474 }
480475 }
481476
@@ -522,8 +517,7 @@ impl Document {
522517 /// line ending.
523518 pub fn detect_indent_and_line_ending(&mut self) {
524519 self.indent_style = auto_detect_indent_style(&self.text).unwrap_or_else(|| {
525− self.language
526− .as_ref()
520+ self.language_config()
527521 .and_then(|config| config.indent.as_ref())
528522 .map_or(DEFAULT_INDENT, |config| IndentStyle::from_str(&config.unit))
529523 });
@@ -537,7 +531,7 @@ impl Document {
537531
538532 // If there is no path or the path no longer exists.
539533 if path.is_none() {
540− return Err(anyhow!("can't find file to reload from"));
534+ bail!("can't find file to reload from");
541535 }
542536
543537 let mut file = std::fs::File::open(path.unwrap())?;
@@ -558,10 +552,8 @@ impl Document {
558552
559553 /// Sets the [`Document`]'s encoding with the encoding correspondent to `label`.
560554 pub fn set_encoding(&mut self, label: &str) -> Result<(), Error> {
561− match encoding::Encoding::for_label(label.as_bytes()) {
562− Some(encoding) => self.encoding = encoding,
563− None => return Err(anyhow::anyhow!("unknown encoding")),
564− }
555+ self.encoding = encoding::Encoding::for_label(label.as_bytes())
556+ .ok_or_else(|| anyhow!("unknown encoding"))?;
565557 Ok(())
566558 }
567559
@@ -646,7 +638,6 @@ impl Document {
646638 );
647639 }
648640
649− // set modified since accessed
650641 self.modified_since_accessed = true;
651642 }
652643
@@ -689,7 +680,7 @@ impl Document {
689680
690681 if let Some(notify) = notify {
691682 tokio::spawn(notify);
692− } //.expect("failed to emit textDocument/didChange");
683+ }
693684 }
694685 }
695686 success
@@ -717,11 +708,11 @@ impl Document {
717708 success
718709 }
719710
720− /// Undo the last modification to the [`Document`]. Returns whether the undo was successful.
721− pub fn undo(&mut self, view_id: ViewId) -> bool {
711+ fn undo_redo_impl(&mut self, view_id: ViewId, undo: bool) -> bool {
722712 let mut history = self.history.take();
723− let success = if let Some(transaction) = history.undo() {
724− self.apply_impl(transaction, view_id)
713+ let txn = if undo { history.undo() } else { history.redo() };
714+ let success = if let Some(txn) = txn {
715+ self.apply_impl(txn, view_id)
725716 } else {
726717 false
727718 };
@@ -734,21 +725,14 @@ impl Document {
734725 success
735726 }
736727
728+ /// Undo the last modification to the [`Document`]. Returns whether the undo was successful.
729+ pub fn undo(&mut self, view_id: ViewId) -> bool {
730+ self.undo_redo_impl(view_id, true)
731+ }
732+
737733 /// Redo the last modification to the [`Document`]. Returns whether the redo was sucessful.
738734 pub fn redo(&mut self, view_id: ViewId) -> bool {
739− let mut history = self.history.take();
740− let success = if let Some(transaction) = history.redo() {
741− self.apply_impl(transaction, view_id)
742− } else {
743− false
744− };
745− self.history.set(history);
746−
747− if success {
748− // reset changeset to fix len
749− self.changes = ChangeSet::new(self.text());
750− }
751− success
735+ self.undo_redo_impl(view_id, false)
752736 }
753737
754738 pub fn savepoint(&mut self) {
@@ -761,9 +745,12 @@ impl Document {
761745 }
762746 }
763747
764− /// Undo modifications to the [`Document`] according to `uk`.
765− pub fn earlier(&mut self, view_id: ViewId, uk: helix_core::history::UndoKind) -> bool {
766− let txns = self.history.get_mut().earlier(uk);
748+ fn earlier_later_impl(&mut self, view_id: ViewId, uk: UndoKind, earlier: bool) -> bool {
749+ let txns = if earlier {
750+ self.history.get_mut().earlier(uk)
751+ } else {
752+ self.history.get_mut().later(uk)
753+ };
767754 let mut success = false;
768755 for txn in txns {
769756 if self.apply_impl(&txn, view_id) {
@@ -777,20 +764,14 @@ impl Document {
777764 success
778765 }
779766
767+ /// Undo modifications to the [`Document`] according to `uk`.
768+ pub fn earlier(&mut self, view_id: ViewId, uk: UndoKind) -> bool {
769+ self.earlier_later_impl(view_id, uk, true)
770+ }
771+
780772 /// Redo modifications to the [`Document`] according to `uk`.
781− pub fn later(&mut self, view_id: ViewId, uk: helix_core::history::UndoKind) -> bool {
782− let txns = self.history.get_mut().later(uk);
783− let mut success = false;
784− for txn in txns {
785− if self.apply_impl(&txn, view_id) {
786− success = true;
787− }
788− }
789− if success {
790− // reset changeset to fix len
791− self.changes = ChangeSet::new(self.text());
792− }
793− success
773+ pub fn later(&mut self, view_id: ViewId, uk: UndoKind) -> bool {
774+ self.earlier_later_impl(view_id, uk, false)
794775 }
795776
796777 /// Commit pending changes to history
@@ -850,18 +831,10 @@ impl Document {
850831 /// `language-server` configuration, or the document language if no
851832 /// `language-id` has been specified.
852833 pub fn language_id(&self) -> Option<&str> {
853− self.language
854− .as_ref()
834+ self.language_config()
855835 .and_then(|config| config.language_server.as_ref())
856− .and_then(|lsp_config| lsp_config.language_id.as_ref())
857− .map_or_else(
858− || {
859− self.language()
860− .and_then(|s| s.rsplit_once('.'))
861− .map(|(_, language_id)| language_id)
862− },
863− |language_id| Some(language_id.as_str()),
864− )
836+ .and_then(|lsp_config| lsp_config.language_id.as_deref())
837+ .or_else(|| Some(self.language()?.rsplit_once('.')?.1))
865838 }
866839
867840 /// Corresponding [`LanguageConfiguration`].
@@ -874,18 +847,10 @@ impl Document {
874847 self.version
875848 }
876849
850+ /// Language server if it has been initialized.
877851 pub fn language_server(&self) -> Option<&helix_lsp::Client> {
878− let server = self.language_server.as_deref();
879− let initialized = server
880− .map(|server| server.is_initialized())
881− .unwrap_or(false);
882−
883− // only resolve language_server if it's initialized
884− if initialized {
885− server
886− } else {
887− None
888− }
852+ let server = self.language_server.as_deref()?;
853+ server.is_initialized().then(|| server)
889854 }
890855
891856 #[inline]
@@ -896,8 +861,7 @@ impl Document {
896861
897862 /// Tab size in columns.
898863 pub fn tab_width(&self) -> usize {
899− self.language
900− .as_ref()
864+ self.language_config()
901865 .and_then(|config| config.indent.as_ref())
902866 .map_or(4, |config| config.tab_width) // fallback to 4 columns
903867 }
@@ -922,7 +886,7 @@ impl Document {
922886
923887 /// File path as a URL.
924888 pub fn url(&self) -> Option<Url> {
925− self.path().map(|path| Url::from_file_path(path).unwrap())
889+ Url::from_file_path(self.path()?).ok()
926890 }
927891
928892 #[inline]
@@ -945,10 +909,6 @@ impl Document {
945909 .map(helix_core::path::get_relative_path)
946910 }
947911
948− // pub fn slice<R>(&self, range: R) -> RopeSlice where R: RangeBounds {
949− // self.state.doc.slice
950− // }
951−
952912 // transact(Fn) ?
953913
954914 // -- LSP methods
@@ -969,7 +929,6 @@ impl Document {
969929
970930 pub fn set_diagnostics(&mut self, diagnostics: Vec<Diagnostic>) {
971931 self.diagnostics = diagnostics;
972− // sort by range
973932 self.diagnostics
974933 .sort_unstable_by_key(|diagnostic| diagnostic.range);
975934 }