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

Bash CLI completion script? #1010

Closed
flipperbw opened this issue May 21, 2020 · 16 comments · Fixed by #1678
Closed

Bash CLI completion script? #1010

flipperbw opened this issue May 21, 2020 · 16 comments · Fixed by #1678
Labels
feature-request New feature or request help wanted Extra attention is needed packaging/tooling

Comments

@flipperbw
Copy link

Unless I'm missing something obvious, is there any autocomplete script for bash? I see one for fish, but couldn't find anything for bash.

I can take a pass at converting that one or writing my own, but wanted to check in first.

@flipperbw flipperbw added the feature-request New feature or request label May 21, 2020
@sharkdp
Copy link
Owner

sharkdp commented May 21, 2020

We used to have automatically created shell completion files for Bash, Zsh, Fish and PowerShell. They were causing some problems though:

bat/build.rs

Lines 1 to 2 in 7e84477

// TODO: Re-enable generation of shell completion files (below) when clap 3 is out.
// For more details, see https://github.com/sharkdp/bat/issues/372

We have since included manually created Fish completion files (#372)

Apart from the reasons given in #524 (comment) I am open to including manually created shell completion files.

As a starting point, you could either take the Fish completion file (which is probably already out of date) or re-enable the automatic generation of completion files and manually fix the autogenerated Bash completion file.

@flipperbw
Copy link
Author

Hmm gotcha. I will take a look.

@flipperbw
Copy link
Author

What I wound up doing, in lieu of making a whole script, was just to add the line complete -F _longopt bat to my profile. It's not perfect but it's a quick and easy fix for some completion without the need for an entire file.

@ernstki
Copy link

ernstki commented Jun 14, 2020

@flipperbw That's a great idea, and not a thing I even knew existed. Now I can stop re-inventing the wheel of parsing the output of a command's --help into a word list for complete -W. :)

Worth noting, though, that that's part of bash-completion, which is often a separate package for people to install / set up.

@flipperbw
Copy link
Author

True, though I suppose it could be tested for in an install script here, and if not, include that function definition.

@sharkdp
Copy link
Owner

sharkdp commented Sep 20, 2020

We now have custom Zsh and Fish completion files. It would be great if someone could write a Bash completion file as well.

@sharkdp sharkdp added help wanted Extra attention is needed packaging/tooling labels Dec 29, 2020
scop added a commit to scop/bat that referenced this issue Jun 3, 2021
scop added a commit to scop/bat that referenced this issue Jun 3, 2021
@ds2606
Copy link

ds2606 commented Jun 22, 2021

Just an FYI, filename completion no longer works for me using zsh with the re-added scripts. For example, with directory ~/Misc, bat ~/mi<tab> doesn't expand to the full directory, whereas it does with any other completion executable (e.g. ls ~/mi<tab> expands to ls ~/Misc) - I'll be re-removing the completion scripts for the time being

@scop
Copy link
Contributor

scop commented Jun 28, 2021

Is this a case sensitivity thing (~/mi vs ~/Misc), or do you see the problem also when completing ~/Mi<tab>? I can't check right now but the bash completion implemented in #1678 certainly didn't break the usual case sensitive completions for me. No idea about zsh.

@ds2606
Copy link

ds2606 commented Jun 28, 2021

It's case-specific: filename completions for e.g. ~/Mi<tab> work fine (I'm accustomed by muscle memory to tab through paths case-insensitively though so even if it's minor it's a bit if a dealbreaker usage-wise for me)

@scop
Copy link
Contributor

scop commented Jun 28, 2021

I've just verified that the bash completion from #1678 does not break case sensitive nor case insensitive path completions (case insensitive ones are enabled with set completion-ignore-case on in e.g. ~/.inputrc for bash (well readline)).

sharkdp pushed a commit that referenced this issue Jun 28, 2021
@rashil2000
Copy link
Contributor

Hey @sharkdp!

I'm looking for the missing PowerShell completion file. What exactly was the problem there, could you elaborate? Can we auto-generate it, fix it, and then include it along with bash, zsh and fish completions?

@sharkdp
Copy link
Owner

sharkdp commented Aug 26, 2021

