use std::sync::Arc;
use tab_api::tab::normalize_name;
use super::workspace::{WorkspaceState, WorkspaceTab};
#[derive(Debug, Clone)]
pub struct FuzzyTabsState {
pub tabs: Arc<Vec<WorkspaceTab>>,
}
impl From<WorkspaceState> for FuzzyTabsState {
fn from(workspace: WorkspaceState) -> Self {
Self {
tabs: workspace.tabs,
}
}
}
#[derive(Debug, Clone)]
pub struct FuzzyQueryState {
pub query: String,
pub cursor_index: usize,
}
impl Default for FuzzyQueryState {
fn default() -> Self {
Self {
query: "".to_string(),
cursor_index: 0,
}
}
}
#[derive(Debug, Clone)]
pub struct FuzzyMatchState {
pub total: usize,
pub matches: Vec<FuzzyMatch>,
}
impl Default for FuzzyMatchState {
fn default() -> Self {
Self {
total: 0,
matches: Vec::with_capacity(0),
}
}
}
#[derive(Debug, Clone)]
pub struct FuzzySelectState {
pub index: usize,
pub tab: Arc<TabEntry>,
}
#[derive(Debug, Clone)]
pub struct FuzzyMatch {
pub score: i64,
pub name_indices: Vec<usize>,
pub doc_indices: Vec<usize>,
pub tab: Arc<TabEntry>,
}
#[derive(Debug, Clone)]
pub struct FuzzyOutputEvent {
pub query_state: Arc<FuzzyQueryState>,
pub select_state: Arc<Option<FuzzySelectState>>,
pub matches: Arc<Vec<FuzzyOutputMatch>>,
pub total: usize,
}
#[derive(Debug, Clone)]
pub struct FuzzyOutputMatch {
pub name: Vec<Token>,
pub doc: Option<Vec<Token>>,
}
#[derive(Debug, Clone)]
pub struct FuzzyEntryState {
pub entries: Vec<Arc<TabEntry>>,
}
#[derive(Debug, Clone)]
pub struct TabEntry {
pub name: String,
pub doc: Option<String>,
pub sticky: bool,
}
impl From<&WorkspaceTab> for TabEntry {
fn from(tab: &WorkspaceTab) -> Self {
Self {
name: tab.name.clone(),
doc: tab.doc.clone().map(|mut doc| {
doc.insert(0, '(');
doc.push(')');
doc
}),
sticky: false,
}
}
}
impl TabEntry {
pub fn entry_new(query: &str) -> TabEntry {
let name = normalize_name(query);
let doc = "(new tab)";
TabEntry {
name,
doc: Some(doc.to_string()),
sticky: true,
}
}
pub fn entry_tutorial() -> TabEntry {
let name = "tab/";
let doc = "(write a tab name to get started, or press enter to use this one)";
TabEntry {
name: name.to_string(),
doc: Some(doc.to_string()),
sticky: true,
}
}
pub fn display(&self, doc_index: usize) -> String {
let mut display = self.name.to_string();
while display.len() < doc_index {
display += " ";
}
if let Some(ref doc) = self.doc {
display += "(";
display += doc;
display += ")";
}
display
}
pub fn tab_len<'a>(tabs: impl Iterator<Item = &'a Self>) -> usize {
let max_len = tabs.map(|tab| tab.name.len()).max().map(|len| len + 2);
max_len.unwrap_or(0)
}
}
#[derive(Debug, Clone)]
pub enum Token {
Unmatched(String),
Matched(String),
}
pub enum TokenJoin {
Same(Token),
Different(Token, Token),
}
impl Token {
pub fn join(self, other: Token) -> TokenJoin {
match (self, other) {
(Token::Unmatched(mut a), Token::Unmatched(b)) => {
a += b.as_str();
TokenJoin::Same(Token::Unmatched(a))
}
(Token::Matched(mut a), Token::Matched(b)) => {
a += b.as_str();
TokenJoin::Same(Token::Matched(a))
}
(s, o) => TokenJoin::Different(s, o),
}
}
}