Skip to content

Instantly share code, notes, and snippets.

@sweiss3
Created March 29, 2014 17:22
Show Gist options
  • Save sweiss3/9858452 to your computer and use it in GitHub Desktop.
Save sweiss3/9858452 to your computer and use it in GitHub Desktop.
A clink script for supporting tab-completion of git branches when using "git checkout"
function git_checkout_match_generator(text, first, last)
found_matches = false;
if rl_state.line_buffer:find("^git checkout ") then
has_start_branch = not rl_state.line_buffer:find("^git checkout[ ]*$")
for line in io.popen("git branch 2>nul"):lines() do
local m = line:match("[%* ] (.+)$")
if m then
if not has_start_branch then
clink.add_match(m)
found_matches = true;
elseif #text > 0 and m:find(text) then
clink.add_match(m)
found_matches = true;
end
end
end
end
return found_matches
end
clink.register_match_generator(git_checkout_match_generator, 10)
@glucas
Copy link

glucas commented Jun 22, 2014

After trying this for a bit, I found that I wanted completion to use any entered text as the beginning the branch name (rather than matching branch names that contain the text anywhere). Changing line 12 works:

                            elseif #text > 0 and m:sub(1, string.len(text)) == text then

@shreejay
Copy link

Works perfectly in Cmder. Thank You!

@Matheo13
Copy link

Thanks

@danwagnerco
Copy link

Works like a champ -- thanks so much!

@tcrammond
Copy link

This worked great, thanks a lot

@fluffynuts
Copy link

fluffynuts commented Aug 16, 2016

Bear with me, I'm a lua noob... If anyone is interested, I've extended the above to also do path completions when any text is found and it doesn't match branches -- for checking out the original version of files within the repo. It's probably not pretty, but seems to do the trick.

function git_checkout_match_generator(text, first, last)
    found_matches = false
    found_branch_match = false
    if rl_state.line_buffer:find("^git checkout ") then
        has_start_branch = not rl_state.line_buffer:find("^git checkout[ ]*$")
        for line in io.popen("git branch 2>nul"):lines() do
            local m = line:match("[%* ] (.+)$")
            if m then
                if not has_start_branch then
                    clink.add_match(m)
                    found_matches = true
                elseif #text > 0 and m:find(text) then
                    clink.add_match(m)
                    found_branch_match = true
                    found_matches = true
                end
            end
        end
    end

    if not found_matches or (#text > 0 and not found_branch_match) then
        local where = "."
        if #text > 0 then
            where = text
        end
        local lsresult = ls(where)
        for k,line in pairs(lsresult) do
            if #text > 0 and line:find(text) then
                clink.add_match(line)
                found_matches = true
            elseif #text == 0 then
                clink.add_match(line)
                found_matches = true
            end
        end
    end

    return found_matches
end

clink.register_match_generator(git_checkout_match_generator, 10)

@charego
Copy link

charego commented Aug 25, 2016

My only problem is it doesn't support aliases for checkout.

Example .gitconfig:

[alias]
        br = branch
        co = checkout
        ca = commit --amend
        cm = commit -m
        cv = commit -v
        df = diff
        dc = diff --cached
        f = fetch --all --prune
        pl = pull
        rbi = rebase -i
        rh = reset HEAD
        st = status

Ideally there would be autocomplete after I type git co.

@bhank
Copy link

bhank commented Jan 26, 2017

I don't know Lua, but I made it work with "git co" by changing lines 3 and 4 to this:

if rl_state.line_buffer:find("^git checkout ") or rl_state.line_buffer:find("^git co ") then
    has_start_branch = not rl_state.line_buffer:find("^git checkout[ ]*$") and not rl_state.line_buffer:find("^git co[ ]*$")

Update: I rewrote it to support a list of git commands (as well as fixing a bug handling branches with "-" in them, by using plain-text find): https://gist.github.com/bhank/a85113b06632fc52f053533f81c2da2d

@wald-tq
Copy link

wald-tq commented Jun 20, 2017

@wald-tq
Copy link

wald-tq commented Jun 20, 2017

I was not satisfied with any of the solutions provided here, so I created a own implementation using the parser of clink.

It features better tab completion for example if you have the branches:

private/deva/ISU-124
private/devb/ISU-243

you can type:

git checkout pri<TAB>b<TAB>

which you can't do with the other solutions.

It's still work in progress but here is it: https://gist.github.com/wald-tq/0f274c3dd561dd8f0f7189c65b825f55

enjoy

@keocra
Copy link

keocra commented Nov 28, 2019

Thanks for this :-) Works like a charm @sweiss3

And thanks for this addition @glucas

After trying this for a bit, I found that I wanted completion to use any entered text as the beginning the branch name (rather than matching branch names that contain the text anywhere). Changing line 12 works:

                            elseif #text > 0 and m:sub(1, string.len(text)) == text then

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment