Skip to content

Instantly share code, notes, and snippets.

@gnfisher
Last active March 17, 2020 18:12
Show Gist options
  • Save gnfisher/16ebb1c9f299b7172f27fce21886cc9a to your computer and use it in GitHub Desktop.
Save gnfisher/16ebb1c9f299b7172f27fce21886cc9a to your computer and use it in GitHub Desktop.
Dotfiles
=== zshrc
# Lines configured by zsh-newuser-install
HISTFILE=~/.histfile
HISTSIZE=10000
SAVEHIST=10000
setopt appendhistory autocd extendedglob
unsetopt beep
bindkey -e
# End of lines configured by zsh-newuser-install
# The following lines were added by compinstall
zstyle :compinstall filename '/home/greg/.zshrc'
zstyle ':completion:*' matcher-list '' 'm:{a-zA-Z}={A-Za-z}'
source ~/zprompts/zprompts.plugin.zsh
autoload -Uz compinit promptinit
compinit
promptinit
prompt scala4
# End of lines added by compinstall
# Disable ctrl+s
stty -ixon
. $HOME/.asdf/asdf.sh
. $HOME/.asdf/completions/asdf.bash
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
export PATH=$PATH:/usr/bin:/home/greg/bin:/Users/greg/bin
export EDITOR=nvim
export JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/
export PATH="/usr/local/opt/scala@2.12/bin:$PATH"
export PATH="/usr/local/sbin:$PATH"
alias ads='cd ~/Code/thoughtbot/ads-quoting-ui'
alias adss='cd ~/Code/thoughtbot/ads-quoting-server'
alias nv=nvim
alias g=git
alias c=clear
alias scratch='nvim ~/Scratch'
alias sf='~/Code/thoughtbot/ads-quoting-server/bin/salesforce'
alias sfq='~/Code/thoughtbot/ads-quoting-server/bin/salesforce query '
alias sfd='~/Code/thoughtbot/ads-quoting-server/bin/salesforce describe '
=== vimrc
set encoding=utf-8
" Leader
let mapleader = " "
set backspace=2 " Backspace deletes like most programs in insert mode
set nobackup
set nowritebackup
set noswapfile " http://robots.thoughtbot.com/post/18739402579/global-gitignore#comment-458413287
set undofile
set undodir=~/.vim/undodir
set history=50
set ruler " show the cursor position all the time
set showcmd " display incomplete commands
set incsearch " do incremental searching
set laststatus=2 " Always display the status line
set autowrite " Automatically :write before running commands
set modelines=0 " Disable modelines as a security precaution
set nomodeline
set ignorecase smartcase
set autoread
set noeb vb t_vb=
set complete=.,w,b,u,t,i
:set completeopt=menu,preview
set nofoldenable
set foldmethod=manual
set nojoinspaces
set scrolloff=10
set sidescrolloff=5
" statusline
:set statusline=%<%f\ (%{&ft})\ %-4(%m%)%=%-19(%3l,%02c%03V%)
" Switch syntax highlighting on, when the terminal has colors
" Also switch on highlighting the last used search pattern.
if (&t_Co > 2 || has("gui_running")) && !exists("syntax_on")
syntax enable
endif
if filereadable(expand("~/.vimrc.bundles"))
source ~/.vimrc.bundles
endif
" Load matchit.vim, but only if the user hasn't installed a newer version.
if !exists('g:loaded_matchit') && findfile('plugin/matchit.vim', &rtp) ==# ''
runtime! macros/matchit.vim
endif
filetype plugin indent on
" Use The Silver Searcher https://github.com/ggreer/the_silver_searcher
if executable('ag')
" Use Ag over Grep
set grepprg=ag\ --nogroup\ --nocolor
" Use ag in fzf for listing files. Lightning fast and respects .gitignore
let $FZF_DEFAULT_COMMAND = 'ag --literal --files-with-matches --nocolor --hidden -g ""'
endif
" Tab completion
" will insert tab at beginning of line,
" will use completion if not at beginning
set wildmode=list:longest,list:full
function! InsertTabWrapper()
let col = col('.') - 1
if !col || getline('.')[col - 1] !~ '\k'
return "\<Tab>"
else
return "\<C-p>"
endif
endfunction
inoremap <Tab> <C-r>=InsertTabWrapper()<CR>
inoremap <S-Tab> <C-n>
augroup vimrcEx
autocmd!
" When editing a file, always jump to the last known cursor position.
" Don't do it for commit messages, when the position is invalid, or when
" inside an event handler (happens when dropping a file on gvim).
autocmd BufReadPost *
\ if &ft != 'gitcommit' && line("'\"") > 0 && line("'\"") <= line("$") |
\ exe "normal g`\"" |
\ endif
" Set syntax highlighting for specific file types
autocmd BufRead,BufNewFile *.md set filetype=markdown
autocmd BufRead,BufNewFile .{jscs,jshint,eslint}rc set filetype=json
autocmd BufRead,BufNewFile aliases.local,zshrc.local,*/zsh/configs/* set filetype=sh
autocmd BufRead,BufNewFile gitconfig.local set filetype=gitconfig
autocmd BufRead,BufNewFile tmux.conf.local set filetype=tmux
autocmd BufRead,BufNewFile vimrc.local set filetype=vim
autocmd BufNewFile,BufRead * if expand('%:t') !~ '\.' | setlocal textwidth=80 | endif
" json
autocmd! FileType json set sw=2 sts=2 expandtab
autocmd! FileType scss set sw=2 sts=2 expandtab
" elm indentation
autocmd! FileType elm set sw=4 sts=4 expandtab autoindent smartindent nocindent
" Remove whitespace at end of lines
autocmd BufWritePre *.erb,*.scss,*.rb,*.js,*.c,*.py,*.php,*.coffee :%s/\s\+$//e
autocmd BufRead,BufNewFile *.sbt set filetype=scala
" Spell check gitcommits and Markdown
autocmd FileType gitcommit setlocal spell
autocmd BufRead,BufNewFile *.md setlocal spell
" Only wrap md and text
autocmd BufRead,BufNewFile *.md,*.txt setlocal textwidth=80
augroup END
" When the type of shell script is /bin/sh, assume a POSIX-compatible
" shell for syntax highlighting purposes.
let g:is_posix = 1
" Softtabs, 2 spaces
set tabstop=2
set shiftwidth=2
set shiftround
set expandtab
" Display extra whitespace
set list listchars=tab:»·,trail:·,nbsp:·
" Use one space, not two, after punctuation.
set nojoinspaces
" Make it obvious where 80 characters is
set colorcolumn=81
" Numbers
set number
set numberwidth=5
" Tab completion
" will insert tab at beginning of line,
" will use completion if not at beginning
set wildmode=list:longest,list:full
function! InsertTabWrapper()
let col = col('.') - 1
if !col || getline('.')[col - 1] !~ '\k'
return "\<Tab>"
else
return "\<C-p>"
endif
endfunction
inoremap <Tab> <C-r>=InsertTabWrapper()<CR>
inoremap <S-Tab> <C-n>
" Switch between the last two files
nnoremap <Leader><Leader> <C-^>
" vim-test mappings
nnoremap <silent> <Leader>tf :TestFile<CR>
nnoremap <silent> <Leader>tn :TestNearest<CR>
nnoremap <silent> <Leader>tl :TestLast<CR>
nnoremap <silent> <Leader>ta :TestSuite<CR>
nnoremap <silent> <Leader>tv :TestVisit<CR>
let test#strategy = "dispatch"
" Run commands that require an interactive shell
nnoremap <Leader>r :RunInInteractiveShell<Space>
" Treat <li> and <p> tags like the block tags they are
let g:html_indent_tags = 'li\|p'
" Set tags for vim-fugitive
set tags^=.git/tags
" Open new split panes to right and bottom, which feels more natural
set splitbelow
set splitright
" Quicker window movement
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-h> <C-w>h
nnoremap <C-l> <C-w>l
" Set spellfile to location that is guaranteed to exist, can be symlinked to
" Dropbox or kept in Git and managed outside of thoughtbot/dotfiles using rcm.
set spellfile=$HOME/.vim-spell-en.utf-8.add
" Autocomplete with dictionary words when spell check is on
set complete+=kspell
" Always use vertical diffs
set diffopt+=vertical
" use C-Space to Esc any mode
nnoremap <C-Space> <Esc>:noh<CR>
vnoremap <C-Space> <Esc>gV
onoremap <C-Space> <Esc>
cnoremap <C-Space> <C-c>
inoremap <C-Space> <Esc>
" terminal sees <C-@> as <C-space>
nnoremap <C-@> <Esc>:noh<CR>
vnoremap <C-@> <Esc>gV
onoremap <C-@> <Esc>
cnoremap <C-@> <C-c>
inoremap <C-@> <Esc>
" convenience
nnoremap <leader>; :
" move between wrapped lines
nmap j gj
nmap k gk
nnoremap <leader>sub :%s///g<left><left>
vnoremap <leader>sub :s///g<left><left>
" CoC config
set updatetime=300
set shortmess+=c
set signcolumn=yes
" Use tab for trigger completion with characters ahead and navigate.
" Use command ':verbose imap <tab>' to make sure tab is not mapped by other plugin.
inoremap <silent><expr> <TAB>
\ pumvisible() ? "\<C-n>" :
\ <SID>check_back_space() ? "\<TAB>" :
\ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
function! s:check_back_space() abort
let col = col('.') - 1
return !col || getline('.')[col - 1] =~# '\s'
endfunction
" Use <c-tag> to trigger completion.
inoremap <silent><expr> <c-tab> coc#refresh()
" Use <cr> to confirm completion, `<C-g>u` means break undo chain at current position.
" Coc only does snippet and additional edit on confirm.
inoremap <expr> <cr> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
" Or use `complete_info` if your vim support it, like:
" noremap <expr> <cr> complete_info()["selected"] != "-1" ? "\<C-y>" : "\<C-g>u\<CR>"
nmap <silent> [g <Plug>(coc-diagnostic-prev)
nmap <silent> ]g <Plug>(coc-diagnostic-next)
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gr <Plug>(coc-references)
nnoremap <expr><C-f> coc#util#has_float() ? coc#util#float_scroll(1) : "\<C-f>"
nnoremap <expr><C-b> coc#util#has_float() ? coc#util#float_scroll(0) : "\<C-b>"
" Use K to show documentation in preview window
nnoremap <silent> K :call <SID>show_documentation()<CR>
function! s:show_documentation()
if (index(['vim','help'], &filetype) >= 0)
execute 'h '.expand('<cword>')
else
call CocAction('doHover')
endif
endfunction
" Remap for format selected region
xmap <leader>f <Plug>(coc-format-selected)
nmap <leader>f <Plug>(coc-format-selected)
nnoremap <silent> <leader>F :call CocAction('format')<CR>
augroup mygroup
autocmd!
" Setup formatexpr specified filetype(s).
autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
" Update signature help on jump placeholder
autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
augroup end
" Use `:Format` to format current buffer
command! -nargs=0 Format :call CocAction('format')
" Use `:Fold` to fold current buffer
command! -nargs=? Fold :call CocAction('fold', <f-args>)
" use `:OR` for organize import of current buffer
command! -nargs=0 OR :call CocAction('runCommand', 'editor.action.organizeImport')
" Add status line support, for integration with other plugin, checkout `:h coc-status`
set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')}
" Using CocList
" Show all diagnostics
nnoremap <silent> <space>d :<C-u>CocList diagnostics<cr>
" fzf
nnoremap <C-p> :Files<CR>
nnoremap <C-a> :Ag<space>
nnoremap <leader>fp :Files<cr>
nnoremap <leader>fb :Buffers<CR>
nnoremap <leader>ft :Tag<cr>
nnoremap <leader>fo :BTag<cr>
nnoremap <leader>fa :Files app/<cr>
nnoremap <leader>fm :Files app/models/<cr>
nnoremap <leader>fv :Files app/views/<cr>
nnoremap <leader>fc :Files app/controllers/<cr>
nnoremap <leader>fy :Files app/assets/stylesheets/<cr>
nnoremap <leader>fj :Files app/assets/javascripts/<cr>
nnoremap <leader>fs :Files spec/<cr>
let g:fzf_files_options = '--preview "(coderay {} || cat {}) 2> /dev/null | head -'.&lines.'"'
" \ '--reverse ' .
" shortcut to open files
map <Leader>e :e <C-R>=expand("%:p:h") . "/" <CR>
map <Leader>te :tabe <C-R>=expand("%:p:h") . "/" <CR>
map <Leader>se :sp <C-R>=expand("%:p:h") . "/" <CR>
nmap <Leader>g :silent !termite -e gitsh &> /dev/null &<CR>
nmap <Leader>z :silent !termite &> /dev/null &<CR>
" Easier than "+
nmap cp "+y
xnoremap cp "+y
nmap cv "+p
nmap cV "+P
" in line, around line operators
xnoremap il g_o0
onoremap il :normal vil<CR>
xnoremap al $o0
onoremap al :normal val<CR>
function CopyToBasecamp() range
echo system('echo '.shellescape(join(getline(a:firstline, a:lastline), "\n")).' | pandoc -f markdown | textutil -stdin -format html -convert rtf -stdout | pbcopy')
endfunction
com -range=% -nargs=0 CopyToBasecamp :<line1>,<line2>call CopyToBasecamp()
xnoremap <Leader>b <esc>:'<,'>CopyToBasecamp<CR>
let g:lightline = {
\ 'colorscheme': 'onedark',
\ }
set termguicolors
set background=light
" colorscheme onedark
=== diffsofancy
#!/usr/bin/env perl
# This chunk of stuff was generated by App::FatPacker. To find the original
# file's code, look for the end of this BEGIN block or the string 'FATPACK'
BEGIN {
my %fatpacked;
$fatpacked{"DiffHighlight.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'DIFFHIGHLIGHT';
package DiffHighlight;
use 5.008;
use warnings FATAL => 'all';
use strict;
# Use the correct value for both UNIX and Windows (/dev/null vs nul)
use File::Spec;
my $NULL = File::Spec->devnull();
# Highlight by reversing foreground and background. You could do
# other things like bold or underline if you prefer.
our @OLD_HIGHLIGHT = (
color_config('color.diff-highlight.oldnormal', "\e[1;31m"),
color_config('color.diff-highlight.oldhighlight', "\e[1;31;48;5;52m"),
"\x1b[27m",
);
our @NEW_HIGHLIGHT = (
color_config('color.diff-highlight.newnormal', "\e[1;32m"),
color_config('color.diff-highlight.newhighlight', "\e[1;32;48;5;22m"),
$OLD_HIGHLIGHT[2],
);
my $RESET = "\x1b[m";
my $COLOR = qr/\x1b\[[0-9;]*m/;
my $BORING = qr/$COLOR|\s/;
my @removed;
my @added;
my $in_hunk;
my $graph_indent = 0;
our $line_cb = sub { print @_ };
our $flush_cb = sub { local $| = 1 };
# Count the visible width of a string, excluding any terminal color sequences.
sub visible_width {
local $_ = shift;
my $ret = 0;
while (length) {
if (s/^$COLOR//) {
# skip colors
} elsif (s/^.//) {
$ret++;
}
}
return $ret;
}
# Return a substring of $str, omitting $len visible characters from the
# beginning, where terminal color sequences do not count as visible.
sub visible_substr {
my ($str, $len) = @_;
while ($len > 0) {
if ($str =~ s/^$COLOR//) {
next
}
$str =~ s/^.//;
$len--;
}
return $str;
}
sub handle_line {
my $orig = shift;
local $_ = $orig;
# match a graph line that begins a commit
if (/^(?:$COLOR?\|$COLOR?[ ])* # zero or more leading "|" with space
$COLOR?\*$COLOR?[ ] # a "*" with its trailing space
(?:$COLOR?\|$COLOR?[ ])* # zero or more trailing "|"
[ ]* # trailing whitespace for merges
/x) {
my $graph_prefix = $&;
# We must flush before setting graph indent, since the
# new commit may be indented differently from what we
# queued.
flush();
$graph_indent = visible_width($graph_prefix);
} elsif ($graph_indent) {
if (length($_) < $graph_indent) {
$graph_indent = 0;
} else {
$_ = visible_substr($_, $graph_indent);
}
}
if (!$in_hunk) {
$line_cb->($orig);
$in_hunk = /^$COLOR*\@\@ /;
}
elsif (/^$COLOR*-/) {
push @removed, $orig;
}
elsif (/^$COLOR*\+/) {
push @added, $orig;
}
else {
flush();
$line_cb->($orig);
$in_hunk = /^$COLOR*[\@ ]/;
}
# Most of the time there is enough output to keep things streaming,
# but for something like "git log -Sfoo", you can get one early
# commit and then many seconds of nothing. We want to show
# that one commit as soon as possible.
#
# Since we can receive arbitrary input, there's no optimal
# place to flush. Flushing on a blank line is a heuristic that
# happens to match git-log output.
if (!length) {
$flush_cb->();
}
}
sub flush {
# Flush any queued hunk (this can happen when there is no trailing
# context in the final diff of the input).
show_hunk(\@removed, \@added);
@removed = ();
@added = ();
}
sub highlight_stdin {
while (<STDIN>) {
handle_line($_);
}
flush();
}
# Ideally we would feed the default as a human-readable color to
# git-config as the fallback value. But diff-highlight does
# not otherwise depend on git at all, and there are reports
# of it being used in other settings. Let's handle our own
# fallback, which means we will work even if git can't be run.
sub color_config {
my ($key, $default) = @_;
my $s = `git config --get-color $key 2>$NULL`;
return length($s) ? $s : $default;
}
sub show_hunk {
my ($a, $b) = @_;
# If one side is empty, then there is nothing to compare or highlight.
if (!@$a || !@$b) {
$line_cb->(@$a, @$b);
return;
}
# If we have mismatched numbers of lines on each side, we could try to
# be clever and match up similar lines. But for now we are simple and
# stupid, and only handle multi-line hunks that remove and add the same
# number of lines.
if (@$a != @$b) {
$line_cb->(@$a, @$b);
return;
}
my @queue;
for (my $i = 0; $i < @$a; $i++) {
my ($rm, $add) = highlight_pair($a->[$i], $b->[$i]);
$line_cb->($rm);
push @queue, $add;
}
$line_cb->(@queue);
}
sub highlight_pair {
my @a = split_line(shift);
my @b = split_line(shift);
# Find common prefix, taking care to skip any ansi
# color codes.
my $seen_plusminus;
my ($pa, $pb) = (0, 0);
while ($pa < @a && $pb < @b) {
if ($a[$pa] =~ /$COLOR/) {
$pa++;
}
elsif ($b[$pb] =~ /$COLOR/) {
$pb++;
}
elsif ($a[$pa] eq $b[$pb]) {
$pa++;
$pb++;
}
elsif (!$seen_plusminus && $a[$pa] eq '-' && $b[$pb] eq '+') {
$seen_plusminus = 1;
$pa++;
$pb++;
}
else {
last;
}
}
# Find common suffix, ignoring colors.
my ($sa, $sb) = ($#a, $#b);
while ($sa >= $pa && $sb >= $pb) {
if ($a[$sa] =~ /$COLOR/) {
$sa--;
}
elsif ($b[$sb] =~ /$COLOR/) {
$sb--;
}
elsif ($a[$sa] eq $b[$sb]) {
$sa--;
$sb--;
}
else {
last;
}
}
if (is_pair_interesting(\@a, $pa, $sa, \@b, $pb, $sb)) {
return highlight_line(\@a, $pa, $sa, \@OLD_HIGHLIGHT),
highlight_line(\@b, $pb, $sb, \@NEW_HIGHLIGHT);
}
else {
return join('', @a),
join('', @b);
}
}
# we split either by $COLOR or by character. This has the side effect of
# leaving in graph cruft. It works because the graph cruft does not contain "-"
# or "+"
sub split_line {
local $_ = shift;
return utf8::decode($_) ?
map { utf8::encode($_); $_ }
map { /$COLOR/ ? $_ : (split //) }
split /($COLOR+)/ :
map { /$COLOR/ ? $_ : (split //) }
split /($COLOR+)/;
}
sub highlight_line {
my ($line, $prefix, $suffix, $theme) = @_;
my $start = join('', @{$line}[0..($prefix-1)]);
my $mid = join('', @{$line}[$prefix..$suffix]);
my $end = join('', @{$line}[($suffix+1)..$#$line]);
# If we have a "normal" color specified, then take over the whole line.
# Otherwise, we try to just manipulate the highlighted bits.
if (defined $theme->[0]) {
s/$COLOR//g for ($start, $mid, $end);
chomp $end;
return join('',
$theme->[0], $start, $RESET,
$theme->[1], $mid, $RESET,
$theme->[0], $end, $RESET,
"\n"
);
} else {
return join('',
$start,
$theme->[1], $mid, $theme->[2],
$end
);
}
}
# Pairs are interesting to highlight only if we are going to end up
# highlighting a subset (i.e., not the whole line). Otherwise, the highlighting
# is just useless noise. We can detect this by finding either a matching prefix
# or suffix (disregarding boring bits like whitespace and colorization).
sub is_pair_interesting {
my ($a, $pa, $sa, $b, $pb, $sb) = @_;
my $prefix_a = join('', @$a[0..($pa-1)]);
my $prefix_b = join('', @$b[0..($pb-1)]);
my $suffix_a = join('', @$a[($sa+1)..$#$a]);
my $suffix_b = join('', @$b[($sb+1)..$#$b]);
return visible_substr($prefix_a, $graph_indent) !~ /^$COLOR*-$BORING*$/ ||
visible_substr($prefix_b, $graph_indent) !~ /^$COLOR*\+$BORING*$/ ||
$suffix_a !~ /^$BORING*$/ ||
$suffix_b !~ /^$BORING*$/;
}
DIFFHIGHLIGHT
s/^ //mg for values %fatpacked;
my $class = 'FatPacked::'.(0+\%fatpacked);
no strict 'refs';
*{"${class}::files"} = sub { keys %{$_[0]} };
if ($] < 5.008) {
*{"${class}::INC"} = sub {
if (my $fat = $_[0]{$_[1]}) {
my $pos = 0;
my $last = length $fat;
return (sub {
return 0 if $pos == $last;
my $next = (1 + index $fat, "\n", $pos) || $last;
$_ .= substr $fat, $pos, $next - $pos;
$pos = $next;
return 1;
});
}
};
}
else {
*{"${class}::INC"} = sub {
if (my $fat = $_[0]{$_[1]}) {
open my $fh, '<', \$fat
or die "FatPacker error loading $_[1] (could be a perl installation issue?)";
return $fh;
}
return;
};
}
unshift @INC, bless \%fatpacked, $class;
} # END OF FATPACK CODE
my $VERSION = "1.2.6";
#################################################################################
use File::Spec; # For catdir
use File::Basename; # For dirname
use Encode; # For handling UTF8 stuff
use Cwd qw(abs_path); # For realpath()
use lib dirname(abs_path(File::Spec->catdir($0))) . "/lib"; # Add the local lib/ to @INC
use DiffHighlight;
use strict;
use warnings FATAL => 'all';
my $remove_file_add_header = 1;
my $remove_file_delete_header = 1;
my $clean_permission_changes = 1;
my $manually_color_lines = 0; # Usually git/hg colorizes the lines, but for raw patches we use this
my $change_hunk_indicators = git_config_boolean("diff-so-fancy.changeHunkIndicators","true");
my $strip_leading_indicators = git_config_boolean("diff-so-fancy.stripLeadingSymbols","true");
my $mark_empty_lines = git_config_boolean("diff-so-fancy.markEmptyLines","true");
my $use_unicode_dash_for_ruler = git_config_boolean("diff-so-fancy.useUnicodeRuler","true");
my $ruler_width = git_config("diff-so-fancy.rulerWidth", undef);
my $git_strip_prefix = git_config_boolean("diff.noprefix","false");
my $has_stdin = has_stdin();
my $ansi_color_regex = qr/(\e\[([0-9]{1,3}(;[0-9]{1,3}){0,10})[mK])?/;
my $reset_color = color("reset");
my $bold = color("bold");
my $meta_color = "";
my ($file_1,$file_2);
my $args = argv(); # Hashref of all the ARGV stuff
my $last_file_seen = "";
my $last_file_mode = "";
my $i = 0;
my $in_hunk = 0;
my $columns_to_remove = 0;
my $is_mercurial = 0;
my $color_forced = 0; # Has the color been forced on/off
# We try and be smart about whether we need to do line coloring, but
# this is an option to force it on/off
if ($args->{color_on}) {
$manually_color_lines = 1;
$color_forced = 1;
} elsif ($args->{color_off}) {
$manually_color_lines = 0;
$color_forced = 1;
}
# We only process ARGV if we don't have STDIN
if (!$has_stdin) {
if ($args->{v} || $args->{version}) {
die(version());
} elsif ($args->{'set-defaults'}) {
my $ok = set_defaults();
} elsif ($args->{colors}) {
# We print this to STDOUT so we can redirect to bash to auto-set the colors
print get_default_colors();
exit;
} elsif (!%$args || $args->{help} || $args->{h}) {
my $first = check_first_run();
if (!$first) {
die(usage());
}
} else {
die("Missing input on STDIN\n");
}
} else {
# Check to see if were using default settings
check_first_run();
my @lines;
local $DiffHighlight::line_cb = sub {
push(@lines,@_);
my $last_line = $lines[-1];
# Buffer X lines before we try and output anything
# Also make sure we're sending enough data to d-s-f to do it's magic.
# Certain things require a look-ahead line or two to function so
# we make sure we don't break on those sections prematurely
if (@lines > 24 && ($last_line !~ /^${ansi_color_regex}(---|index|old mode|similarity index|rename (from|to))/)) {
do_dsf_stuff(\@lines);
@lines = ();
}
};
my $line_count = 0;
while (my $line = <STDIN>) {
# If the very first line of the diff doesn't start with ANSI color we're assuming
# it's a raw patch file, and we have to color the added/removed lines ourself
if (!$color_forced && $line_count == 0 && starts_with_ansi($line)) {
$manually_color_lines = 1;
}
my $ok = DiffHighlight::handle_line($line);
$line_count++;
}
DiffHighlight::flush();
do_dsf_stuff(\@lines);
}
#################################################################################
sub do_dsf_stuff {
my $input = shift();
#print STDERR "START -------------------------------------------------\n";
#print STDERR join("",@$input);
#print STDERR "END ---------------------------------------------------\n";
while (my $line = shift(@$input)) {
######################################################
# Pre-process the line before we do any other markup #
######################################################
# If the first line of the input is a blank line, skip that
if ($i == 0 && $line =~ /^\s*$/) {
next;
}
######################
# End pre-processing #
######################
#######################################################################
####################################################################
# Look for git index and replace it horizontal line (header later) #
####################################################################
if ($line =~ /^${ansi_color_regex}index /) {
# Print the line color and then the actual line
$meta_color = $1 || get_config_color("meta");
# Get the next line without incrementing counter while loop
my $next = $input->[0] || "";
my ($file_1,$file_2);
# The line immediately after the "index" line should be the --- file line
# If it's not it's an empty file add/delete
if ($next !~ /^$ansi_color_regex(---|Binary files)/) {
# We fake out the file names since it's a raw add/delete
if ($last_file_mode eq "add") {
$file_1 = "/dev/null";
$file_2 = $last_file_seen;
} elsif ($last_file_mode eq "delete") {
$file_1 = $last_file_seen;
$file_2 = "/dev/null";
}
}
if ($file_1 && $file_2) {
print horizontal_rule($meta_color);
print $meta_color . file_change_string($file_1,$file_2) . "\n";
print horizontal_rule($meta_color);
}
#########################
# Look for the filename #
#########################
# $4 $5
} elsif ($line =~ /^${ansi_color_regex}diff (-r|--git|--cc) (.+?)(\s|\e|$)/) {
# Mercurial looks like: diff -r 82e55d328c8c hello.c
if ($4 eq "-r") {
$is_mercurial = 1;
$meta_color ||= get_config_color("meta");
# Git looks like: diff --git a/diff-so-fancy b/diff-so-fancy
} else {
$last_file_seen = $5;
}
$last_file_seen =~ s|^\w/||; # Remove a/ (and handle diff.mnemonicPrefix).
$in_hunk = 0;
########################################
# Find the first file: --- a/README.md #
########################################
} elsif (!$in_hunk && $line =~ /^$ansi_color_regex--- (\w\/)?(.+?)(\e|\t|$)/) {
$meta_color ||= get_config_color("meta");
if ($git_strip_prefix) {
my $file_dir = $4 || "";
$file_1 = $file_dir . $5;
} else {
$file_1 = $5;
}
# Find the second file on the next line: +++ b/README.md
my $next = shift(@$input);
$next =~ /^$ansi_color_regex\+\+\+ (\w\/)?(.+?)(\e|\t|$)/;
if ($1) {
print $1; # Print out whatever color we're using
}
if ($git_strip_prefix) {
my $file_dir = $4 || "";
$file_2 = $file_dir . $5;
} else {
$file_2 = $5;
}
if ($file_2 ne "/dev/null") {
$last_file_seen = $file_2;
}
# Print out the top horizontal line of the header
print $reset_color;
print horizontal_rule($meta_color);
# Mercurial coloring is slightly different so we need to hard reset colors
if ($is_mercurial) {
print $reset_color;
}
print $meta_color;
print file_change_string($file_1,$file_2) . "\n";
# Print out the bottom horizontal line of the header
print horizontal_rule($meta_color);
########################################
# Check for "@@ -3,41 +3,63 @@" syntax #
########################################
} elsif ($change_hunk_indicators && $line =~ /^${ansi_color_regex}(@@@* .+? @@@*)(.*)/) {
$in_hunk = 1;
my $hunk_header = $4;
my $remain = bleach_text($5);
# The number of colums to remove (1 or 2) is based on how many commas in the hunk header
$columns_to_remove = (char_count(",",$hunk_header)) - 1;
# On single line removes there is NO comma in the hunk so we force one
if ($columns_to_remove <= 0) {
$columns_to_remove = 1;
}
if ($1) {
print $1; # Print out whatever color we're using
}
my ($orig_offset, $orig_count, $new_offset, $new_count) = parse_hunk_header($hunk_header);
#$last_file_seen = basename($last_file_seen);
# Figure out the start line
my $start_line = start_line_calc($new_offset,$new_count);
# Last function has it's own color
my $last_function_color = get_config_color("last_function");
print "@ $last_file_seen:$start_line \@${bold}${last_function_color}${remain}${reset_color}\n";
###################################
# Remove any new file permissions #
###################################
} elsif ($remove_file_add_header && $line =~ /^${ansi_color_regex}.*new file mode/) {
# Don't print the line (i.e. remove it from the output);
$last_file_mode = "add";
######################################
# Remove any delete file permissions #
######################################
} elsif ($remove_file_delete_header && $line =~ /^${ansi_color_regex}deleted file mode/) {
# Don't print the line (i.e. remove it from the output);
$last_file_mode = "delete";
################################
# Look for binary file changes #
################################
} elsif ($line =~ /^Binary files (\w\/)?(.+?) and (\w\/)?(.+?) differ/) {
my $change = file_change_string($2,$4);
print horizontal_rule($meta_color);
print "$meta_color$change (binary)\n";
print horizontal_rule($meta_color);
#####################################################
# Check if we're changing the permissions of a file #
#####################################################
} elsif ($clean_permission_changes && $line =~ /^${ansi_color_regex}old mode (\d+)/) {
my ($old_mode) = $4;
my $next = shift(@$input);
if ($1) {
print $1; # Print out whatever color we're using
}
my ($new_mode) = $next =~ m/new mode (\d+)/;
print "$last_file_seen changed file mode from $old_mode to $new_mode\n";
###############
# File rename #
###############
} elsif ($line =~ /^${ansi_color_regex}similarity index (\d+)%/) {
my $simil = $4;
# If it's a move with content change we ignore this and the next two lines
if ($simil != 100) {
shift(@$input);
shift(@$input);
next;
}
my $next = shift(@$input);
my ($file1) = $next =~ /rename from (.+)/;
$next = shift(@$input);
my ($file2) = $next =~ /rename to (.+)/;
if ($file1 && $file2) {
# We may not have extracted this yet, so we pull from the config if not
$meta_color ||= get_config_color("meta");
my $change = file_change_string($file1,$file2);
print horizontal_rule($meta_color);
print $meta_color . $change . "\n";
print horizontal_rule($meta_color);
}
$i += 3; # We've consumed three lines
next;
#####################################
# Just a regular line, print it out #
#####################################
} else {
# Mark empty line with a red/green box indicating addition/removal
if ($mark_empty_lines) {
$line = mark_empty_line($line);
}
# Remove the correct number of leading " " or "+" or "-"
if ($strip_leading_indicators) {
$line = strip_leading_indicators($line,$columns_to_remove);
}
print $line;
}
$i++;
}
}
######################################################################################################
# End regular code, begin functions
######################################################################################################
# Courtesy of github.com/git/git/blob/ab5d01a/git-add--interactive.perl#L798-L805
sub parse_hunk_header {
my ($line) = @_;
my ($o_ofs, $o_cnt, $n_ofs, $n_cnt) = $line =~ /^\@\@+(?: -(\d+)(?:,(\d+))?)+ \+(\d+)(?:,(\d+))? \@\@+/;
$o_cnt = 1 unless defined $o_cnt;
$n_cnt = 1 unless defined $n_cnt;
return ($o_ofs, $o_cnt, $n_ofs, $n_cnt);
}
# Mark the first char of an empty line
sub mark_empty_line {
my $line = shift();
my $reset_color = "\e\\[0?m";
my $reset_escape = "\e\[m";
my $invert_color = "\e\[7m";
$line =~ s/^($ansi_color_regex)[+-]$reset_color\s*$/$invert_color$1 $reset_escape\n/;
return $line;
}
# String to boolean
sub boolean {
my $str = shift();
$str = trim($str);
if ($str eq "" || $str =~ /^(no|false|0)$/i) {
return 0;
} else {
return 1;
}
}
# Memoize getting the git config
{
my $static_config;
sub git_config_raw {
if ($static_config) {
# If we already have the config return that
return $static_config;
}
my $cmd = "git config --list";
my @out = `$cmd`;
$static_config = \@out;
return \@out;
}
}
# Fetch a textual item from the git config
sub git_config {
my $search_key = lc($_[0] || "");
my $default_value = lc($_[1] || "");
my $out = git_config_raw();
# If we're in a unit test, use the default (don't read the users config)
if (in_unit_test()) {
return $default_value;
}
my $raw = {};
foreach my $line (@$out) {
if ($line =~ /=/) {
my ($key,$value) = split("=",$line,2);
$value =~ s/\s+$//;
$raw->{$key} = $value;
}
}
# If we're given a search key return that, else return the hash
if ($search_key) {
return $raw->{$search_key} || $default_value;
} else {
return $raw;
}
}
# Fetch a boolean item from the git config
sub git_config_boolean {
my $search_key = lc($_[0] || "");
my $default_value = lc($_[1] || 0); # Default to false
# If we're in a unit test, use the default (don't read the users config)
if (in_unit_test()) {
return boolean($default_value);
}
my $result = git_config($search_key,$default_value);
my $ret = boolean($result);
return $ret;
}
# Check if we're inside of BATS
sub in_unit_test {
if ($ENV{BATS_CWD}) {
return 1;
} else {
return 0;
}
}
sub get_less_charset {
my @less_char_vars = ("LESSCHARSET", "LESSCHARDEF", "LC_ALL", "LC_CTYPE", "LANG");
foreach (@less_char_vars) {
return $ENV{$_} if defined $ENV{$_};
}
return "";
}
sub should_print_unicode {
if (-t STDOUT) {
# Always print unicode chars if we're not piping stuff, e.g. to less(1)
return 1;
}
# Otherwise, assume we're piping to less(1)
my $less_charset = get_less_charset();
if ($less_charset =~ /utf-?8/i) {
return 1;
}
return 0;
}
# Try and be smart about what line the diff hunk starts on
sub start_line_calc {
my ($line_num,$diff_context) = @_;
my $ret;
if ($line_num == 0 && $diff_context == 0) {
return 1;
}
# Git defaults to three lines of context
my $default_context_lines = 3;
# Three lines on either side, and the line itself = 7
my $expected_context = ($default_context_lines * 2 + 1);
# The first three lines
if ($line_num == 1 && $diff_context < $expected_context) {
$ret = $diff_context - $default_context_lines;
} else {
$ret = $line_num + $default_context_lines;
}
if ($ret < 1) {
$ret = 1;
}
return $ret;
}
# Remove + or - at the beginning of the lines
sub strip_leading_indicators {
my $line = shift(); # Array passed in by reference
my $columns_to_remove = shift(); # Don't remove any lines by default
if ($columns_to_remove == 0) {
return $line; # Nothing to do
}
$line =~ s/^(${ansi_color_regex})([ +-]){${columns_to_remove}}/$1/;
if ($manually_color_lines) {
if (defined($5) && $5 eq "+") {
my $add_line_color = get_config_color("add_line");
$line = $add_line_color . $line . $reset_color;
} elsif (defined($5) && $5 eq "-") {
my $remove_line_color = get_config_color("remove_line");
$line = $remove_line_color . $line . $reset_color;
}
}
return $line;
}
# Count the number of a given char in a string
sub char_count {
my ($needle,$str) = @_;
my $len = length($str);
my $ret = 0;
for (my $i = 0; $i < $len; $i++) {
my $found = substr($str,$i,1);
if ($needle eq $found) { $ret++; }
}
return $ret;
}
# Remove all ANSI codes from a string
sub bleach_text {
my $str = shift();
$str =~ s/\e\[\d*(;\d+)*m//mg;
return $str;
}
# Remove all trailing and leading spaces
sub trim {
my $s = shift();
if (!$s) { return ""; }
$s =~ s/^\s*|\s*$//g;
return $s;
}
# Print a line of em-dash or line-drawing chars the full width of the screen
sub horizontal_rule {
my $color = $_[0] || "";
my $width = $ruler_width || `tput cols`;
if (is_windows()) {
$width--;
}
# em-dash http://www.fileformat.info/info/unicode/char/2014/index.htm
#my $dash = "\x{2014}";
# BOX DRAWINGS LIGHT HORIZONTAL http://www.fileformat.info/info/unicode/char/2500/index.htm
my $dash;
if ($use_unicode_dash_for_ruler && should_print_unicode()) {
$dash = Encode::encode('UTF-8', "\x{2500}");
} else {
$dash = "-";
}
# Draw the line
my $ret = $color . ($dash x $width) . "\n";
return $ret;
}
sub file_change_string {
my $file_1 = shift();
my $file_2 = shift();
# If they're the same it's a modify
if ($file_1 eq $file_2) {
return "modified: $file_1";
# If the first is /dev/null it's a new file
} elsif ($file_1 eq "/dev/null") {
my $add_color = $DiffHighlight::NEW_HIGHLIGHT[1];
return "added: $add_color$file_2$reset_color";
# If the second is /dev/null it's a deletion
} elsif ($file_2 eq "/dev/null") {
my $del_color = $DiffHighlight::OLD_HIGHLIGHT[1];
return "deleted: $del_color$file_1$reset_color";
# If the files aren't the same it's a rename
} elsif ($file_1 ne $file_2) {
my ($old, $new) = DiffHighlight::highlight_pair($file_1,$file_2,{only_diff => 1});
$old = trim($old);
$new = trim($new);
# highlight_pair resets the colors, but we want it to be the meta color
$old =~ s/(\e0?\[m)/$1$meta_color/g;
$new =~ s/(\e0?\[m)/$1$meta_color/g;
return "renamed: $old to $new";
# Something we haven't thought of yet
} else {
return "$file_1 -> $file_2";
}
}
# Check to see if STDIN is connected to an interactive terminal
sub has_stdin {
my $i = -t STDIN;
my $ret = int(!$i);
return $ret;
}
# We use this instead of Getopt::Long because it's faster and we're not parsing any
# crazy arguments
# Borrowed from: https://www.perturb.org/display/1153_Perl_Quick_extract_variables_from_ARGV.html
sub argv {
my $ret = {};
for (my $i = 0; $i < scalar(@ARGV); $i++) {
# If the item starts with "-" it's a key
if ((my ($key) = $ARGV[$i] =~ /^--?([a-zA-Z_-]*\w)$/) && ($ARGV[$i] !~ /^-\w\w/)) {
# If the next item does not start with "--" it's the value for this item
if (defined($ARGV[$i + 1]) && ($ARGV[$i + 1] !~ /^--?\D/)) {
$ret->{$key} = $ARGV[$i + 1];
# Bareword like --verbose with no options
} else {
$ret->{$key}++;
}
}
}
# We're looking for a certain item
if ($_[0]) { return $ret->{$_[0]}; }
return $ret;
}
# Output the command line usage for d-s-f
sub usage {
my $out = color("white_bold") . version() . color("reset") . "\n";
$out .= "Usage:
git diff --color | diff-so-fancy # Use d-s-f on one diff
diff-so-fancy --colors # View the commands to set the recommended colors
diff-so-fancy --set-defaults # Configure git-diff to use diff-so-fancy and suggested colors
# Configure git to use d-s-f for *all* diff operations
git config --global core.pager \"diff-so-fancy | less --tabs=4 -RFX\"\n";
return $out;
}
sub get_default_colors {
my $out = "# Recommended default colors for diff-so-fancy\n";
$out .= "# --------------------------------------------\n";
$out .= 'git config --global color.ui true
git config --global color.diff-highlight.oldNormal "red bold"
git config --global color.diff-highlight.oldHighlight "red bold 52"
git config --global color.diff-highlight.newNormal "green bold"
git config --global color.diff-highlight.newHighlight "green bold 22"
git config --global color.diff.meta "yellow"
git config --global color.diff.frag "magenta bold"
git config --global color.diff.commit "yellow bold"
git config --global color.diff.old "red bold"
git config --global color.diff.new "green bold"
git config --global color.diff.whitespace "red reverse"
';
return $out;
}
# Output the current version string
sub version {
my $ret = "Diff-so-fancy: https://github.com/so-fancy/diff-so-fancy\n";
$ret .= "Version : $VERSION\n";
return $ret;
}
sub is_windows {
if ($^O eq 'MSWin32' or $^O eq 'dos' or $^O eq 'os2' or $^O eq 'cygwin' or $^O eq 'msys') {
return 1;
} else {
return 0;
}
}
# Return value is whether this is the first time they've run d-s-f
sub check_first_run {
my $ret = 0;
# If first-run is not set, or it's set to "true"
my $first_run = git_config_boolean('diff-so-fancy.first-run');
# See if they're previously set SOME diff-highlight colors
my $has_dh_colors = git_config_boolean('color.diff-highlight.oldnormal') || git_config_boolean('color.diff-highlight.newnormal');
#$first_run = 1; $has_dh_colors = 0;
if (!$first_run || $has_dh_colors) {
return 0;
} else {
print "This appears to be the first time you've run diff-so-fancy, please note\n";
print "that the default git colors are not ideal. Diff-so-fancy recommends the\n";
print "following colors.\n\n";
print get_default_colors();
# Set the first run flag to false
my $cmd = 'git config --global diff-so-fancy.first-run false';
system($cmd);
exit;
}
return 1;
}
sub set_defaults {
my $color_config = get_default_colors();
my $git_config = 'git config --global core.pager "diff-so-fancy | less --tabs=4 -RFX"';
my $first_cmd = 'git config --global diff-so-fancy.first-run false';
my @cmds = split(/\n/,$color_config);
push(@cmds,$git_config);
push(@cmds,$first_cmd);
# Remove all comments from the commands
foreach my $x (@cmds) {
$x =~ s/#.*//g;
}
# Remove any empty commands
@cmds = grep($_,@cmds);
foreach my $cmd (@cmds) {
system($cmd);
my $exit = ($? >> 8);
if ($exit != 0) {
die("Error running: '$cmd' (error #18941)\n");
}
}
return 1;
}
# Borrowed from: https://www.perturb.org/display/1167_Perl_ANSI_colors.html
# String format: '115', '165_bold', '10_on_140', 'reset', 'on_173', 'red', 'white_on_blue'
sub color {
my $str = shift();
# No string sent in, so we just reset
if (!length($str) || $str eq 'reset') { return "\e[0m"; }
# Some predefined colors
my %color_map = qw(red 160 blue 21 green 34 yellow 226 orange 214 purple 93 white 15 black 0);
$str =~ s|([A-Za-z]+)|$color_map{$1} // $1|eg;
# Get foreground/background and any commands
my ($fc,$cmd) = $str =~ /(\d+)?_?(\w+)?/g;
my ($bc) = $str =~ /on_?(\d+)/g;
# Some predefined commands
my %cmd_map = qw(bold 1 italic 3 underline 4 blink 5 inverse 7);
my $cmd_num = $cmd_map{$cmd // 0};
my $ret = '';
if ($cmd_num) { $ret .= "\e[${cmd_num}m"; }
if (defined($fc)) { $ret .= "\e[38;5;${fc}m"; }
if (defined($bc)) { $ret .= "\e[48;5;${bc}m"; }
return $ret;
}
# Get colors used for various output sections (memoized)
{
my $static_config;
sub get_config_color {
my $str = shift();
my $ret = "";
if ($static_config->{$str}) {
return $static_config->{$str};
}
if ($str eq "meta") {
# Default ANSI yellow
$ret = DiffHighlight::color_config('color.diff.meta', color(11));
} elsif ($str eq "reset") {
$ret = color("reset");
} elsif ($str eq "add_line") {
# Default ANSI green
$ret = DiffHighlight::color_config('color.diff.new', color('bold') . color(2));
} elsif ($str eq "remove_line") {
# Default ANSI red
$ret = DiffHighlight::color_config('color.diff.old', color('bold') . color(1));
} elsif ($str eq "last_function") {
$ret = DiffHighlight::color_config('color.diff.func', color(146));
}
# Cache (memoize) the entry for later
$static_config->{$str} = $ret;
return $ret;
}
}
sub starts_with_ansi {
my $str = shift();
if ($str =~ /^$ansi_color_regex/) {
return 1;
} else {
return 0;
}
}
# vim: tabstop=4 shiftwidth=4 noexpandtab autoindent softtabstop=4
=== tat
#!/bin/sh
#
# Attach or create tmux session named the same as current directory.
path_name="$(basename "$PWD" | tr . -)"
session_name=${1-$path_name}
not_in_tmux() {
[ -z "$TMUX" ]
}
session_exists() {
tmux has-session -t "$session_name"
}
create_detached_session() {
(TMUX='' tmux new-session -Ad -s "$session_name")
}
create_if_needed_and_attach() {
if not_in_tmux; then
tmux new-session -As "$session_name"
else
if ! session_exists; then
create_detached_session
fi
tmux switch-client -t "$session_name"
fi
}
create_if_needed_and_attach
=== vimrc.bundles
call plug#begin('~/.vim/bundle')
" Define bundles via Github repos
Plug 'janko-m/vim-test'
Plug 'pangloss/vim-javascript'
Plug 'pbrisbin/vim-mkdir'
Plug 'slim-template/vim-slim'
Plug 'tpope/vim-bundler'
Plug 'tpope/vim-eunuch'
Plug 'tpope/vim-fugitive'
Plug 'tpope/vim-projectionist'
Plug 'tpope/vim-rails'
Plug 'tpope/vim-rake'
Plug 'tpope/vim-repeat'
Plug 'tpope/vim-rhubarb'
Plug 'tpope/vim-surround'
Plug 'vim-ruby/vim-ruby'
Plug 'vim-scripts/tComment'
Plug 'ElmCast/elm-vim'
Plug 'tpope/vim-dispatch'
Plug 'tpope/vim-markdown'
Plug 'tpope/vim-vinegar'
Plug 'nelstrom/vim-textobj-rubyblock'
Plug 'kana/vim-textobj-user'
Plug 'altercation/vim-colors-solarized'
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'derekwyatt/vim-scala'
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
Plug 'junegunn/fzf.vim'
Plug 'KabbAmine/zeavim.vim'
Plug 'christoomey/vim-tmux-navigator'
Plug 'morhetz/gruvbox'
Plug 'jiangmiao/auto-pairs'
Plug 'tomasr/molokai'
Plug 'fatih/vim-go'
Plug 'joshdick/onedark.vim'
Plug 'itchyny/lightline.vim'
call plug#end()
@gnfisher
Copy link
Author

[alias]
  aa = add --all
  bselect = !git branch | grep -v '^*' | fzf-tmux --reverse | xargs git checkout
  ca = commit --amend --verbose
  car = commit --amend --no-edit
  co = checkout
  copysha = !git rev-parse HEAD | xclip
  df = "!f() { [ \"$GIT_PREFIX\" != \"\" ] && cd "$GIT_PREFIX"; git diff --color $@ | diff-so-fancy | less --tabs=4 -RFX; }; f"
  dfw = !git df -w
  dc = "!f() { [ \"$GIT_PREFIX\" != \"\" ] && cd "$GIT_PREFIX"; git diff --color --cached $@ | diff-so-fancy | less --tabs=4 -RFX; }; f"
  dcw = !git dc -w
  fall = fetch --all
  glog = log -E -i --grep
  mup = !git checkout master && git fetch origin && echo && git sl master..origin/master && echo && git pull --quiet && git checkout -
  pl = pull
  ps = push
  rbc = rebase --continue
  riu = !git rebase -i $(git rev-parse --abbrev-ref --symbolic-full-name @{u})
  rid = !git rebase -i $(git merge-base develop HEAD)
  rim = !git rebase -i $(git merge-base master HEAD)
  rmup = !git mup && git rebase master
  sl = log --oneline --decorate -20
  sla = log --oneline --decorate --graph --all -20
  slp = log --oneline --decorate
  slap = log --oneline --decorate --graph --all
  todo = !git log --format=%B -n 1 | grep -A999 '^This change$'
  uncommit = reset --soft HEAD^
  unstage = reset
  upstream = rev-parse --abbrev-ref --symbolic-full-name @{u}
  ureset = !git reset --hard $(git upstream)
[color]
  ui = auto
[core]
  excludesfile = ~/.gitignore_global
  autocrlf = input
  editor = /usr/bin/nvim
  pager = "diff-so-fancy | less --tabs=2 -RFX"
[merge]
  ff = only
[push]
  default = upstream
[fetch]
  prune = true
[gitsh "color"]
  default = cyan
[gitsh]
  defaultcommand = status -sb
  gitcommand = git
  nogreeting = true
  prompt = "\n%D %c(%b%#)%w $ "
[user]
  name = Greg Fisher
  email = gnfisher@thoughtbot.com
*.sw[nop]
.bundle
.git
db/*.sqlite3
log/*.log
rerun.txt
tags
tags.*
tmp/**/*
!tmp/cache/.keep
.sass-cache/
vendor/bundler_gems
vim/.netrwhist
.spring
binstubs
tags.lock
scratch.md
gf_notes.md
project_notes.md
/bundle/**/*
node_modules/**/*
.env

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