# HG changeset patch # User Jeff Hammel # Date 1393803187 28800 # Node ID 88a69d5873263980064a17ea6277c0e1c793372d # Parent de314841219106d75c7bba5a3de4275ca6707cc4 round1 of commands diff -r de3148412191 -r 88a69d587326 textshaper/commands.py --- a/textshaper/commands.py Sun Feb 23 16:48:09 2014 -0800 +++ b/textshaper/commands.py Sun Mar 02 15:33:07 2014 -0800 @@ -1,23 +1,53 @@ -#!/usr/bin/env python # -*- coding: utf-8 -*- """ CLI commands for textshaper """ +import inspect + class Shaper(object): - """individual text shaper component""" + """ + individual text shaper component + (function wrapper) + """ def __init__(self, function): self.function = function + self.func_name = function.func_name + + def __call__(self, text, **kwargs): + return self.function(text, **kwargs) + + def __str__(self): + return self.func_name + class Commands(object): def __init__(self): self.shapers = [] self.keys = {} + self.display_keys = [] def add(self, function, key=None): self.shapers.append(Shaper(function)) - if key: - self.keys[key] = self.shapers[-1] + if not key: + key = str(self.shapers[-1]) + key = key.lower() + self.keys[key] = self.shapers[-1] + name = str(self.shapers[-1]).lower() + if name.startswith(key): + display_name = '{}{}'.format(key, name[len(key):].upper()) + else: + display_name = '{}:{}'.format(key, name.upper()) + self.display_keys.append(display_name) + + def call(self, key, text, **kwargs): + if key in self.keys: + return self.keys[key](text, **kwargs) + + __call__ = call + + def display(self): + return ' '.join(self.display_keys) diff -r de3148412191 -r 88a69d587326 textshaper/decorator.py --- a/textshaper/decorator.py Sun Feb 23 16:48:09 2014 -0800 +++ b/textshaper/decorator.py Sun Mar 02 15:33:07 2014 -0800 @@ -16,6 +16,9 @@ self.function = function self.line_separator = line_separator + # record function information from function object + self.func_name = function.func_name + def __call__(self, text, *args, **kwargs): is_string = False if isinstance(text, string): diff -r de3148412191 -r 88a69d587326 textshaper/indent.py --- a/textshaper/indent.py Sun Feb 23 16:48:09 2014 -0800 +++ b/textshaper/indent.py Sun Mar 02 15:33:07 2014 -0800 @@ -43,6 +43,12 @@ return retval +@lines +def deindent(text): + """strip lines""" + return [line.strip() for line in text] + +### CLI def add_arguments(parser): parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), @@ -52,6 +58,7 @@ def main(args=sys.argv[1:]): + """CLI""" # parse command line description = """indent files or stdin if no files given""" diff -r de3148412191 -r 88a69d587326 textshaper/main.py --- a/textshaper/main.py Sun Feb 23 16:48:09 2014 -0800 +++ b/textshaper/main.py Sun Mar 02 15:33:07 2014 -0800 @@ -10,8 +10,11 @@ import subprocess import sys import time +from .commands import Commands +from .indent import deindent, indent from which import which +HR = '--' def info(content): """gathers info about the content and returns a dict""" @@ -22,7 +25,7 @@ 'columns': max([len(line) for line in lines])} -def display(content, keys=('lines', 'chars', 'columns'), hr='--'): +def display(content, keys=('lines', 'chars', 'columns'), hr=HR): """displays the content""" print (content) if keys: @@ -31,6 +34,13 @@ print ('; '.join(['{}: {}'.format(key, _info[key]) for key in keys])) +def add_commands(): + # TODO: do this dynamically + commands = Commands() + commands.add(indent, 'i') + commands.add(deindent, 'd') + return commands + def add_options(parser): """add options to the parser instance""" @@ -42,13 +52,16 @@ help="do not strip whitespace before processing") if which('xclip'): # TODO: support e.g. xsel or python native - parser.add_argument('-c', '--clip', '--copy', dest='copy_to_clipboard', + parser.add_argument('-c', '-o', '--clip', '--copy', dest='copy_to_clipboard', action='store_true', default=False, help="copy to clipboard") - + parser.add_argument('-i', dest='input_from_clipboard', + action='store_true', default=False, + help="copy from clipboard") def main(args=sys.argv[1:]): + """CLI""" # TODO: read ~/.textshaper @@ -58,24 +71,38 @@ options = parser.parse_args(args) # read input - content = options.input.read() + if getattr(options, 'input_from_clipboard', False): + content = subprocess.check_output(['xclip', '-o']) + else: + content = options.input.read() + + # get formatting commands + commands = add_commands() # pre-process output if options.strip: content = content.strip() - # print formatted content - display(content) - # main display loop # TODO: read input + commands - while True: - time.sleep(1) # XXX + try: + while True: + # print formatted content + display(content) + print (commands.display()) + choice = raw_input('? ') + new_content = commands(choice, content) + if new_content is None: + print ("Choice '{}' not recognized".format(choice)) + continue + content = new_content - if options.copy_to_clipboard: - # copy content to X clipboard - process = subprocess.Popen(['xclip', '-i'], stdin=subprocess.PIPE) - _, _ = process.communicate(content) + if options.copy_to_clipboard: + # copy content to X clipboard + process = subprocess.Popen(['xclip', '-i'], stdin=subprocess.PIPE) + _, _ = process.communicate(content) + except KeyboardInterrupt: + sys.exit(0) if __name__ == '__main__': main()