From 1dddce3aa11818fd641542f5f79c20e5ecb5b837 Mon Sep 17 00:00:00 2001 From: sharkdp Date: Sun, 19 Aug 2018 10:49:09 +0200 Subject: [PATCH] Separate syntax set and theme set This commit separates the handling of syntax sets and theme sets. It also changes the way how new syntax definitions are loaded from `bat`'s configuration folder. New syntax definitions are now loaded *in addition* to the ones that are stored in the `bat` binary by default. This fixes #172 --- README.md | 59 +++++++++++++++++++++++++++++---------------------- src/assets.rs | 57 ++++++++++++++++++++++++++++--------------------- 2 files changed, 67 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 010962d4..865d25b5 100644 --- a/README.md +++ b/README.md @@ -140,50 +140,33 @@ You can use the `--style` option to control the appearance of `bat`s output. You can use `--style=numbers,changes`, for example, to show only Git changes and line numbers but no grid and no file header. -### Add new syntaxes and highlighting themes +### Adding new syntaxes / language definitions `bat` uses the excellent [`syntect`](https://github.com/trishume/syntect/) library for syntax highlighting. `syntect` can read any [Sublime Text `.sublime-syntax` file](https://www.sublimetext.com/docs/3/syntax.html) -and theme. +and theme. To add new syntax definitions, do the following. -To build your own language-set and theme, follow these steps: - -Create a folder with a syntax highlighting theme: +Create a folder with syntax definition files: ```bash BAT_CONFIG_DIR="$(bat cache --config-dir)" -mkdir -p "$BAT_CONFIG_DIR/themes" -cd "$BAT_CONFIG_DIR/themes" - -# Download a theme, for example: -git clone https://github.com/greggb/sublime-snazzy - -# Create a link for the default theme -ln -sf "sublime-snazzy/Sublime Snazzy.tmTheme" Default.tmTheme -``` - -Create a folder with language definition files: - -```bash mkdir -p "$BAT_CONFIG_DIR/syntaxes" cd "$BAT_CONFIG_DIR/syntaxes" -# Download some language definition files, for example: -git clone https://github.com/sublimehq/Packages -git clone https://github.com/danro/LESS-sublime +# Put new '.sublime-syntax' language definition files +# in this folder (or its subdirectories), for example: +git clone https://github.com/tellnobody1/sublime-purescript-syntax ``` -Finally, use the following command to parse all these files into a binary -cache: +Now use the following command to parse these files into a binary cache: ```bash bat cache --init ``` -Use `bat --list-languages` and `bat --list-themes` to check if all languages and themes are -available. +Finally, use `bat --list-languages` to check if the new languages are available. If you ever want to go back to the default settings, call: @@ -191,6 +174,32 @@ If you ever want to go back to the default settings, call: bat cache --clear ``` +### Adding new themes + +This works very similar to how we add new syntax definitions. + +First, create a folder with the new syntax highlighting themes: +```bash +BAT_CONFIG_DIR="$(bat cache --config-dir)" + +mkdir -p "$BAT_CONFIG_DIR/themes" +cd "$BAT_CONFIG_DIR/themes" + +# Download a theme in '.tmTheme' format, for example: +git clone https://github.com/greggb/sublime-snazzy + +# Create a link to specify the new default theme +ln -sf "sublime-snazzy/Sublime Snazzy.tmTheme" Default.tmTheme + +# Update the binary cache +bat cache --init +``` + +Finally, use `bat --list-themes` to check if the new themes are available. + +**Note:** Unlike for syntax definitions, adding custom themes currently *removes all default +themes*. If you want to go back to the default themes, call `bat cache --clear`. + ### Using a different pager `bat` uses the pager that is specified in the `PAGER` environment variable. If this variable is not diff --git a/src/assets.rs b/src/assets.rs index 7cddd186..c497cfa4 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -28,28 +28,32 @@ impl HighlightingAssets { pub fn from_files(dir: Option<&Path>) -> Result { let source_dir = dir.unwrap_or_else(|| PROJECT_DIRS.config_dir()); - let theme_dir = source_dir.join("themes"); - let theme_set = ThemeSet::load_from_folder(&theme_dir).chain_err(|| { - format!( - "Could not load themes from '{}'", - theme_dir.to_string_lossy() - ) - })?; - let mut syntax_set = SyntaxSet::new(); - let syntax_dir = source_dir.join("syntaxes"); - if !syntax_dir.exists() { - return Err(format!( - "Could not load syntaxes from '{}'", - syntax_dir.to_string_lossy() - ).into()); - } - syntax_set.load_syntaxes(syntax_dir, true)?; - syntax_set.load_plain_text_syntax(); + let mut assets = Self::from_binary_unlinked(); - Ok(HighlightingAssets { - syntax_set, - theme_set, - }) + let theme_dir = source_dir.join("themes"); + + if let Ok(theme_set) = ThemeSet::load_from_folder(&theme_dir) { + // TODO: If syntect would support this, it would be great to + // load the new themes in addition to the ones in the binary. + assets.theme_set = theme_set; + } else { + println!( + "No themes were found in '{}', using the default set", + theme_dir.to_string_lossy() + ); + } + + let syntax_dir = source_dir.join("syntaxes"); + if syntax_dir.exists() { + assets.syntax_set.load_syntaxes(syntax_dir, true)?; + } else { + println!( + "No syntaxes were found in '{}', using the default set.", + syntax_dir.to_string_lossy() + ); + } + + Ok(assets) } fn from_cache() -> Result { @@ -79,9 +83,8 @@ impl HighlightingAssets { }) } - fn from_binary() -> Self { - let mut syntax_set: SyntaxSet = from_binary(include_bytes!("../assets/syntaxes.bin")); - syntax_set.link_syntaxes(); + fn from_binary_unlinked() -> Self { + let syntax_set: SyntaxSet = from_binary(include_bytes!("../assets/syntaxes.bin")); let theme_set: ThemeSet = from_binary(include_bytes!("../assets/themes.bin")); HighlightingAssets { @@ -90,6 +93,12 @@ impl HighlightingAssets { } } + fn from_binary() -> Self { + let mut assets = Self::from_binary_unlinked(); + assets.syntax_set.link_syntaxes(); + assets + } + pub fn save(&self, dir: Option<&Path>) -> Result<()> { let target_dir = dir.unwrap_or_else(|| PROJECT_DIRS.cache_dir()); let _ = fs::create_dir(target_dir);