sharkdp/bat

Git config inside $XDG_CONFIG_HOME/git is not highlighted

ahmedelgabri opened this issue · 7 comments

What version of bat are you using?
bat 0.15.4

Describe the bug you encountered:
Git configuration files inside $XDG_CONFIG_HOME/git/{ignore,config,attributes} are not highlighted

From man git-config

FILES
       If not set explicitly with --file, there are four files where git config will search for
       configuration options:

       $(prefix)/etc/gitconfig
           System-wide configuration file.

       $XDG_CONFIG_HOME/git/config
           Second user-specific configuration file. If $XDG_CONFIG_HOME is not set or empty,
           $HOME/.config/git/config will be used. Any single-valued variable set in this file will be
           overwritten by whatever is in ~/.gitconfig. It is a good idea not to create this file if you
           sometimes use older versions of Git, as support for this file was added fairly recently.

       ~/.gitconfig
           User-specific configuration file. Also called "global" configuration file.

       $GIT_DIR/config
           Repository specific configuration file.

       $GIT_DIR/config.worktree
           This is optional and is only searched when extensions.worktreeConfig is present in
           $GIT_DIR/config.

Describe what you expected to happen?
They should be highlighted

How did you install bat?
homebrew


system

$ uname -srm
Darwin 19.6.0 x86_64

$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.6
BuildVersion: 19G2021

bat

$ bat --version
bat 0.15.4

$ env
BAT_CONFIG_PATH=/Users/ahmed/.config/bat/config
PAGER=less

bat_config

$ cat /Users/ahmed/.config/bat/config

--theme="TwoDark"
--style="numbers,changes,header"
--italic-text=always
--map-syntax '.*ignore:Git Ignore'
--map-syntax '.gitconfig.local:Git Config'
--map-syntax '.zsh*:Bourne Again Shell (bash)'
--map-syntax '.vimrc.local:VimL'
--map-syntax 'vimrc:VimL'

bat_wrapper

No wrapper script for 'bat'.

bat_wrapper_function

No wrapper function for 'bat'.

$ /usr/local/bin/zsh --login -i -c type cat

cat is an alias for bat
cat is /usr/local/opt/coreutils/libexec/gnubin/cat
cat is /bin/cat

tool

$ less --version
less 487 (POSIX regular expressions)

Thank you for reporting this.

If we feel this is something that should be fixed inside bat, we could either

  • add an explicit **/git/config => Git Config mapping in src/syntax_mapping.rs.
  • actually look up $XDG_CONFIG_HOME and, if it exists, add a $XDG_CONFIG_HOME/git/config => Git Config mapping to src/syntax_mapping.rs.

For now, you can add

--map-syntax '$XDG_CONFIG_HOME/git/config:Git Config'

to your config file, where you would have to replace $XDG_CONFIG_HOME by the actual value.

@sharkdp I can open a PR but I will need some help with this logic.

  • actually look up $XDG_CONFIG_HOME and, if it exists, add a $XDG_CONFIG_HOME/git/config => Git Config mapping to src/syntax_mapping.rs.

How can I do that? (Rust noob here)

This is the diff I currently have locally

diff --git a/src/syntax_mapping.rs b/src/syntax_mapping.rs
index 96ce7fc..9029c02 100644
--- a/src/syntax_mapping.rs
+++ b/src/syntax_mapping.rs
@@ -101,6 +101,10 @@ impl<'a> SyntaxMapping<'a> {
         // pacman hooks
         mapping.insert("*.hook", MappingTarget::MapTo("INI")).unwrap();
 
+        mapping.insert("$XDG_CONFIG_HOME/git/config", MappingTarget::MapTo("Git Config")).unwrap();
+        mapping.insert("$XDG_CONFIG_HOME/git/ignore", MappingTarget::MapTo("Git Ignore")).unwrap();
+        mapping.insert("$XDG_CONFIG_HOME/git/attributes", MappingTarget::MapTo("Git Attributes")).unwrap();
+
         mapping
     }
 

Also, how to test that with $XDG_CONFIG_HOME, we need to set it before the test & clean up after?

mapping.insert("$XDG_CONFIG_HOME/git/…

this will not work. $… is bash syntax. The variable is not going to be expanded. In Rust, we would use std::env::var_os("XDG_CONFIG_HOME") to get an Optional<OsString>. If it's present, the OsString can be used as a path. We would then add git/… to that path and insert the mappings.

Also, how to test that with $XDG_CONFIG_HOME, we need to set it before the test & clean up after?

Yes. A test for this would be a bit more involved. Cleanup would not be needed as changes to the environment would only be visible to the child bat process that is called from the tests. Check out tests/integration_tests.rs for some tests like this (look out for .env(…, …) calls).

I'm trying something like this but it's not working, is this even the right approach?

if std::env::var_os("XDG_CONFIG_HOME").is_some() {
    let xdg_config_home = std::env::var_os("XDG_CONFIG_HOME").unwrap();

    mapping
        .insert(
            std::env::join_paths([xdg_config_home, Path.new("/git/config")]),
            MappingTarget::MapTo("Git Config"),
        )
        .unwrap();
}

You want Path::join, not join_paths. Also, instead of checking for .is_some() and then .unwrap()-ping, you can use pattern matching. Something like:

if let Some(xdg_config_home) = std::env::var_os("XDG_CONFIG_HOME") {
  mapping
      .insert(
          Path::new(xdg_config_home).join("git").join("config"),
          MappingTarget::MapTo("Git Config"),
      )
      .unwrap();
}

Fixed in v0.16.0.