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

git add with numbered file paths #5

Open
simonlindholm opened this issue May 1, 2022 · 0 comments
Open

git add with numbered file paths #5

simonlindholm opened this issue May 1, 2022 · 0 comments

Comments

@simonlindholm
Copy link
Owner

Aron has the following for fish:

# From https://github.com/ErinCall/Dotfiles/tree/master/.config/fish/functions

function git
    set -l translated_argv

    if test (count $argv) -lt 1 >/dev/null
        command git
        return $status
    end

    # TODO: this won't detect commands with e.g. `git --git-dir ...`
    set -l cmd $argv[1]
    set -e argv[1]

    for arg in $argv
        set translated_argv $translated_argv (python3 ~/.config/fish/functions/git.py --translate "$arg" "$c")
    end

    switch $cmd
    case 'status'
        begin
            set -l IFS
            set -g last_git_output (command git status --short $translated_argv)
        end
        python3 ~/.config/fish/functions/git.py --status "$last_git_output"
        # split0 to make $c be a multiline string instead of a list
        set -g c (python3 ~/.config/fish/functions/git.py --list "$last_git_output" | string split0)
        return $status
    case '*'
        command git $cmd $translated_argv
        return $status
    end
end
# from subprocess import check_output
from colorama import Fore, Style
from sys import stdout, argv, stdin
import os


def acquire_changes(git_short_status):
    # lines = check_output(["git", "status", "--short"]).decode('utf-8').split('\n')
    lines = git_short_status.split('\n')

    result = []
    index = 1

    staged = [line for line in lines if len(line) > 0 and (line[0] != ' ' and line[0] != '?')]
    unstaged = [line for line in lines if len(line) > 0 and not (line[0] != ' ' and line[0] != '?')]

    for line in (staged + unstaged):
        if len(line) == 0:
            continue

        mode = line[0:2]
        if mode[0] == 'R':
            # 'R' in a short-status indicates a staged renamed file. In
            # this case we have two filenames to think about. This code
            # will break in the inexcusable case that the old filename
            # contained ' -> '.
            line = line[3:]
            files = line.split(" -> ")
            file_items = []
            for file in files:
                if file[0] == '"' and file[-1] == '"':
                    file = file[1:-1]

                file_items.append((file, index))
                index += 1

            result.append((mode[0], mode[1], file_items))
        else:
            file = line[3:]
            if file[0] == '"' and file[-1] == '"':
                file = file[1:-1]
            result.append((mode[0], mode[1], [(file, index)]))
            index += 1

    return result


def list(git_short_status):
    changes = acquire_changes(git_short_status)
    for item in changes:
        for file in item[2]:
            print(file[0])


def git_status(git_short_status):
    changes = acquire_changes(git_short_status)
    display([item for item in changes if item[0] not in ['?', ' ']], "Changes to be committed", Fore.GREEN, 0)
    print()
    display([item for item in changes if item[1] not in ['?', ' ']], "Unstaged changes", Fore.YELLOW, 1)
    print()
    display([item for item in changes if item[1] == '?'], "Untracked files", Fore.RED, 1)


def wrap_in_quotes(filename):
    if " " in filename:
        return '"' + filename + '"'
    else:
        return filename


def display(items, header, color, state_index):
    if len(items) == 0:
        return

    print(color + Style.BRIGHT + header + Style.RESET_ALL)

    state_names = {
        'M': '  modified',
        'A': '  new file',
        'D': '   deleted',
        'R': '   renamed',
        'C': '    copied',
        'T': 'typechange',
        '?': ' untracked',
        ' ': '         ?'
    }

    for item in items:
        padding(color)

        state = item[state_index]

        if state in state_names:
            stdout.write(state_names[state])
        else:
            stdout.write('         ' + state)

        # Special case for renamed files in the unstaged section
        # only show the new filename, not the renames
        if item[0] == 'R' and state_index == 1:
            files = item[2]
            stdout.write(": [" + str(files[1][1]) + "] ")
            stdout.write(color + wrap_in_quotes(files[1][0]))
        else:
            files = item[2]
            stdout.write(": [" + str(files[0][1]) + "] ")
            stdout.write(color + wrap_in_quotes(files[0][0]))

            if len(files) > 1:
                stdout.write(Fore.RESET + ' -> ' + '[' + str(files[1][1]) + '] ')
                stdout.write(color + wrap_in_quotes(files[1][0]))

        stdout.write('\n')

def translate(s: str, options: str):
    lines = options.strip().split("\n")
    
    try:
        if "-" in s:
            splits = s.split("-")
            if len(splits) != 2:
                print(s)
                return
            r = (int(splits[0]), int(splits[1]))
            if r[0] <= 0 or r[1] <= 0:
                print(s)
                return
            for i in range(r[0], r[1]+1):
                print(lines[i-1])
        else:
            v = int(s)
            if v <= 0:
                print(s)
                return

            print(lines[v-1])
    except:
        print(s)


def padding(color):
    stdout.write(color + Style.BRIGHT + '#' + Style.RESET_ALL + '      ')

if argv[1] == '--list':
    list(argv[2])
elif argv[1] == '--status':
    git_status(argv[2])
elif argv[1] == '--translate':
    translate(argv[2], argv[3])
else:
    print("Unknown command")
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