From 0712a8d6a855216d8efff4634bcb730f8e0fe29a Mon Sep 17 00:00:00 2001 From: Felix Zeller Date: Sat, 2 Mar 2024 16:42:51 -0500 Subject: [PATCH] cargo fmt --- src/completion.rs | 336 ++++++++++++++++--------------- src/hover.rs | 21 +- src/ui.rs | 28 ++- src/vault/mod.rs | 499 ++++++++++++++++++++++++++-------------------- 4 files changed, 501 insertions(+), 383 deletions(-) diff --git a/src/completion.rs b/src/completion.rs index fbe723ed..be684cce 100644 --- a/src/completion.rs +++ b/src/completion.rs @@ -13,13 +13,15 @@ use rayon::prelude::*; use regex::Regex; use tower_lsp::lsp_types::{ Command, CompletionItem, CompletionItemKind, CompletionItemLabelDetails, CompletionList, - CompletionParams, CompletionResponse, CompletionTextEdit, Documentation, MarkupContent, - MarkupKind, Position, Range, TextEdit, Url, InsertTextFormat, + CompletionParams, CompletionResponse, CompletionTextEdit, Documentation, InsertTextFormat, + MarkupContent, MarkupKind, Position, Range, TextEdit, Url, }; use crate::{ ui::preview_referenceable, - vault::{get_obsidian_ref_path, Block, Preview, Referenceable, Vault, MyRange, Refname, Reference}, + vault::{ + get_obsidian_ref_path, Block, MyRange, Preview, Reference, Referenceable, Refname, Vault, + }, }; fn get_wikilink_index(line: &Vec, cursor_character: usize) -> Option { @@ -46,8 +48,7 @@ struct CompletableMDLink { full_range: LineRange, } -fn get_completable_mdlink (line: &Vec , cursor_character: usize) -> Option { - +fn get_completable_mdlink(line: &Vec, cursor_character: usize) -> Option { let line_to_cursor = line.get(0..cursor_character)?; static PARTIAL_MDLINK_REGEX: Lazy = Lazy::new(|| { @@ -56,34 +57,45 @@ fn get_completable_mdlink (line: &Vec , cursor_character: usize) -> Option let string_to_char = String::from_iter(line_to_cursor); + let captures = PARTIAL_MDLINK_REGEX.captures(&string_to_char)?; - let captures = PARTIAL_MDLINK_REGEX - .captures(&string_to_char)?; - - let (full, display, reftext, infileref) = (captures.get(0)?, captures.name("display")?, captures.name("path")?, captures.name("infileref")); - - - let reference_under_cursor = Reference::new(&String::from_iter(line)).into_iter().find(|reference| - reference.range.start.character <= cursor_character as u32 - && reference.range.end.character >= cursor_character as u32 + let (full, display, reftext, infileref) = ( + captures.get(0)?, + captures.name("display")?, + captures.name("path")?, + captures.name("infileref"), ); + let reference_under_cursor = + Reference::new(&String::from_iter(line)) + .into_iter() + .find(|reference| { + reference.range.start.character <= cursor_character as u32 + && reference.range.end.character >= cursor_character as u32 + }); + let full_range = match reference_under_cursor { - Some(reference @ (Reference::MDFileLink(..) | Reference::MDHeadingLink(..) | Reference::MDIndexedBlockLink(..))) => - reference.range.start.character as usize .. reference.range.end.character as usize, - None if line.get(cursor_character) == Some(&')') => full.range().start .. full.range().end + 1, - _ => full.range() + Some( + reference @ (Reference::MDFileLink(..) + | Reference::MDHeadingLink(..) + | Reference::MDIndexedBlockLink(..)), + ) => reference.range.start.character as usize..reference.range.end.character as usize, + None if line.get(cursor_character) == Some(&')') => { + full.range().start..full.range().end + 1 + } + _ => full.range(), }; let partial = Some(CompletableMDLink { path: (reftext.as_str().to_string(), reftext.range()), display: (display.as_str().to_string(), display.range()), - infile_ref: infileref.map(|infile_ref| (infile_ref.as_str().to_string(), infile_ref.range())), + infile_ref: infileref + .map(|infile_ref| (infile_ref.as_str().to_string(), infile_ref.range())), partial: (full.as_str().to_string(), full.range()), - full_range + full_range, }); - return partial + return partial; } pub fn get_completions( @@ -106,7 +118,8 @@ pub fn get_completions( let selected_line = vault.select_line(&path.to_path_buf(), line as isize)?; - if let Some(index) = get_wikilink_index(&selected_line, character) { // completions for wikilinks `[[text|` where | is the cursor + if let Some(index) = get_wikilink_index(&selected_line, character) { + // completions for wikilinks `[[text|` where | is the cursor let range = Range { start: Position { line: line as u32, @@ -152,7 +165,9 @@ pub fn get_completions( ) }) .flatten() - .filter_map(|referenceable| default_completion_item(vault, &referenceable, None)) + .filter_map(|referenceable| { + default_completion_item(vault, &referenceable, None) + }) .collect::>(), is_incomplete: true, })), @@ -249,7 +264,6 @@ pub fn get_completions( })); } ref filter_text @ [..] if !filter_text.contains(&']') => { - let all_links = MatchableReferenceable::from_vault(vault); let matches = fuzzy_match(&String::from_iter(filter_text), all_links); @@ -262,15 +276,20 @@ pub fn get_completions( *name != String::from_iter(filter_text) }) .filter_map(|(MatchableReferenceable(referenceable, _), rank)| { - default_completion_item(vault, &referenceable, Some(CompletionTextEdit::Edit(TextEdit { - range, - new_text: referenceable.get_refname(vault.root_dir())?.to_string(), - }))).map(|item| { - CompletionItem { - sort_text: Some(rank.to_string()), - ..item - } - }) + default_completion_item( + vault, + &referenceable, + Some(CompletionTextEdit::Edit(TextEdit { + range, + new_text: referenceable + .get_refname(vault.root_dir())? + .to_string(), + })), + ) + .map(|item| CompletionItem { + sort_text: Some(rank.to_string()), + ..item + }) }) .collect::>(), })); @@ -278,10 +297,22 @@ pub fn get_completions( _ => None, }; } else if let Some(partialmdlink) = get_completable_mdlink(&selected_line, character) { - match partialmdlink { - CompletableMDLink {path, infile_ref, full_range, display, partial} => { - let inputted_refname = format!("{}{}", path.0, infile_ref.clone().map(|(string, _)| format!("#{}", string)).unwrap_or("".to_string())); + CompletableMDLink { + path, + infile_ref, + full_range, + display, + partial, + } => { + let inputted_refname = format!( + "{}{}", + path.0, + infile_ref + .clone() + .map(|(string, _)| format!("#{}", string)) + .unwrap_or("".to_string()) + ); let all_links = MatchableReferenceable::from_vault(vault); @@ -292,13 +323,11 @@ pub fn get_completions( items: matches .into_iter() .take(50) - .filter(|(MatchableReferenceable(_, name), _)| { - *name != inputted_refname - }) + .filter(|(MatchableReferenceable(_, name), _)| *name != inputted_refname) .flat_map(|(MatchableReferenceable(referenceable, _), rank)| { default_completion_item( - vault, - &referenceable, + vault, + &referenceable, Some(CompletionTextEdit::Edit(TextEdit { range: Range { start: Position { @@ -312,70 +341,90 @@ pub fn get_completions( }, new_text: format!( "[${{1:{}}}]({}{}{}{})", - match (display.0.as_str(), referenceable.get_refname(vault.root_dir())?.infile_ref) { + match ( + display.0.as_str(), + referenceable.get_refname(vault.root_dir())?.infile_ref + ) { ("", Some(infile_ref_text)) => infile_ref_text.clone(), ("", None) => { match referenceable { Referenceable::File(_, mdfile) => { match mdfile.headings.first() { - Some(heading) => heading.heading_text.clone(), - None => "".to_string() + Some(heading) => { + heading.heading_text.clone() + } + None => "".to_string(), } } - _ => "".to_string() + _ => "".to_string(), } - }, + } (display_text, _) => display_text.to_string(), }, - if referenceable.get_refname(vault.root_dir())?.path?.contains(" ") { + if referenceable + .get_refname(vault.root_dir())? + .path? + .contains(" ") + { "<" } else { "" }, - referenceable.get_refname(vault.root_dir())?.path?.to_string(), - match referenceable.get_refname(vault.root_dir())?.infile_ref { + referenceable + .get_refname(vault.root_dir())? + .path? + .to_string(), + match referenceable + .get_refname(vault.root_dir())? + .infile_ref + { Some(string) => format!("#{}", string), None => "".to_string(), }, - if referenceable.get_refname(vault.root_dir())?.path?.contains(" ") { + if referenceable + .get_refname(vault.root_dir())? + .path? + .contains(" ") + { ">" } else { "" }, - ) + ), })), - ).and_then(|item| { - Some(CompletionItem { - sort_text: Some(rank.to_string()), - insert_text_format: Some(InsertTextFormat::SNIPPET), - filter_text: Some(format!("[{}]({}", display.0, referenceable.get_refname(vault.root_dir())?.to_string())), - ..item - - }) + ) + .and_then(|item| { + Some(CompletionItem { + sort_text: Some(rank.to_string()), + insert_text_format: Some(InsertTextFormat::SNIPPET), + filter_text: Some(format!( + "[{}]({}", + display.0, + referenceable.get_refname(vault.root_dir())?.to_string() + )), + ..item }) + }) }) .collect::>(), - })) - + })); } } - - } else if character .checked_sub(1) .and_then(|start| selected_line.get(start..character)) - == Some(&['#']) + == Some(&['#']) { // Initial Tag completion let tag_refereneables = - vault - .select_referenceable_nodes(None) - .into_iter() - .flat_map(|referenceable| match referenceable { - tag @ Referenceable::Tag(_, _) => Some(tag), - _ => None, - }); + vault + .select_referenceable_nodes(None) + .into_iter() + .flat_map(|referenceable| match referenceable { + tag @ Referenceable::Tag(_, _) => Some(tag), + _ => None, + }); return Some(CompletionResponse::Array( tag_refereneables @@ -393,7 +442,7 @@ pub fn get_completions( } else if character .checked_sub(1) .and_then(|start| selected_line.get(start..character)) - == Some(&['[']) + == Some(&['[']) { let footnote_referenceables = vault .select_referenceable_nodes(Some(&path)) @@ -401,9 +450,9 @@ pub fn get_completions( .flat_map(|referenceable| match referenceable { Referenceable::Footnote(footnote_path, _) if footnote_path.as_path() == path.as_path() => - { - Some(referenceable) - } + { + Some(referenceable) + } _ => None, }); @@ -462,16 +511,14 @@ fn default_completion_item( struct MatchableReferenceable<'a>(Referenceable<'a>, String); - impl MatchableReferenceable<'_> { fn from_vault<'a>(vault: &'a Vault) -> Vec> { - let all_links = vault .select_referenceable_nodes(None) .into_par_iter() .filter(|referenceable| { !matches!(referenceable, Referenceable::Tag(..)) - && !matches!(referenceable, Referenceable::Footnote(..)) + && !matches!(referenceable, Referenceable::Footnote(..)) }) .filter_map(|referenceable| { referenceable @@ -513,75 +560,59 @@ mod tests { assert_eq!(Some("lin"), s.get(expected + 1..10)); } - #[test] fn test_partial_mdlink() { let line = "This is line [display](partialpa"; // (th) - let expected = Some( - CompletableMDLink { - partial: ("[display](partialpa".to_string(), 13..32), - display: ("display".to_string(), 14..21), - path: ("partialpa".to_string(), 23..32), - infile_ref: None, - full_range: 13..32 - } - ); - + let expected = Some(CompletableMDLink { + partial: ("[display](partialpa".to_string(), 13..32), + display: ("display".to_string(), 14..21), + path: ("partialpa".to_string(), 23..32), + infile_ref: None, + full_range: 13..32, + }); let actual = super::get_completable_mdlink(&line.chars().collect(), 32); assert_eq!(actual, expected); - let line = "This is line [display](partialpath)"; // (th) - let expected = Some( - CompletableMDLink { - partial: ("[display](partialpa".to_string(), 13..32), - display: ("display".to_string(), 14..21), - path: ("partialpa".to_string(), 23..32), - infile_ref: None, - full_range: 13..35 - } - ); - + let expected = Some(CompletableMDLink { + partial: ("[display](partialpa".to_string(), 13..32), + display: ("display".to_string(), 14..21), + path: ("partialpa".to_string(), 23..32), + infile_ref: None, + full_range: 13..35, + }); let actual = super::get_completable_mdlink(&line.chars().collect(), 32); assert_eq!(actual, expected); - let line = "[disp](pp) This is line [display](partialpath)"; // (th) - let expected = Some( - CompletableMDLink { - partial: ("[display](partialpa".to_string(), 24..43), - display: ("display".to_string(), 25..32), - path: ("partialpa".to_string(), 34..43), - infile_ref: None, - full_range: 24..46 - } - ); - + let expected = Some(CompletableMDLink { + partial: ("[display](partialpa".to_string(), 24..43), + display: ("display".to_string(), 25..32), + path: ("partialpa".to_string(), 34..43), + infile_ref: None, + full_range: 24..46, + }); let actual = super::get_completable_mdlink(&line.chars().collect(), 43); assert_eq!(actual, expected); - let line = "[disp](pp) This is line [display](partialpath)"; // (th) - let expected = Some( - CompletableMDLink { - partial: ("[display](partialpath".to_string(), 24..45), - display: ("display".to_string(), 25..32), - path: ("partialpath".to_string(), 34..45), - infile_ref: None, - full_range: 24..46 - } - ); - + let expected = Some(CompletableMDLink { + partial: ("[display](partialpath".to_string(), 24..45), + display: ("display".to_string(), 25..32), + path: ("partialpath".to_string(), 34..45), + infile_ref: None, + full_range: 24..46, + }); let actual = super::get_completable_mdlink(&line.chars().collect(), 45); @@ -592,16 +623,13 @@ mod tests { fn test_partial_mdlink_infile_refs() { let line = "This is line [display](partialpa#"; // (th) - let expected = Some( - CompletableMDLink { - partial: ("[display](partialpa#".to_string(), 13..33), - display: ("display".to_string(), 14..21), - path: ("partialpa".to_string(), 23..32), - infile_ref: Some(("".to_string(), 33..33)), - full_range: 13..33 - } - ); - + let expected = Some(CompletableMDLink { + partial: ("[display](partialpa#".to_string(), 13..33), + display: ("display".to_string(), 14..21), + path: ("partialpa".to_string(), 23..32), + infile_ref: Some(("".to_string(), 33..33)), + full_range: 13..33, + }); let actual = super::get_completable_mdlink(&line.chars().collect(), 33); @@ -609,16 +637,13 @@ mod tests { let line = "[disp](pp) This is line [display](partialpath#Display)"; // (th) - let expected = Some( - CompletableMDLink { - partial: ("[display](partialpath#Display".to_string(), 24..53), - display: ("display".to_string(), 25..32), - path: ("partialpath".to_string(), 34..45), - infile_ref: Some(("Display".to_string(), 46..53)), - full_range: 24..54 - } - ); - + let expected = Some(CompletableMDLink { + partial: ("[display](partialpath#Display".to_string(), 24..53), + display: ("display".to_string(), 25..32), + path: ("partialpath".to_string(), 34..45), + infile_ref: Some(("Display".to_string(), 46..53)), + full_range: 24..54, + }); let actual = super::get_completable_mdlink(&line.chars().collect(), 53); @@ -626,16 +651,13 @@ mod tests { let line = "[disp](pp) This is line [display](partialpath#Display)"; // (th) - let expected = Some( - CompletableMDLink { - partial: ("[display](partialpath#Disp".to_string(), 24..50), - display: ("display".to_string(), 25..32), - path: ("partialpath".to_string(), 34..45), - infile_ref: Some(("Disp".to_string(), 46..50)), - full_range: 24..54 - } - ); - + let expected = Some(CompletableMDLink { + partial: ("[display](partialpath#Disp".to_string(), 24..50), + display: ("display".to_string(), 25..32), + path: ("partialpath".to_string(), 34..45), + infile_ref: Some(("Disp".to_string(), 46..50)), + full_range: 24..54, + }); let actual = super::get_completable_mdlink(&line.chars().collect(), 50); @@ -643,15 +665,17 @@ mod tests { } } -fn fuzzy_match(filter_text: &str, items: impl IntoIterator) -> Vec<(T, u32)> { - +fn fuzzy_match( + filter_text: &str, + items: impl IntoIterator, +) -> Vec<(T, u32)> { let mut matcher = Matcher::new(nucleo_matcher::Config::DEFAULT); let matches = pattern::Pattern::parse( filter_text, pattern::CaseMatching::Ignore, Normalization::Smart, ) - .match_list(items, &mut matcher); + .match_list(items, &mut matcher); - return matches + return matches; } diff --git a/src/hover.rs b/src/hover.rs index b85c8ac4..e4ccd492 100644 --- a/src/hover.rs +++ b/src/hover.rs @@ -2,21 +2,28 @@ use std::path::Path; use tower_lsp::lsp_types::{Hover, HoverContents, HoverParams}; -use crate::{ui::{preview_reference, preview_referenceable}, vault::Vault}; +use crate::{ + ui::{preview_reference, preview_referenceable}, + vault::Vault, +}; pub fn hover(vault: &Vault, params: &HoverParams, path: &Path) -> Option { let cursor_position = params.text_document_position_params.position; - - match (vault.select_reference_at_position(path, cursor_position), vault.select_referenceable_at_position(path, cursor_position)) { + match ( + vault.select_reference_at_position(path, cursor_position), + vault.select_referenceable_at_position(path, cursor_position), + ) { (Some(reference), _) => preview_reference(vault, path, reference).map(|markup| Hover { contents: HoverContents::Markup(markup), range: None, }), - (None, Some(referenceable)) => preview_referenceable(vault, &referenceable).map(|markup| Hover { - contents: HoverContents::Markup(markup), - range: None, - }), + (None, Some(referenceable)) => { + preview_referenceable(vault, &referenceable).map(|markup| Hover { + contents: HoverContents::Markup(markup), + range: None, + }) + } _ => None, } } diff --git a/src/ui.rs b/src/ui.rs index 3fb3e04b..a34e3b05 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -3,7 +3,7 @@ use std::{path::Path, time::SystemTime}; use itertools::Itertools; use tower_lsp::lsp_types::{MarkupContent, MarkupKind}; -use crate::vault::{Preview, Reference, Referenceable, Vault, get_obsidian_ref_path}; +use crate::vault::{get_obsidian_ref_path, Preview, Reference, Referenceable, Vault}; fn referenceable_string(vault: &Vault, referenceable: &Referenceable) -> Option { let preview = vault.select_referenceable_preview(referenceable); @@ -20,26 +20,29 @@ fn referenceable_string(vault: &Vault, referenceable: &Referenceable) -> Option< None => "No Preview".into(), }; - let backlinks_preview = match vault.select_references_for_referenceable(referenceable) { - Some(references) => references.into_iter() + Some(references) => references + .into_iter() .flat_map(|(path, reference)| { - let line = String::from_iter(vault.select_line(path, reference.data().range.start.line as isize)?); + let line = String::from_iter( + vault.select_line(path, reference.data().range.start.line as isize)?, + ); let path = get_obsidian_ref_path(&vault.root_dir(), path)?; Some(format!("- `{}`: `{}`", path, line)) // and select indented list }) .join("\n"), - None => format!("No Backlinks") + None => format!("No Backlinks"), }; - - return Some(format!("{}\n\n`...`\n\n---\n\n# Backlinks\n\n{}", written_text_preview, backlinks_preview)) + return Some(format!( + "{}\n\n`...`\n\n---\n\n# Backlinks\n\n{}", + written_text_preview, backlinks_preview + )); } pub fn preview_referenceable( - vault: &Vault, referenceable: &Referenceable, ) -> Option { @@ -59,7 +62,14 @@ pub fn preview_reference( reference: &Reference, ) -> Option { match reference { - WikiFileLink(..) | WikiHeadingLink(..) | WikiIndexedBlockLink(..) | Footnote(_) | MDFileLink(..) | MDHeadingLink(..) | MDIndexedBlockLink(..) | LinkRef(..) => { + WikiFileLink(..) + | WikiHeadingLink(..) + | WikiIndexedBlockLink(..) + | Footnote(_) + | MDFileLink(..) + | MDHeadingLink(..) + | MDIndexedBlockLink(..) + | LinkRef(..) => { let positions = vault.select_referenceable_nodes(None); let referenceable = positions .iter() diff --git a/src/vault/mod.rs b/src/vault/mod.rs index edee0506..d2f84aea 100644 --- a/src/vault/mod.rs +++ b/src/vault/mod.rs @@ -1,9 +1,11 @@ use std::{ + char, collections::{HashMap, HashSet}, hash::Hash, iter, - ops::{Deref, DerefMut, Range, Not}, - path::{Path, PathBuf}, char, time::SystemTime, + ops::{Deref, DerefMut, Not, Range}, + path::{Path, PathBuf}, + time::SystemTime, }; use itertools::Itertools; @@ -217,7 +219,9 @@ impl Vault { let resolved_referenceables_refnames: HashSet = resolved_referenceables .iter() - .filter_map(|resolved| resolved.get_refname(self.root_dir()).as_deref().cloned()) + .filter_map(|resolved| { + resolved.get_refname(self.root_dir()).as_deref().cloned() + }) .collect(); let unresolved = self.select_references(None).map(|references| { @@ -249,7 +253,9 @@ impl Vault { Some(Referenceable::UnresovledIndexedBlock(path, end_path, index)) } - Reference::Tag(..) | Reference::Footnote(..) | Reference::LinkRef(..) => None, + Reference::Tag(..) + | Reference::Footnote(..) + | Reference::LinkRef(..) => None, }) .collect_vec() }); @@ -293,9 +299,11 @@ impl Vault { .filter(|(ref_path, reference)| { referenceable.matches_reference(&self.root_dir, reference, ref_path) }) - .map(|(path, reference)| match std::fs::metadata(path).and_then(|meta| meta.modified()) { - Ok(modified) => (path, reference, modified), - Err(_) => (path, reference, SystemTime::UNIX_EPOCH), + .map(|(path, reference)| { + match std::fs::metadata(path).and_then(|meta| meta.modified()) { + Ok(modified) => (path, reference, modified), + Err(_) => (path, reference, SystemTime::UNIX_EPOCH), + } }) .sorted_by_key(|(_, _, modified)| *modified) .rev() @@ -463,7 +471,7 @@ pub struct MDFile { pub tags: Vec, pub footnotes: Vec, pub path: PathBuf, - pub link_reference_definitions: Vec + pub link_reference_definitions: Vec, } impl MDFile { @@ -482,7 +490,7 @@ impl MDFile { tags, footnotes, path, - link_reference_definitions: link_refs + link_reference_definitions: link_refs, } } } @@ -496,7 +504,7 @@ impl MDFile { tags, footnotes, path: _, - link_reference_definitions + link_reference_definitions, } = self; iter::once(Referenceable::File(&self.path, self)) @@ -519,7 +527,7 @@ impl MDFile { .chain( link_reference_definitions .iter() - .map(|link_ref| Referenceable::LinkRefDef(&self.path, link_ref)) + .map(|link_ref| Referenceable::LinkRefDef(&self.path, link_ref)), ) .collect() } @@ -552,7 +560,7 @@ pub enum Reference { MDHeadingLink(ReferenceData, File, Specialref), MDIndexedBlockLink(ReferenceData, File, Specialref), Footnote(ReferenceData), - LinkRef(ReferenceData) + LinkRef(ReferenceData), } impl Deref for Reference { @@ -581,7 +589,7 @@ impl Reference { MDFileLink(data, ..) => data, MDHeadingLink(data, ..) => data, MDIndexedBlockLink(data, ..) => data, - LinkRef(data, ..) => data + LinkRef(data, ..) => data, } } @@ -595,7 +603,7 @@ impl Reference { MDFileLink(..) => matches!(self, MDFileLink(..)), MDHeadingLink(..) => matches!(self, MDHeadingLink(..)), MDIndexedBlockLink(..) => matches!(self, MDIndexedBlockLink(..)), - LinkRef(..) => matches!(self, LinkRef(..)) + LinkRef(..) => matches!(self, LinkRef(..)), } } @@ -654,35 +662,35 @@ impl Reference { }) .collect_vec(); - let link_ref_references: Vec = if MDLinkReferenceDefinition::new(text).is_empty().not() { - - static LINK_REF_RE: Lazy = - Lazy::new(|| Regex::new(r"([^\[]|^)(?\[(?[^\^][^\[\] ]+)\])([^\]\(\:]|$)").unwrap()); + let link_ref_references: Vec = + if MDLinkReferenceDefinition::new(text).is_empty().not() { + static LINK_REF_RE: Lazy = Lazy::new(|| { + Regex::new(r"([^\[]|^)(?\[(?[^\^][^\[\] ]+)\])([^\]\(\:]|$)") + .unwrap() + }); - let link_ref_references: Vec = LINK_REF_RE - .captures_iter(text) - .par_bridge() - .flat_map( - |capture| match (capture.name("full"), capture.name("index")) { - (Some(full), Some(index)) => Some((full, index)), - _ => None, - }, - ) - .map(|(outer, index)| { - LinkRef(ReferenceData { - reference_text: index.as_str().into(), - range: range_to_position(&Rope::from_str(text), outer.range()), - display_text: None, + let link_ref_references: Vec = LINK_REF_RE + .captures_iter(text) + .par_bridge() + .flat_map( + |capture| match (capture.name("full"), capture.name("index")) { + (Some(full), Some(index)) => Some((full, index)), + _ => None, + }, + ) + .map(|(outer, index)| { + LinkRef(ReferenceData { + reference_text: index.as_str().into(), + range: range_to_position(&Rope::from_str(text), outer.range()), + display_text: None, + }) }) - }) - .collect::>(); - - link_ref_references - } else { - vec![] - }; - + .collect::>(); + link_ref_references + } else { + vec![] + }; wiki_links .into_iter() @@ -717,7 +725,7 @@ impl Reference { &Referenceable::Footnote(path, _footnote) => match self { Footnote(..) => { referenceable.get_refname(root_dir).as_deref() == Some(text) - && path.as_path() == file_path + && path.as_path() == file_path } Tag(_) => false, WikiFileLink(_) => false, @@ -729,8 +737,14 @@ impl Reference { LinkRef(_) => false, }, &Referenceable::File(..) | &Referenceable::UnresovledFile(..) => match self { - MDFileLink(ReferenceData { reference_text: file_ref_text, .. }) - | WikiFileLink(ReferenceData { reference_text: file_ref_text, .. }) => matches_path_or_file(file_ref_text, referenceable.get_refname(root_dir)), + MDFileLink(ReferenceData { + reference_text: file_ref_text, + .. + }) + | WikiFileLink(ReferenceData { + reference_text: file_ref_text, + .. + }) => matches_path_or_file(file_ref_text, referenceable.get_refname(root_dir)), Tag(_) => false, WikiHeadingLink(_, _, _) => false, WikiIndexedBlockLink(_, _, _) => false, @@ -739,21 +753,34 @@ impl Reference { Footnote(_) => false, LinkRef(_) => false, }, - &Referenceable::Heading(.., MDHeading { heading_text: infile_ref, ..}) - | &Referenceable::UnresolvedHeading(.., _, infile_ref) - | &Referenceable::IndexedBlock(.., MDIndexedBlock { index: infile_ref, ..}) - | &Referenceable::UnresovledIndexedBlock(.., infile_ref) => match self { - WikiHeadingLink(.., file_ref_text, link_infile_ref) - | WikiIndexedBlockLink(.., file_ref_text, link_infile_ref) - | MDHeadingLink(.., file_ref_text, link_infile_ref) - | MDIndexedBlockLink(.., file_ref_text, link_infile_ref) => - matches_path_or_file(file_ref_text, referenceable.get_refname(root_dir)) && link_infile_ref == infile_ref, - Tag(_) => false, - WikiFileLink(_) => false, - MDFileLink(_) => false, - Footnote(_) => false, - LinkRef(_) => false, + &Referenceable::Heading( + .., + MDHeading { + heading_text: infile_ref, + .. + }, + ) + | &Referenceable::UnresolvedHeading(.., _, infile_ref) + | &Referenceable::IndexedBlock( + .., + MDIndexedBlock { + index: infile_ref, .. }, + ) + | &Referenceable::UnresovledIndexedBlock(.., infile_ref) => match self { + WikiHeadingLink(.., file_ref_text, link_infile_ref) + | WikiIndexedBlockLink(.., file_ref_text, link_infile_ref) + | MDHeadingLink(.., file_ref_text, link_infile_ref) + | MDIndexedBlockLink(.., file_ref_text, link_infile_ref) => { + matches_path_or_file(file_ref_text, referenceable.get_refname(root_dir)) + && link_infile_ref == infile_ref + } + Tag(_) => false, + WikiFileLink(_) => false, + MDFileLink(_) => false, + Footnote(_) => false, + LinkRef(_) => false, + }, Referenceable::LinkRefDef(path, _link_ref) => match self { Tag(_) => false, WikiFileLink(_) => false, @@ -763,8 +790,15 @@ impl Reference { MDHeadingLink(_, _, _) => false, MDIndexedBlockLink(_, _, _) => false, Footnote(_) => false, - LinkRef(data) => Some(data.reference_text.to_lowercase()) == referenceable.get_refname(root_dir).as_deref().map(|string| string.to_lowercase()) && file_path == *path - } + LinkRef(data) => { + Some(data.reference_text.to_lowercase()) + == referenceable + .get_refname(root_dir) + .as_deref() + .map(|string| string.to_lowercase()) + && file_path == *path + } + }, } } } @@ -784,14 +818,14 @@ impl RegexTuple<'_> { capture.name("infileref"), capture.name("display"), ) { - (Some(range), Some(file_path), infile_ref, display_text) => Some(RegexTuple { - range, - file_path, - infile_ref, - display_text, - }), - _ => None, - } + (Some(range), Some(file_path), infile_ref, display_text) => Some(RegexTuple { + range, + file_path, + infile_ref, + display_text, + }), + _ => None, + } } } @@ -831,11 +865,11 @@ impl ParseableReferenceConstructor for MDReferenceConstructor { fn generic_link_constructor( text: &str, RegexTuple { - range, - file_path, - infile_ref, - display_text, -}: RegexTuple, + range, + file_path, + infile_ref, + display_text, + }: RegexTuple, ) -> Reference { match (range, file_path, infile_ref, display_text) { // Pure file reference as there is no infileref such as #... for headings or #^... for indexed blocks @@ -855,7 +889,7 @@ fn generic_link_constructor( }, filepath.as_str(), &infile.as_str()[1..], // drop the ^ for the index - ) + ); } (full, filepath, Some(infile), display) => { return T::new_heading( @@ -922,7 +956,7 @@ impl From for MyRange { impl MDHeading { fn new(text: &str) -> Vec { static HEADING_RE: Lazy = - Lazy::new(|| Regex::new(r"(?#+) (?.+)").unwrap()); + Lazy::new(|| Regex::new(r"(?#+) (?.+)").unwrap()); let headings: Vec = HEADING_RE .captures_iter(text) @@ -960,7 +994,7 @@ impl Hash for MDIndexedBlock { impl MDIndexedBlock { fn new(text: &str) -> Vec { static INDEXED_BLOCK_RE: Lazy = - Lazy::new(|| Regex::new(r".+ (\^(?\w+))").unwrap()); + Lazy::new(|| Regex::new(r".+ (\^(?\w+))").unwrap()); let indexed_blocks: Vec = INDEXED_BLOCK_RE .captures_iter(text) @@ -996,7 +1030,7 @@ impl MDFootnote { fn new(text: &str) -> Vec { // static FOOTNOTE_RE: Lazy = Lazy::new(|| Regex::new(r".+ (\^(?\w+))").unwrap()); static FOOTNOTE_RE: Lazy = - Lazy::new(|| Regex::new(r"\[(?\^[^ \[\]]+)\]\:(?.+)").unwrap()); + Lazy::new(|| Regex::new(r"\[(?\^[^ \[\]]+)\]\:(?.+)").unwrap()); let footnotes: Vec = FOOTNOTE_RE .captures_iter(text) @@ -1032,7 +1066,7 @@ impl Hash for MDTag { impl MDTag { fn new(text: &str) -> Vec { static TAG_RE: Lazy = - Lazy::new(|| Regex::new(r"(\n|\A| )(?#(?[.[^ \n\#]]+))(\n|\z| )").unwrap()); + Lazy::new(|| Regex::new(r"(\n|\A| )(?#(?[.[^ \n\#]]+))(\n|\z| )").unwrap()); let tagged_blocks = TAG_RE .captures_iter(text) @@ -1051,42 +1085,39 @@ impl MDTag { } } - #[derive(Clone, Hash, Eq, PartialEq, Debug)] pub struct MDLinkReferenceDefinition { pub link_ref_name: String, pub range: MyRange, pub url: String, - pub title: Option + pub title: Option, } impl MDLinkReferenceDefinition { fn new(text: &str) -> Vec { static REGEX: Lazy = - Lazy::new(|| Regex::new(r"\[(?[^\^][^ \[\]]+)\]\:(?.+)").unwrap()); + Lazy::new(|| Regex::new(r"\[(?[^\^][^ \[\]]+)\]\:(?.+)").unwrap()); let result = REGEX .captures_iter(text) .flat_map(|c| match (c.get(0), c.name("index"), c.name("text")) { (Some(full), Some(index), Some(text)) => Some((full, index, text)), - _ => None + _ => None, + }) + .flat_map(|(full, index, url)| { + Some(MDLinkReferenceDefinition { + link_ref_name: index.as_str().to_string(), + range: range_to_position(&Rope::from_str(&text), full.range()), + url: url.as_str().trim().to_string(), + title: None, + }) }) - .flat_map(|(full, index, url)| Some(MDLinkReferenceDefinition { - link_ref_name: index.as_str().to_string(), - range: range_to_position(&Rope::from_str(&text), full.range()), - url: url.as_str().trim().to_string(), - title: None - }) ) .collect_vec(); - return result - - + return result; } } - - #[derive(Debug, Clone, Eq, PartialEq, Hash)] /** An Algebreic type for methods for all referenceables, which are anything able to be referenced through obsidian link or tag. These include @@ -1105,7 +1136,7 @@ pub enum Referenceable<'a> { UnresovledFile(PathBuf, &'a String), UnresolvedHeading(PathBuf, &'a String, &'a String), UnresovledIndexedBlock(PathBuf, &'a String, &'a String), - LinkRefDef(&'a PathBuf, &'a MDLinkReferenceDefinition) + LinkRefDef(&'a PathBuf, &'a MDLinkReferenceDefinition), } /// Utility function @@ -1113,12 +1144,11 @@ pub fn get_obsidian_ref_path(root_dir: &Path, path: &Path) -> Option { diff_paths(path, root_dir).and_then(|diff| diff.with_extension("").to_str().map(String::from)) } - #[derive(Debug, PartialEq, Eq, Default)] pub struct Refname { pub full_refname: String, pub path: Option, - pub infile_ref: Option + pub infile_ref: Option, } impl Deref for Refname { @@ -1130,14 +1160,19 @@ impl Deref for Refname { impl From for Refname { fn from(value: String) -> Self { - Refname{full_refname: value.clone(), ..Default::default()} + Refname { + full_refname: value.clone(), + ..Default::default() + } } } - impl From<&str> for Refname { fn from(value: &str) -> Self { - Refname{full_refname: value.to_string(), ..Default::default()} + Refname { + full_refname: value.to_string(), + ..Default::default() + } } } @@ -1146,35 +1181,65 @@ impl Referenceable<'_> { pub fn get_refname(&self, root_dir: &Path) -> Option { match self { - Referenceable::File(path, _) => get_obsidian_ref_path(root_dir, path).map(|string| Refname{full_refname: string.to_owned(), path: string.to_owned().into(), ..Default::default()}), + Referenceable::File(path, _) => { + get_obsidian_ref_path(root_dir, path).map(|string| Refname { + full_refname: string.to_owned(), + path: string.to_owned().into(), + ..Default::default() + }) + } Referenceable::Heading(path, heading) => get_obsidian_ref_path(root_dir, path) - .map(|refpath| (refpath.clone(), format!("{}#{}", refpath, heading.heading_text))) - .map(|(path, full_refname)| Refname{full_refname, path: path.into(), infile_ref: ::clone(&heading.heading_text).into()}), - + .map(|refpath| { + ( + refpath.clone(), + format!("{}#{}", refpath, heading.heading_text), + ) + }) + .map(|(path, full_refname)| Refname { + full_refname, + path: path.into(), + infile_ref: ::clone(&heading.heading_text).into(), + }), Referenceable::IndexedBlock(path, index) => get_obsidian_ref_path(root_dir, path) .map(|refpath| (refpath.clone(), format!("{}#^{}", refpath, index.index))) - .map(|(path, full_refname)| Refname{full_refname, path: path.into(), infile_ref: format!("^{}", index.index).into()}), + .map(|(path, full_refname)| Refname { + full_refname, + path: path.into(), + infile_ref: format!("^{}", index.index).into(), + }), Referenceable::Tag(_, tag) => Some(format!("#{}", tag.tag_ref).into()), Referenceable::Footnote(_, footnote) => Some(footnote.index.clone().into()), Referenceable::UnresolvedHeading(_, path, heading) => { - Some(format!("{}#{}", path, heading)) - .map(|full_ref| Refname { full_refname: full_ref, path: path.to_string().into(), infile_ref: heading.to_string().into()}) - }, - - Referenceable::UnresovledFile(_, path) => Some(Refname{full_refname: path.to_string(), path: Some(path.to_string()), ..Default::default()}), + Some(format!("{}#{}", path, heading)).map(|full_ref| Refname { + full_refname: full_ref, + path: path.to_string().into(), + infile_ref: heading.to_string().into(), + }) + } + Referenceable::UnresovledFile(_, path) => Some(Refname { + full_refname: path.to_string(), + path: Some(path.to_string()), + ..Default::default() + }), Referenceable::UnresovledIndexedBlock(_, path, index) => { - Some(format!("{}#^{}", path, index)) - .map(|full_ref| Refname{full_refname: full_ref, path: path.to_string().into(), infile_ref: format!("^{}", index.to_string()).into()} ) - }, - Referenceable::LinkRefDef(_, refdef) => Some(Refname{full_refname: refdef.link_ref_name.clone(), infile_ref: None, path: None}) - + Some(format!("{}#^{}", path, index)).map(|full_ref| Refname { + full_refname: full_ref, + path: path.to_string().into(), + infile_ref: format!("^{}", index.to_string()).into(), + }) + } + Referenceable::LinkRefDef(_, refdef) => Some(Refname { + full_refname: refdef.link_ref_name.clone(), + infile_ref: None, + path: None, + }), } } @@ -1188,17 +1253,17 @@ impl Referenceable<'_> { match &self { Referenceable::Tag(_, _) => { matches!(reference, Tag(_)) - && self.get_refname(root_dir).is_some_and(|refname| { - let refname_split = refname.split('/').collect_vec(); - let text_split = text.split('/').collect_vec(); + && self.get_refname(root_dir).is_some_and(|refname| { + let refname_split = refname.split('/').collect_vec(); + let text_split = text.split('/').collect_vec(); - return text_split.get(0..refname_split.len()) == Some(&refname_split); - }) + return text_split.get(0..refname_split.len()) == Some(&refname_split); + }) } Referenceable::Footnote(path, _footnote) => match reference { Footnote(..) => { self.get_refname(root_dir).as_deref() == Some(text) - && path.as_path() == reference_path + && path.as_path() == reference_path } MDFileLink(..) => false, Tag(_) => false, @@ -1214,29 +1279,25 @@ impl Referenceable<'_> { reference_text: file_ref_text, .. }) - | WikiHeadingLink(.., file_ref_text, _) - | WikiIndexedBlockLink(.., file_ref_text, _) - | MDFileLink(ReferenceData { + | WikiHeadingLink(.., file_ref_text, _) + | WikiIndexedBlockLink(.., file_ref_text, _) + | MDFileLink(ReferenceData { reference_text: file_ref_text, .. }) - | MDHeadingLink(.., file_ref_text, _) - | MDIndexedBlockLink(.., file_ref_text, _) => { - matches_path_or_file(file_ref_text, self.get_refname(root_dir)) - } + | MDHeadingLink(.., file_ref_text, _) + | MDIndexedBlockLink(.., file_ref_text, _) => { + matches_path_or_file(file_ref_text, self.get_refname(root_dir)) + } Tag(_) => false, Footnote(_) => false, - LinkRef(_) => false + LinkRef(_) => false, }, - _ => reference.references(root_dir, reference_path, self) - - + _ => reference.references(root_dir, reference_path, self), } } - - pub fn get_path(&self) -> &Path { match self { Referenceable::File(path, _) => path, @@ -1247,7 +1308,7 @@ impl Referenceable<'_> { Referenceable::UnresovledIndexedBlock(path, ..) => path, Referenceable::UnresovledFile(path, ..) => path, Referenceable::UnresolvedHeading(path, ..) => path, - Referenceable::LinkRefDef(path, ..) => path + Referenceable::LinkRefDef(path, ..) => path, } } @@ -1264,7 +1325,7 @@ impl Referenceable<'_> { character: 1, }, } - .into(), + .into(), ), Referenceable::Heading(_, heading) => Some(heading.range), Referenceable::IndexedBlock(_, indexed_block) => Some(indexed_block.range), @@ -1272,8 +1333,8 @@ impl Referenceable<'_> { Referenceable::Footnote(_, footnote) => Some(footnote.range), Referenceable::LinkRefDef(_, refdef) => Some(refdef.range), Referenceable::UnresovledFile(..) - | Referenceable::UnresolvedHeading(..) - | Referenceable::UnresovledIndexedBlock(..) => None, + | Referenceable::UnresolvedHeading(..) + | Referenceable::UnresovledIndexedBlock(..) => None, } } @@ -1281,35 +1342,33 @@ impl Referenceable<'_> { matches!( self, Referenceable::UnresolvedHeading(..) - | Referenceable::UnresovledFile(..) - | Referenceable::UnresovledIndexedBlock(..) + | Referenceable::UnresovledFile(..) + | Referenceable::UnresovledIndexedBlock(..) ) } } - fn matches_path_or_file(file_ref_text: &str, refname: Option) -> bool { (|| { let refname_path = refname?.path?; // this function should not be used for tags, ... only for heading, files, indexed blocks - if file_ref_text.contains('/') { - let file_ref_text = file_ref_text.replace(r"%20", " "); let file_ref_text = file_ref_text.replace(r"\ ", " "); - - let chars: Vec = String::from(file_ref_text).chars().collect(); match chars.as_slice() { - &['.', '/', ref path @ ..] | &['/', ref path @ ..] => Some(String::from_iter(path) == refname_path), - path @ _ => Some( String::from_iter(path) == refname_path ) + &['.', '/', ref path @ ..] | &['/', ref path @ ..] => { + Some(String::from_iter(path) == refname_path) + } + path @ _ => Some(String::from_iter(path) == refname_path), } } else { let last_segment = refname_path.split('/').last()?; Some(file_ref_text == last_segment) } - })().is_some_and(|b| b) + })() + .is_some_and(|b| b) } // tests @@ -1319,8 +1378,8 @@ mod vault_tests { use tower_lsp::lsp_types::{Position, Range}; - use crate::vault::{Refname, MDLinkReferenceDefinition}; use crate::vault::{HeadingLevel, ReferenceData}; + use crate::vault::{MDLinkReferenceDefinition, Refname}; use super::Reference::*; use super::Vault; @@ -1344,7 +1403,7 @@ mod vault_tests { character: 18, }, } - .into(), + .into(), ..ReferenceData::default() }), WikiFileLink(ReferenceData { @@ -1359,7 +1418,7 @@ mod vault_tests { character: 29, }, } - .into(), + .into(), ..ReferenceData::default() }), WikiFileLink(ReferenceData { @@ -1374,7 +1433,7 @@ mod vault_tests { character: 10, }, } - .into(), + .into(), ..ReferenceData::default() }), ]; @@ -1387,8 +1446,8 @@ mod vault_tests { let text = "This is a [[link#heading]]"; let parsed = Reference::new(text); - let expected = vec![ - WikiHeadingLink(ReferenceData { + let expected = vec![WikiHeadingLink( + ReferenceData { reference_text: "link#heading".into(), range: tower_lsp::lsp_types::Range { start: tower_lsp::lsp_types::Position { @@ -1400,10 +1459,12 @@ mod vault_tests { character: 26, }, } - .into(), + .into(), ..ReferenceData::default() - }, "link".into(), "heading".into()), - ]; + }, + "link".into(), + "heading".into(), + )]; assert_eq!(parsed, expected) } @@ -1413,8 +1474,8 @@ mod vault_tests { let text = "This is a [[link#^index1]]"; let parsed = Reference::new(text); - let expected = vec![ - WikiIndexedBlockLink(ReferenceData { + let expected = vec![WikiIndexedBlockLink( + ReferenceData { reference_text: "link#^index1".into(), range: tower_lsp::lsp_types::Range { start: tower_lsp::lsp_types::Position { @@ -1426,10 +1487,12 @@ mod vault_tests { character: 26, }, } - .into(), + .into(), ..ReferenceData::default() - }, "link".into(), "index1".into()), - ]; + }, + "link".into(), + "index1".into(), + )]; assert_eq!(parsed, expected) } @@ -1452,7 +1515,7 @@ mod vault_tests { character: 39, }, } - .into(), + .into(), display_text: Some("but called different".into()), }), WikiFileLink(ReferenceData { @@ -1467,7 +1530,7 @@ mod vault_tests { character: 54, }, } - .into(), + .into(), display_text: Some("222".into()), }), WikiFileLink(ReferenceData { @@ -1482,7 +1545,7 @@ mod vault_tests { character: 14, }, } - .into(), + .into(), display_text: Some("333".into()), }), ]; @@ -1509,7 +1572,7 @@ mod vault_tests { character: 40, }, } - .into(), + .into(), })]; assert_eq!(parsed, expected); @@ -1531,7 +1594,7 @@ mod vault_tests { character: 42, }, } - .into(), + .into(), })]; assert_eq!(parsed, expected); @@ -1553,36 +1616,33 @@ mod vault_tests { character: 45, }, } - .into(), + .into(), })]; assert_eq!(parsed, expected) } - #[test] fn advanced_md_link_parsing() { let text = "Test text test text [link]()"; let parsed = Reference::new(text); - let expected = vec![Reference::MDFileLink( - ReferenceData { - reference_text: "path to/link".into(), - display_text: Some("link".into()), - range: Range { - start: Position { - line: 0, - character: 20, - }, - end: Position { - line: 0, - character: 42, - }, - } - .into(), - }, - )]; + let expected = vec![Reference::MDFileLink(ReferenceData { + reference_text: "path to/link".into(), + display_text: Some("link".into()), + range: Range { + start: Position { + line: 0, + character: 20, + }, + end: Position { + line: 0, + character: 42, + }, + } + .into(), + })]; assert_eq!(parsed, expected); @@ -1604,7 +1664,7 @@ mod vault_tests { character: 53, }, } - .into(), + .into(), }, "path/to/link".into(), "heading".into(), @@ -1633,7 +1693,7 @@ mod vault_tests { character: 48, }, } - .into(), + .into(), }, "path/to/link".into(), "heading".into(), @@ -1659,7 +1719,7 @@ mod vault_tests { character: 51, }, } - .into(), + .into(), }, "path/to/link".into(), "heading".into(), @@ -1688,7 +1748,7 @@ mod vault_tests { character: 48, }, } - .into(), + .into(), }, "path/to/link".into(), "index1".into(), @@ -1714,7 +1774,7 @@ mod vault_tests { character: 51, }, } - .into(), + .into(), }, "path/to/link".into(), "index1".into(), @@ -1741,7 +1801,7 @@ mod vault_tests { character: 22, }, } - .into(), + .into(), ..ReferenceData::default() })]; @@ -1786,7 +1846,7 @@ more text character: 19, }, } - .into(), + .into(), ..Default::default() }, MDHeading { @@ -1801,7 +1861,7 @@ more text character: 28, }, } - .into(), + .into(), level: HeadingLevel(2), }, ]; @@ -1839,7 +1899,14 @@ more text let root_dir = Path::new("/home/vault"); let refname = linkable.get_refname(root_dir); - assert_eq!(refname, Some(Refname{full_refname: "test".into(), path: "test".to_string().into(), ..Default::default()})) + assert_eq!( + refname, + Some(Refname { + full_refname: "test".into(), + path: "test".to_string().into(), + ..Default::default() + }) + ) } #[test] @@ -1856,7 +1923,14 @@ more text let root_dir = Path::new("/home/vault"); let refname = linkable.get_refname(root_dir); - assert_eq!(refname, Some(Refname {full_refname: "test#Test Heading".to_string(), path: Some("test".to_string()), infile_ref: Some("Test Heading".to_string())})) + assert_eq!( + refname, + Some(Refname { + full_refname: "test#Test Heading".to_string(), + path: Some("test".to_string()), + infile_ref: Some("Test Heading".to_string()) + }) + ) } #[test] @@ -1872,7 +1946,14 @@ more text let root_dir = Path::new("/home/vault"); let refname = linkable.get_refname(root_dir); - assert_eq!(refname, Some(Refname {full_refname: "test#^12345".into(), path: Some("test".into()), infile_ref: "^12345".to_string().into()})) + assert_eq!( + refname, + Some(Refname { + full_refname: "test#^12345".into(), + path: Some("test".into()), + infile_ref: "^12345".to_string().into() + }) + ) } #[test] @@ -1893,7 +1974,7 @@ more text character: 18, }, } - .into(), + .into(), ..ReferenceData::default() }), WikiFileLink(ReferenceData { @@ -1908,7 +1989,7 @@ more text character: 29, }, } - .into(), + .into(), ..ReferenceData::default() }), WikiFileLink(ReferenceData { @@ -1923,7 +2004,7 @@ more text character: 10, }, } - .into(), + .into(), ..ReferenceData::default() }), ]; @@ -1968,7 +2049,7 @@ and a third tag#notatag [[link#not a tag]] character: 14, }, } - .into(), + .into(), }, MDTag { tag_ref: "tag/ttagg".into(), @@ -1982,7 +2063,7 @@ and a third tag#notatag [[link#not a tag]] character: 22, }, } - .into(), + .into(), }, MDTag { tag_ref: "MapOfContext/apworld".into(), @@ -1996,7 +2077,7 @@ and a third tag#notatag [[link#not a tag]] character: 21, }, } - .into(), + .into(), }, ]; @@ -2022,7 +2103,7 @@ and a third tag#notatag [[link#not a tag]] character: 24, }, } - .into(), + .into(), }]; assert_eq!(parsed, expected); @@ -2053,7 +2134,7 @@ Continued character: 19, }, } - .into(), + .into(), }, MDFootnote { index: "^2".into(), @@ -2068,7 +2149,7 @@ Continued character: 22, }, } - .into(), + .into(), }, MDFootnote { index: "^a".into(), @@ -2083,14 +2164,13 @@ Continued character: 19, }, } - .into(), + .into(), }, ]; assert_eq!(parsed, expected) } - #[test] fn parse_link_ref_def() { let text = "[ab]: ohreally"; @@ -2111,14 +2191,12 @@ Continued character: 14, }, } - .into(), + .into(), }]; - assert_eq!(parsed, expected); } - #[test] fn parse_link_ref() { let text = "This is a [link]j\n\n[link]: linktext"; @@ -2137,11 +2215,10 @@ Continued character: 16, }, } - .into(), + .into(), ..ReferenceData::default() })]; assert_eq!(parsed, expected); } - }