From e557c263777191d9da7efbf678fbfde4ddd245ad Mon Sep 17 00:00:00 2001 From: Matthieu Keller Date: Mon, 2 Sep 2013 16:08:09 +0200 Subject: [PATCH 1/8] Create head --- cheatsheets/head | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 cheatsheets/head diff --git a/cheatsheets/head b/cheatsheets/head new file mode 100644 index 0000000..5380daa --- /dev/null +++ b/cheatsheets/head @@ -0,0 +1,8 @@ +# To show the 10 first line of file +head file + +# To show the n first line of file +head -l n file + +# To show the n first bytes of file +head -b n file From fda6125657e5cc0b97f340f923b2447412aa222b Mon Sep 17 00:00:00 2001 From: Matthieu Keller Date: Mon, 2 Sep 2013 16:09:38 +0200 Subject: [PATCH 2/8] minor spell corrections --- cheatsheets/head | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cheatsheets/head b/cheatsheets/head index 5380daa..3bf5a48 100644 --- a/cheatsheets/head +++ b/cheatsheets/head @@ -1,7 +1,7 @@ -# To show the 10 first line of file +# To show the 10 first lines of file head file -# To show the n first line of file +# To show the n first lines of file head -l n file # To show the n first bytes of file From 0501f8cbfe68dd64d7c19a18a3581e7e111d5dec Mon Sep 17 00:00:00 2001 From: Matthieu Keller Date: Sun, 15 Sep 2013 17:34:15 +0200 Subject: [PATCH 3/8] correction --- cheatsheets/head | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cheatsheets/head b/cheatsheets/head index 3bf5a48..60f7f53 100644 --- a/cheatsheets/head +++ b/cheatsheets/head @@ -2,7 +2,7 @@ head file # To show the n first lines of file -head -l n file +head -n l file # To show the n first bytes of file -head -b n file +head -c b file From c87e741f34283c05460f0c6503ce484502c0d780 Mon Sep 17 00:00:00 2001 From: roemer_j Date: Mon, 16 Sep 2013 04:07:34 +0200 Subject: [PATCH 4/8] Made a OO refactoring, cleaner in my mind --- cheat | 227 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 115 insertions(+), 112 deletions(-) diff --git a/cheat b/cheat index d3aafb8..dca76f6 100755 --- a/cheat +++ b/cheat @@ -40,76 +40,6 @@ if os.name == 'posix' and 'CHEATCOLORS' in os.environ: except ImportError: pass -def cheat_directories(): - "Assembles a list of directories containing cheatsheets." - default_directories = [DEFAULT_CHEAT_DIR] - try: - import cheatsheets - default_directories.append(cheatsheets.cheat_dir) - except ImportError: - pass - - default = [default_dir for default_dir in default_directories - if os.path.isdir(default_dir)] - - if 'CHEATPATH' in os.environ and os.environ['CHEATPATH']: - return [path for path in os.environ['CHEATPATH'].split(os.pathsep) - if os.path.isdir(path)] + default - else: - return default - - -def cheat_files(cheat_directories): - "Assembles a dictionary of cheatsheets found in the above directories." - cheats = {} - for cheat_dir in reversed(cheat_directories): - cheats.update(dict([(cheat, cheat_dir) - for cheat in os.listdir(cheat_dir) - if not cheat.startswith('.') - and not cheat.startswith('__')])) - return cheats - - -def edit_cheatsheet(cheat, cheatsheets): - "Creates or edits a cheatsheet" - - # Assert that the EDITOR environment variable is set and that at least 3 - # arguments have been given - if 'EDITOR' not in os.environ: - print('In order to use "create" or "edit" you must set your ' - 'EDITOR environment variable to your favorite editor\'s path') - exit() - - elif len(sys.argv) < 3: - print('Must provide a cheatsheet to edit/create') - exit() - - # if the cheatsheet already exists, open it for editing - if cheat in cheatsheets: - subprocess.call([os.environ['EDITOR'], - os.path.join(cheatsheets[cheat], cheat)]) - - # otherwise, create it - else: - import cheatsheets as cs - # Attempt to write the new cheatsheet to the user's ~/.cheat dir if it - # exists. If it does not exist, attempt to create it. - if os.access(DEFAULT_CHEAT_DIR, os.W_OK) or os.makedirs(DEFAULT_CHEAT_DIR): - subprocess.call([os.environ['EDITOR'], - os.path.join(DEFAULT_CHEAT_DIR, cheat)]) - - # If the directory cannot be created, write to the python package - # directory, though that will likely require the use of sudo - else: - subprocess.call([os.environ['EDITOR'], - os.path.join(cs.cheat_dir, cheat)]) - -def list_cheatsheets(cheatsheets): - "Lists the cheatsheets that are currently available" - max_command = max([len(x) for x in cheatsheets.keys()]) + 3 - return ('\n'.join(sorted(['%s [%s]' % (key.ljust(max_command), value) - for key, value in cheatsheets.items()]))) - def pretty_print(filename): "Applies syntax highlighting to a cheatsheet and writes it to stdout" try: @@ -128,55 +58,109 @@ def pretty_print(filename): fmt = TerminalFormatter() highlight(code, lexer, fmt, sys.stdout) -def main(): - cheat_dirs = cheat_directories() +class CheatSheets(object): + + dirs = None + sheets = None - # verify that we have at least one cheat directory - if not cheat_dirs: - error_msg = 'The {default} dir does not exist or the CHEATPATH var is not set.' - print >> sys.stderr, error_msg.format(default=DEFAULT_CHEAT_DIR) - exit() + def __init__(self): + self.dirs = self.__cheat_directories() + # verify that we have at least one cheat directory + if not self.dirs: + error_msg = 'The {default} dir does not exist or the CHEATPATH var is not set.' + print >> sys.stderr, error_msg.format(default=DEFAULT_CHEAT_DIR) + exit() + self.sheets = self.__cheat_files() - # list the files in the ~/.cheat directory - cheatsheets = cheat_files(cheat_dirs) + def __cheat_directories(self): + """Assembles a list of directories containing cheatsheets.""" + default_directories = [DEFAULT_CHEAT_DIR] + try: + import cheatsheets + default_directories.append(cheatsheets.cheat_dir) + except ImportError: + pass - # list cheat directories and exit - class ListDirectories(argparse.Action): - def __call__(self, parser, namespace, values, option_string=None): - print cheat_directories() - parser.exit() + default = [default_dir for default_dir in default_directories + if os.path.isdir(default_dir)] - # list cheatsheets and exit - class ListCheatsheets(argparse.Action): - def __call__(self, parser, namespace, values, option_string=None): - print list_cheatsheets(cheatsheets) - parser.exit() + if 'CHEATPATH' in os.environ and os.environ['CHEATPATH']: + return [path for path in os.environ['CHEATPATH'].split(os.pathsep) + if os.path.isdir(path)] + default + else: + return default - # if the user wants to edit a cheatsheet - class EditSheet(argparse.Action): - def __call__(self, parser, namespace, values, option_string=None): - edit_cheatsheet(values[0], cheatsheets) - parser.exit() + def __cheat_files(self): + """Assembles a dictionary of cheatsheets found in the above directories.""" + cheats = {} + for cheat_dir in reversed(self.dirs): + cheats.update(dict([(cheat, cheat_dir) + for cheat in os.listdir(cheat_dir) + if not cheat.startswith('.') + and not cheat.startswith('__')])) + return cheats - # print the cheatsheet if it exists - class PrintSheet(argparse.Action): - def __call__(self, parser, namespace, value, option_string=None): - if not value or value in ['help', 'cheat']: - parser.print_help() - elif value in cheatsheets: - filename = os.path.join(cheatsheets[value], value) - if USE_PYGMENTS: - pretty_print(filename) - else: - with open(filename) as istream: - for l in istream: - sys.stdout.write(l) + def edit(self, cheat): + """Creates or edits a cheatsheet""" - # if it does not, say so + # Assert that the EDITOR environment variable is set and that at least 3 + # arguments have been given + if 'EDITOR' not in os.environ: + print('In order to use "create" or "edit" you must set your ' + 'EDITOR environment variable to your favorite editor\'s path') + exit() + + # if the cheatsheet already exists, open it for editing + if cheat in sheets.sheets: + subprocess.call([os.environ['EDITOR'], + os.path.join(self.sheets[cheat], cheat)]) + + # otherwise, create it + else: + import cheatsheets as cs + # Attempt to write the new cheatsheet to the user's ~/.cheat dir if it + # exists. If it does not exist, attempt to create it. + if os.access(DEFAULT_CHEAT_DIR, os.W_OK) or os.makedirs(DEFAULT_CHEAT_DIR): + subprocess.call([os.environ['EDITOR'], + os.path.join(DEFAULT_CHEAT_DIR, cheat)]) + + # If the directory cannot be created, write to the python package + # directory, though that will likely require the use of sudo else: - print >> sys.stderr, ('No cheatsheet found for %s.' % value) - parser.exit(1) - parser.exit() + subprocess.call([os.environ['EDITOR'], + os.path.join(cs.cheat_dir, cheat)]) + + def list(self): + """Lists the cheatsheets that are currently available""" + max_command = max([len(x) for x in self.sheets.keys()]) + 3 + return ('\n'.join(sorted(['%s [%s]' % (key.ljust(max_command), value) + for key, value in self.sheets.items()]))) + +# Custom action for argparse + +class ListDirectories(argparse.Action): + """List cheat directories and exit""" + def __call__(self, parser, namespace, values, option_string=None): + print sheets.dirs + parser.exit() + +class ListCheatsheets(argparse.Action): + """List cheatsheets and exit""" + def __call__(self, parser, namespace, values, option_string=None): + print sheets.list() + parser.exit() + + +class EditSheet(argparse.Action): + """If the user wants to edit a cheatsheet""" + def __call__(self, parser, namespace, values, option_string=None): + sheets.edit(values[0]) + parser.exit() + +def main(): + + global sheets + sheets = CheatSheets() desc = dedent(''' cheat allows you to create and view interactive cheatsheets on the @@ -205,7 +189,7 @@ def main(): formatter_class=argparse.RawDescriptionHelpFormatter) parser_group = parser.add_mutually_exclusive_group() parser_group.add_argument('sheet', metavar='cheatsheet', - action=PrintSheet, type=str, nargs='?', + action='store', type=str, nargs='?', help='Look at ') parser_group.add_argument('-c', '--create', metavar='cheatsheet', action=EditSheet, type=str, nargs=1, @@ -220,6 +204,25 @@ def main(): action=ListDirectories, nargs=0, help='List all current cheat dirs') args = parser.parse_args() + sheet = args.sheet + + # Print the cheatsheet if it exists + if not sheet or sheet in ['help', 'cheat']: + parser.print_help() + elif sheet in sheets.sheets: + filename = os.path.join(sheets.sheets[sheet], sheet) + if USE_PYGMENTS: + pretty_print(filename) + else: + with open(filename) as istream: + for l in istream: + sys.stdout.write(l) + + # if it does not, say so + else: + print >> sys.stderr, ('No cheatsheet found for %s.' % sheet) + exit(1) + exit() if __name__ == '__main__': main() From bbed1c58519f808434106b819ca1a73ea2896a05 Mon Sep 17 00:00:00 2001 From: Chris Lane Date: Thu, 19 Sep 2013 18:43:56 -0400 Subject: [PATCH 5/8] Removed the -c option from argparse A previous revision merged the functionality implemented by the -c and -e options, but the -c option was reintroduced during the last revision (probably) by accident. I took that out given that it no longer serves a purpose. --- cheat | 4 +--- cheatsheets/foo | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) create mode 100644 cheatsheets/foo diff --git a/cheat b/cheat index dca76f6..d234190 100755 --- a/cheat +++ b/cheat @@ -159,6 +159,7 @@ class EditSheet(argparse.Action): def main(): + # @todo: refactor out this global global sheets sheets = CheatSheets() @@ -191,9 +192,6 @@ def main(): parser_group.add_argument('sheet', metavar='cheatsheet', action='store', type=str, nargs='?', help='Look at ') - parser_group.add_argument('-c', '--create', metavar='cheatsheet', - action=EditSheet, type=str, nargs=1, - help='Create ') parser_group.add_argument('-e', '--edit', metavar='cheatsheet', action=EditSheet, type=str, nargs=1, help='Edit ') diff --git a/cheatsheets/foo b/cheatsheets/foo new file mode 100644 index 0000000..f749bbf --- /dev/null +++ b/cheatsheets/foo @@ -0,0 +1 @@ +This is the new cheatsheet for foo. From da2b0a872d778ed7b14903fb59bcc8dd708b429b Mon Sep 17 00:00:00 2001 From: Chris Lane Date: Thu, 19 Sep 2013 18:45:43 -0400 Subject: [PATCH 6/8] Deleted cruft Deleted a 'foo' cheatsheet I accidentally committed while testing. --- cheatsheets/foo | 1 - 1 file changed, 1 deletion(-) delete mode 100644 cheatsheets/foo diff --git a/cheatsheets/foo b/cheatsheets/foo deleted file mode 100644 index f749bbf..0000000 --- a/cheatsheets/foo +++ /dev/null @@ -1 +0,0 @@ -This is the new cheatsheet for foo. From 963496db86d2f15a0be6799ee40f8e55607f602f Mon Sep 17 00:00:00 2001 From: Chris Lane Date: Thu, 19 Sep 2013 19:05:22 -0400 Subject: [PATCH 7/8] Restored -d functionality to original During the last commit, the -d functionality was changed (likely unintentionally) such that it outputted a raw Python list rather than lines printed to stdout. I've restored the original functionality, because the autocompletion scripts rely upon it. --- cheat | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cheat b/cheat index d234190..de2d63b 100755 --- a/cheat +++ b/cheat @@ -137,11 +137,10 @@ class CheatSheets(object): for key, value in self.sheets.items()]))) # Custom action for argparse - class ListDirectories(argparse.Action): """List cheat directories and exit""" def __call__(self, parser, namespace, values, option_string=None): - print sheets.dirs + print("\n".join(sheets.dirs)) parser.exit() class ListCheatsheets(argparse.Action): @@ -150,7 +149,6 @@ class ListCheatsheets(argparse.Action): print sheets.list() parser.exit() - class EditSheet(argparse.Action): """If the user wants to edit a cheatsheet""" def __call__(self, parser, namespace, values, option_string=None): @@ -159,7 +157,6 @@ class EditSheet(argparse.Action): def main(): - # @todo: refactor out this global global sheets sheets = CheatSheets() From 0cc76a78a1ff3b530dd83e38f94b54765ce98f41 Mon Sep 17 00:00:00 2001 From: Chris Lane Date: Thu, 19 Sep 2013 19:45:28 -0400 Subject: [PATCH 8/8] Trivial changes to the head cheatsheet. --- cheatsheets/head | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cheatsheets/head b/cheatsheets/head index 60f7f53..0cb3c78 100644 --- a/cheatsheets/head +++ b/cheatsheets/head @@ -1,8 +1,8 @@ -# To show the 10 first lines of file +# To show the first 10 lines of file head file -# To show the n first lines of file -head -n l file +# To show the first N lines of file +head -n N file -# To show the n first bytes of file -head -c b file +# To show the first N bytes of file +head -c N file