Giter Club home page Giter Club logo

Comments (5)

eth-p avatar eth-p commented on May 28, 2024 1

Hi @marslo

Your understanding of both of those is correct, yes.

For your issue with bat displaying the file name as "STDIN", you can use the --file-name argument in bat to have it change the name in the header. Let me know if the modified code below works for you:

rg --vimgrep --with-filename 'TODO' --color never |
   cut -d':' -f1 |
   uniq |
   xargs -r -I{} bash -c "sed -ne '/TODO:/,/^\s*$/p' {} |
   bat -l groovy --file-name='{}'"

from bat.

eth-p avatar eth-p commented on May 28, 2024

I think having an extra opt-in command line flag to disable printing the header for binary and/or empty files would be fine. It would be especially useful when using bat in bash scripts, like with what you're doing here.

It's nice to have a feature to setup header manually if content is from stdin to easier identify where the output comes from

The --file-name option may be helpful here. It's even used to detect the language type :)

image


For your specific example of finding TODOs in source code files, ripgrep might be a more performant approach compared to fd+sed:

rg --vimgrep --with-filename 'TODO' | cut -d':' -f1 | uniq | xargs bat

There's also batgrep if you want a bit more of a tailored experience:

image


from bat.

marslo avatar marslo commented on May 28, 2024

Hi @eth-p ,

for me, it's just show ALL contents of files contains TODO, for my understanding:

  • rg --vimgrep --with-filename 'TODO' | cut -d':' -f1 | uniq: list all filepath contains TODO
  • xargs bat: bat all contents

using sed -ne '/TODO:/,/^\s*$/p', means print lines between TODO line to first empty line ^\s*$, since almost of all TODO is added before function, so using sed will show whole function body

base on your example, following commands resolved STDIN <EMPTY> issue:

rg --vimgrep --with-filename 'TODO' --color never |
   cut -d':' -f1 |
   uniq |
   xargs -r -I{} bash -c "sed -ne '/TODO:/,/^\s*$/p' {} |
   bat -l groovy"

However, it still didn't show the exact file name... i.e.:

TODO

here is my batconfig

$ cat ~/.config/bat/config | sed -r '/^(#.*)$/d' | sed -r '/^\s*$/d'
--theme="gruvbox-dark"
--style="numbers,changes,header"
--italic-text=always
--pager="less --RAW-CONTROL-CHARS --quit-if-one-screen --mouse"
--map-syntax "*.ino:C++"
--map-syntax ".ignore:Git Ignore"
--map-syntax='*.conf:INI'
--map-syntax='/etc/apache2/**/*.conf:Apache Conf'
--map-syntax "**/jenkinsfile/**/*:Groovy"

more on sed && sed+bat:

TODO-with-sed

from bat.

marslo avatar marslo commented on May 28, 2024

ops... forgot to let you know, your solution works like charm, you can close this issue.
thanks again.

image

from bat.

marslo avatar marslo commented on May 28, 2024

btw to show the correct line number in the file, it can be handled by nl {} and without -l groovy to let bat automatic use:

rg --vimgrep --with-filename 'TODO:' --color never |
   cut -d':' -f1 |
   uniq |
   xargs -r -I{} bash -c "sed -ne '/TODO:/,/^\s*$/p' < <(nl {}) |
   bat --style="grid,changes,header" --file-name='{}'"

Since we haven lot of files/dotfiles has not extension, so, to identify the language automatically, I'm using the following function ( a little bit ugly, but I don't how to handle via complex shell logic in xargs, so using while read instead of ):

function showTODO() {
  local option='--style="grid,changes,header"'
  while [[ $# -gt 0 ]]; do
    case "$1" in
         -p | --plain ) option+=" $1"    ; shift 1 ;;
                   -* ) option+=" $1 $2" ; shift 2 ;;
    esac
  done

  rg --vimgrep --with-filename 'TODO:' --color never |
     cut -d':' -f1 |
     uniq |
     while read -r _file; do
       # identify language automatically
       local lang='';
       lang="$(sed -r 's/^.+\.(.+)$/\1/' <<< "${_file}")";
       if ! bat --list-languages | command grep -iE -q "[,:]${lang}|${lang},"; then
         # check shebang and reset to empty if shebang not found
         lang=$(sed -rn 's/^#!.*[/\ ](\w+)$/\1/p' < <(head -n1 "${_file}"));
       fi
       sed -ne '/TODO:/,/^\s*$/p' < <(nl "${_file}") |
           eval "bat -l ${lang:-groovy} ${option} --file-name=\"${_file}\"" ;
     done

if bat can detect filetype via shebang line ( i.e.: #!/usr/bin/env bash or #!/bin/bash, via ^#!.*[/\ ](\w+)$), then the simple version will be the best answer.

Screenshot 2024-05-02 at 16 36 43

btw, just curious why bat will using _fzf_path_completion as completion function by default.

from bat.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.