<commit_before>#!/usr/bin/env python

import argparse
import os.path
import re
import subprocess
import sys
import traceback

import tkinter as tk
import tkinter.filedialog
import tkinter.messagebox
import tkinter.scrolledtext
import tkinter.simpledialog

from truce.catcher import Catcher

VERSION = [0, 1, 0]
ABANDON_MSG = 'Abandon unsaved changes?'


def signature():
    return '{} {}.{}.{}'.format(os.path.basename(sys.argv[0]), *VERSION)


ABOUT = """{}

http://github.com/jangler/truce""".format(signature())


class App(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.pack(expand=1, fill='both')
        self.createWidgets()
        self.filename = None
        self.settitle()
        master.protocol("WM_DELETE_WINDOW", self.quit)

    def createWidgets(self):
        self.menu = tk.Menu(self)

        filemenu = tk.Menu(self.menu, tearoff=0)
        filemenu.add_command(label='Open', underline=0, command=self.open,
                             accelerator='Ctrl+O')
        self.bind_all('<Control-o>', self.open)
        filemenu.add_command(label='Save', underline=0, command=self.save,
                             accelerator='Ctrl+S')
        self.bind_all('<Control-s>', self.save)
        filemenu.add_command(label='Save As...', underline=5,
                             command=self.saveas, accelerator='Ctrl+Shift+S')
        self.bind_all('<Control-S>', self.saveas)
        filemenu.add_separator()
        filemenu.add_command(label='Quit', underline=0, accelerator='Ctrl+Q',
                             command=self.quit)
        self.bind_all('<Control-q>', self.quit)
        filemenu.add_command(label='Force Quit', underline=0,
                             accelerator='Ctrl+Shift+Q',
                             command=self.powerquit)
        self.bind_all('<Control-Q>', self.powerquit)
        self.menu.add_cascade(label='File', underline=0, menu=filemenu)

        editmenu = tk.Menu(self.menu, tearoff=0)
        editmenu.add_command(label='Undo', underline=0, command=self.undo,
                             accelerator='Ctrl+Z')
        editmenu.add_command(label='Redo', underline=0, command=self.redo,
                             accelerator='Ctrl+Y')
        editmenu.add_separator()
        editmenu.add_command(label='Pipe', underline=0, command=self.pipe,
                             accelerator='Ctrl+P')
        self.bind_all('<Control-p>', self.pipe)
        self.menu.add_cascade(label='Edit', underline=0, menu=editmenu)

        helpmenu = tk.Menu(self.menu, tearoff=0)
        helpmenu.add_command(label='About', underline=0, command=self.about)
        self.menu.add_cascade(label='Help', underline=0, menu=helpmenu)

        root.config(menu=self.menu)

        self.status = tkinter.Label(self, text='', relief='sunken',
                                    anchor='w')
        self.status.pack(side='bottom', fill='x')

        self.textin = tk.Text(self, height=0, undo=1)
        self.textin.bind('<Return>', self.sendtext)
        self.textin.pack(side='bottom', fill='x')

        self.textout = tkinter.scrolledtext.ScrolledText(self, undo=1)
        self.textout.bind('<Return>', self.autoindent)
        self.textout.pack(side='bottom', expand=1, fill='both')

        for widget in (self.textin, self.textout):
            widget.bind('<Control-z>', self.undo)
            widget.bind('<Control-y>', self.redo)
            widget.bind('<Control-Z>', self.redo)
            widget.bind('<Control-o>', self.open)
            widget.bind('<Control-v>', self.deletesel)

    def about(self):
        tkinter.messagebox.showinfo('About', ABOUT)

    def state(self, text=''):
        self.status['text'] = text

    def settitle(self):
        if self.filename:
            self.master.title(os.path.basename(self.filename))
        else:
            self.master.title(signature())

    def abandon(self):
        if not self.textout.edit_modified():
            return True
        elif tkinter.messagebox.askokcancel(ABANDON_MSG, ABANDON_MSG):
            return True
        return False

    def error(self, e):
        self.state()
        traceback.print_exc()
        tkinter.messagebox.showerror(type(e).__name__, str(e))

    def readin(self, filename, quiet=False):
        self.state('Opening...')
        try:
            with open(filename) as f:
                text = f.read()
        except Exception as e:
            if quiet:
                self.state('New file "{}".'.format(os.path.basename(filename)))
            else:
                self.error(e)
            return
        self.textout.delete('1.0', 'end')
        self.textout.insert('end', text)
        self.textout.delete('end - 1 char', 'end')  # delete extra newline
        self.state('Opened "{}".'.format(os.path.basename(filename)))
        self.textout.edit_modified(0)
        self.filename = filename
        self.settitle()

    def open(self, event=None):
        if self.abandon():
            filename = tkinter.filedialog.askopenfilename()
            if filename:
                self.readin(filename)
        return 'break'

    def save(self, event=None):
        if self.filename:
            self.writeout(self.filename)
        else:
            self.saveas(event)

    def saveas(self, event=None):
        filename = tkinter.filedialog.asksaveasfilename()
        if filename:
            self.writeout(filename)

    def writeout(self, filename):
        self.state('Saving...')
        try:
            with open(filename, 'w') as f:
                f.write(self.textout.get('1.0', 'end'))
            self.state('Saved "{}".'.format(os.path.basename(filename)))
            self.textout.edit_modified(0)
            self.filename = filename
            self.settitle()
        except Exception as e:
            self.error(e)

    def sendtext(self, event):
        self.textout.insert('end', self.textin.get('1.0', 'end'))
        self.textin.delete('1.0', 'end')
        return 'break'

    def autoindent(self, event):
        line = self.textout.get('insert linestart', 'insert lineend')
        indent = re.match('^[\t ]*', line).group(0)
        self.textout.insert('insert', '\n' + indent)
        return 'break'

    def geteditfocus(self):
        widget = self.focus_get()
        if widget not in (self.textin, self.textout):
            widget = self.textout
        return widget

    def deletesel(self, event):
        widget = event.widget
        try:
            widget.delete('sel.first', 'sel.last')
        except tkinter.TclError:
            pass

    def pipe(self, event=None):
        widget = self.geteditfocus()
        try:
            cmd = tkinter.simpledialog.askstring(
                'Pipe', 'Pipe selection through command:')
            if not cmd:
                return
            intext = ''
            try:
                intext = widget.get('sel.first', 'sel.last')
            except tkinter.TclError:
                pass
            text = subprocess.check_output(cmd, input=intext, shell=True,
                                           universal_newlines=True, timeout=1)
            try:
                widget.delete('sel.first', 'sel.last')
            except tkinter.TclError:
                pass
            widget.insert('insert', text)<commit_msg>Add select menu and select all command<commit_after>#!/usr/bin/env python

import argparse
import os.path
import re
import subprocess
import sys
import traceback

import tkinter as tk
import tkinter.filedialog
import tkinter.messagebox
import tkinter.scrolledtext
import tkinter.simpledialog

from truce.catcher import Catcher

VERSION = [0, 1, 0]
ABANDON_MSG = 'Abandon unsaved changes?'


def signature():
    return '{} {}.{}.{}'.format(os.path.basename(sys.argv[0]), *VERSION)


ABOUT = """{}

http://github.com/jangler/truce""".format(signature())


class App(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.pack(expand=1, fill='both')
        self.createWidgets()
        self.filename = None
        self.settitle()
        master.protocol("WM_DELETE_WINDOW", self.quit)

    def createWidgets(self):
        self.menu = tk.Menu(self)

        filemenu = tk.Menu(self.menu, tearoff=0)
        filemenu.add_command(label='Open', underline=0, command=self.open,
                             accelerator='Ctrl+O')
        self.bind_all('<Control-o>', self.open)
        filemenu.add_command(label='Save', underline=0, command=self.save,
                             accelerator='Ctrl+S')
        self.bind_all('<Control-s>', self.save)
        filemenu.add_command(label='Save As...', underline=5,
                             command=self.saveas, accelerator='Ctrl+Shift+S')
        self.bind_all('<Control-S>', self.saveas)
        filemenu.add_separator()
        filemenu.add_command(label='Quit', underline=0, accelerator='Ctrl+Q',
                             command=self.quit)
        self.bind_all('<Control-q>', self.quit)
        filemenu.add_command(label='Force Quit', underline=0,
                             accelerator='Ctrl+Shift+Q',
                             command=self.powerquit)
        self.bind_all('<Control-Q>', self.powerquit)
        self.menu.add_cascade(label='File', underline=0, menu=filemenu)

        editmenu = tk.Menu(self.menu, tearoff=0)
        editmenu.add_command(label='Undo', underline=0, command=self.undo,
                             accelerator='Ctrl+Z')
        editmenu.add_command(label='Redo', underline=0, command=self.redo,
                             accelerator='Ctrl+Y')
        editmenu.add_separator()
        editmenu.add_command(label='Pipe', underline=0, command=self.pipe,
                             accelerator='Ctrl+P')
        self.bind_all('<Control-p>', self.pipe)
        self.menu.add_cascade(label='Edit', underline=0, menu=editmenu)

        selectmenu = tk.Menu(self.menu, tearoff=0)
        selectmenu.add_command(label='All', underline=0,
                               command=self.selectall, accelerator='Ctrl+A')
        self.bind_all('<Control-a>', self.selectall)
        self.menu.add_cascade(label='Select', underline=0, menu=selectmenu)

        helpmenu = tk.Menu(self.menu, tearoff=0)
        helpmenu.add_command(label='About', underline=0, command=self.about)
        self.menu.add_cascade(label='Help', underline=0, menu=helpmenu)

        root.config(menu=self.menu)

        self.status = tkinter.Label(self, text='', relief='sunken',
                                    anchor='w')
        self.status.pack(side='bottom', fill='x')

        self.textin = tk.Text(self, height=0, undo=1)
        self.textin.bind('<Return>', self.sendtext)
        self.textin.pack(side='bottom', fill='x')

        self.textout = tkinter.scrolledtext.ScrolledText(self, undo=1)
        self.textout.bind('<Return>', self.autoindent)
        self.textout.pack(side='bottom', expand=1, fill='both')

        for widget in (self.textin, self.textout):
            widget.bind('<Control-z>', self.undo)
            widget.bind('<Control-y>', self.redo)
            widget.bind('<Control-Z>', self.redo)
            widget.bind('<Control-o>', self.open)
            widget.bind('<Control-v>', self.deletesel)
            widget.bind('<Control-a>', self.selectall)

    def about(self):
        tkinter.messagebox.showinfo('About', ABOUT)

    def state(self, text=''):
        self.status['text'] = text

    def settitle(self):
        if self.filename:
            self.master.title(os.path.basename(self.filename))
        else:
            self.master.title(signature())

    def abandon(self):
        if not self.textout.edit_modified():
            return True
        elif tkinter.messagebox.askokcancel(ABANDON_MSG, ABANDON_MSG):
            return True
        return False

    def error(self, e):
        self.state()
        traceback.print_exc()
        tkinter.messagebox.showerror(type(e).__name__, str(e))

    def readin(self, filename, quiet=False):
        self.state('Opening...')
        try:
            with open(filename) as f:
                text = f.read()
        except Exception as e:
            if quiet:
                self.state('New file "{}".'.format(os.path.basename(filename)))
            else:
                self.error(e)
            return
        self.textout.replace('1.0', 'end', text)
        self.textout.delete('end - 1 char', 'end')  # delete extra newline
        self.state('Opened "{}".'.format(os.path.basename(filename)))
        self.textout.edit_modified(0)
        self.filename = filename
        self.settitle()

    def open(self, event=None):
        if self.abandon():
            filename = tkinter.filedialog.askopenfilename()
            if filename:
                self.readin(filename)
        return 'break'

    def save(self, event=None):
        if self.filename:
            self.writeout(self.filename)
        else:
            self.saveas(event)

    def saveas(self, event=None):
        filename = tkinter.filedialog.asksaveasfilename()
        if filename:
            self.writeout(filename)

    def writeout(self, filename):
        self.state('Saving...')
        try:
            with open(filename, 'w') as f:
                f.write(self.textout.get('1.0', 'end'))
            self.state('Saved "{}".'.format(os.path.basename(filename)))
            self.textout.edit_modified(0)
            self.filename = filename
            self.settitle()
        except Exception as e:
            self.error(e)

    def sendtext(self, event):
        self.textout.insert('end', self.textin.get('1.0', 'end'))
        self.textin.delete('1.0', 'end')
        return 'break'

    def autoindent(self, event):
        line = self.textout.get('insert linestart', 'insert lineend')
        indent = re.match('^[\t ]*', line).group(0)
        self.textout.insert('insert', '\n' + indent)
        return 'break'

    def geteditfocus(self):
        widget = self.focus_get()
        if widget not in (self.textin, self.textout):
            widget = self.textout
        return widget

    def deletesel(self, event):
        widget = event.widget
        try:
            widget.delete('sel.first', 'sel.last')
        except tkinter.TclError:
            pass

    def selectall(self, event=None):
        widget = self.geteditfocus()
        widget.tag_add('sel', '1.0', 'end')
        return 'break'

    def pipe(self, event=None):
        widget = self.geteditfocus()
        try:
            cmd = tkinter.simpledialog.askstring(
                'Pipe', 'Pipe selection through command:')
            if not cmd:
                return
            intext = ''
            try:
                intext = widget.get('sel.first', 'sel.last')
            except tkinter.TclError:
                pass
            text = subprocess.check_output(cmd, input=intext, shell=True,
                                           universal_newlines=True, timeout=1)
            try:
                widget.delete('sel.first', 'sel.last')
            except tkinter.TclError:
                pass
            widget.insert('insert', text)
{'fraction_non_alphanumeric': 0.1360728184156718, 'fraction_numerical': 0.005210738077963195, 'mean_word_length': 2.0804550995530273, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1143629', 'n_tokens_mistral': 4645, 'n_tokens_neox': 4550, 'n_words': 810}