summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Isidoro <denis.isidoro@uber.com>2020-09-11 11:59:34 -0300
committerDenis Isidoro <denis.isidoro@uber.com>2020-09-11 11:59:34 -0300
commit566f7c9f2c09ce1a577a8b8621a123c151fdb220 (patch)
tree3dd22b45c9bf2c9acbb5dd2c0438adf89951b811
parent579eef7c74e843bed2fc7d35da87bef2ff7d7844 (diff)
Revamp preview window for argument selection (#398)v2.11.0
-rw-r--r--Cargo.lock2
-rw-r--r--Cargo.toml2
-rw-r--r--src/cmds/alfred.rs4
-rw-r--r--src/cmds/core.rs117
-rw-r--r--src/cmds/preview.rs7
-rw-r--r--src/common/clipboard.rs4
-rw-r--r--src/common/url.rs4
-rw-r--r--src/display/terminal.rs117
-rw-r--r--src/env_vars.rs18
-rw-r--r--src/finder.rs12
-rw-r--r--src/handler.rs6
-rw-r--r--src/lib.rs1
-rw-r--r--src/structures/config.rs19
-rw-r--r--tests/core.bash2
14 files changed, 231 insertions, 84 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 34501da..fef4774 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -172,7 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "navi"
-version = "2.10.0"
+version = "2.11.0"
dependencies = [
"anyhow 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"dirs 3.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/Cargo.toml b/Cargo.toml
index 094eca2..3865ccf 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "navi"
-version = "2.10.0"
+version = "2.11.0"
authors = ["Denis Isidoro <denis_isidoro@live.com>"]
edition = "2018"
description = "An interactive cheatsheet tool for the command-line"
diff --git a/src/cmds/alfred.rs b/src/cmds/alfred.rs
index 9379bae..b541c8d 100644
--- a/src/cmds/alfred.rs
+++ b/src/cmds/alfred.rs
@@ -28,7 +28,7 @@ pub fn main(config: Config) -> Result<(), Error> {
Ok(())
}
-fn prompt_with_suggestions(suggestion: &Suggestion) -> Result<String, Error> {
+fn prompt_finder(suggestion: &Suggestion) -> Result<String, Error> {
let (suggestion_command, _suggestion_opts) = suggestion;
let child = Command::new("bash")
@@ -77,7 +77,7 @@ pub fn suggestions(config: Config, dry_run: bool) -> Result<(), Error> {
display::alfred::print_items_start(Some(varname));
let command = command.context("Invalid command")?;
- let lines = prompt_with_suggestions(command).context("Invalid lines")?;
+ let lines = prompt_finder(command).context("Invalid lines")?;
writer.reset();
diff --git a/src/cmds/core.rs b/src/cmds/core.rs
index d95ac0c..3fcd734 100644
--- a/src/cmds/core.rs
+++ b/src/cmds/core.rs
@@ -2,6 +2,7 @@ use crate::cheatsh;
use crate::common::clipboard;
use crate::common::shell::BashSpawnError;
use crate::display;
+use crate::env_vars;
use crate::fetcher::Fetcher;
use crate::filesystem;
use crate::finder::Finder;
@@ -37,7 +38,7 @@ fn gen_core_finder_opts(config: &Config) -> Result<FinderOpts, Error> {
Ok(opts)
}
-fn extract_from_selections(raw_snippet: &str, is_single: bool) -> Result<(&str, &str, &str), Error> {
+fn extract_from_selections(raw_snippet: &str, is_single: bool) -> Result<(&str, &str, &str, &str), Error> {
let mut lines = raw_snippet.split('\n');
let key = if !is_single {
lines.next().context("Key was promised but not present in `selections`")?
@@ -48,31 +49,65 @@ fn extract_from_selections(raw_snippet: &str, is_single: bool) -> Result<(&str,
let mut parts = lines.next().context("No more parts in `selections`")?.split(display::DELIMITER).skip(3);
let tags = parts.next().unwrap_or("");
- parts.next();
-
+ let comment = parts.next().unwrap_or("");
let snippet = parts.next().unwrap_or("");
- Ok((key, tags, snippet))
+ Ok((key, tags, comment, snippet))
}
-fn prompt_with_suggestions(variable_name: &str, config: &Config, suggestion: &Suggestion, _snippet: String) -> Result<String, Error> {
- let (suggestion_command, suggestion_opts) = suggestion;
+fn prompt_finder(variable_name: &str, config: &Config, suggestion: Option<&Suggestion>, variable_count: usize) -> Result<String, Error> {
+ env::remove_var(env_vars::PREVIEW_COLUMN);
+ env::remove_var(env_vars::PREVIEW_DELIMITER);
+ env::remove_var(env_vars::PREVIEW_MAP);
- let child = Command::new("bash")
- .stdout(Stdio::piped())
- .arg("-c")
- .arg(&suggestion_command)
- .spawn()
- .map_err(|e| BashSpawnError::new(suggestion_command, e))?;
+ let (suggestions, opts) = if let Some(s) = suggestion {
+ let (suggestion_command, suggestion_opts) = s;
- let suggestions = String::from_utf8(child.wait_with_output().context("Failed to wait and collect output from bash")?.stdout)
- .context("Suggestions are invalid utf8")?;
+ if let Some(sopts) = suggestion_opts {
+ if let Some(c) = &sopts.column {
+ env::set_var(env_vars::PREVIEW_COLUMN, c.to_string());
+ }
+ if let Some(d) = &sopts.delimiter {
+ env::set_var(env_vars::PREVIEW_DELIMITER, d);
+ }
+ if let Some(m) = &sopts.map {
+ env::set_var(env_vars::PREVIEW_MAP, m);
+ }
+ }
- let opts = suggestion_opts.clone().unwrap_or_default();
- let opts = FinderOpts {
+ let child = Command::new("bash")
+ .stdout(Stdio::piped())
+ .arg("-c")
+ .arg(&suggestion_command)
+ .spawn()
+ .map_err(|e| BashSpawnError::new(suggestion_command, e))?;
+
+ let text = String::from_utf8(child.wait_with_output().context("Failed to wait and collect output from bash")?.stdout)
+ .context("Suggestions are invalid utf8")?;
+
+ (text, suggestion_opts)
+ } else {
+ ('\n'.to_string(), &None)
+ };
+
+ let mut opts = FinderOpts {
autoselect: !config.get_no_autoselect(),
overrides: config.fzf_overrides_var.clone(),
- prompt: Some(display::terminal::variable_prompt(variable_name)),
- ..opts
+ preview: Some(format!(
+ r#"navi preview-var "$(cat <<NAVIEOF
+{{}}
+NAVIEOF
+)" "$(cat <<NAVIEOF
+{{q}}
+NAVIEOF
+)" "{}""#,
+ variable_name
+ )),
+ preview_window: Some(format!("up:{}", variable_count + 3)),
+ ..opts.clone().unwrap_or_default()
+ };
+
+ if suggestion.is_none() {
+ opts.suggestion_type = SuggestionType::Disabled;
};
let (output, _) = config
@@ -86,45 +121,31 @@ fn prompt_with_suggestions(variable_name: &str, config: &Config, suggestion: &Su
Ok(output)
}
-fn prompt_without_suggestions(variable_name: &str, config: &Config) -> Result<String, Error> {
- let opts = FinderOpts {
- autoselect: false,
- prompt: Some(display::terminal::variable_prompt(variable_name)),
- suggestion_type: SuggestionType::Disabled,
- preview_window: Some("up:1".to_string()),
- ..Default::default()
- };
-
- let (output, _) = config
- .finder
- .call(opts, |_stdin| Ok(None))
- .context("finder was unable to prompt without suggestions")?;
-
- Ok(output)
+fn unique_result_count(results: &[&str]) -> usize {
+ let mut vars = results.to_owned();
+ vars.sort();
+ vars.dedup();
+ vars.len()
}
fn replace_variables_from_snippet(snippet: &str, tags: &str, variables: VariableMap, config: &Config) -> Result<String, Error> {
let mut interpolated_snippet = String::from(snippet);
+ let variables_found: Vec<&str> = display::VAR_REGEX.find_iter(snippet).map(|m| m.as_str()).collect();
+ let variable_count = unique_result_count(&variables_found);
- for captures in display::VAR_REGEX.captures_iter(snippet) {
- let bracketed_variable_name = &captures[0];
+ for bracketed_variable_name in variables_found {
let variable_name = &bracketed_variable_name[1..bracketed_variable_name.len() - 1];
let env_value = env::var(variable_name);
let value = if let Ok(e) = env_value {
e
+ } else if let Some(suggestion) = variables.get_suggestion(&tags, &variable_name) {
+ let mut new_suggestion = suggestion.clone();
+ new_suggestion.0 = replace_variables_from_snippet(&new_suggestion.0, tags, variables.clone(), config)?;
+ prompt_finder(variable_name, &config, Some(&new_suggestion), variable_count)?
} else {
- variables
- .get_suggestion(&tags, &variable_name)
- .ok_or_else(|| anyhow!("No suggestions"))
- .and_then(|suggestion| {
- let mut new_suggestion = suggestion.clone();
- new_suggestion.0 = replace_variables_from_snippet(&new_suggestion.0, tags, variables.clone(), config)?;
-
- prompt_with_suggestions(variable_name, &config, &new_suggestion, interpolated_snippet.clone())
- })
- .or_else(|_| prompt_without_suggestions(variable_name, &config))?
+ prompt_finder(variable_name, &config, None, variable_count)?
};
env::set_var(variable_name, &value);
@@ -166,7 +187,11 @@ pub fn main(config: Config) -> Result<(), Error> {
})
.context("Failed getting selection and variables from finder")?;
- let (key, tags, snippet) = extract_from_selections(&raw_selection[..], config.get_best_match())?;
+ let (key, tags, comment, snippet) = extract_from_selections(&raw_selection, config.get_best_match())?;
+
+ env::set_var(env_vars::PREVIEW_INITIAL_SNIPPET, &snippet);
+ env::set_var(env_vars::PREVIEW_TAGS, &tags);
+ env::set_var(env_vars::PREVIEW_COMMENT, &comment);
let interpolated_snippet = display::with_new_lines(
replace_variables_from_snippet(snippet, tags, variables.expect("No variables received from finder"), &config)
diff --git a/src/cmds/preview.rs b/src/cmds/preview.rs
index 36aa3c2..c540c52 100644
--- a/src/cmds/preview.rs
+++ b/src/cmds/preview.rs
@@ -1,5 +1,7 @@
use crate::display;
+
use anyhow::Error;
+
use std::process;
fn extract_elements(argstr: &str) -> (&str, &str, &str) {
@@ -15,3 +17,8 @@ pub fn main(line: &str) -> Result<(), Error> {
display::terminal::preview(comment, tags, snippet);
process::exit(0)
}
+
+pub fn main_var(selection: &str, query: &str, variable: &str) -> Result<(), Error> {
+ display::terminal::preview_var(selection, query, variable);
+ process::exit(0)
+}
diff --git a/src/common/clipboard.rs b/src/common/clipboard.rs
index 1295afb..12b7c58 100644
--- a/src/common/clipboard.rs
+++ b/src/common/clipboard.rs
@@ -25,9 +25,9 @@ _copy() {
.arg(
format!(
r#"{}
- read -r -d '' x <<'EOF'
+ read -r -d '' x <<'NAVIEOF'
{}
-EOF
+NAVIEOF
echo -n "$x" | _copy"#,
cmd, text
diff --git a/src/common/url.rs b/src/common/url.rs
index a37a49b..0856eb3 100644
--- a/src/common/url.rs
+++ b/src/common/url.rs
@@ -22,9 +22,9 @@ _open_url() {
let cmd = format!(
r#"{}
-read -r -d '' url <<'EOF'
+read -r -d '' url <<'NAVIEOF'
{}
-EOF
+NAVIEOF
_open_url "$url""#,
code, url
diff --git a/src/display/terminal.rs b/src/display/terminal.rs
index 39fe379..d0968e8 100644
--- a/src/display/terminal.rs
+++ b/src/display/terminal.rs
@@ -1,42 +1,35 @@
use crate::common::terminal_width;
use crate::display;
+use crate::env_vars;
+use crate::finder;
use crate::structures::item::Item;
use std::cmp::max;
+use std::collections::HashSet;
use std::env;
+use std::str::FromStr;
use termion::color;
-fn parse_env_var_u8(varname: &str) -> Option<u8> {
+// TODO: extract
+pub fn parse_env_var<T: FromStr>(varname: &str) -> Option<T> {
if let Ok(x) = env::var(varname) {
- x.parse::<u8>().ok()
- } else {
- None
- }
-}
-
-fn parse_env_var_u16(varname: &str) -> Option<u16> {
- if let Ok(x) = env::var(varname) {
- x.parse::<u16>().ok()
+ x.parse::<T>().ok()
} else {
None
}
}
lazy_static! {
- pub static ref TAG_COLOR: color::AnsiValue = color::AnsiValue(parse_env_var_u8("NAVI_TAG_COLOR").unwrap_or(14));
- pub static ref COMMENT_COLOR: color::AnsiValue = color::AnsiValue(parse_env_var_u8("NAVI_COMMENT_COLOR").unwrap_or(4));
- pub static ref SNIPPET_COLOR: color::AnsiValue = color::AnsiValue(parse_env_var_u8("NAVI_SNIPPET_COLOR").unwrap_or(7));
- pub static ref TAG_WIDTH_PERCENTAGE: u16 = parse_env_var_u16("NAVI_TAG_WIDTH").unwrap_or(20);
- pub static ref COMMENT_WIDTH_PERCENTAGE: u16 = parse_env_var_u16("NAVI_COMMENT_WIDTH").unwrap_or(40);
-}
-
-pub fn variable_prompt(varname: &str) -> String {
- format!("{}: ", varname)
+ pub static ref TAG_COLOR: color::AnsiValue = color::AnsiValue(parse_env_var(env_vars::TAG_COLOR).unwrap_or(14));
+ pub static ref COMMENT_COLOR: color::AnsiValue = color::AnsiValue(parse_env_var(env_vars::COMMENT_COLOR).unwrap_or(4));
+ pub static ref SNIPPET_COLOR: color::AnsiValue = color::AnsiValue(parse_env_var(env_vars::SNIPPET_COLOR).unwrap_or(7));
+ pub static ref TAG_WIDTH_PERCENTAGE: u16 = parse_env_var(env_vars::TAG_WIDTH).unwrap_or(20);
+ pub static ref COMMENT_WIDTH_PERCENTAGE: u16 = parse_env_var(env_vars::COMMENT_WIDTH).unwrap_or(40);
}
pub fn preview(comment: &str, tags: &str, snippet: &str) {
println!(
"{comment_color}{comment} {tag_color}{tags} \n{snippet_color}{snippet}",
- comment = format!("# {}", comment),
+ comment = comment.to_string(),
tags = format!("[{}]", tags),
snippet = display::fix_newlines(snippet),
comment_color = color::Fg(*COMMENT_COLOR),
@@ -45,6 +38,90 @@ pub fn preview(comment: &str, tags: &str, snippet: &str) {
);
}
+pub fn wrapped_by_map(text: &str, map: Option<&str>) -> String {
+ if map.is_none() {
+ text.to_string()
+ } else {
+ format!("map({})", text)
+ }
+}
+
+fn get_env_var(name: &str) -> String {
+ if let Ok(v) = env::var(name) {
+ v
+ } else {
+ panic!(format!("{} not set", name))
+ }
+}
+
+pub fn preview_var(selection: &str, query: &str, variable: &str) {
+ let snippet = &get_env_var(env_vars::PREVIEW_INITIAL_SNIPPET);
+ let tags = get_env_var(env_vars::PREVIEW_TAGS);
+ let comment = get_env_var(env_vars::PREVIEW_COMMENT);
+ let column = display::terminal::parse_env_var(env_vars::PREVIEW_COLUMN);
+ let delimiter = env::var(env_vars::PREVIEW_DELIMITER).ok();
+ let map = env::var(env_vars::PREVIEW_MAP).ok();
+
+ let reset = color::Fg(color::Reset);
+ let active_color = color::Fg(*TAG_COLOR);
+ let inactive_color = color::Fg(*COMMENT_COLOR);
+
+ let mut colored_snippet = String::from(snippet);
+ let mut variables = String::from("");
+ let mut visited_vars: HashSet<&str> = HashSet::new();
+
+ for bracketed_variable_name in display::VAR_REGEX.find_iter(snippet).map(|m| m.as_str()) {
+ let variable_name = &bracketed_variable_name[1..bracketed_variable_name.len() - 1];
+
+ if visited_vars.contains(variable_name) {
+ continue;
+ } else {
+ visited_vars.insert(variable_name);
+ }
+
+ let is_current = variable_name == variable;
+ let variable_color = if is_current { active_color } else { inactive_color };
+
+ let value = if is_current {
+ let v = selection.trim_matches('\'');
+ if v.is_empty() { query.trim_matches('\'') } else { v }.to_string()
+ } else if let Ok(v) = env::var(&variable_name) {
+ v
+ } else {
+ "".to_string()
+ };
+
+ let replacement = format!(
+ "{color}{variable}{reset}",
+ color = variable_color,
+ variable = bracketed_variable_name,
+ reset = reset
+ );
+
+ colored_snippet = colored_snippet.replacen(bracketed_variable_name, &replacement, 999);
+
+ variables = format!(
+ "{variables}\n{color}{variable}{reset} = {value}",
+ variables = variables,
+ color = variable_color,
+ variable = variable_name,
+ reset = reset,
+ value = wrapped_by_map(&finder::get_column(value, column, delimiter.as_deref()), map.as_deref())
+ );
+ }
+
+ println!(
+ "{comment_color}{comment} {tag_color}{tags}{reset} \n{snippet}\n{variables}",
+ comment = comment,
+ tags = format!("[{}]", tags),
+ snippet = display::fix_newlines(&colored_snippet),
+ comment_color = color::Fg(*COMMENT_COLOR),
+ tag_color = color::Fg(*TAG_COLOR),
+ variables = variables,
+ reset = reset
+ );
+}
+
fn limit_str(text: &str, length: usize) -> String {
if text.len() > length {
format!("{}…", text.chars().take(length - 1).collect::<String>())
diff --git a/src/env_vars.rs b/src/env_vars.rs
new file mode 100644
index 0000000..0b280ea
--- /dev/null
+++ b/src/env_vars.rs
@@ -0,0 +1,18 @@
+pub const PREVIEW_INITIAL_SNIPPET: &str = "NAVI_PREVIEW_INITIAL_SNIPPET";
+pub const PREVIEW_TAGS: &str = "NAVI_PREVIEW_TAGS";
+pub const PREVIEW_COMMENT: &str = "NAVI_PREVIEW_COMMENT";
+pub const PREVIEW_COLUMN: &str = "NAVI_PREVIEW_COLUMN";
+pub const PREVIEW_DELIMITER: &str = "NAVI_PREVIEW_DELIMITER";
+pub const PREVIEW_MAP: &str = "NAVI_PREVIEW_MAP";
+
+pub const TAG_COLOR: &str = "NAVI_TAG_COLOR";
+pub const COMMENT_COLOR: &str = "NAVI_COMMENT_COLOR";
+pub const SNIPPET_COLOR: &str = "NAVI_SNIPPET_COLOR";
+
+pub const TAG_WIDTH: &str = "NAVI_TAG_WIDTH";
+pub const COMMENT_WIDTH: &str = "NAVI_COMMENT_WIDTH";
+
+pub const PATH: &str = "NAVI_PATH";
+pub const FZF_OVERRIDES: &str = "NAVI_FZF_OVERRIDES";
+pub const FZF_OVERRIDES_VAR: &str = "NAVI_FZF_OVERRIDES_VAR";
+pub const FINDER: &str = "NAVI_FINDER";
diff --git a/src/finder.rs b/src/finder.rs
index b1f7d6b..d35a8ab 100644
--- a/src/finder.rs
+++ b/src/finder.rs
@@ -35,7 +35,8 @@ fn apply_map(text: String, map_fn: Option<String>) -> String {
}
}
-fn get_column(text: String, column: Option<u8>, delimiter: Option<&str>) -> String {
+// TODO: extract
+pub fn get_column(text: String, column: Option<u8>, delimiter: Option<&str>) -> String {
if let Some(c) = column {
let mut result = String::from("");
let re = regex::Regex::new(delimiter.unwrap_or(r"\s\s+")).expect("Invalid regex");
@@ -113,9 +114,14 @@ impl Finder for FinderChoice {
let mut command = Command::new(&finder_str);
let opts = finder_opts.clone();
+ let preview_height = match self {
+ FinderChoice::Skim => 3,
+ _ => 2,
+ };
+
command.args(&[
"--preview-window",
- "up:2",
+ format!("up:{}", preview_height).as_str(),
"--with-nth",
"1,2,3",
"--delimiter",
@@ -135,7 +141,7 @@ impl Finder for FinderChoice {
command.arg("--multi");
}
SuggestionType::Disabled => {
- command.args(&["--print-query", "--no-select-1", "--height", "1"]);
+ command.args(&["--print-query", "--no-select-1"]);
}
SuggestionType::SnippetSelection => {
command.args(&["--expect", "ctrl-y,enter"]);
diff --git a/src/handler.rs b/src/handler.rs
index 9a6a976..b6914be 100644
--- a/src/handler.rs
+++ b/src/handler.rs
@@ -1,5 +1,5 @@
use crate::cmds;
-use crate::structures::config::Command::{Alfred, Fn, Preview, Repo, Widget};
+use crate::structures::config::Command::{Alfred, Fn, Preview, PreviewVar, Repo, Widget};
use crate::structures::config::{AlfredCommand, Config, RepoCommand};
use anyhow::Context;
use anyhow::Error;
@@ -9,7 +9,9 @@ pub fn handle_config(config: Config) -> Result<(), Error> {
None => cmds::core::main(config),
Some(c) => match c {
- Preview { line } => cmds::preview::main(&line[..]),
+ Preview { line } => cmds::preview::main(&line),
+
+ PreviewVar { selection, query, variable } => cmds::preview::main_var(&selection, &query, &variable),
Widget { shell } => cmds::shell::main(&shell).context("Failed to print shell widget code"),
diff --git a/src/lib.rs b/src/lib.rs
index b116e7d..637a826 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -7,6 +7,7 @@ mod cheatsh;
mod cmds;
mod common;
mod display;
+mod env_vars;
mod fetcher;
mod filesystem;
mod finder;
diff --git a/src/structures/config.rs b/src/structures/config.rs
index 2d775f5..317199a 100644
--- a/src/structures/config.rs
+++ b/src/structures/config.rs
@@ -1,3 +1,4 @@
+use crate::env_vars;
use crate::finder::FinderChoice;
use anyhow::Error;
use structopt::{clap::AppSettings, StructOpt};
@@ -37,7 +38,7 @@ EXAMPLES:
#[structopt(setting = AppSettings::AllowLeadingHyphen)]
pub struct Config {
/// List of :-separated paths containing .cheat files
- #[structopt(short, long, env = "NAVI_PATH")]
+ #[structopt(short, long, env = env_vars::PATH)]
pub path: Option<String>,
/// [Experimental] Instead of executing a snippet, saves it to a file
@@ -73,15 +74,15 @@ pub struct Config {
query: Option<String>,
/// finder overrides for cheat selection
- #[structopt(long, env = "NAVI_FZF_OVERRIDES")]
+ #[structopt(long, env = env_vars::FZF_OVERRIDES)]
pub fzf_overrides: Option<String>,
/// finder overrides for variable selection
- #[structopt(long, env = "NAVI_FZF_OVERRIDES_VAR")]
+ #[structopt(long, env = env_vars::FZF_OVERRIDES_VAR)]
pub fzf_overrides_var: Option<String>,
/// which finder application to use
- #[structopt(long, env = "NAVI_FINDER", default_value = "fzf", parse(try_from_str = parse_finder))]
+ #[structopt(long, env = env_vars::FINDER, default_value = "fzf", parse(try_from_str = parse_finder))]
pub finder: FinderChoice,
#[structopt(subcommand)]
@@ -122,6 +123,16 @@ pub enum Command {
/// Selection line
line: String,
},
+ /// Used for fzf's preview window
+ #[structopt(setting = AppSettings::Hidden)]
+ PreviewVar {
+ /// Selection line
+ selection: String,
+ /// Query match
+ query: String,
+ /// Typed text
+ variable: String,
+ },
/// Shows the path for shell widget files
Widget {
/// bash, zsh or fish
diff --git a/tests/core.bash b/tests/core.bash
index fc1f711..865c1fa 100644
--- a/tests/core.bash
+++ b/tests/core.bash
@@ -63,4 +63,4 @@ test::finish() {
log::success "All ${PASSED} tests passed! :)"
exit 0
fi
-} \ No newline at end of file
+}