mirror of
https://github.com/denisidoro/navi
synced 2025-02-16 12:38:28 +00:00
parent
5423cd8ccb
commit
3fa141846b
5 changed files with 89 additions and 37 deletions
|
@ -157,6 +157,15 @@ $ branch: git branch | awk '{print $NF}'
|
|||
|
||||
It's irrelevant how many files are used to store cheatsheets. They can be all in a single file if you wish, as long as you split them accordingly with lines starting with `%`.
|
||||
|
||||
Commands may be multiline:
|
||||
```sh
|
||||
# This will output foo\nyes
|
||||
echo foo
|
||||
echo bar | grep q -b \
|
||||
&& echo yes \
|
||||
|| echo no
|
||||
```
|
||||
|
||||
### Variables
|
||||
|
||||
The interface prompts for variable names inside brackets (eg `<branch>`).
|
||||
|
|
72
src/cheat.rs
72
src/cheat.rs
|
@ -31,14 +31,6 @@ pub enum SuggestionType {
|
|||
|
||||
pub type Suggestion = (String, Option<SuggestionOpts>);
|
||||
|
||||
fn gen_snippet(snippet: &str, line: &str) -> String {
|
||||
if snippet.is_empty() {
|
||||
line.to_string()
|
||||
} else {
|
||||
format!("{}{}", &snippet[..snippet.len() - 2], line)
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_quote(txt: &str) -> String {
|
||||
txt.replace('"', "").replace('\'', "")
|
||||
}
|
||||
|
@ -87,6 +79,32 @@ fn parse_variable_line(line: &str) -> (&str, &str, Option<SuggestionOpts>) {
|
|||
(variable, command, command_options)
|
||||
}
|
||||
|
||||
fn write_cmd(
|
||||
tags: &str,
|
||||
comment: &str,
|
||||
snippet: &str,
|
||||
tag_width: usize,
|
||||
comment_width: usize,
|
||||
stdin: &mut std::process::ChildStdin,
|
||||
) -> bool {
|
||||
if snippet.is_empty() {
|
||||
true
|
||||
} else {
|
||||
stdin
|
||||
.write_all(
|
||||
display::format_line(
|
||||
&tags[..],
|
||||
&comment[..],
|
||||
&snippet[3..],
|
||||
tag_width,
|
||||
comment_width,
|
||||
)
|
||||
.as_bytes(),
|
||||
)
|
||||
.is_ok()
|
||||
}
|
||||
}
|
||||
|
||||
fn read_file(
|
||||
path: &str,
|
||||
variables: &mut HashMap<String, Suggestion>,
|
||||
|
@ -104,6 +122,10 @@ fn read_file(
|
|||
|
||||
// tag
|
||||
if line.starts_with('%') {
|
||||
if !write_cmd(&tags, &comment, &snippet, tag_width, comment_width, stdin) {
|
||||
break;
|
||||
}
|
||||
snippet = String::from("");
|
||||
tags = String::from(&line[2..]);
|
||||
}
|
||||
// metacomment
|
||||
|
@ -111,46 +133,36 @@ fn read_file(
|
|||
}
|
||||
// comment
|
||||
else if line.starts_with('#') {
|
||||
if !write_cmd(&tags, &comment, &snippet, tag_width, comment_width, stdin) {
|
||||
break;
|
||||
}
|
||||
snippet = String::from("");
|
||||
comment = String::from(&line[2..]);
|
||||
}
|
||||
// variable
|
||||
else if line.starts_with('$') {
|
||||
if !write_cmd(&tags, &comment, &snippet, tag_width, comment_width, stdin) {
|
||||
break;
|
||||
}
|
||||
snippet = String::from("");
|
||||
let (variable, command, opts) = parse_variable_line(&line);
|
||||
variables.insert(
|
||||
format!("{};{}", tags, variable),
|
||||
(String::from(command), opts),
|
||||
);
|
||||
}
|
||||
// snippet with line break
|
||||
else if line.ends_with('\\') {
|
||||
snippet = if !snippet.is_empty() {
|
||||
format!("{}{}", &snippet[..snippet.len() - 2], line)
|
||||
} else {
|
||||
line
|
||||
}
|
||||
}
|
||||
// blank
|
||||
else if line.is_empty() {
|
||||
}
|
||||
// snippet
|
||||
else {
|
||||
let full_snippet = gen_snippet(&snippet, &line);
|
||||
match stdin.write_all(
|
||||
display::format_line(
|
||||
&tags[..],
|
||||
&comment[..],
|
||||
&full_snippet[..],
|
||||
tag_width,
|
||||
comment_width,
|
||||
)
|
||||
.as_bytes(),
|
||||
) {
|
||||
Ok(_) => snippet = String::from(""),
|
||||
Err(_) => break,
|
||||
}
|
||||
snippet.push_str(display::LINE_SEPARATOR);
|
||||
snippet.push_str(&line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
write_cmd(&tags, &comment, &snippet, tag_width, comment_width, stdin);
|
||||
}
|
||||
|
||||
pub fn read_all(
|
||||
|
|
|
@ -173,6 +173,10 @@ fn replace_variables_from_snippet(
|
|||
interpolated_snippet
|
||||
}
|
||||
|
||||
fn with_new_lines(txt: String) -> String {
|
||||
txt.replace(display::LINE_SEPARATOR, "\n")
|
||||
}
|
||||
|
||||
pub fn main(variant: Variant, config: Config, contains_key: bool) -> Result<(), Box<dyn Error>> {
|
||||
let _ = display::WIDTHS;
|
||||
|
||||
|
@ -181,8 +185,12 @@ pub fn main(variant: Variant, config: Config, contains_key: bool) -> Result<(),
|
|||
});
|
||||
|
||||
let (key, tags, snippet) = extract_from_selections(&raw_selection[..], contains_key);
|
||||
let interpolated_snippet =
|
||||
replace_variables_from_snippet(snippet, tags, variables.unwrap(), &config);
|
||||
let interpolated_snippet = with_new_lines(replace_variables_from_snippet(
|
||||
snippet,
|
||||
tags,
|
||||
variables.unwrap(),
|
||||
&config,
|
||||
));
|
||||
|
||||
if key == "ctrl-y" {
|
||||
cmds::aux::abort("copying snippets to the clipboard", 201)?
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::terminal;
|
||||
|
||||
use regex::Regex;
|
||||
use std::cmp::max;
|
||||
use termion::color;
|
||||
|
||||
|
@ -7,6 +8,8 @@ static COMMENT_COLOR: color::LightCyan = color::LightCyan;
|
|||
static TAG_COLOR: color::Blue = color::Blue;
|
||||
static SNIPPET_COLOR: color::White = color::White;
|
||||
|
||||
static NEWLINE_ESCAPE_CHAR: char = '\x15';
|
||||
pub static LINE_SEPARATOR: &str = " \x15 ";
|
||||
pub static DELIMITER: &str = r" ⠀";
|
||||
|
||||
lazy_static! {
|
||||
|
@ -24,12 +27,22 @@ pub fn variable_prompt(varname: &str) -> String {
|
|||
format!("{}: ", varname)
|
||||
}
|
||||
|
||||
fn fix_newlines(txt: &str) -> String {
|
||||
if txt.contains(NEWLINE_ESCAPE_CHAR) {
|
||||
let re = Regex::new(r"\\\s+").unwrap();
|
||||
re.replace_all(txt.replace(LINE_SEPARATOR, " ").as_str(), "")
|
||||
.to_string()
|
||||
} else {
|
||||
txt.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn preview(comment: &str, tags: &str, snippet: &str) {
|
||||
println!(
|
||||
"{comment_color}{comment} {tag_color}{tags} \n{snippet_color}{snippet}",
|
||||
comment = format!("# {}", comment),
|
||||
tags = format!("[{}]", tags),
|
||||
snippet = snippet,
|
||||
snippet = fix_newlines(snippet),
|
||||
comment_color = color::Fg(COMMENT_COLOR),
|
||||
tag_color = color::Fg(TAG_COLOR),
|
||||
snippet_color = color::Fg(SNIPPET_COLOR),
|
||||
|
@ -47,7 +60,7 @@ fn limit_str(text: &str, length: usize) -> String {
|
|||
pub fn format_line(
|
||||
tags: &str,
|
||||
comment: &str,
|
||||
full_snippet: &str,
|
||||
snippet: &str,
|
||||
tag_width: usize,
|
||||
comment_width: usize,
|
||||
) -> String {
|
||||
|
@ -55,12 +68,12 @@ pub fn format_line(
|
|||
"{tag_color}{tags_short}{delimiter}{comment_color}{comment_short}{delimiter}{snippet_color}{snippet_short}{delimiter}{tags}{delimiter}{comment}{delimiter}{snippet}{delimiter}\n",
|
||||
tags_short = limit_str(tags, tag_width),
|
||||
comment_short = limit_str(comment, comment_width),
|
||||
snippet_short = full_snippet,
|
||||
snippet_short = fix_newlines(snippet),
|
||||
comment_color = color::Fg(COMMENT_COLOR),
|
||||
tag_color = color::Fg(TAG_COLOR),
|
||||
snippet_color = color::Fg(SNIPPET_COLOR),
|
||||
tags = tags,
|
||||
comment = comment,
|
||||
delimiter = DELIMITER,
|
||||
snippet = &full_snippet)
|
||||
snippet = &snippet)
|
||||
}
|
||||
|
|
|
@ -7,4 +7,14 @@ echo -ne "\033]0;$(hostname)\007"
|
|||
echo "8.8.8.8 via 172.17.0.1 dev eth0 src 172.17.0.2" | sed -E 's/.*src ([0-9.]+).*/\1/p' | head -n1
|
||||
|
||||
# simple echo
|
||||
echo "foo"
|
||||
echo "foo"
|
||||
|
||||
# multiline command without backslash
|
||||
echo "foo"
|
||||
echo "bar"
|
||||
|
||||
# multiline command with backslash
|
||||
echo "foo" \
|
||||
| grep -q "bar" \
|
||||
&& echo "match" \
|
||||
|| echo "no match"
|
Loading…
Add table
Reference in a new issue