git-extras.plugin.zsh 14.3 KB
Newer Older
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
1
2
3
4
# ------------------------------------------------------------------------------
# Description
# -----------
#
Janosch Schwalm's avatar
Janosch Schwalm committed
5
#  Completion script for git-extras (https://github.com/tj/git-extras).
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
6
#
Paul Calabro's avatar
Paul Calabro committed
7
#  This depends on and reuses some of the internals of the _git completion
8
9
10
#  function that ships with zsh itself. It will not work with the _git that ships
#  with git.
#
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
11
12
13
14
15
# ------------------------------------------------------------------------------
# Authors
# -------
#
#  * Alexis GRIMALDI (https://github.com/agrimaldi)
spacewander's avatar
spacewander committed
16
#  * spacewander (https://github.com/spacewander)
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
17
18
19
20
21
#
# ------------------------------------------------------------------------------
# Inspirations
# -----------
#
Janosch Schwalm's avatar
Janosch Schwalm committed
22
23
#  * git-extras (https://github.com/tj/git-extras)
#  * git-flow-completion (https://github.com/bobthecow/git-flow-completion)
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
24
25
#
# ------------------------------------------------------------------------------
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
26
27


28
29
# Internal functions
# These are a lot like their __git_* equivalents inside _git
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
30

31
32
33
34
35
36
37
__gitex_command_successful () {
  if (( ${#*:#0} > 0 )); then
    _message 'not a git repository'
    return 1
  fi
  return 0
}
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
38

39
__gitex_commits() {
spacewander's avatar
spacewander committed
40
41
42
43
44
45
46
47
48
49
    declare -A commits
    git log --oneline -15 | sed 's/\([[:alnum:]]\{7\}\) /\1:/' | while read commit
    do
        hash=$(echo $commit | cut -d':' -f1)
        commits[$hash]="$commit"
    done
    local ret=1
    _describe -t commits commit commits && ret=0
}

50
51
52
53
54
55
56
57
__gitex_remote_names() {
    local expl
    declare -a remote_names
    remote_names=(${(f)"$(_call_program remotes git remote 2>/dev/null)"})
    __git_command_successful || return
    _wanted remote-names expl remote-name compadd $* - $remote_names
}

58
__gitex_tag_names() {
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
59
60
    local expl
    declare -a tag_names
spacewander's avatar
spacewander committed
61
    tag_names=(${${(f)"$(_call_program tags git for-each-ref --format='"%(refname)"' refs/tags 2>/dev/null)"}#refs/tags/})
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
62
63
64
65
66
    __git_command_successful || return
    _wanted tag-names expl tag-name compadd $* - $tag_names
}


67
__gitex_branch_names() {
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
68
69
70
71
72
73
74
    local expl
    declare -a branch_names
    branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads 2>/dev/null)"}#refs/heads/})
    __git_command_successful || return
    _wanted branch-names expl branch-name compadd $* - $branch_names
}

75
__gitex_specific_branch_names() {
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
76
77
    local expl
    declare -a branch_names
spacewander's avatar
spacewander committed
78
    branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads/"$1" 2>/dev/null)"}#refs/heads/$1/})
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
79
    __git_command_successful || return
80
81
82
83
84
    _wanted branch-names expl branch-name compadd - $branch_names
}

__gitex_chore_branch_names() {
    __gitex_specific_branch_names 'chore'
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
85
86
}

87
88
__gitex_feature_branch_names() {
    __gitex_specific_branch_names 'feature'
spacewander's avatar
spacewander committed
89
90
}

91
92
__gitex_refactor_branch_names() {
    __gitex_specific_branch_names 'refactor'
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
93
94
}

95
96
__gitex_bug_branch_names() {
    __gitex_specific_branch_names 'bug'
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
97
98
}

99
__gitex_submodule_names() {
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
100
101
    local expl
    declare -a submodule_names
102
    submodule_names=(${(f)"$(_call_program branchrefs git submodule status | awk '{print $2}')"})  # '
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
103
104
105
106
107
    __git_command_successful || return
    _wanted submodule-names expl submodule-name compadd $* - $submodule_names
}


108
__gitex_author_names() {
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
109
110
111
112
113
114
115
    local expl
    declare -a author_names
    author_names=(${(f)"$(_call_program branchrefs git log --format='%aN' | sort -u)"})
    __git_command_successful || return
    _wanted author-names expl author-name compadd $* - $author_names
}

spacewander's avatar
spacewander committed
116
# subcommands
117
118
119
120
121
_git-authors() {
    _arguments  -C \
        '(--list -l)'{--list,-l}'[show authors]' \
        '--no-email[without email]' \
}
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
122

spacewander's avatar
spacewander committed
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
_git-bug() {
    local curcontext=$curcontext state line ret=1
    declare -A opt_args

    _arguments -C \
        ': :->command' \
        '*:: :->option-or-argument' && ret=0

    case $state in
        (command)
            declare -a commands
            commands=(
                'finish:merge bug into the current branch'
            )
            _describe -t commands command commands && ret=0
            ;;
        (option-or-argument)
            curcontext=${curcontext%:*}-$line[1]:
            case $line[1] in
                (finish)
                    _arguments -C \
144
                        ':branch-name:__gitex_bug_branch_names'
spacewander's avatar
spacewander committed
145
                    ;;
146
147
148
149
                -r|--remote )
                    _arguments -C \
                        ':remote-name:__gitex_remote_names'
                    ;;
spacewander's avatar
spacewander committed
150
            esac
151
            return 0
spacewander's avatar
spacewander committed
152
    esac
153
154
155

    _arguments \
        '(--remote -r)'{--remote,-r}'[setup remote tracking branch]'
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
156
157
158
}


spacewander's avatar
spacewander committed
159
_git-changelog() {
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
160
    _arguments \
spacewander's avatar
spacewander committed
161
        '(-l --list)'{-l,--list}'[list commits]' \
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
162
163
}

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
_git-chore() {
    local curcontext=$curcontext state line ret=1
    declare -A opt_args

    _arguments -C \
        ': :->command' \
        '*:: :->option-or-argument' && ret=0

    case $state in
        (command)
            declare -a commands
            commands=(
                'finish:merge and delete the chore branch'
            )
            _describe -t commands command commands && ret=0
            ;;
        (option-or-argument)
            curcontext=${curcontext%:*}-$line[1]:
            case $line[1] in
                (finish)
                    _arguments -C \
                        ':branch-name:__gitex_chore_branch_names'
                    ;;
                -r|--remote )
                    _arguments -C \
                        ':remote-name:__gitex_remote_names'
                    ;;
            esac
            return 0
    esac

    _arguments \
        '(--remote -r)'{--remote,-r}'[setup remote tracking branch]'
}
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
198

spacewander's avatar
spacewander committed
199

Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
200
201
_git-contrib() {
    _arguments \
202
        ':author:__gitex_author_names'
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
203
204
205
206
207
208
209
210
}


_git-count() {
    _arguments \
        '--all[detailed commit count]'
}

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
_git-create-branch() {
    local curcontext=$curcontext state line
    _arguments -C \
        ': :->command' \
        '*:: :->option-or-argument'

    case "$state" in
        (command)
            _arguments \
                '(--remote -r)'{--remote,-r}'[setup remote tracking branch]'
            ;;
        (option-or-argument)
            curcontext=${curcontext%:*}-$line[1]:
            case $line[1] in
                -r|--remote )
                    _arguments -C \
                        ':remote-name:__gitex_remote_names'
                    ;;
            esac
    esac
}
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
232
233
234

_git-delete-branch() {
    _arguments \
235
        ':branch-name:__gitex_branch_names'
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
236
237
238
239
240
}


_git-delete-submodule() {
    _arguments \
241
        ':submodule-name:__gitex_submodule_names'
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
242
243
244
245
246
}


_git-delete-tag() {
    _arguments \
247
        ':tag-name:__gitex_tag_names'
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
248
249
250
}


spacewander's avatar
spacewander committed
251
252
253
254
255
_git-effort() {
    _arguments \
        '--above[ignore file with less than x commits]'
}

256

Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
_git-extras() {
    local curcontext=$curcontext state line ret=1
    declare -A opt_args

    _arguments -C \
        ': :->command' \
        '*:: :->option-or-argument' && ret=0

    case $state in
        (command)
            declare -a commands
            commands=(
                'update:update git-extras'
            )
            _describe -t commands command commands && ret=0
            ;;
    esac

    _arguments \
spacewander's avatar
spacewander committed
276
        '(-v --version)'{-v,--version}'[show current version]'
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
}


_git-feature() {
    local curcontext=$curcontext state line ret=1
    declare -A opt_args

    _arguments -C \
        ': :->command' \
        '*:: :->option-or-argument' && ret=0

    case $state in
        (command)
            declare -a commands
            commands=(
                'finish:merge feature into the current branch'
            )
            _describe -t commands command commands && ret=0
            ;;
        (option-or-argument)
            curcontext=${curcontext%:*}-$line[1]:
            case $line[1] in
                (finish)
                    _arguments -C \
301
                        ':branch-name:__gitex_feature_branch_names'
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
302
                    ;;
303
304
305
306
                -r|--remote )
                    _arguments -C \
                        ':remote-name:__gitex_remote_names'
                    ;;
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
307
            esac
308
            return 0
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
309
310
    esac

311
312
313
    _arguments \
        '(--remote -r)'{--remote,-r}'[setup remote tracking branch]'
}
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
314

spacewander's avatar
spacewander committed
315
316
_git-graft() {
    _arguments \
317
318
        ':src-branch-name:__gitex_branch_names' \
        ':dest-branch-name:__gitex_branch_names'
spacewander's avatar
spacewander committed
319
320
}

321
322
323
324
325
326
327
_git-guilt() {
    _arguments -C \
        '(--email -e)'{--email,-e}'[display author emails instead of names]' \
        '(--ignore-whitespace -w)'{--ignore-whitespace,-w}'[ignore whitespace only changes]' \
        '(--debug -d)'{--debug,-d}'[output debug information]' \
        '-h[output usage information]'
}
spacewander's avatar
spacewander committed
328
329
330
331

_git-ignore() {
    _arguments  -C \
        '(--local -l)'{--local,-l}'[show local gitignore]' \
332
333
        '(--global -g)'{--global,-g}'[show global gitignore]' \
        '(--private -p)'{--private,-p}'[show repo gitignore]'
spacewander's avatar
spacewander committed
334
335
}

336

337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
_git-ignore() {
    _arguments  -C \
        '(--append -a)'{--append,-a}'[append .gitignore]' \
        '(--replace -r)'{--replace,-r}'[replace .gitignore]' \
        '(--list-in-table -l)'{--list-in-table,-l}'[print available types in table format]' \
        '(--list-alphabetically -L)'{--list-alphabetically,-L}'[print available types in alphabetical order]' \
        '(--search -s)'{--search,-s}'[search word in available types]'
}


_git-merge-into() {
    _arguments '--ff-only[merge only fast-forward]'
    _arguments \
        ':src:__gitex_branch_names' \
        ':dest:__gitex_branch_names'
}

spacewander's avatar
spacewander committed
354
355
_git-missing() {
    _arguments \
356
357
        ':first-branch-name:__gitex_branch_names' \
        ':second-branch-name:__gitex_branch_names'
spacewander's avatar
spacewander committed
358
359
}

360

Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
_git-refactor() {
    local curcontext=$curcontext state line ret=1
    declare -A opt_args

    _arguments -C \
        ': :->command' \
        '*:: :->option-or-argument' && ret=0

    case $state in
        (command)
            declare -a commands
            commands=(
                'finish:merge refactor into the current branch'
            )
            _describe -t commands command commands && ret=0
            ;;
        (option-or-argument)
            curcontext=${curcontext%:*}-$line[1]:
            case $line[1] in
                (finish)
                    _arguments -C \
382
                        ':branch-name:__gitex_refactor_branch_names'
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
383
                    ;;
384
385
386
387
                -r|--remote )
                    _arguments -C \
                        ':remote-name:__gitex_remote_names'
                    ;;
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
388
            esac
389
            return 0
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
390
    esac
391
392
393

    _arguments \
        '(--remote -r)'{--remote,-r}'[setup remote tracking branch]'
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
394
395
396
}


spacewander's avatar
spacewander committed
397
398
_git-squash() {
    _arguments \
399
        ':branch-name:__gitex_branch_names'
spacewander's avatar
spacewander committed
400
}
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
401

402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
_git-stamp() {
    _arguments  -C \
         '(--replace -r)'{--replace,-r}'[replace stamps with same id]'
}

_git-standup() {
    _arguments -C \
        '-a[Specify the author of commits. Use "all" to specify all authors.]' \
        '-d[Show history since N days ago]' \
        '-D[Specify the date format displayed in commit history]' \
        '-f[Fetch commits before showing history]' \
        '-g[Display GPG signed info]' \
        '-h[Display help message]' \
        '-L[Enable the inclusion of symbolic links]' \
        '-m[The depth of recursive directory search]'
}

spacewander's avatar
spacewander committed
419
_git-summary() {
420
421
    _arguments '--line[summarize with lines rather than commits]'
    __gitex_commits
Alexis GRIMALDI's avatar
Alexis GRIMALDI committed
422
423
424
}


spacewander's avatar
spacewander committed
425
426
427
428
429
430
_git-undo(){
    _arguments  -C \
        '(--soft -s)'{--soft,-s}'[only rolls back the commit but changes remain un-staged]' \
        '(--hard -h)'{--hard,-h}'[wipes your commit(s)]'
}

431
432
433
zstyle -g existing_user_commands ':completion:*:*:git:*' user-commands

zstyle ':completion:*:*:git:*' user-commands $existing_user_commands \
spacewander's avatar
spacewander committed
434
    alias:'define, search and show aliases' \
435
436
    archive-file:'export the current head of the git repository to an archive' \
    authors:'generate authors report' \
spacewander's avatar
spacewander committed
437
    back:'undo and stage latest commits' \
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
    bug:'create bug branch' \
    bulk:'run bulk commands' \
    changelog:'generate a changelog report' \
    chore:'create chore branch' \
    clear-soft:'soft clean up a repository' \
    clear:'rigorously clean up a repository' \
    commits-since:'show commit logs since some date' \
    contrib:'show user contributions' \
    count:'show commit count' \
    create-branch:'create branches' \
    delete-branch:'delete branches' \
    delete-merged-branches:'delete merged branches' \
    delete-submodule:'delete submodules' \
    delete-tag:'delete tags' \
    delta:'lists changed files' \
    effort:'show effort statistics on file(s)' \
    extras:'awesome git utilities' \
    feature:'create/merge feature branch' \
    force-clone:'overwrite local repositories with clone' \
Kewang's avatar
Kewang committed
457
    fork:'fork a repo on GitHub' \
458
    fresh-branch:'create fresh branches' \
Kewang's avatar
Kewang committed
459
    gh-pages:'create the GitHub pages branch' \
460
461
462
463
464
465
    graft:'merge and destroy a given branch' \
    guilt:'calculate change between two revisions' \
    ignore-io:'get sample gitignore file' \
    ignore:'add .gitignore patterns' \
    info:'returns information on current repository' \
    local-commits:'list local commits' \
spacewander's avatar
spacewander committed
466
467
    lock:'lock a file excluded from version control' \
    locked:'ls files that have been locked' \
468
469
    merge-into:'merge one branch into another' \
    merge-repo:'merge two repo histories' \
spacewander's avatar
spacewander committed
470
    missing:'show commits missing from another branch' \
471
472
    mr:'checks out a merge request locally' \
    obliterate:'rewrite past commits to remove some files' \
spacewander's avatar
spacewander committed
473
    pr:'checks out a pull request locally' \
474
475
476
    psykorebase:'rebase a branch with a merge commit' \
    pull-request:'create pull request to GitHub project' \
    reauthor:'replace the author and/or committer identities in commits and tags' \
spacewander's avatar
spacewander committed
477
    rebase-patch:'rebases a patch' \
478
    refactor:'create refactor branch' \
spacewander's avatar
spacewander committed
479
    release:'commit, tag and push changes to the repository' \
480
    rename-branch:'rename a branch' \
spacewander's avatar
spacewander committed
481
    rename-tag:'rename a tag' \
482
    repl:'git read-eval-print-loop' \
spacewander's avatar
spacewander committed
483
484
    reset-file:'reset one file' \
    root:'show path of root' \
485
486
487
488
    scp:'copy files to ssh compatible `git-remote`' \
    sed:'replace patterns in git-controlled files' \
    setup:'set up a git repository' \
    show-merged-branches:'show merged branches' \
spacewander's avatar
spacewander committed
489
    show-tree:'show branch tree of commit history' \
490
491
492
493
494
495
496
497
    show-unmerged-branches:'show unmerged branches' \
    squash:'import changes from a branch' \
    stamp:'stamp the last commit message' \
    standup:'recall the commit history' \
    summary:'show repository summary' \
    sync:'sync local branch with remote branch' \
    touch:'touch and add file to the index' \
    undo:'remove latest commits' \
spacewander's avatar
spacewander committed
498
    unlock:'unlock a file excluded from version control'