TMO3SOZBNVAM5QFULQWSGJEODJ2MRY5EJSG2WGV6MIAPKF5YDMEAC
VNNLT6UHLT7C3RE7T6JCY5DPZZGZPHQONRMT45V23QI5JDODH6DAC
WGI3IUPW6LMURHIZBKES6TYB66HIJDATICOOU6FQ4QOS2GRJ5HWQC
OZNRYN7G4GHLBAB7NWKFB6MMF7XWWXU7RA4ZWT266OJPEXZTEEXAC
5AXP35TT5ALRP6CZMFXPGNLUHLVIBDC67YKE42VWIWKHQM222D5QC
Q3AR2IUV6XK56LP7TGY5MMAGDGHN5IXAL7R77A5XPDHEYGM6Y45QC
QRIYVGRSKSTFFG67OZI4FKGLGKRULNO67VUPCZKNLDKNPV7O3RJQC
TV3UCUKAIECQR4QCXWDN3YZVSZ3RKXE6466TWLWGCKDJ2JAIYLMQC
GOAWMLDLQBSRTG6XJQL24KBJTUNDRKA43MUZBO5QISKR6AI57CQQC
GLQOSYQ3WGR23PFZ7OYPWPN724T5WTXIPTXVSBD6SKC3JIOLAR7AC
VUQ3M2PAMIUCUTL3Q5D6PE5FDTZEPPWGR7FYZ2DCF3I2K2TYRTYQC
AM6UBUWJJZGH34SJEZLJ5M244FLKTF3KG3PQ7SDXIIHQ7WB26V4AC
IGPZOX3MPDH6UEV5D4HHB2H37E6KTIVM4DKM5RZE7HRYJFHSRKFQC
UATCBX2NJNUSOUJ5KCXRM6RY7FIGWJ6NUXU3Y666MFJYQPE7PD6QC
5FLTMCXWFLP6MI36R73NDC5ZZGKRB66IXOWY7ZTESTLC7M357H2QC
WQBYW3K4L4DFULCVEC3PNFGBDHESVBPON576F7ZTVR3P3HQ4C2KAC
IMOTK232APTO5HACVM2LWJXLF77PYVDGWPCMFBX3NMQUWRAFCUOAC
T43Q2EZ2JQWK4WMW7RRYU7MNP3QJJXW4BQKIQMRYFCGKHL7FJ7SQC
FMGFUBY6PIX35Y5VK25RQGR4P6ZJCWUSZ4U3M7VA7BEYPVMMQK2AC
XPYTDFC3JLNLAYYJ5PILP2LFNKZBQSXHELWRLNZNJ7GTBBWXPRGAC
VB7SQS5KNBIK4CZJNWV2C7OV3XJYIFORVQR4EXCWECPQGLDOZ3AQC
2WCOODWOS4Q63X6PGYX5VLOP5W7Y77YBPYYHBWAWSVFTA476FQZAC
6O56ZSVNIKRQAWGU7SFRA7CVFSFFNT3ZE2QR7A77DSQTEAPAO6MAC
PMHPTL5RUFWZWMOTA6LKNS5I42EI6VMHCGEQBE5ZGOQYCAXWXQOAC
BX6TV7XWLRYKA36CVPFL7RJFV3QWDFBH5XP4PXLB72JXWBAAJCNQC
A2FIR5BWCAVNXUFPIMO3A66M7VGYB4FL667QWVF7F22TBIVVYWVAC
7KXKJ2Z7GX7L5PUURMJDAHVZS25BMYHPYI7ZNMLZ4COHMW4EBXKAC
MB2H34CMUKR3BUW3IOEIMROAJKZ6VCIIJDXHC25RFURURVJFOEGQC
BPRUDUQBUILYWWQK7K5A4WQG3SJQKZVYYBYRXGLLNYHIN4N25ZVQC
THSBL5M5W2SACGBK3OUSOZ4J2KO3EJG6TALMPOONXZYPFKAS5UTAC
IOLIXBY7WOCZ55U7UJYTFNZ7OPLNW7VCJFBGKKZL6FZXAZFIO3XAC
RIA7ABJHVCBKK2LBAPE4TIO2U2ZU2DXXPFR3H4EFUHDPZURN4CJQC
B4PZNM4LGYALBYO4JGWBR2D6DAAP2CDTJDYMTMMSEHTOOW6DXA6QC
LIUBV543TVVQQTCUSTSNQ6STV3A2H42HJODYDAWOLKNWI4UOLSEQC
4BXYTJPI3YWWXJ4JFUNFUO6ANCMJNALQ7L3XK3U3AXQGFDV7CAEQC
OAK763HGKP7PPLTNTZAB32CJXP7NHBB6DUIWXBGPRH4IGYQ5HA3AC
DB4M2XBWMJBMXBA7GOMJIYNR4S2XPK47RI65XKSMTCLZB27FAFBAC
7OOJFR5YEVMWKWPKPNNS2KORW2NNLB6KH74AOZWHLJO6JYJGUIUQC
6UJUYFJEYOTAY73OYDTQZT3KRBTWYLRTNGWJDYDD4T7P4J7PXARQC
5PQD3P5ZSBMT7ZS3QBMWHYI4EUQW4IVZFOSLIEB3YEZMU3NOXC4QC
UCURO7DUH5DA7O4YQQBNZVPO7V63BJ6KKY3DOTCRWYNIT5DKXP5AC
JPYY22Q5VCEZDNEBTHXYXUQWA2JUGOPHRYDSWIQM7KXHGTWS3GOQC
QBLVLMEM55CW32JBAJGVQEUMA2QOPNBHMP3XNCBR5RIMBNYUAOGAC
6BLD6IH4TA5VQZAKWZNDGQRR5WH2QFCA5FSUHS2EXJGYVCNJSENQC
XPRFKBOMSZVTDHISLXEWWSJ4XSMLAACMWVUTXDM6QDLAJKA7GDVQC
7S723KBOAGTNAAHZNYJR7OXJ2F4WXIOFF23CCIVHQNNUBQBJ5WRAC
ONMM7DGS45XMAQXFZBYP4BBCTZJWCECNGCNOI6UFGYZGJ5TYXPAAC
57YU55IK55Q4QDV45LD3ILNQDQV46NKLYK3HS6VWR2SDTOFSYXKAC
CDREIJJY5W3HWMX5SBTP72RV4KCZSDPAH3RIWVXTCDCPM6JG52IAC
K5PQ626TQQRIYJPYDZ5OM77ZIBX2G2QXALFRJCSKVF3PKO37C7KAC
674WSHB4WR6RY67PKK53GYUBY22BRMFHYNRLOTWE66CWJI2RNMJAC
LEY3QGCOMNZLJFZ5JQBSAUAZIJ7JRTMRFQADOG3EUPLNDZZB2YZQC
73ADP3OYJPH4DOQU3G3VS4T66GCP5EQF5FWRRLTLCTSTDGHCEAUQC
KYBCX6CAMAG25UXT2JJAGZZFFQVUPKZPLOJXJVA7NTVARXJ6BGMAC
RBBBDTNM7J6BR3SUIZQQ3FATAVWTXFQ5472JJGVH3TC37VYGSTFAC
ALPWY5IXTS4MY3Z5GP6MW732JBR6SZ5UAUZOZNZJKRC7BJWSEXUAC
XUAOI2I7CV3BQZYNYMD6BOJZBL3OFLACP5NZZNA4JUXGS44FTCQQC
73SIMA4UUQLBETG2RE6NTN57VEMVQHG552E4WIDATW7IRI36CHHAC
XZDJ2Z4M2MKWIDXN7EYBYQHGO7P5RSWPUGOQ3W2MHIUF55XQSXHQC
VSGSN57DJWUM5XTB76IDCPLWXQ7NWN2I25XROSZIFLF6PT5AVZOAC
I2WI2EWK3OXLC47KJJMXKLFDTHZLHAUXFVQCET26NMXODEHY244AC
V7RZRPMQYYGRPEWE5UOJ74FGC6IWRWXKQHS7CR6SL4FBEWB7OVYQC
AFJJ42LKJYUUPNSL22AUXUCFWXE4T4732YYXEJUEY2SJO6HHJUWAC
3YPPQLTAKKPK5CLJUZEH3A55Z76EUAXCOCGWW6XLRXSDQKKJCWOQC
RLKZ33HEPHQ6EAYJTQDHYOG7KE34XBH7V7TQ37BIU2DBCAFRPRJQC
5M2FYS5GTEPSCGLG6VPUMFXTKCP7ETDIOVOC2YSEGQHGKG3IFMKQC
AT4I3XSN3KN4K56GP5ZV55NKYDZ7LFV4AHKMB3PHQCXN56SADVTAC
{
"discount": {
"fields": [
{
"name": "code",
"caseSensitive": false,
"maxLength": 0,
"minLength": 3,
"type": "whitelist"
}
]
},
"regex-example-rule": {
"fields": [
{
"name": "first",
"pattern": "\\w+",
"caseSensitive": false,
"maxLength": 0,
"minLength": 1,
"type": "regex"
},
{
"name": "last",
"pattern": "\\w+",
"caseSensitive": false,
"maxLength": 0,
"minLength": 1,
"type": "regex"
},
{
"name": "email",
"pattern": "[a-z]+@[a-z]+\\.[a-z]+",
"caseSensitive": false,
"maxLength": 0,
"minLength": 6,
"type": "regex"
}
]
}
}
"pattern": "@.-_!abcdefghijklmnopqrstuvwxyz1234567890",
Metadata-Version: 1.0
Name: csvcheck
Version: 0.0.1
Summary: UNKNOWN
Home-page: UNKNOWN
Author: UNKNOWN
Author-email: UNKNOWN
License: UNKNOWN
Description-Content-Type: UNKNOWN
Description: UNKNOWN
Platform: UNKNOWN
lib.py
main.py
csvcheck.egg-info/PKG-INFO
csvcheck.egg-info/SOURCES.txt
csvcheck.egg-info/dependency_links.txt
csvcheck.egg-info/entry_points.txt
csvcheck.egg-info/requires.txt
csvcheck.egg-info/top_level.txt
from __future__ import division, absolute_import, print_function
from collections import OrderedDict
import csv
import json
import os
import re
import six
class FileNewLineError(Exception):
pass
class RuleDoesNotExist(Exception):
pass
class RuleCannotBeParsed(Exception):
pass
class RuleField():
def __init__(self, field):
# TODO set these attributes in stone and make this explicit
for k, v in six.iteritems(field):
setattr(self, k, v)
if not self.caseSensitive:
self.pattern = self.pattern.lower()
def errors(self, check):
return [e for e in self.errors_iter(check)]
def errors_iter(self, check):
if self.type in ('whitelist', 'blacklist'):
check = check if self.caseSensitive else check.lower()
return self._iter_chars(check)
elif self.type in ('regex', 'regular expression'):
return self._iter_regex(check)
def is_valid(self, check):
'''returns true on the first error encountered'''
return not any(self.errors_iter(check))
def _iter_chars(self, check):
for c in check:
matches = c in self.pattern
if self.type == 'whitelist' and not matches:
yield c
elif self.type == 'blacklist' and matches:
yield c
def _iter_regex(self, check):
flags = 0
if not self.caseSensitive:
flags = re.IGNORECASE
pattern = re.compile(self.pattern, flags)
does_not_match = pattern.sub('', check)
if does_not_match != '':
yield does_not_match
def __repr__(self):
return 'RuleField({}) -> Pattern: {}'.format(self.name, self.pattern)
class Rule():
def __init__(self,
rule_name=None,
rules='rules.json',
required_rule_fields=None):
if required_rule_fields is None:
required_rule_fields = set([
'name', 'pattern', 'caseSensitive', 'maxLength', 'minLength',
'type'
])
self.name = rule_name or ''
self._field_map = self.create_field_map(
self.parse_json(rules), rule_name, required_rule_fields)
def __getitem__(self, key):
index = None
try:
index = int(key)
except ValueError:
return self._field_map[key]
keys = self._field_map.keys()
return self._field_map[keys[index]]
def __iter__(self):
for rule_field in six.itervalues(self._field_map):
yield rule_field
def __len__(self):
return len(self._field_map)
def __repr__(self):
return '<Rule({}) -> fields: {}>'.format(self.name,
self._field_map.keys())
@staticmethod
def create_field_map(rules_object, rule_name, required_rule_fields):
field_map = OrderedDict()
field_list = rules_object
try:
field_list = rules_object[rule_name]['fields']
except KeyError:
raise RuleDoesNotExist()
except AttributeError:
# assume a single rule - object is a list of the fields
pass
for field in field_list:
# assure each field has everything needed to validate
if set(field.keys()) < required_rule_fields:
raise ValueError(
'Rules must contain these keys for validation: %s' %
required_rule_fields)
field_map[field['name']] = RuleField(field)
return field_map
@staticmethod
def parse_json(rules):
'''returns parsed json from string or file'''
if os.path.exists(rules):
with open(rules) as f:
rules = f.read()
try:
return json.loads(rules)
except ValueError:
raise RuleCannotBeParsed()
class Validator():
'''Validates the contents of a csv file against a set of rules. The rules should be in json format and
can be read in a string or file.
PARAMS:
csv_file_path: STRING a filepath to a csv file to validate
rules: (Optional) STRING a string or filepath to json data that contain rules. see rules.json for formatting
rule_name: (Optional) STRING select a rule from the rules json to use for validation
fix_line_endings: (Optional) BOOL write a fixed version of the file if it contains non-unix line endings
NOTES:
arbitrary key word arguments are passed to the csv reader
USAGE:
Validator('~/Desktop/discounts.csv').errors
v = Validator('~/Desktop/discounts.csv', rule_name='Event Upload', rules='~/Desktop/my_rules.json')
errs = v.errors
for err in errs:
print(err)
print(v.line(err['line_num']))
'''
def __init__(self, csv_data, rules, rule_name=None, **kwargs):
self.rule = Rule(rule_name=rule_name, rules=rules)
self.csv_data = self._clean_lines(csv_data)
self.csv_iter = csv.reader(self.csv_data, **kwargs)
self.errors = self._all_errors()
def line(self, num):
'''returns the contents of the line at the given index (not 0 indexed) and error inormation for that line'''
num = num - 1
line = self.csv_data[num]
errors = filter(lambda e: e.get('line_num') == num, self.errors)
return (line, errors)
def _all_errors(self):
'''iterates through all of the csv data and computes the errors, returns a list dict objects containing
error information'''
return [{
'line_num': line_num,
'col_num': col_num,
'errors': errs
} for line_num, col_num, errs in self._errors_iter()]
def _errors_iter(self):
'''lazily iterates through the csv data yielding errors for each column'''
for line_num, row in enumerate(self.csv_iter):
for col_num, (col, rule) in enumerate(zip(row, self.rule)):
errors = rule.errors(col)
if errors:
yield line_num, col_num, errors
def _clean_lines(self, csv_data):
non_unix_line_ending_char = '\r'
if non_unix_line_ending_char in csv_data:
raise FileNewLineError(
'File has a mix of non-unix line endings which cannot be parsed as csv'
)
else:
# remove literal newline from each line
return [l.replace('\n', '') for l in csv_data]
def __repr__(self):
return '<Validator(csv) Rule({}) -> {} Errors>'.format(self.rule.name, len(self.errors))
from traceback import format_exc
import click
from lib import Validator, RuleDoesNotExist, RuleCannotBeParsed, FileNewLineError
@click.group(invoke_without_command=True)
@click.option('--rules-string', type=click.STRING)
@click.argument('csv', type=click.File('r'))
@click.argument('rule_name', type=click.STRING, required=False)
@click.pass_context
def run(context, csv, rule_name, rules, rules_string):
'''csvcheck accepts a path to a csv file and will validate it against rules'''
if rules_string:
rules = rules_string
context.obj = {
'file': csv,
'validator': get_validator(csv, rules, rule_name)
}
if not context.invoked_subcommand:
errors = pretty_errors(context.obj['validator'].errors,
context.obj['validator'].csv_data)
if not errors:
click.echo('there are no errors in {}'.format(csv.name))
else:
print_csv_errors(errors)
@run.command()
@click.option('-l', '--line-endings/--no-line-endings', default=False)
@click.option('-e', '--remove-errors/--no-remove-errors', default=False)
@click.pass_context
def fix(context, line_endings, remove_errors):
handle_fix(line_endings, remove_errors)
@click.pass_context
def handle_fix(context, line_endings, remove_errors):
fixed_file_name = ''
if line_endings:
fixed_file_name = fix_line_endings(context.obj['file'])
elif remove_errors:
csv_data = context.obj['validator'].csv_data
errors = context.obj['validator'].errors
err_explaination = '''CONTENTS OF LINE: {line}
INVALID CHARACTERS: {invalid}'''
initial_msg = '''
There are {count} errors in {file_name}.
The first error is:
{first_err}
'''.format(
count=len(errors),
file_name=context.obj['file'].name,
first_err=err_explaination.format(
line=csv_data[errors[0]['line_num']],
invalid=errors[0]['errors']))
strategy_prompt = '''Choose a strategy:
delete - remove the line completely
fix - remove the invalid characters, but keep the valid ones
skip - skip this line'''
invalid_input_msg = '"{}" is not a valid strategy. Please choose from above.'
strategy = None
block_on_each_iteration = True
REMOVE_LINE = 1
STRIP_ERRORS = 2
SKIP_LINE = 3
allowed_inputs = {
'd': REMOVE_LINE,
'delete': REMOVE_LINE,
'f': STRIP_ERRORS,
'fix': STRIP_ERRORS,
's': SKIP_LINE,
'skip': SKIP_LINE
}
click.echo(initial_msg)
for index, err in enumerate(errors):
line_contents = csv_data[err['line_num']]
if block_on_each_iteration:
if index != 0:
click.echo(err_explaination.format(line=line_contents, invalid=err['errors']))
click.echo(strategy_prompt)
strategy = get_user_input(
allowed_map=allowed_inputs, invalid_msg=invalid_input_msg)
if index == 0:
block_on_each_iteration = not click.confirm(
'Do you want to do this for the rest of the errors?')
if strategy == STRIP_ERRORS:
csv_data[err['line_num']] = fix_line(
line_contents, err, strip=True)
elif strategy == REMOVE_LINE:
csv_data[err['line_num']] = fix_line(line_contents, err)
click.echo('--------------------')
fixed_file_name = 'fixed-{}'.format(context.obj['file'].name)
with open(fixed_file_name, 'w') as f:
new_csv_data = ''.join('{}\n'.format(l) for l in csv_data
if len(l) > 0)
f.write(new_csv_data)
click.echo('{} saved to current directory'.format(fixed_file_name))
def fix_line(line_contents, error, strip=False):
'''returns the line without invalid characters or an empty string if strategy == "line"
'''
result = ''
if strip:
errors = error['errors']
result = ''.join(c for c in line_contents if c not in errors)
return result
def get_validator(csv, rules, rule_name):
csv_data = csv.readlines()
try:
return Validator(csv_data, rules, rule_name=rule_name)
except FileNewLineError:
handle_file_new_line_error(promt_fix=True)
except RuleDoesNotExist:
handle_rule_does_not_exist_error(rule_name)
except RuleCannotBeParsed:
handle_rule_cannot_be_parsed_error()
except Exception:
print_prog_error(
'There was a fatal error, the file was not processed.',
tb=format_exc())
def handle_file_new_line_error(context, prompt_fix=False):
err_message = 'CSV file has non-standard line endings and cannot be parsed as csv.'
suggestion = 'Use the fix command to fix line endings.'
example = 'csvcheck /path/to/file.csv rule_name fix -l'
click.echo(err_message, err=True, color='red')
if prompt_fix:
if click.confirm(
'Save new file with fixed line endings to the current directory?'
):
handle_fix(True, False)
else:
click.echo(suggestion, err=True, color='yellow')
click.echo(example, err=True)
raise click.BadParameter(
'csv file contains malformed line ending characters')
def handle_rule_does_not_exist_error(rule_name):
err_message = 'Rule "{}" does not exist in rules json.'.format(rule_name)
raise click.BadArgumentUsage(err_message)
def handle_rule_cannot_be_parsed_error():
raise click.BadOptionUsage('invalid json passed into --rules-string')
def pretty_errors(errors, csv_data):
'''returns a list of end-user friendly formatted strings describing the errors '''
err_lines = []
for error in errors:
line_number = error['line_num']
column_number = error['col_num']
contents = csv_data[line_number]
err_lines.append('L{line}:{col} ({errors}) --> "{contents}"'.format(
line=line_number + 1,
col='' if column_number == 0 else 'C{}:'.format(column_number),
contents=contents,
errors=error['errors']))
return err_lines
def fix_line_endings(csv_file, out_path=None):
'''accept file object, remove bad line endings, write to a file of the same
basename with fixed- as a prefix
options
out_path: write file to a specific path instead of the same path as csv
windows line endings can have a carriage return in addition
to the \n char - csv has trouble parsing these line endings
so just remove them here instead of opening the file in
universal line endings mode since it's a big reason uploads fail
'''
contents = ''.join(
line.replace('\r', '\n') for line in csv_file.readlines())
out_file_name = 'fixed-{}'.format(csv_file.name)
with open(out_file_name, mode='w') as out_file:
out_file.write(contents)
return out_file_name
def get_user_input(prompt_str='>>> ',
allowed_map=None,
invalid_msg='{} is invalid input please try again.'):
choice = None
while not choice:
user_input = click.prompt(prompt_str, prompt_suffix='').lower().strip()
choice = allowed_map.get(user_input) if allowed_map else user_input
if not choice:
formatted = invalid_msg.format(
choice) if '{}' in invalid_msg else invalid_msg
click.echo(formatted)
return choice
def print_csv_errors(errors):
for error in errors:
click.echo(error)
def print_prog_error(msg, tb=None):
click.echo(msg, err=True)
if tb:
for line in tb:
click.echo(line)
@click.option('--rules', type=click.Path(exists=True), default=DEFAULT_RULES_PATH)
DEFAULT_RULES_PATH = path.expanduser('~/dotfiles/csv_validator/rules.json')
DEFAULT_RULES_PATH = DEFAULT_RULES_PATH if path.exists(DEFAULT_RULES_PATH) else 'rules.json'
from os import path
from setuptools import setup
setup(
name='csvcheck',
version='0.0.1',
py_modules=['main', 'lib'],
install_requires=['Click', 'six'],
entry_points='''
[console_scripts]
csvcheck=main:run
'''
)
################
# PATH SETTINGS
################
export GOPATH=$HOME/go_projects
#####################
#####################
#############################
# to make sure global python packages are only installed intentionally, limit pip to running only in venv
export PIP_REQUIRE_VIRTUALENV=true
# auto-activate pyvenv python versions when entering that dir
export PYENV_ROOT=$HOME/.pyenv
export PYENV_VIRTUALENV_DISABLE_PROMPT=1
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
# terminal prompt
PS1=' \u @ \[\033[0;35m\]\h\[\033[0m\]\n| \[\033[1;34m\]\w\[\033[0;32m\]$(__git_ps1)\[\033[0m\]\n└─ $ '
export PATH="$HOME/.cargo/bin:$PATH"
export PATH="$HOME/.poetry/bin:$PATH"
# IMPRTANT STUFF TO LOAD LAST
#############################
if [ -d "$HOME/eventbrite_github" ]; then
export EBPATH=~/eventbrite_github/eventbrite
export ARCANIST_INSTALL_DIR=/Users/ccummings/.evbdevtools
export ARCANISTHELPERS=~/.evbdevtools/devtools/scripts/devenv_bash/arcanist_helpers.sh
test -f $ARCANISTHELPERS && source $ARCANISTHELPERS
export BAY_HOME=/Users/ccummings/eventbrite_github/eventbrite/docker-dev
export DM_START=/Users/ccummings/.evbdevtools/devtools/scripts/install_devenv/dm_start.sh
source $DM_START
fi
# Eventbrite Stuff
export RUSTPATH=$HOME/.cargo/bin
export RUST_SRC_PATH=$HOME/.multirust/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/src
export PATH=/usr/local/bin:$GOPATH/bin:$RUSTPATH:$PATH
export YARNPATH=/usr/local/bin
# Load brew git completion and git prompt scripts
else
echo brew git not installed at expected location, to install it, run: brew install git
fi
export EDITOR=`which nvim`
if [ -d "/usr/local/Cellar/git/2.13.3" ]; then
source /usr/local/Cellar/git/2.13.3/etc/bash_completion.d/git-completion.bash
source /usr/local/Cellar/git/2.13.3/etc/bash_completion.d/git-prompt.sh
export CLICOLOR=1 # enable colors
test -f ~/.bashrc && . ~/.bashrc
set -o vi
[ -d ~/dotfiles ] && for f in ~/dotfiles/bash/functions/*; do source $f; done
#############################
#############################
[ -f ~/.fzf.bash ] && source ~/.fzf.bash
# use ripgrep (default is find)
export FZF_DEFAULT_COMMAND='rg --files --no-ignore --hidden --follow -g "!{.git,node_modules}/*" 2> /dev/null'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
bind -x '"\C-p": vim $(fzf);'
_fzf_compgen_path() {
rg -g "" "$1"
}
#####################
# GENERAL USE ALIASES
#####################
alias cp='cp -iv' # copy a file with the verbose and warning flags
alias mv='mv -iv' # move a file/dir with verbose and warning flags
alias mkdir='mkdir -pv' # make directory with the path and verbose flags
alias cd..='cd ../' # Go back 1 directory level
alias finder='open -a Finder ./' # Open current directory in MacOS Finder
alias path='echo -e ${PATH//:/\\n}' # Echo all executable Paths
alias numFiles='echo $(ls -1 | wc -l)' # Count of non-hidden files in current dir
alias staticip='dig +short myip.opendns.com @resolver1.opendns.com' # get the static ip of the current network
# lr is a full recursive directory listing piped to less
alias lr='ls -R | grep ":$" | sed -e '\''s/:$//'\'' -e '\''s/[^-][^\/]*\//--/g'\'' -e '\''s/^/ /'\'' -e '\''s/-/|/'\'' | less'
###################
# QUICK NAV Aliases
###################
export GOCODE=$GOPATH/src/github.com/mistahchris/
#######################
# GENERAL USE FUNCTIONS
#######################
# Always list directory contents after 'cd'
cd () {
builtin cd "$@"; ls -a;
}
# moves a file to the macOS Trash
trash () {
command mv "$@" ~/.Trash ;
}
# opens a file in the macOS preview
preview () {
qlmanage -p "$*" >& /dev/null;
}
# creates a zip archive folder
zipf () {
zip -r "$1".zip "$1" ;
}
# make a directory and change into it
mcd () {
mkdir -p $1;
cd $1;
}
# cdfinder changes the directory to the frontmost open finder window
cdfinder () {
currFolderPath=$( /usr/bin/osascript <<EOT
tell application "Finder"
try
set currFolder to (folder of the front window as alias)
on error
set currFolder to (path to desktop folder as alias)
end try
POSIX path of currFolder
end tell
EOT
)
echo "cd to \"$currFolderPath\""
cd "$currFolderPath"
}
# sets the contents of a file to the macOS clipboard
copy () {
cat $1 | pbcopy
}
# kill a process by name
die () {
name=$1
firstChar=${name:0:1}
rest=${name:1:${#name}}
pid=`ps aux | grep "[$firstChar]$rest" | awk '{print $2}'`
kill $pid
}
# extracts the git branch name
parseBranch() {
git branch | grep "^\* " | sed "s/\* //g"
}
# useful for extracting compressed folders
extract () {
if [ -f $1 ] ; then
case $1 in
*.tar.bz2) tar xjf $1 ;;
*.tar.gz) tar xzf $1 ;;
*.bz2) bunzip2 $1 ;;
*.rar) unrar e $1 ;;
*.gz) gunzip $1 ;;
*.tar) tar xf $1 ;;
*.tbz2) tar xjf $1 ;;
*.tgz) tar xzf $1 ;;
*.zip) unzip $1 ;;
*.Z) uncompress $1 ;;
*.7z) 7z x $1 ;;
*) echo "'$1' cannot be extracted via extract()" ;;
esac
else
echo "'$1' is not a valid file"
fi
}
PATH=$HOME/dotfiles/bin:$PATH
complete -C /usr/local/bin/terraform terraform
# Enable fzf cool stuff
export EDITOR="emacsclient -t"
export VISUAL="emacsclient -n"
function srch() {
RG_ARGS=""
N_LARGEST=0
for arg in $@
do
case "$arg" in
-n*)
RG_ARGS="$RG_ARGS -c" # add count flag to rg
N_LARGEST=$num
fi
;;
*)
RG_ARGS="$RG_ARGS $arg"
esac
done
from heapq import nlargest
from sys import stdin
fi
}
if [ -f $PY_FILE ]; then
rm $PY_FILE
eval $COMMAND
for match in nlargest($N_LARGEST, stdin.readlines(), key=lambda l: l.split(':')[-1]):
print(match.strip())
" > $PY_FILE
COMMAND="$COMMAND | python $PY_FILE"
fi
if ((USE_FZF > 0)); then
FILTER_FILE_NAME='cut -f 1 -d :'
FZF_COMMAND="fzf --preview 'cat {}'"
COMMAND="$COMMAND | $FILTER_FILE_NAME | $FZF_COMMAND"
fi
COMMAND="rg $RG_ARGS"
if ((N_LARGEST > 0)); then
PY_FILE=$(mktemp /tmp/srch_py.XXXXXXXXXXXXX)
printf "
--print)
USE_FZF=0
;;
num=$(echo "$arg" | rg --replace '$1' -- '-n(\d+)')
if ((num > 0)); then
USE_FZF=1
# wrapper around ripgrep and fzf.
# USAGE: find top 5 files by num of matches:
# $ srch PATTERN -g GLOB -n5
emacs() {
if ! ps aux | grep -v grep | grep -q 'emacs.* \-\-daemon'; then
/usr/local/bin/emacs --daemon > /dev/null 2>&1
fi;
passed_args="$@"
if [ $(echo -n "$passed_args" | wc -c) -lt "1" ]; then
echo "USAGE: emacs [PATH TO FILE] [OPTIONAL ARGS PASSED TO EMACS CLIENT]"
return 1
fi;
# create an emacsclient frame if one does not exist otherwise use existing frame
passed_args="-c $passed_args"
fi;
/usr/local/bin/emacsclient "$passed_args" > /dev/null &
}
if ! ps aux | grep -v grep | grep -q 'emacsclient'; then
export VISUAL="/usr/local/bin/emacsclient -c"
export PATH="$HOME/.cargo/bin:$PATH"
export PATH="$HOME/.poetry/bin:$PATH"
export PATH="/usr/local/bin/:$HOME/.cargo/bin:$PATH"
" --- the plugins are between the call plug begin and end
call plug#begin('~/.vim/plugged')
Plug 'tpope/vim-surround'
call plug#end()
" -- LOOK AND FEEL
filetype on
syntax enable " enable syntax processing
set showcmd " show command in bottom bar
set lazyredraw " redraw only when needed. (speeds things up)
set showmatch " highlight matching braces, brackets, parens
set autowrite
" -- SEARCHING
set ignorecase " ignore case for searches
set incsearch " search as characters are input
set hlsearch " highlight search matches
set magic
" -- INDENT SETTINGS
autocmd Filetype html setlocal ts=2 sw=2 expandtab
autocmd Filetype ruby setlocal ts=2 sw=2 expandtab
autocmd Filetype c setlocal ts=4 sw=4 expandtab cindent
autocmd Filetype swift setlocal ts=4 sw=4 expandtab cindent
autocmd BufNewFile,BufRead *.go setlocal noexpandtab ts=4 sw=4
filetype indent on
imap <S-tab> <C-d>
set smartindent
set autoindent
set nowrap
" -- KEY BINDINGS / REMAPS
" \pp - paste into buffer
nnoremap <leader>pp :r !pbpaste<CR>
set tabstop=4
set shiftwidth=4
set softtabstop=4
set expandtab
filetype plugin indent on
autocmd Filetype javascript setlocal ts=4 sw=4 sts=0 expandtab
autocmd Filetype css setlocal ts=2 sw=2 expandtab
set hidden
set history=30
set scrolloff=8 " scroll down when 8 lines away from being off screen
set sidescrolloff=20 " scroll sideways when 20 columns away from being off screen
set sidescroll=1
set nocompatible
{
"Profiles": [
{
"Ansi 0 Color" : {
"Green Component" : 0,
"Blue Component" : 0,
"Red Component" : 0
},
"Tags" : [
],
"Ansi 12 Color" : {
"Green Component" : 0.6352941176,
"Blue Component" : 0.7450980392,
"Red Component" : 0.5058823529000001
},
"Guid" : "B9C5A152-BFD5-4B7D-B311-903D39F3EE4A",
"Normal Font" : "PTMono-Regular 14",
"Bold Color" : {
"Green Component" : 0.7843137255,
"Blue Component" : 0.7764705882,
"Red Component" : 0.7725490196
},
"Horizontal Spacing" : 1.104939288403614,
"Link Color" : {
"Red Component" : 0.023,
"Color Space" : "Calibrated",
"Blue Component" : 0.678,
"Alpha Component" : 1,
"Green Component" : 0.27
},
"Ansi 4 Color" : {
"Green Component" : 0.6352941176470588,
"Blue Component" : 0.7450980392156863,
"Red Component" : 0.5058823529411764
},
"Rows" : 45,
"Default Bookmark" : "No",
"Cursor Guide Color" : {
"Red Component" : 0.65,
"Color Space" : "Calibrated",
"Blue Component" : 1,
"Alpha Component" : 0.25,
"Green Component" : 0.91
},
"Non-ASCII Anti Aliased" : true,
"Use Bright Bold" : true,
"Ansi 10 Color" : {
"Green Component" : 0.7411764706,
"Blue Component" : 0.4078431373,
"Red Component" : 0.7098039216000001
},
"Ambiguous Double Width" : false,
"Jobs to Ignore" : [
"rlogin",
"ssh",
"slogin",
"telnet"
],
"Ansi 15 Color" : {
"Green Component" : 0.9999743700027466,
"Blue Component" : 0.9999912977218628,
"Red Component" : 1
},
"Foreground Color" : {
"Green Component" : 0.7843137254901961,
"Blue Component" : 0.7764705882352941,
"Red Component" : 0.7725490196078432
},
"Working Directory" : "\/Users\/chris",
"Blinking Cursor" : false,
"Disable Window Resizing" : true,
"Sync Title" : false,
"Prompt Before Closing 2" : false,
"BM Growl" : true,
"Command" : "",
"Description" : "Default",
"Mouse Reporting" : true,
"Screen" : -1,
"Selection Color" : {
"Green Component" : 0.2313725490196079,
"Blue Component" : 0.2549019607843137,
"Red Component" : 0.2156862745098039
},
"Columns" : 90,
"Idle Code" : 0,
"Ansi 13 Color" : {
"Green Component" : 0.5803921569,
"Blue Component" : 0.7333333332999999,
"Red Component" : 0.6980392157
},
"Custom Command" : "No",
"ASCII Anti Aliased" : true,
"Non Ascii Font" : "Monaco 12",
"Vertical Spacing" : 1,
"Use Bold Font" : true,
"Option Key Sends" : 0,
"Selected Text Color" : {
"Green Component" : 0.7843137255,
"Blue Component" : 0.7764705882,
"Red Component" : 0.7725490196
},
"Background Color" : {
"Green Component" : 0.1215686276555061,
"Blue Component" : 0.1294117718935013,
"Red Component" : 0.1137254908680916
},
"Character Encoding" : 4,
"Ansi 11 Color" : {
"Green Component" : 0.7764705882,
"Blue Component" : 0.4549019608,
"Red Component" : 0.9411764706
},
"Use Italic Font" : true,
"Unlimited Scrollback" : false,
"Keyboard Map" : {
"0xf700-0x260000" : {
"Text" : "[1;6A",
"Action" : 10
},
"0x37-0x40000" : {
"Text" : "0x1f",
"Action" : 11
},
"0x32-0x40000" : {
"Text" : "0x00",
"Action" : 11
},
"0xf709-0x20000" : {
"Text" : "[17;2~",
"Action" : 10
},
"0xf70c-0x20000" : {
"Text" : "[20;2~",
"Action" : 10
},
"0xf729-0x20000" : {
"Text" : "[1;2H",
"Action" : 10
},
"0xf72b-0x40000" : {
"Text" : "[1;5F",
"Action" : 10
},
"0xf705-0x20000" : {
"Text" : "[1;2Q",
"Action" : 10
},
"0xf703-0x260000" : {
"Text" : "[1;6C",
"Action" : 10
},
"0xf700-0x220000" : {
"Text" : "[1;2A",
"Action" : 10
},
"0xf701-0x280000" : {
"Text" : "0x1b 0x1b 0x5b 0x42",
"Action" : 11
},
"0x38-0x40000" : {
"Text" : "0x7f",
"Action" : 11
},
"0x33-0x40000" : {
"Text" : "0x1b",
"Action" : 11
},
"0xf703-0x220000" : {
"Text" : "[1;2C",
"Action" : 10
},
"0xf701-0x240000" : {
"Text" : "[1;5B",
"Action" : 10
},
"0xf70d-0x20000" : {
"Text" : "[21;2~",
"Action" : 10
},
"0xf702-0x260000" : {
"Text" : "[1;6D",
"Action" : 10
},
"0xf729-0x40000" : {
"Text" : "[1;5H",
"Action" : 10
},
"0xf706-0x20000" : {
"Text" : "[1;2R",
"Action" : 10
},
"0x34-0x40000" : {
"Text" : "0x1c",
"Action" : 11
},
"0xf700-0x280000" : {
"Text" : "0x1b 0x1b 0x5b 0x41",
"Action" : 11
},
"0x2d-0x40000" : {
"Text" : "0x1f",
"Action" : 11
},
"0xf70e-0x20000" : {
"Text" : "[23;2~",
"Action" : 10
},
"0xf702-0x220000" : {
"Text" : "[1;2D",
"Action" : 10
},
"0xf703-0x280000" : {
"Text" : "0x1b 0x1b 0x5b 0x43",
"Action" : 11
},
"0xf700-0x240000" : {
"Text" : "[1;5A",
"Action" : 10
},
"0xf707-0x20000" : {
"Text" : "[1;2S",
"Action" : 10
},
"0xf70a-0x20000" : {
"Text" : "[18;2~",
"Action" : 10
},
"0x35-0x40000" : {
"Text" : "0x1d",
"Action" : 11
},
"0xf70f-0x20000" : {
"Text" : "[24;2~",
"Action" : 10
},
"0xf703-0x240000" : {
"Text" : "[1;5C",
"Action" : 10
},
"0xf701-0x260000" : {
"Text" : "[1;6B",
"Action" : 10
},
"0xf702-0x280000" : {
"Text" : "0x1b 0x1b 0x5b 0x44",
"Action" : 11
},
"0xf72b-0x20000" : {
"Text" : "[1;2F",
"Action" : 10
},
"0x36-0x40000" : {
"Text" : "0x1e",
"Action" : 11
},
"0xf708-0x20000" : {
"Text" : "[15;2~",
"Action" : 10
},
"0xf701-0x220000" : {
"Text" : "[1;2B",
"Action" : 10
},
"0xf70b-0x20000" : {
"Text" : "[19;2~",
"Action" : 10
},
"0xf702-0x240000" : {
"Text" : "[1;5D",
"Action" : 10
},
"0xf704-0x20000" : {
"Text" : "[1;2P",
"Action" : 10
}
},
"Window Type" : 0,
"Background Image Location" : "",
"Blur" : false,
"Badge Color" : {
"Red Component" : 1,
"Color Space" : "Calibrated",
"Blue Component" : 0,
"Alpha Component" : 0.5,
"Green Component" : 0
},
"Scrollback Lines" : 1000,
"Send Code When Idle" : false,
"Close Sessions On End" : true,
"Terminal Type" : "xterm-256color",
"Visual Bell" : true,
"Flashing Bell" : false,
"Silence Bell" : false,
"Ansi 14 Color" : {
"Green Component" : 0.7450980392,
"Blue Component" : 0.7176470588,
"Red Component" : 0.5411764706
},
"Name" : "Default",
"Cursor Text Color" : {
"Green Component" : 0.1215686276555061,
"Blue Component" : 0.1294117718935013,
"Red Component" : 0.1137254908680916
},
"Shortcut" : "",
"Cursor Color" : {
"Green Component" : 0.7843137255,
"Blue Component" : 0.7764705882,
"Red Component" : 0.7725490196
},
"Transparency" : 0,
"Ansi 1 Color" : {
"Green Component" : 0.4,
"Blue Component" : 0.4,
"Red Component" : 0.8
},
"Ansi 2 Color" : {
"Green Component" : 0.7411764705882353,
"Blue Component" : 0.407843137254902,
"Red Component" : 0.7098039215686275
},
"Ansi 3 Color" : {
"Green Component" : 0.7764705882352941,
"Blue Component" : 0.4549019607843137,
"Red Component" : 0.9411764705882353
},
"Custom Directory" : "No",
"Right Option Key Sends" : 0,
"Use Non-ASCII Font" : false,
"Ansi 7 Color" : {
"Green Component" : 0.9999743700027466,
"Blue Component" : 0.9999912977218628,
"Red Component" : 1
},
"Ansi 8 Color" : {
"Green Component" : 0,
"Blue Component" : 0,
"Red Component" : 0
},
"Ansi 9 Color" : {
"Green Component" : 0.4,
"Blue Component" : 0.4,
"Red Component" : 0.8
},
"Ansi 6 Color" : {
"Green Component" : 0.7450980392156863,
"Blue Component" : 0.7176470588235294,
"Red Component" : 0.5411764705882353
},
"Ansi 5 Color" : {
"Green Component" : 0.580392156862745,
"Blue Component" : 0.7333333333333333,
"Red Component" : 0.6980392156862745
}
},
{
"Ansi 2 Color" : {
"Green Component" : 0.7333333492279053,
"Red Component" : 0,
"Blue Component" : 0
},
"Tags" : [
],
"Ansi 12 Color" : {
"Green Component" : 0.3333333432674408,
"Red Component" : 0.3333333432674408,
"Blue Component" : 1
},
"Normal Font" : "Monaco 12",
"Ansi 4 Color" : {
"Green Component" : 0,
"Red Component" : 0,
"Blue Component" : 0.7333333492279053
},
"Bold Color" : {
"Green Component" : 1,
"Red Component" : 1,
"Blue Component" : 1
},
"Right Option Key Sends" : 0,
"Ansi 6 Color" : {
"Green Component" : 0.7333333492279053,
"Red Component" : 0,
"Blue Component" : 0.7333333492279053
},
"Rows" : 50,
"Default Bookmark" : "No",
"Non-ASCII Anti Aliased" : true,
"Use Bright Bold" : true,
"Ansi 10 Color" : {
"Green Component" : 1,
"Red Component" : 0.3333333432674408,
"Blue Component" : 0.3333333432674408
},
"Ambiguous Double Width" : false,
"Jobs to Ignore" : [
"rlogin",
"ssh",
"slogin",
"telnet"
],
"Ansi 15 Color" : {
"Green Component" : 1,
"Red Component" : 1,
"Blue Component" : 1
},
"Foreground Color" : {
"Green Component" : 0.7333333492279053,
"Red Component" : 0.7333333492279053,
"Blue Component" : 0.7333333492279053
},
"Working Directory" : "\/Users\/chris",
"Blinking Cursor" : false,
"Disable Window Resizing" : true,
"Sync Title" : false,
"Prompt Before Closing 2" : false,
"BM Growl" : true,
"Command" : "",
"Description" : "Default",
"Mouse Reporting" : true,
"Screen" : -1,
"Selection Color" : {
"Green Component" : 0.8353000283241272,
"Red Component" : 0.7098000049591064,
"Blue Component" : 1
},
"Columns" : 172,
"Idle Code" : 0,
"Ansi 13 Color" : {
"Green Component" : 0.3333333432674408,
"Red Component" : 1,
"Blue Component" : 1
},
"Custom Command" : "No",
"ASCII Anti Aliased" : true,
"Non Ascii Font" : "Monaco 12",
"Vertical Spacing" : 1,
"Use Bold Font" : true,
"Option Key Sends" : 0,
"Selected Text Color" : {
"Green Component" : 0,
"Red Component" : 0,
"Blue Component" : 0
},
"Background Color" : {
"Red Component" : 0,
"Color Space" : "Calibrated",
"Blue Component" : 0,
"Alpha Component" : 1,
"Green Component" : 0
},
"Character Encoding" : 4,
"Ansi 11 Color" : {
"Green Component" : 1,
"Red Component" : 1,
"Blue Component" : 0.3333333432674408
},
"Use Italic Font" : true,
"Unlimited Scrollback" : false,
"Keyboard Map" : {
"0xf700-0x260000" : {
"Text" : "[1;6A",
"Action" : 10
},
"0x37-0x40000" : {
"Text" : "0x1f",
"Action" : 11
},
"0x32-0x40000" : {
"Text" : "0x00",
"Action" : 11
},
"0xf709-0x20000" : {
"Text" : "[17;2~",
"Action" : 10
},
"0xf70c-0x20000" : {
"Text" : "[20;2~",
"Action" : 10
},
"0xf729-0x20000" : {
"Text" : "[1;2H",
"Action" : 10
},
"0xf72b-0x40000" : {
"Text" : "[1;5F",
"Action" : 10
},
"0xf705-0x20000" : {
"Text" : "[1;2Q",
"Action" : 10
},
"0xf703-0x260000" : {
"Text" : "[1;6C",
"Action" : 10
},
"0xf700-0x220000" : {
"Text" : "[1;2A",
"Action" : 10
},
"0xf701-0x280000" : {
"Text" : "0x1b 0x1b 0x5b 0x42",
"Action" : 11
},
"0x38-0x40000" : {
"Text" : "0x7f",
"Action" : 11
},
"0x33-0x40000" : {
"Text" : "0x1b",
"Action" : 11
},
"0xf703-0x220000" : {
"Text" : "[1;2C",
"Action" : 10
},
"0xf701-0x240000" : {
"Text" : "[1;5B",
"Action" : 10
},
"0xf70d-0x20000" : {
"Text" : "[21;2~",
"Action" : 10
},
"0xf702-0x260000" : {
"Text" : "[1;6D",
"Action" : 10
},
"0xf729-0x40000" : {
"Text" : "[1;5H",
"Action" : 10
},
"0xf706-0x20000" : {
"Text" : "[1;2R",
"Action" : 10
},
"0x34-0x40000" : {
"Text" : "0x1c",
"Action" : 11
},
"0xf700-0x280000" : {
"Text" : "0x1b 0x1b 0x5b 0x41",
"Action" : 11
},
"0x2d-0x40000" : {
"Text" : "0x1f",
"Action" : 11
},
"0xf70e-0x20000" : {
"Text" : "[23;2~",
"Action" : 10
},
"0xf702-0x220000" : {
"Text" : "[1;2D",
"Action" : 10
},
"0xf703-0x280000" : {
"Text" : "0x1b 0x1b 0x5b 0x43",
"Action" : 11
},
"0xf700-0x240000" : {
"Text" : "[1;5A",
"Action" : 10
},
"0xf707-0x20000" : {
"Text" : "[1;2S",
"Action" : 10
},
"0xf70a-0x20000" : {
"Text" : "[18;2~",
"Action" : 10
},
"0x35-0x40000" : {
"Text" : "0x1d",
"Action" : 11
},
"0xf70f-0x20000" : {
"Text" : "[24;2~",
"Action" : 10
},
"0xf703-0x240000" : {
"Text" : "[1;5C",
"Action" : 10
},
"0xf701-0x260000" : {
"Text" : "[1;6B",
"Action" : 10
},
"0xf702-0x280000" : {
"Text" : "0x1b 0x1b 0x5b 0x44",
"Action" : 11
},
"0xf72b-0x20000" : {
"Text" : "[1;2F",
"Action" : 10
},
"0x36-0x40000" : {
"Text" : "0x1e",
"Action" : 11
},
"0xf708-0x20000" : {
"Text" : "[15;2~",
"Action" : 10
},
"0xf701-0x220000" : {
"Text" : "[1;2B",
"Action" : 10
},
"0xf70b-0x20000" : {
"Text" : "[19;2~",
"Action" : 10
},
"0xf702-0x240000" : {
"Text" : "[1;5D",
"Action" : 10
},
"0xf704-0x20000" : {
"Text" : "[1;2P",
"Action" : 10
}
},
"Window Type" : 0,
"Background Image Location" : "",
"Blur" : false,
"Scrollback Lines" : 1000,
"Send Code When Idle" : false,
"Close Sessions On End" : true,
"Terminal Type" : "xterm-256color",
"Visual Bell" : true,
"Flashing Bell" : false,
"Silence Bell" : false,
"Ansi 14 Color" : {
"Green Component" : 1,
"Red Component" : 0.3333333432674408,
"Blue Component" : 1
},
"Name" : "tmux",
"Cursor Text Color" : {
"Green Component" : 1,
"Red Component" : 1,
"Blue Component" : 1
},
"Shortcut" : "",
"Cursor Color" : {
"Green Component" : 0.7333333492279053,
"Red Component" : 0.7333333492279053,
"Blue Component" : 0.7333333492279053
},
"Transparency" : 0,
"Ansi 1 Color" : {
"Green Component" : 0,
"Red Component" : 0.7333333492279053,
"Blue Component" : 0
},
"Custom Directory" : "No",
"Ansi 3 Color" : {
"Green Component" : 0.7333333492279053,
"Red Component" : 0.7333333492279053,
"Blue Component" : 0
},
"Horizontal Spacing" : 1,
"Ansi 5 Color" : {
"Green Component" : 0,
"Red Component" : 0.7333333492279053,
"Blue Component" : 0.7333333492279053
},
"Use Non-ASCII Font" : false,
"Ansi 7 Color" : {
"Green Component" : 0.7333333492279053,
"Red Component" : 0.7333333492279053,
"Blue Component" : 0.7333333492279053
},
"Ansi 8 Color" : {
"Green Component" : 0.3333333432674408,
"Red Component" : 0.3333333432674408,
"Blue Component" : 0.3333333432674408
},
"Ansi 9 Color" : {
"Green Component" : 0.3333333432674408,
"Red Component" : 1,
"Blue Component" : 0.3333333432674408
},
"Ansi 0 Color" : {
"Green Component" : 0,
"Red Component" : 0,
"Blue Component" : 0
},
"Guid" : "E1DF35B7-1587-48F8-A8DE-708E75D9D9EB"
}
]
}
# python related
export PYENV_ROOT=$HOME/.pyenv
export PYTHON_2_PATH=$PYENV_ROOT/versions/misc2/bin
export PYTHON_3_PATH=$PYENV_ROOT/versions/misc3/bin
PYENV_SHIMS=/Users/ccummings/.pyenv/shims
PYENV_VENV_SHIMS=/usr/local/Cellar/pyenv-virtualenv/1.1.1/shims
fi
# rust related
if [ -d $HOME/.cargo/bin ]; then
export RUSTPATH=$HOME/.cargo/bin
export PATH=$PATH:$RUSTPATH
fi
# go related
if [ -d $HOME/go ]; then
export PATH=$PATH:$HOME/go
fi
export RUST_SRC_PATH=$HOME/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/src
test -f $HOME/.zfunc && fpath+=~/.zfunc
POETRY_PATH="$HOME/.poetry/bin"
export PATH=$PYENV_ROOT/bin:$PYENV_ROOT/shims:$PYENV_VENVSHIMS:$PYENV_SHIMS:$PYTHON_2_PATH:$PYTHON_3_PATH:$POETRY_PATH:$PATH
if [ -d $HOME/.pyenv ]; then
export PATH=$DOTFILES/bin:/usr/local/bin:/usr/local/sbin:$PATH
export DOTFILES=$HOME/dotfiles
export EDITOR="emacsclient -t"
export LESS="-SRXF"
fzf_bin=$HOME/.fzf/bin
test -f $fzf_bin && export PATH=$PATH:$fzf_bin
# broken out configs
source $DOTFILES/zsh/path_setup
export WORKON_HOME=$HOME/.local/share/virtualenvs/
# Path to your oh-my-zsh installation.
# Set name of the theme to load. Optionally, if you set this to "random"
# it'll load a random theme each time that oh-my-zsh is loaded.
# See https://github.com/robbyrussell/oh-my-zsh/wiki/Themes
ZSH_THEME="bira"
# Set list of themes to load
# Setting this variable when ZSH_THEME=random
# cause zsh load theme from this variable instead of
# looking in ~/.oh-my-zsh/themes/
# An empty array have no effect
# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )
DISABLE_UNTRACKED_FILES_DIRTY="true"
# Would you like to use another custom folder than $ZSH/custom?
# ZSH_CUSTOM=/path/to/new-custom-folder
# Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*)
# Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
plugins=(
)
source $ZSH/oh-my-zsh.sh
# User configuration
export LANG=en_US.UTF-8
# vi mode config
bindkey -v
export KEYTIMEOUT=1
###################################
# below here are things appended to
# automatically by various tools
###################################
if which pyenv-virtualenv-init > /dev/null; then eval "$(pyenv virtualenv-init -)"; fi
# pip zsh completion start
function _pip_completion {
local words cword
read -Ac words
read -cn cword
reply=( $( COMP_WORDS="$words[*]" \
COMP_CWORD=$(( cword-1 )) \
PIP_AUTO_COMPLETE=1 $words[1] ) )
}
compctl -K _pip_completion pip
# pip zsh completion end
autoload -U +X bashcompinit && bashcompinit
complete -o nospace -C /usr/local/bin/terraform terraform
# broken out configs
source $DOTFILES/zsh/fzf_config
source $DOTFILES/zsh/os_specific_config
source $DOTFILES/zsh/general_aliases
test -f $HOME/.zfunc && fpath+=~/.zfunc
test -f ~/.fzf.zsh && source ~/.fzf.zsh # this is here cause fzf looks here on install
# lazy load functions defined in dotfiles/zsh/functions
my_funcs=$DOTFILES/zsh/functions
fpath=($my_funcs $fpath)
for func in $(ls $my_funcs); do autoload $func; done;
git
pyenv
ruby
poetry
export ZSH=$HOME/.oh-my-zsh
# try to find it by name explicitly
local lpass_result=$(lpass show -p -G "$@" 2> /dev/null)
local multiple_matches=$(echo "$lpass_result" | grep -io "multiple matches found")
if [[ multiple_matches = "" ]];
then
echo $lpass_result
else
# otherwise list all lastpass entries filtered by grep regex and fuzzy find multiple matches in fzf
if [[ "$@" = "" ]];
then
lpass show -p "$(lpass ls | fzf | grep -Eo 'id: [0-9]+' | cut -d ' ' -f 2)"
else
lpass show -p "$(lpass ls | grep -i -E "$@" | fzf | grep -Eo 'id: [0-9]+' | cut -d ' ' -f 2)"
fi
fi
if test "$(uname)" = "Darwin";
then
script_lpass | pbcopy
else
script_lpass | xclip -i -selection clipboard
fi
#! /usr/bin/env python3
import json
import os
import sys
from stat import S_ISFIFO
def extract_email_objects(notmuch_blob):
for email in notmuch_blob:
e = email
email_object = None
while email_object is None:
try:
e.get('body')
except AttributeError:
e = e[0]
continue
email_object = e
yield email_object
def parse_emails(blob):
emails = (e for e in extract_email_objects(blob) if e['headers']['From'] != 'ccummings@eventbrite.com')
for email in emails:
tags = email['tags']
try:
except:
pass
yield {"tags": tags, "date": date, "to": to, "from": from_address, "subject": subject, "body": body}
def run(blob):
print(json.dumps(list(parse_emails(blob))))
if __name__ == "__main__":
try:
blob = None
if S_ISFIFO(os.fstat(0).st_mode):
blob = json.loads(sys.stdin.read())
else:
with open(sys.argv[1], mode='r') as f:
blob = json.load(f)
except FileNotFoundError:
print('argument must be a path to a json file', file=sys.stderr)
sys.exit(1)
except IndexError:
print('filename argument is required', file=sys.stderr)
sys.exit(2)
except json.decoder.JSONDecodeError:
print('content is not json encoded', file=sys.stderr)
sys.exit(3)
run(blob)
body = str(body).replace('\n', ' ').replace('\t', '').replace(' ', ' ')
body = body[0].get('content')[0].get('content')
date = email.get('headers').get('Date') or ""
to = email.get('headers').get('To') or ""
from_address = email.get('headers').get('From') or ""
subject = email.get('headers').get('Subject') or ""
body = email.get('body') or ""
#! /usr/bin/env fish
function script_lpass
# if logged out, log in
if not lpass status -q
/usr/local/bin/lpass login $EB_LAST_PASS_USER > /dev/null
end
set result (/usr/local/bin/lpass show -p -G "$argv")
if echo $result | grep -iq "multiple matches found"
set result (lpass show -p (lpass ls | grep -i -E "$argv" | fzf | rg -o --replace '$1' '\[id: (\d+)\]'))
end
echo $result
end
script_lpass $argv
import glob
import os
import sys
template = """# -*- mode: snippet -*-
# name: {name}
# key: phab {name}
# --
{name}
"""
prefix = "phabricator_username_"
with open(load_path) as f:
users = f.readlines()
for old_snippet_file in glob.glob("{}{}*".format(save_dir, prefix)):
os.remove(old_snippet_file)
for name in users:
name = name.strip()
save_path = f"{save_dir}{prefix}{name}"
with open(save_path.format(name=name), mode="w") as f:
f.write(name)
print(f"Updated snippets for {len(users)} users.")
home = os.environ.get("HOME")
dotfiles = os.environ.get("DOTFILES")
load_path = f"{home}/.evbdevtools/phabricator_users.txt"
save_dir = f"{dotfiles}/spacemacs/snippets/phabricator/"
if not os.path.exists(load_path):
print("phabricator_users.txt is required, but does not exist.", file=sys.stderr)
sys.exit(1)
#! /usr/bin/env python3