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

Potential solution to the TODO in Fish shell completions. #553

Closed
eth-p opened this issue May 2, 2019 · 1 comment
Closed

Potential solution to the TODO in Fish shell completions. #553

eth-p opened this issue May 2, 2019 · 1 comment

Comments

@eth-p
Copy link
Collaborator

eth-p commented May 2, 2019

I was just taking a look through the fish completions, and I noticed the TODO at line 19.

# TODO: add parameter completion for available languages using option: -xka "(bat --list-languages | cat)"
# but replace 'cat' with some sed/awk like command that only outputs lines of valid options for this flag

After playing around with it, I have a solution that should work on both Linux and MacOS without having to install any extra tools. It's kind of a dirty hack, but it's pure awk, tr, and sed (and optionally sort and uniq).

bat --list-languages | awk 'NR==1{dc=0; while(substr($0,dc,2)!="  ") dc++; while(substr($0,dc,1)==" ") dc++}; {print substr($0,dc)}' | tr ',' '\n' | sed 's/^ \+//; s/ \+$//; /^$/d' | sort | uniq

Explanation:

First of all, the language list needs to be parsed. The implementation of bat --list-languages wasn't really meant to be read by anything but a human, but with a little hackery, awk is perfectly capable of parsing it provided the following two properties are met:

  1. The name of the first language is not the longest one in the list (breaks the double space assumption).
  2. The name of the first language does not contain two consecutive spaces (same reason as above).

If these properties are met, the following awk script can be used:

NR == 1 { # Run this for the first column.
    dc = 0                                   # Set the column split counter to zero.
    while (substr($0, dc, 2) != "  ") dc++;  # Skip past the language name column.
    while (substr($0, dc, 1) == " ") dc++;   # Skip past the whitespace that separates the columns.
};

{
    print substr($0, dc) # Prints everything after the `dc` variable (i.e. only the second column).
}

After piping bat --list-languages to that script, the output will look something like this:

as
csv, tsv
applescript, script editor
s, S
adoc, asciidoc, asc
asa
yasm, nasm, asm, inc, mac
awk
bat, cmd

From here, we have two options: use the first entry, or just split them all. Since the first entry isn't always the most common extension for the language, it's safer to just use them all. That can be achieved by using tr to replace the commas with newlines, and sed to clean up the empty lines and garbage (leading/trailing) whitespace.

... | tr ',' '\n' | sed 's/^ \+//; s/ \+$//; /^$/d'

After that, you can optionally sort and de-duplicate any languages using ... | sort | uniq.

Options:

If you want to exclude non-extension files, you can modify the sed patterns to do the following:

  • /^.\+\..\+/d - Delete any lines that match filename.ext but not .file
  • /^[A-Z]/d - Delete any lines that start with an uppercase letter (i.e. languages that are probably just config files).
@eth-p
Copy link
Collaborator Author

eth-p commented May 2, 2019

Closed in favour of #555.

@eth-p eth-p closed this as completed May 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant