diff --git a/cheat b/cheat
new file mode 100755
index 0000000..de2d63b
--- /dev/null
+++ b/cheat
@@ -0,0 +1,223 @@
+#!/usr/bin/env python
+"""
+cheat.py -- cheat allows you to create and view interactive cheatsheets on the
+ command-line. It was designed to help remind *nix system
+ administrators of options for commands that they use frequently,
+ but not frequently enough to remember.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+"""
+
+import os
+import sys
+import argparse
+import subprocess
+from textwrap import dedent
+
+DEFAULT_CHEAT_DIR = os.environ.get('DEFAULT_CHEAT_DIR') or \
+ os.path.join(os.path.expanduser('~'), '.cheat')
+USE_PYGMENTS = False
+
+# NOTE remove this check if it is confirmed to work on windows
+if os.name == 'posix' and 'CHEATCOLORS' in os.environ:
+ try:
+ from pygments import highlight
+ from pygments.util import ClassNotFound
+ from pygments.lexers import get_lexer_for_filename, TextLexer
+ from pygments.formatters import TerminalFormatter
+ USE_PYGMENTS = True
+ except ImportError:
+ pass
+
+def pretty_print(filename):
+ "Applies syntax highlighting to a cheatsheet and writes it to stdout"
+ try:
+ if os.path.splitext(filename)[1]:
+ lexer = get_lexer_for_filename(filename)
+ else:
+ # shell is a sensible default when there is no extension
+ lexer = get_lexer_for_filename(filename + '.sh')
+
+ except ClassNotFound:
+ lexer = TextLexer()
+
+ with open(filename) as istream:
+ code = istream.read()
+
+ fmt = TerminalFormatter()
+ highlight(code, lexer, fmt, sys.stdout)
+
+class CheatSheets(object):
+
+ dirs = None
+ sheets = None
+
+ 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()
+
+ 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
+
+ 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(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
+
+ def edit(self, cheat):
+ """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()
+
+ # 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:
+ 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("\n".join(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
+ command-line. It was designed to help remind *nix system
+ administrators of options for commands that they use frequently,
+ but not frequently enough to remember.''').strip()
+
+ epi = dedent('''
+ Examples:
+
+ To look up 'tar':
+ cheat tar
+
+ To create or edit the cheatsheet for 'foo':
+ cheat -e foo
+
+ To list the directories on the CHEATPATH
+ cheat -d
+
+ To list the available cheatsheets:
+ cheat -l
+ ''').strip()
+
+ parser = argparse.ArgumentParser(prog='cheat',
+ description=desc, epilog=epi,
+ formatter_class=argparse.RawDescriptionHelpFormatter)
+ parser_group = parser.add_mutually_exclusive_group()
+ parser_group.add_argument('sheet', metavar='cheatsheet',
+ action='store', type=str, nargs='?',
+ help='Look at ')
+ parser_group.add_argument('-e', '--edit', metavar='cheatsheet',
+ action=EditSheet, type=str, nargs=1,
+ help='Edit ')
+ parser_group.add_argument('-l', '--list',
+ action=ListCheatsheets, nargs=0,
+ help='List all available cheatsheets')
+ parser_group.add_argument('-d', '--cheat-directories',
+ 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()
diff --git a/cheatsheets/head b/cheatsheets/head
new file mode 100644
index 0000000..0cb3c78
--- /dev/null
+++ b/cheatsheets/head
@@ -0,0 +1,8 @@
+# To show the first 10 lines of file
+head file
+
+# To show the first N lines of file
+head -n N file
+
+# To show the first N bytes of file
+head -c N file