@rashil2000 I'm not a PowerShell user, so I don't really know/remember if the PowerShell completions worked as expected. If someone wants to try, that would be a viable option (either directly autogenerate or check in a modified version of the autogen output).

@rashil2000
Copy link
Contributor

I can test it.

How do I build it? Do you have the old file lying around somewhere?

Or I can directly download the release zip when it was still being shipped. At which version did it stop being included?

@rashil2000
Copy link
Contributor

I modified build.rs and generated the completion script. It seems to work fine, both with filenames and arguments. Can you include it in the assets?
Here is the script:

using namespace System.Management.Automation
using namespace System.Management.Automation.Language

Register-ArgumentCompleter -Native -CommandName 'bat' -ScriptBlock {
    param($wordToComplete, $commandAst, $cursorPosition)

    $commandElements = $commandAst.CommandElements
    $command = @(
        'bat'
        for ($i = 1; $i -lt $commandElements.Count; $i++) {
            $element = $commandElements[$i]
            if ($element -isnot [StringConstantExpressionAst] -or
                $element.StringConstantType -ne [StringConstantType]::BareWord -or
                $element.Value.StartsWith('-')) {
                break
        }
        $element.Value
    }) -join ';'

    $completions = @(switch ($command) {
        'bat' {
            [CompletionResult]::new('-l', 'l', [CompletionResultType]::ParameterName, 'Set the language for syntax highlighting.')
            [CompletionResult]::new('--language', 'language', [CompletionResultType]::ParameterName, 'Set the language for syntax highlighting.')
            [CompletionResult]::new('-H', 'H', [CompletionResultType]::ParameterName, 'Highlight lines N through M.')
            [CompletionResult]::new('--highlight-line', 'highlight-line', [CompletionResultType]::ParameterName, 'Highlight lines N through M.')
            [CompletionResult]::new('--file-name', 'file-name', [CompletionResultType]::ParameterName, 'Specify the name to display for a file.')
            [CompletionResult]::new('--diff-context', 'diff-context', [CompletionResultType]::ParameterName, 'diff-context')
            [CompletionResult]::new('--tabs', 'tabs', [CompletionResultType]::ParameterName, 'Set the tab width to T spaces.')
            [CompletionResult]::new('--wrap', 'wrap', [CompletionResultType]::ParameterName, 'Specify the text-wrapping mode (*auto*, never, character).')
            [CompletionResult]::new('--terminal-width', 'terminal-width', [CompletionResultType]::ParameterName, 'Explicitly set the width of the terminal instead of determining it automatically. If prefixed with ''+'' or ''-'', the value will be treated as an offset to the actual terminal width. See also: ''--wrap''.')
            [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'When to use colors (*auto*, never, always).')
            [CompletionResult]::new('--italic-text', 'italic-text', [CompletionResultType]::ParameterName, 'Use italics in output (always, *never*)')
            [CompletionResult]::new('--decorations', 'decorations', [CompletionResultType]::ParameterName, 'When to show the decorations (*auto*, never, always).')
            [CompletionResult]::new('--paging', 'paging', [CompletionResultType]::ParameterName, 'Specify when to use the pager, or use `-P` to disable (*auto*, never, always).')
            [CompletionResult]::new('--pager', 'pager', [CompletionResultType]::ParameterName, 'Determine which pager to use.')
            [CompletionResult]::new('-m', 'm', [CompletionResultType]::ParameterName, 'Use the specified syntax for files matching the glob pattern (''*.cpp:C++'').')
            [CompletionResult]::new('--map-syntax', 'map-syntax', [CompletionResultType]::ParameterName, 'Use the specified syntax for files matching the glob pattern (''*.cpp:C++'').')
            [CompletionResult]::new('--theme', 'theme', [CompletionResultType]::ParameterName, 'Set the color theme for syntax highlighting.')
            [CompletionResult]::new('--style', 'style', [CompletionResultType]::ParameterName, 'Comma-separated list of style elements to display (*auto*, full, plain, changes, header, grid, rule, numbers, snip).')
            [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Only print the lines from N to M.')
            [CompletionResult]::new('--line-range', 'line-range', [CompletionResultType]::ParameterName, 'Only print the lines from N to M.')
            [CompletionResult]::new('-A', 'A', [CompletionResultType]::ParameterName, 'Show non-printable characters (space, tab, newline, ..).')
            [CompletionResult]::new('--show-all', 'show-all', [CompletionResultType]::ParameterName, 'Show non-printable characters (space, tab, newline, ..).')
            [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'Show plain style (alias for ''--style=plain'').')
            [CompletionResult]::new('--plain', 'plain', [CompletionResultType]::ParameterName, 'Show plain style (alias for ''--style=plain'').')
            [CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'Only show lines that have been added/removed/modified.')
            [CompletionResult]::new('--diff', 'diff', [CompletionResultType]::ParameterName, 'Only show lines that have been added/removed/modified.')
            [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Show line numbers (alias for ''--style=numbers'').')
            [CompletionResult]::new('--number', 'number', [CompletionResultType]::ParameterName, 'Show line numbers (alias for ''--style=numbers'').')
            [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'f')
            [CompletionResult]::new('--force-colorization', 'force-colorization', [CompletionResultType]::ParameterName, 'force-colorization')
            [CompletionResult]::new('-P', 'P', [CompletionResultType]::ParameterName, 'Alias for ''--paging=never''')
            [CompletionResult]::new('--no-paging', 'no-paging', [CompletionResultType]::ParameterName, 'Alias for ''--paging=never''')
            [CompletionResult]::new('--list-themes', 'list-themes', [CompletionResultType]::ParameterName, 'Display all supported highlighting themes.')
            [CompletionResult]::new('-L', 'L', [CompletionResultType]::ParameterName, 'Display all supported languages.')
            [CompletionResult]::new('--list-languages', 'list-languages', [CompletionResultType]::ParameterName, 'Display all supported languages.')
            [CompletionResult]::new('-u', 'u', [CompletionResultType]::ParameterName, 'u')
            [CompletionResult]::new('--unbuffered', 'unbuffered', [CompletionResultType]::ParameterName, 'unbuffered')
            [CompletionResult]::new('--no-config', 'no-config', [CompletionResultType]::ParameterName, 'Do not use the configuration file')
            [CompletionResult]::new('--no-custom-assets', 'no-custom-assets', [CompletionResultType]::ParameterName, 'Do not load custom assets')
            [CompletionResult]::new('--config-file', 'config-file', [CompletionResultType]::ParameterName, 'Show path to the configuration file.')
            [CompletionResult]::new('--generate-config-file', 'generate-config-file', [CompletionResultType]::ParameterName, 'Generates a default configuration file.')
            [CompletionResult]::new('--config-dir', 'config-dir', [CompletionResultType]::ParameterName, 'Show bat''s configuration directory.')
            [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Show bat''s cache directory.')
            [CompletionResult]::new('--diagnostic', 'diagnostic', [CompletionResultType]::ParameterName, 'Show diagnostic information for bug reports.')
            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print this help message.')
            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print this help message.')
            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Show version information.')
            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Show version information.')
            [CompletionResult]::new('cache', 'cache', [CompletionResultType]::ParameterValue, 'Modify the syntax-definition and theme cache')
            break
        }
        'bat;cache' {
            [CompletionResult]::new('--source', 'source', [CompletionResultType]::ParameterName, 'Use a different directory to load syntaxes and themes from.')
            [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'Use a different directory to store the cached syntax and theme set.')
            [CompletionResult]::new('-b', 'b', [CompletionResultType]::ParameterName, 'Initialize (or update) the syntax/theme cache.')
            [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'Initialize (or update) the syntax/theme cache.')
            [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'Remove the cached syntax definitions and themes.')
            [CompletionResult]::new('--clear', 'clear', [CompletionResultType]::ParameterName, 'Remove the cached syntax definitions and themes.')
            [CompletionResult]::new('--blank', 'blank', [CompletionResultType]::ParameterName, 'Create completely new syntax and theme sets (instead of appending to the default sets).')
            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information')
            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information')
            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information')
            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information')
            break
        }
    })

    $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
        Sort-Object -Property ListItemText
}

@Enselic
Copy link
Collaborator

Enselic commented Aug 27, 2021

@rashil2000 Thank you!

Can you open a Pull Request that adds that file please?

@rashil2000
Copy link
Contributor

@Enselic #1826

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 help wanted Extra attention is needed packaging/tooling
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants