Skip to content

Instantly share code, notes, and snippets.

@davidh-raybeam
Created August 26, 2014 14:31
Show Gist options
  • Save davidh-raybeam/0bb4075a2c7549e877c2 to your computer and use it in GitHub Desktop.
Save davidh-raybeam/0bb4075a2c7549e877c2 to your computer and use it in GitHub Desktop.
Shelly (https://github.com/davidh-raybeam/shelly) script for a git shell with a nice prompt and tab completion for remotes and branches.
#!/usr/bin/env ruby
require 'shelly'
require 'shellwords'
include Shelly
$YELLOW = `tput setaf 3`
$BLUE = `tput setaf 4`
$WHITE = `tput setaf 7`
$RESET = `tput sgr0`
def is_git?
system('git log &>/dev/null')
end
def branch
branches = `git branch 2>/dev/null`.each_line.to_a
active_branch = branches.select { |b| b =~ %r/^\*/ }.first
active_branch.strip.gsub(%r/^\* (.*)$/) { $1 }
end
def changes?
`git status --porcelain 2>/dev/null`.strip.length > 0
end
def all_branches
branches = []
`git branch 2>/dev/null`.each_line do |line|
branches << line.strip.gsub(%r/^\* /, '')
end
branches
end
def all_remotes
`git remote 2>/dev/null`.each_line.to_a.collect(&:strip)
end
# Custom command: \grep
command 'grep',
description: 'searches the repo for the given pattern',
usage: '\grep PATTERN' do |shell, argstring|
system "egrep #{argstring} -r . -n --exclude='*.git*' --color=tty"
puts; puts
end
# Prompt:
# [current_branch]± (when there are no uncommitted changes)
# [current_branch(!)]± (when there are uncommitted changes)
# ?? (when cwd is not a git repo)
prompt do |cont|
if cont
"#{$WHITE}> #{$RESET}"
else
if is_git?
if changes?
changestr = "#{$YELLOW}(!)"
else
changestr = ""
end
"#{$WHITE}[#{$BLUE}#{branch}#{changestr}#{$WHITE}]\u00b1 #{$RESET}"
else
"#{$YELLOW}?? #{$RESET}"
end
end
end
# Tab-completion:
# If the partial matches any branches or remotes, return those.
# If not, fall back to filenames.
# NOTE: if you want filenames, branches, and remotes to have the same
# priority, change tab_complete's first argument to :filenames
tab_complete :filenames_after do |partial|
candidates = all_branches + all_remotes
matches = candidates.grep %r/^#{Regexp.escape partial}/
if matches.length == 1
[matches[0] + ' ']
else
matches
end
end
shelly 'git'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment