mirror of
https://github.com/tealdeer-rs/tealdeer.git
synced 2026-08-09 09:49:10 +02:00
parent
6f91c3a765
commit
b19517097a
7 changed files with 89 additions and 16 deletions
|
|
@ -29,3 +29,5 @@ Options:
|
||||||
-h, --help Print help
|
-h, --help Print help
|
||||||
|
|
||||||
To view the user documentation, please visit https://tealdeer-rs.github.io/tealdeer/.
|
To view the user documentation, please visit https://tealdeer-rs.github.io/tealdeer/.
|
||||||
|
|
||||||
|
To view usage examples, run tldr tldr or tldr tealdeer.
|
||||||
|
|
|
||||||
42
pages/tealdeer.md
Normal file
42
pages/tealdeer.md
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
# tldr
|
||||||
|
|
||||||
|
> This is a builtin page that shows information for your installed tealdeer version.
|
||||||
|
> More information: <https://tealdeer-rs.github.io/tealdeer/>.
|
||||||
|
|
||||||
|
> This page shows tealdeer specific functionality. See tldr tldr for more examples.
|
||||||
|
|
||||||
|
- Render a local markdown file as a tldr page:
|
||||||
|
|
||||||
|
`tldr --render {{path/to/file.md}}`
|
||||||
|
|
||||||
|
- Show the raw markdown source of a page instead of rendering it:
|
||||||
|
|
||||||
|
`tldr --raw {{command}}`
|
||||||
|
|
||||||
|
- Show file and directory paths used by tealdeer:
|
||||||
|
|
||||||
|
`tldr --show-paths`
|
||||||
|
|
||||||
|
- Create an initial config file:
|
||||||
|
|
||||||
|
`tldr --seed-config`
|
||||||
|
|
||||||
|
- Override config file location:
|
||||||
|
|
||||||
|
`tldr --config-path <FILE>`
|
||||||
|
|
||||||
|
- Open a custom page for a command in `$EDITOR` (creates it if it doesn't exist):
|
||||||
|
|
||||||
|
`tldr --edit-page {{command}}`
|
||||||
|
|
||||||
|
- Open a custom patch for a command in `$EDITOR` (appended to the existing page):
|
||||||
|
|
||||||
|
`tldr --edit-patch {{command}}`
|
||||||
|
|
||||||
|
- Clear the local cache:
|
||||||
|
|
||||||
|
`tldr --clear-cache`
|
||||||
|
|
||||||
|
- If auto update is configured, disable it for this run:
|
||||||
|
|
||||||
|
`tldr --no-auto-update`
|
||||||
10
src/cache.rs
10
src/cache.rs
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{
|
use std::{
|
||||||
fs::{self, File},
|
fs::{self, File},
|
||||||
io::{BufReader, Cursor, ErrorKind, Read},
|
io::{Cursor, ErrorKind, Read},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
time::{Duration, SystemTime},
|
time::{Duration, SystemTime},
|
||||||
};
|
};
|
||||||
|
|
@ -277,12 +277,12 @@ impl PageLookupResult {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a buffered reader that sequentially reads from the page and the
|
/// Create a reader that sequentially reads from the page and the
|
||||||
/// patch, as if they were concatenated.
|
/// patch, as if they were concatenated.
|
||||||
///
|
///
|
||||||
/// This will return an error if either the page file or the patch file
|
/// This will return an error if either the page file or the patch file
|
||||||
/// cannot be opened.
|
/// cannot be opened.
|
||||||
pub fn reader(&self) -> Result<BufReader<Box<dyn Read>>> {
|
pub fn reader(&self) -> Result<Box<dyn Read>> {
|
||||||
// Open page file
|
// Open page file
|
||||||
let page_file = File::open(&self.page_path)
|
let page_file = File::open(&self.page_path)
|
||||||
.with_context(|| format!("Could not open page file at {}", self.page_path.display()))?;
|
.with_context(|| format!("Could not open page file at {}", self.page_path.display()))?;
|
||||||
|
|
@ -302,11 +302,11 @@ impl PageLookupResult {
|
||||||
// the page and patch files and that will read them sequentially,
|
// the page and patch files and that will read them sequentially,
|
||||||
// because it avoids the boxing below. However, the performance impact
|
// because it avoids the boxing below. However, the performance impact
|
||||||
// would first need to be shown to be significant using a benchmark.
|
// would first need to be shown to be significant using a benchmark.
|
||||||
Ok(BufReader::new(if let Some(patch_file) = patch_file_opt {
|
Ok(if let Some(patch_file) = patch_file_opt {
|
||||||
Box::new(page_file.chain(&b"\n"[..]).chain(patch_file)) as Box<dyn Read>
|
Box::new(page_file.chain(&b"\n"[..]).chain(patch_file)) as Box<dyn Read>
|
||||||
} else {
|
} else {
|
||||||
Box::new(page_file) as Box<dyn Read>
|
Box::new(page_file) as Box<dyn Read>
|
||||||
}))
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,9 @@ use crate::types::{ColorOptions, PlatformType};
|
||||||
{usage-heading} {usage}
|
{usage-heading} {usage}
|
||||||
|
|
||||||
{all-args}{after-help}",
|
{all-args}{after-help}",
|
||||||
after_help = "To view the user documentation, please visit https://tealdeer-rs.github.io/tealdeer/.",
|
after_help = "To view the user documentation, please visit https://tealdeer-rs.github.io/tealdeer/.
|
||||||
|
|
||||||
|
To view usage examples, run tldr tldr or tldr tealdeer.",
|
||||||
arg_required_else_help = true,
|
arg_required_else_help = true,
|
||||||
help_expected = true,
|
help_expected = true,
|
||||||
group = ArgGroup::new("command_or_file").args(&["command", "render"]),
|
group = ArgGroup::new("command_or_file").args(&["command", "render"]),
|
||||||
|
|
|
||||||
29
src/main.rs
29
src/main.rs
|
|
@ -68,6 +68,8 @@ const APP_INFO: AppInfo = AppInfo {
|
||||||
name: NAME,
|
name: NAME,
|
||||||
author: NAME,
|
author: NAME,
|
||||||
};
|
};
|
||||||
|
static TEALDEER_PAGE: &str =
|
||||||
|
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/pages/tealdeer.md"));
|
||||||
|
|
||||||
/// Clear the cache
|
/// Clear the cache
|
||||||
fn clear_cache(cache: Cache, quietly: bool) -> Result<()> {
|
fn clear_cache(cache: Cache, quietly: bool) -> Result<()> {
|
||||||
|
|
@ -258,8 +260,20 @@ fn try_main(args: Cli, enable_styles: bool) -> Result<ExitCode> {
|
||||||
|
|
||||||
// If a local file was passed in, render it and exit
|
// If a local file was passed in, render it and exit
|
||||||
if let Some(file) = args.render {
|
if let Some(file) = args.render {
|
||||||
let path = PageLookupResult::with_page(file);
|
let reader = PageLookupResult::with_page(file).reader()?;
|
||||||
print_page(&path, args.raw, enable_styles, args.pager, &config)?;
|
print_page(reader, args.raw, enable_styles, args.pager, &config)?;
|
||||||
|
return Ok(ExitCode::SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The tealdeer page is embedded in the binary, no cache needed
|
||||||
|
if command == "tealdeer" {
|
||||||
|
print_page(
|
||||||
|
TEALDEER_PAGE.as_bytes(),
|
||||||
|
args.raw,
|
||||||
|
enable_styles,
|
||||||
|
args.pager,
|
||||||
|
&config,
|
||||||
|
)?;
|
||||||
return Ok(ExitCode::SUCCESS);
|
return Ok(ExitCode::SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -407,7 +421,7 @@ fn try_main(args: Cli, enable_styles: bool) -> Result<ExitCode> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(lookup_result) = cache.find_page(&command) else {
|
let Some(result) = cache.find_page(&command) else {
|
||||||
if !args.quiet {
|
if !args.quiet {
|
||||||
print_warning(
|
print_warning(
|
||||||
enable_styles,
|
enable_styles,
|
||||||
|
|
@ -419,11 +433,16 @@ fn try_main(args: Cli, enable_styles: bool) -> Result<ExitCode> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(ExitCode::FAILURE);
|
return Ok(ExitCode::FAILURE);
|
||||||
};
|
};
|
||||||
|
|
||||||
print_page(&lookup_result, args.raw, enable_styles, args.pager, &config)?;
|
print_page(
|
||||||
|
result.reader()?,
|
||||||
|
args.raw,
|
||||||
|
enable_styles,
|
||||||
|
args.pager,
|
||||||
|
&config,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ExitCode::SUCCESS)
|
Ok(ExitCode::SUCCESS)
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
//! Functions for printing pages to the terminal
|
//! Functions for printing pages to the terminal
|
||||||
|
|
||||||
use std::io::{self, BufRead, Write};
|
use std::io::{self, BufRead, BufReader, Read, Write};
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use yansi::Paint;
|
use yansi::Paint;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cache::PageLookupResult,
|
|
||||||
config::{Config, StyleConfig},
|
config::{Config, StyleConfig},
|
||||||
formatter::{highlight_lines, PageSnippet},
|
formatter::{highlight_lines, PageSnippet},
|
||||||
line_iterator::LineIterator,
|
line_iterator::LineIterator,
|
||||||
|
|
@ -30,14 +29,13 @@ fn configure_pager(enable_styles: bool) {
|
||||||
|
|
||||||
/// Print page by path
|
/// Print page by path
|
||||||
pub fn print_page(
|
pub fn print_page(
|
||||||
lookup_result: &PageLookupResult,
|
reader: impl Read,
|
||||||
enable_markdown: bool,
|
enable_markdown: bool,
|
||||||
enable_styles: bool,
|
enable_styles: bool,
|
||||||
use_pager: bool,
|
use_pager: bool,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// Create reader from file(s)
|
let reader = BufReader::new(reader);
|
||||||
let reader = lookup_result.reader()?;
|
|
||||||
|
|
||||||
// Configure pager if applicable
|
// Configure pager if applicable
|
||||||
if use_pager || config.display.use_pager {
|
if use_pager || config.display.use_pager {
|
||||||
|
|
|
||||||
10
tests/lib.rs
10
tests/lib.rs
|
|
@ -301,6 +301,16 @@ fn test_missing_cache() {
|
||||||
.stderr(contains("Page cache not found. Please run `tldr --update`"));
|
.stderr(contains("Page cache not found. Please run `tldr --update`"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_tealdeer_page_works_without_cache() {
|
||||||
|
TestEnv::new()
|
||||||
|
.command()
|
||||||
|
.args(["tealdeer"])
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout(contains("for your installed tealdeer version"));
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "ignore-online-tests", ignore = "online test")]
|
#[cfg_attr(feature = "ignore-online-tests", ignore = "online test")]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_update_cache_default_features() {
|
fn test_update_cache_default_features() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue