You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
4.8 KiB
145 lines
4.8 KiB
# IDLEX EXTENSION
|
|
## """
|
|
## Copyright(C) 2011-2012 The Board of Trustees of the University of Illinois.
|
|
## All rights reserved.
|
|
##
|
|
## Developed by: Roger D. Serwy
|
|
## University of Illinois
|
|
##
|
|
## Permission is hereby granted, free of charge, to any person obtaining
|
|
## a copy of this software and associated documentation files (the
|
|
## "Software"), to deal with the Software without restriction, including
|
|
## without limitation the rights to use, copy, modify, merge, publish,
|
|
## distribute, sublicense, and/or sell copies of the Software, and to
|
|
## permit persons to whom the Software is furnished to do so, subject to
|
|
## the following conditions:
|
|
##
|
|
## + Redistributions of source code must retain the above copyright
|
|
## notice, this list of conditions and the following disclaimers.
|
|
## + Redistributions in binary form must reproduce the above copyright
|
|
## notice, this list of conditions and the following disclaimers in the
|
|
## documentation and/or other materials provided with the distribution.
|
|
## + Neither the names of Roger D. Serwy, the University of Illinois, nor
|
|
## the names of its contributors may be used to endorse or promote
|
|
## products derived from this Software without specific prior written
|
|
## permission.
|
|
##
|
|
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
## MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
## IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
## ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
## CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
|
|
## THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
|
|
##
|
|
##
|
|
##
|
|
##
|
|
## Clear Window Extension
|
|
##
|
|
## About:
|
|
##
|
|
## It provides "Clear Shell Window" under "Options"
|
|
## with ability to undo.
|
|
##
|
|
## Part of Issue 6143
|
|
##
|
|
## """
|
|
|
|
config_extension_def = """
|
|
[ClearWindow]
|
|
enable=1
|
|
enable_editor=0
|
|
enable_shell=1
|
|
[ClearWindow_cfgBindings]
|
|
clear-window=<Control-Key-l>
|
|
"""
|
|
|
|
|
|
jn = lambda x,y: '%i.%i' % (x,y) # join integers to text coordinates
|
|
sp = lambda x: tuple(map(int, x.split('.'))) # convert tkinter Text coordinate to a line and column tuple
|
|
|
|
import sys
|
|
import re
|
|
from idlelib.UndoDelegator import DeleteCommand
|
|
|
|
ansi_re = re.compile(r'\x01?\x1b\[(.*?)m\x02?')
|
|
def strip_ansi(s):
|
|
return ansi_re.sub("", s)
|
|
|
|
class ClearWindow:
|
|
menudefs = [
|
|
('options', [
|
|
('Clear Shell Window', '<<clear-window>>'),
|
|
]),]
|
|
|
|
def __init__(self, editwin):
|
|
self.editwin = editwin
|
|
self.text = self.editwin.text
|
|
self.text.bind("<<clear-window>>", self.clear_window)
|
|
|
|
def clear_window_event(self, ev=None):
|
|
self.clear_window(ev)
|
|
return "break"
|
|
|
|
def clear_window(self, event):
|
|
|
|
per = self.editwin.per
|
|
text = per.bottom
|
|
|
|
iomark_orig = text.index('iomark')
|
|
line_io, col_io = sp(iomark_orig)
|
|
|
|
# if cursor is at the prompt, preserve the prompt (multiline)
|
|
prompt = strip_ansi(sys.ps1)
|
|
backlines = prompt.count('\n')
|
|
prompt_start = jn(line_io-backlines, 0)
|
|
maybe_prompt = text.get(prompt_start, prompt_start + '+%ic' % len(prompt))
|
|
at_prompt = maybe_prompt == prompt
|
|
|
|
if at_prompt:
|
|
endpos = text.index(prompt_start)
|
|
else:
|
|
endpos = text.index('iomark linestart')
|
|
|
|
dump = text.dump('1.0', endpos, all=True)
|
|
|
|
# Add a command to the undo delegator
|
|
undo = self.editwin.undo
|
|
if undo:
|
|
dc = ClearWindowDeleteCommand('1.0', endpos, dump)
|
|
undo.addcmd(dc)
|
|
|
|
text.edit_reset() # clear out Tkinter's undo history
|
|
|
|
|
|
class ClearWindowDeleteCommand(DeleteCommand):
|
|
def __init__(self, index1, index2, dump):
|
|
DeleteCommand.__init__(self, index1, index2)
|
|
self.dump = dump
|
|
|
|
def do(self, text):
|
|
text.delete(self.index1, self.index2)
|
|
text.see('insert')
|
|
|
|
def redo(self, text):
|
|
text.delete(self.index1, self.index2)
|
|
text.see('insert')
|
|
|
|
def undo(self, text):
|
|
# inspired by "Serializing a text widget" at http://wiki.tcl.tk/9167
|
|
dump = self.dump
|
|
tag = {} # remember the index where a tag was activated
|
|
for key, value, index in dump:
|
|
if key == 'text':
|
|
text.insert(index, value, '')
|
|
elif key == 'tagon':
|
|
tag[value] = index
|
|
elif key == 'tagoff':
|
|
text.tag_add(value, tag[value], index)
|
|
del tag[value]
|
|
# extend existing tags to the end position
|
|
for value in tag:
|
|
text.tag_add(value, tag[value], self.index2)
|
|
text.see('insert')
|