Skip to content

Commit

Permalink
Separate syntax set and theme set
Browse files Browse the repository at this point in the history
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
  • Loading branch information
sharkdp committed Aug 19, 2018
1 parent 76be0d3 commit 60a1c6f
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 44 deletions.
59 changes: 34 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,57 +140,66 @@ 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:

```bash
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
Expand Down
47 changes: 28 additions & 19 deletions src/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,32 @@ impl HighlightingAssets {
pub fn from_files(dir: Option<&Path>) -> Result<Self> {
let source_dir = dir.unwrap_or_else(|| PROJECT_DIRS.config_dir());

let mut assets = Self::from_binary_unlinked();

let theme_dir = source_dir.join("themes");
let theme_set = ThemeSet::load_from_folder(&theme_dir).chain_err(|| {
format!(
"Could not load themes from '{}'",

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 mut syntax_set = SyntaxSet::new();
);
}

let syntax_dir = source_dir.join("syntaxes");
if !syntax_dir.exists() {
return Err(format!(
"Could not load syntaxes from '{}'",
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()
).into());
);
}
syntax_set.load_syntaxes(syntax_dir, true)?;
syntax_set.load_plain_text_syntax();

Ok(HighlightingAssets {
syntax_set,
theme_set,
})
Ok(assets)
}

fn from_cache() -> Result<Self> {
Expand Down Expand Up @@ -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 {
Expand All @@ -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);
Expand Down

0 comments on commit 60a1c6f

Please sign in to comment.