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
This commit is contained in:
sharkdp 2018-08-19 10:49:09 +02:00 committed by David Peter
parent 76be0d3933
commit 1dddce3aa1
2 changed files with 67 additions and 49 deletions

View File

@ -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 You can use `--style=numbers,changes`, for example, to show only Git changes
and line numbers but no grid and no file header. 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/) `bat` uses the excellent [`syntect`](https://github.com/trishume/syntect/)
library for syntax highlighting. `syntect` can read any library for syntax highlighting. `syntect` can read any
[Sublime Text `.sublime-syntax` file](https://www.sublimetext.com/docs/3/syntax.html) [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 syntax definition files:
Create a folder with a syntax highlighting theme:
```bash ```bash
BAT_CONFIG_DIR="$(bat cache --config-dir)" 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" mkdir -p "$BAT_CONFIG_DIR/syntaxes"
cd "$BAT_CONFIG_DIR/syntaxes" cd "$BAT_CONFIG_DIR/syntaxes"
# Download some language definition files, for example: # Put new '.sublime-syntax' language definition files
git clone https://github.com/sublimehq/Packages # in this folder (or its subdirectories), for example:
git clone https://github.com/danro/LESS-sublime git clone https://github.com/tellnobody1/sublime-purescript-syntax
``` ```
Finally, use the following command to parse all these files into a binary Now use the following command to parse these files into a binary cache:
cache:
```bash ```bash
bat cache --init bat cache --init
``` ```
Use `bat --list-languages` and `bat --list-themes` to check if all languages and themes are Finally, use `bat --list-languages` to check if the new languages are available.
available.
If you ever want to go back to the default settings, call: 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 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 ### Using a different pager
`bat` uses the pager that is specified in the `PAGER` environment variable. If this variable is not `bat` uses the pager that is specified in the `PAGER` environment variable. If this variable is not

View File

@ -28,28 +28,32 @@ impl HighlightingAssets {
pub fn from_files(dir: Option<&Path>) -> Result<Self> { pub fn from_files(dir: Option<&Path>) -> Result<Self> {
let source_dir = dir.unwrap_or_else(|| PROJECT_DIRS.config_dir()); let source_dir = dir.unwrap_or_else(|| PROJECT_DIRS.config_dir());
let theme_dir = source_dir.join("themes"); let mut assets = Self::from_binary_unlinked();
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();
Ok(HighlightingAssets { let theme_dir = source_dir.join("themes");
syntax_set,
theme_set, 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<Self> { fn from_cache() -> Result<Self> {
@ -79,9 +83,8 @@ impl HighlightingAssets {
}) })
} }
fn from_binary() -> Self { fn from_binary_unlinked() -> Self {
let mut syntax_set: SyntaxSet = from_binary(include_bytes!("../assets/syntaxes.bin")); let syntax_set: SyntaxSet = from_binary(include_bytes!("../assets/syntaxes.bin"));
syntax_set.link_syntaxes();
let theme_set: ThemeSet = from_binary(include_bytes!("../assets/themes.bin")); let theme_set: ThemeSet = from_binary(include_bytes!("../assets/themes.bin"));
HighlightingAssets { 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<()> { pub fn save(&self, dir: Option<&Path>) -> Result<()> {
let target_dir = dir.unwrap_or_else(|| PROJECT_DIRS.cache_dir()); let target_dir = dir.unwrap_or_else(|| PROJECT_DIRS.cache_dir());
let _ = fs::create_dir(target_dir); let _ = fs::create_dir(target_dir);