Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"ls" functionality when called with a directory #971

Closed
samuelcolvin opened this issue May 2, 2020 · 3 comments
Closed

"ls" functionality when called with a directory #971

samuelcolvin opened this issue May 2, 2020 · 3 comments
Labels
feature-request New feature or request

Comments

@samuelcolvin
Copy link

(I'm sorry if this is a duplicate, I can't imagine it's not, yet I've search a lot and can't find anything)

It would be wonderful if bat behaved like ls -lh ... when executed with a directory as an arg.

This would be particularly useful when looking for a file to display; currently I often end up replacing bat with ls -lh at the beginning of a long path.

Obviously it would be useful if the output was highlighted unlike normal ls.

The main downside I can imagine would be confusion when "conbatenating" multiple files: if I accidentally included a directory instead of a file as one of the paths, however:

  1. unlike cat I imagine bat is rarely used for this, especially in scripts
  2. bat could continue to use a non-zero exit code when executed with a path to show it's not the primary intended purpose, while still showing the list of files - I'm not advocating this, just a potential work around

If this is something you'd be interested in, I'd be willing to have a crack at a PR, through I a somewhat novice rust developer.

@samuelcolvin samuelcolvin added the feature-request New feature or request label May 2, 2020
@eth-p
Copy link
Collaborator

eth-p commented May 9, 2020

This is a pretty cool idea, but I think it could also be solved in a few easier ways too:

  1. If we add support for lesspipe, it could probably be configured to ls and highlight any directories passed as an input.

  2. A wrapper script that combines bat and exa. Exa is already a well-established project that provides exactly what you're looking for, and it shouldn't be much harder to implement as a wrapper than adding this to your .bash_profile:

bat() {
    local arg
    local files=()
    local dirs=()

    for arg in "$@"; do
        if [ "${arg:0:1}" = "-" ]; then continue; fi
        if [ -d "$arg" ]; then
            dirs+=("$arg")
        elif [ -e "$arg" ]; then
            files+=("$arg")
        fi
    done

    if [ "${#files[@]}" -gt 0 ] && [ "${#dirs[@]}" -gt 0 ]; then
        printf "\x1B[31m[%s error]: %s\x1B[0m%s\n" "$0" "Cannot concatenate files and directories"
        return 1
    fi

    if [ "${#dirs[@]}" -gt 0 ]; then
        exa "${dirs[@]}"
        return $?
    fi

    bat "$@"
    return $?
}

The main downside I can imagine would be confusion when "conbatenating" multiple files: if I accidentally included a directory instead of a file as one of the paths

I would just consider it an error, to be honest. There's such a low likelihood of it being intentional that it would make more sense to err on the side of caution and make it a clear error.

@samuelcolvin
Copy link
Author

samuelcolvin commented May 9, 2020

Thanks so much that (almost) worked for me.

I'm using zsh as I'm on macos and I had to use command ... to avoid a recursion error.

What I ended up with was

exa () {
    command exa -l "$@"
    return $?
}

bat() {
    local arg
    local files=()
    local dirs=()

    for arg in "$@"; do
        if [ "${arg:0:1}" = "-" ]; then continue; fi
        if [ -d "$arg" ]; then
            dirs+=("$arg")
        elif [ -e "$arg" ]; then
            files+=("$arg")
        fi
    done

    if [ "${#files[@]}" -gt 0 ] && [ "${#dirs[@]}" -gt 0 ]; then
        printf "\x1B[31m[%s error]: %s\x1B[0m%s\n" "$0" "Cannot concatenate files and directories"
        return 1
    fi

    if [ "${#dirs[@]}" -gt 0 ]; then
        exa "${dirs[@]}"
        return $?
    fi

    command bat "$@"
    return $?
}

Very close to what you had.

I'd be willing to have a crack at a PR

I think this probably isn't true, I'm too busy and the above works well for me, so I doubt I'll be able to make time to work on a fix.

@sharkdp
Copy link
Owner

sharkdp commented May 11, 2020

I agree that the wrapper option is probably the best idea. I currently don't see this being integrated into bat itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants