parent
4b36c23942
commit
ad71553553
|
@ -8,37 +8,11 @@ import bufferlist, color, completer, keyinput, method, minibuffer, mode
|
|||
import util, window
|
||||
from point import Point
|
||||
|
||||
def run(buffers, jump_to_line=None, init_mode=None):
|
||||
# save terminal state so we can restore it when the program exits
|
||||
attr = termios.tcgetattr(sys.stdin)
|
||||
keyinput.disable_control_chars()
|
||||
|
||||
retval = 1
|
||||
try:
|
||||
retval = curses.wrapper(run_app, buffers, jump_to_line, init_mode)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
# restore terminal state
|
||||
termios.tcsetattr(sys.stdin, termios.TCSANOW, attr)
|
||||
return retval
|
||||
|
||||
def run_app(stdscr, buffers, jump_to_line=None, init_mode=None):
|
||||
curses.def_shell_mode()
|
||||
a = Application(stdscr, buffers, jump_to_line, init_mode)
|
||||
a.run()
|
||||
|
||||
MAX_ERROR_DISPLAY = 128
|
||||
KILL_RING_LIMIT = 128
|
||||
WORD_LETTERS = list(string.letters + string.digits)
|
||||
ERROR_TIMEOUT = -1
|
||||
#ERROR_TIMEOUT = 2
|
||||
|
||||
class Application(object):
|
||||
def __init__(self, stdscr, buffers=[], jump_to_line=None, init_mode=None):
|
||||
# initalize curses primitives
|
||||
self.stdscr = stdscr
|
||||
(self.y, self.x) = self.stdscr.getmaxyx()
|
||||
self.y, self.x = self.stdscr.getmaxyx()
|
||||
|
||||
# initialize some basic stuff
|
||||
# a highlighted_range contains three things: (window, start_p, end_p)
|
||||
|
@ -51,7 +25,15 @@ class Application(object):
|
|||
self.mini_prompt = ""
|
||||
self.error_string = ""
|
||||
self.error_timestamp = None
|
||||
self.need_draw = True
|
||||
self.input = keyinput.Handler()
|
||||
|
||||
# some constants
|
||||
self.error_timeout = -1
|
||||
self.max_error_len = 192
|
||||
self.max_num_kills = 64
|
||||
self.def_word_letters = string.letters + string.digits
|
||||
|
||||
# let's prepopulate some default token colors
|
||||
self.token_colors = {
|
||||
'comment': ('red', 'default', 'bold'),
|
||||
|
@ -544,7 +526,8 @@ class Application(object):
|
|||
self.kill_ring[-1] = self.kill_ring[-1] + s
|
||||
else:
|
||||
self.kill_ring.append(s)
|
||||
if KILL_RING_LIMIT and len(self.kill_ring) > KILL_RING_LIMIT:
|
||||
#if KILL_RING_LIMIT and len(self.kill_ring) > KILL_RING_LIMIT:
|
||||
if self.max_num_kills and len(self.kill_ring) > self.max_num_kills:
|
||||
self.kill_ring.pop(0)
|
||||
def pop_kill(self):
|
||||
return self.kill_ring.pop(-1)
|
||||
|
@ -605,16 +588,22 @@ class Application(object):
|
|||
while i == curses.KEY_RESIZE:
|
||||
i = self.win.getch()
|
||||
self.resize_event()
|
||||
self.need_draw = True
|
||||
err = ''
|
||||
try:
|
||||
self.input.parse(i)
|
||||
except Exception, e:
|
||||
err = str(e)
|
||||
while len(self.input.tokens):
|
||||
|
||||
if self.input.tokens:
|
||||
self.need_draw = True
|
||||
while self.input.tokens:
|
||||
t = self.input.tokens.pop(0)
|
||||
self.active_window().mode.handle_token(t)
|
||||
|
||||
if self.need_draw:
|
||||
self.draw(err)
|
||||
self.need_draw = False
|
||||
|
||||
# clear the error line; it might look confusing to the user
|
||||
try:
|
||||
|
@ -667,8 +656,8 @@ class Application(object):
|
|||
self.resize_event()
|
||||
if err:
|
||||
self.set_error(err)
|
||||
if self.error_timestamp is not None and ERROR_TIMEOUT > 0 and \
|
||||
time.time() - self.error_timestamp > ERROR_TIMEOUT:
|
||||
if self.error_timestamp is not None and self.error_timeout > 0 and \
|
||||
time.time() - self.error_timestamp > self.error_timeout:
|
||||
self.clear_error()
|
||||
(y, x) = self.stdscr.getmaxyx()
|
||||
if y != self.y or x != self.x:
|
||||
|
@ -861,10 +850,10 @@ class Application(object):
|
|||
def get_minibuffer_lines(self):
|
||||
lines, lines2 = [], []
|
||||
if self.error_string:
|
||||
if len(self.error_string) < MAX_ERROR_DISPLAY:
|
||||
if len(self.error_string) < self.max_error_len:
|
||||
s = self.error_string
|
||||
else:
|
||||
s = self.error_string[:MAX_ERROR_DISPLAY] + '...'
|
||||
s = self.error_string[:self.max_error_len] + '...'
|
||||
elif self.mini_buffer_is_open():
|
||||
s = self.mini_prompt + self.mini_buffer.lines[0]
|
||||
lines2 = self.mini_buffer.lines[1:]
|
||||
|
@ -895,6 +884,11 @@ def open_plain_file(path, name=None, binary=False):
|
|||
else:
|
||||
raise Exception, "can't open %r; unsupported file type" % path
|
||||
|
||||
def run_app(stdscr, buffers, jump_to_line=None, init_mode=None):
|
||||
curses.def_shell_mode()
|
||||
a = Application(stdscr, buffers, jump_to_line, init_mode)
|
||||
a.run()
|
||||
|
||||
if __name__ == "__main__":
|
||||
ciphers = {
|
||||
'none': open_plain_file,
|
||||
|
@ -986,5 +980,17 @@ if __name__ == "__main__":
|
|||
paths.add(path)
|
||||
names.add(name)
|
||||
|
||||
# save terminal state so we can restore it when the program exits
|
||||
attr = termios.tcgetattr(sys.stdin)
|
||||
keyinput.disable_control_chars()
|
||||
|
||||
# ok, now run our app
|
||||
run(buffers, opts.goto, opts.mode)
|
||||
retval = 1
|
||||
try:
|
||||
retval = curses.wrapper(run_app, buffers, opts.goto, opts.mode)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
# restore terminal state
|
||||
termios.tcsetattr(sys.stdin, termios.TCSANOW, attr)
|
||||
sys.exit(retval)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import codecs, datetime, grp, md5, os, pwd, re, sets, shutil, stat, string
|
||||
import codecs, datetime, grp, md5, os, pwd, re, shutil, stat, string
|
||||
import fcntl, select, pty, threading
|
||||
import aes, dirutil, regex, highlight, lex, term
|
||||
from point import Point
|
||||
|
|
|
@ -10,9 +10,10 @@ class XTermBuffer(Buffer, XTerm):
|
|||
modename = 'pipe'
|
||||
termtype = 'xterm'
|
||||
#termtype = 'vt100'
|
||||
def __init__(self, cmd, args, name=None):
|
||||
def __init__(self, app, cmd, args, name=None):
|
||||
XTerm.__init__(self)
|
||||
Buffer.__init__(self)
|
||||
self.application = app
|
||||
self._name = name or '*XTerm*'
|
||||
self._pid, self._pty = pty.fork()
|
||||
if self._pid == 0:
|
||||
|
@ -102,6 +103,7 @@ class XTermBuffer(Buffer, XTerm):
|
|||
if ifd:
|
||||
data = os.read(ifd[0], 1024)
|
||||
self.term_receive(data)
|
||||
self.application.need_draw = True
|
||||
if ofd:
|
||||
self._lock.acquire()
|
||||
n = os.write(ofd[0], self._towrite)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import glob, os, pwd, sets
|
||||
import glob, os, pwd
|
||||
import method, util
|
||||
|
||||
def find_common_string(candidates):
|
||||
|
@ -78,7 +78,7 @@ class CommandCompleter(Completer):
|
|||
def get_candidates(self, s, w=None):
|
||||
path = os.getenv('PATH')
|
||||
path_dirs = path.split(':')
|
||||
candidates = sets.Set()
|
||||
candidates = set()
|
||||
for d in path_dirs:
|
||||
if (not os.path.isdir(d) or not os.access(d, os.R_OK)):
|
||||
continue
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import os, commands, re, sets, tempfile
|
||||
import os, commands, re, tempfile
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
|
||||
import buffer, default, dirutil, regex, util, window
|
||||
|
@ -216,7 +216,9 @@ class KillRegion(Method):
|
|||
class Copy(Method):
|
||||
'''Copy the contents of the current line'''
|
||||
def _execute(self, w, **vargs):
|
||||
w.copy_line()
|
||||
result = w.copy_line()
|
||||
if result is None:
|
||||
w.set_error("Empty kill region")
|
||||
class CopyRegion(Method):
|
||||
'''Copy the region between the mark and the cursor'''
|
||||
def _execute(self, w, **vargs):
|
||||
|
@ -1017,23 +1019,3 @@ class SetModeTabWidth(Method):
|
|||
return
|
||||
app.modes[mode].tabwidth = vargs['width']
|
||||
w.set_error('Default tab width set to %d' % app.modes[mode].tabwidth)
|
||||
|
||||
#class HideRange(Method):
|
||||
# def _execute(self, w, **vargs):
|
||||
# cursor = w.logical_cursor()
|
||||
# if cursor.y < w.mark.y:
|
||||
# y1, y2 = cursor.y, w.mark.y
|
||||
# elif w.mark.y < cursor.y:
|
||||
# y1, y2 = w.mark.y, cursor.y
|
||||
# else:
|
||||
# w.set_error("No line range selected")
|
||||
# w.hide(y1, y2)
|
||||
# w.set_error("Lines %d through %d hidden" % (y1, y2))
|
||||
#class UnhideLine(Method):
|
||||
# def _execute(self, w, **vargs):
|
||||
# cursor = w.logical_cursor()
|
||||
# if w.ishidden(cursor.y):
|
||||
# w.unhide(cursor.y)
|
||||
# w.set_error("Line %d is no longer hidden" % cursor.y)
|
||||
# else:
|
||||
# w.set_error("Line %d is not hidden" % cursor.y)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import os, commands, re, sets, tempfile
|
||||
import os, commands, re, tempfile
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
|
||||
import buffer, default, dirutil, regex, util, window
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import os, commands, re, sets, tempfile
|
||||
import os, commands, re, tempfile
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
|
||||
import buffer, default, dirutil, lex, regex, util, window
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import os, commands, re, sets, tempfile
|
||||
import os, commands, re, tempfile
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
|
||||
import buffer, buffer.about
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import os, commands, re, sets, tempfile
|
||||
import os, commands, re, tempfile
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
|
||||
import buffer, buffer.console
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import os, commands, re, sets, tempfile
|
||||
import os, commands, re, tempfile
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
|
||||
import buffer, default, dirutil, regex, util, window
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import os, commands, re, sets, tempfile
|
||||
import os, commands, re, tempfile
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
|
||||
import buffer, default, dirutil, regex, util, window
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import os, commands, re, sets, tempfile
|
||||
import os, commands, re, tempfile
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
|
||||
import buffer, default, dirutil, regex, term, util, window
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import os, commands, re, sets, tempfile
|
||||
import os, commands, re, tempfile
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
|
||||
import buffer, default, dirutil, lex, regex, util, window
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import math, os, sets, string
|
||||
import math, os, string
|
||||
import color, method
|
||||
from lex import Lexer
|
||||
from point import Point
|
||||
|
@ -88,6 +88,7 @@ class Fundamental(Handler):
|
|||
tabber = None
|
||||
context = None
|
||||
colors = {}
|
||||
word_letters = None
|
||||
|
||||
# config settings installed/modified by the mode
|
||||
config = {}
|
||||
|
@ -124,7 +125,7 @@ class Fundamental(Handler):
|
|||
for val2 in val:
|
||||
app.config[key].append(val2)
|
||||
for (key, val) in cls.sconfig.iteritems():
|
||||
app.config.setdefault(key, sets.Set())
|
||||
app.config.setdefault(key, set())
|
||||
app.config[key].add(val)
|
||||
for (key, d) in cls.dconfig.iteritems():
|
||||
app.config.setdefault(key, {})
|
||||
|
@ -231,6 +232,10 @@ class Fundamental(Handler):
|
|||
self.add_bindings('insert-text2', ('C-c M-i',))
|
||||
self.add_bindings('insert-multiline-text', ('C-c m',))
|
||||
|
||||
# used for all word operations
|
||||
if not self.word_letters:
|
||||
self.word_letters = w.application.def_word_letters
|
||||
|
||||
# create all the insert actions for the basic text input
|
||||
for c in string.letters + string.digits + string.punctuation:
|
||||
self.add_binding('insert-string-%s' % c, c)
|
||||
|
@ -259,8 +264,6 @@ class Fundamental(Handler):
|
|||
c, fg, bg = " ", "red", "default"
|
||||
if cont:
|
||||
c = "\\"
|
||||
if w.hiddenindicator(y):
|
||||
bg = "green"
|
||||
return [RenderString(s=c, attrs=color.build(fg, bg))]
|
||||
def get_lmargin(self, w, y, x, ended=False, cont=False):
|
||||
lm = self.lmargin
|
||||
|
@ -342,10 +345,10 @@ class Fundamental(Handler):
|
|||
self.window.application.last_action = act.name
|
||||
except ActionError, e:
|
||||
#XYZ: HACK--should fix
|
||||
if t not in ('C-]', 'C-g'):
|
||||
self.window.set_error(str(e))
|
||||
else:
|
||||
if t in ('C-]', 'C-g'):
|
||||
self.window.set_error('Cancelled')
|
||||
else:
|
||||
self.window.set_error(str(e))
|
||||
except Exception, e:
|
||||
if DEBUG:
|
||||
raise
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import re, sets, string
|
||||
import re, string
|
||||
|
||||
import color, method, minibuffer, mode, searchutil
|
||||
from point import Point
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import commands, os.path, sets, string, sys, traceback
|
||||
import commands, os.path, string, sys, traceback
|
||||
import color, completer, default, mode, method, regex, tab
|
||||
from point import Point
|
||||
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import commands, os.path, sets, string, sys, traceback
|
||||
import commands, os.path, string, sys, traceback
|
||||
import color, completer, default, mode, method, regex, tab
|
||||
from point import Point
|
||||
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule, NocasePatternRule
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import commands, os.path, sets, string, sys, traceback
|
||||
import commands, os.path, string, sys, traceback
|
||||
import color, completer, default, mode, method, regex, tab
|
||||
from point import Point
|
||||
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule, NocasePatternRule
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import commands, os.path, sets, string, sys, traceback
|
||||
import commands, os.path, string, sys, traceback
|
||||
import color, completer, default, mode, method, regex, tab
|
||||
from point import Point
|
||||
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import commands, os.path, sets, string, sys, traceback
|
||||
import commands, os.path, string, sys, traceback
|
||||
import color, completer, default, mode, method, regex, tab
|
||||
from point import Point
|
||||
from lex import Grammar, PatternRule, RegionRule, NocasePatternRule
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import os, re, sets, string, sys
|
||||
import os, re, string, sys
|
||||
import buffer, color, commands, completer, context, default, method, mode, regex, tab
|
||||
from point import Point
|
||||
from lex import Grammar, PatternRule, ContextPatternRule, RegionRule, \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import commands, os.path, sets, string, sys, traceback
|
||||
import commands, os.path, string, sys, traceback
|
||||
import color, completer, context, default, mode, method, regex, tab, method.introspect
|
||||
from point import Point
|
||||
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import re, sets, string
|
||||
import re, string
|
||||
|
||||
import color, method, minibuffer, mode, searchutil
|
||||
from point import Point
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import commands, os.path, sets, string, sys, traceback
|
||||
import commands, os.path, string, sys, traceback
|
||||
import color, completer, default, mode, method, regex, tab
|
||||
from point import Point
|
||||
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import re, sets, string
|
||||
import re, string
|
||||
|
||||
import color, method, minibuffer, mode, searchutil
|
||||
from point import Point
|
||||
|
|
|
@ -123,7 +123,7 @@ class OpenShell(Method):
|
|||
a = w.application
|
||||
if not a.has_buffer_name('*Shell*'):
|
||||
#b = buffer.pipe.PipeBuffer('/bin/bash', [], name="*Shell*", term='xterm')
|
||||
b = buffer.emul.XTermBuffer('/bin/bash', [], name="*Shell*")
|
||||
b = buffer.emul.XTermBuffer(a, '/bin/bash', [], name="*Shell*")
|
||||
a.add_buffer(b)
|
||||
window.Window(b, a)
|
||||
b = a.bufferlist.get_buffer_by_name('*Shell*')
|
||||
|
|
174
window.py
174
window.py
|
@ -3,8 +3,6 @@ import color, highlight, regex
|
|||
from point import Point
|
||||
from render import RenderString
|
||||
|
||||
WORD_LETTERS = list(string.letters + string.digits)
|
||||
|
||||
# note about the cursor: the cursor position will insert in front of the
|
||||
# character it highlights. to this end, it needs to be able to highlight behind
|
||||
# the last character on a line. thus, the x coordinate of the (logical) cursor
|
||||
|
@ -26,15 +24,12 @@ class Window(object):
|
|||
self.application = a
|
||||
self.height = height
|
||||
self.width = width
|
||||
|
||||
self.first = Point(0, 0)
|
||||
self.last = None
|
||||
self.cursor = Point(0, 0)
|
||||
self.mark = None
|
||||
self.active_point = None
|
||||
self.input_line = ""
|
||||
self.hidden_ranges = {}
|
||||
self.hidden_lines = {}
|
||||
|
||||
if mode_name is not None:
|
||||
pass
|
||||
|
@ -311,14 +306,14 @@ class Window(object):
|
|||
x = len(self.buffer.lines[y])
|
||||
else:
|
||||
x -= 1
|
||||
while (y, x) >= start and self.xy_char(x, y) not in WORD_LETTERS:
|
||||
while (y, x) >= start and self.xy_char(x, y) not in self.mode.word_letters:
|
||||
if x == 0:
|
||||
y -= 1
|
||||
x = len(self.buffer.lines[y])
|
||||
else:
|
||||
x -= 1
|
||||
found_word = False
|
||||
while (y, x) >= start and self.xy_char(x, y) in WORD_LETTERS:
|
||||
while (y, x) >= start and self.xy_char(x, y) in self.mode.word_letters:
|
||||
found_word = True
|
||||
if x == 0:
|
||||
y -= 1
|
||||
|
@ -339,13 +334,13 @@ class Window(object):
|
|||
else:
|
||||
(x, y) = p.xy()
|
||||
end = self.buffer.get_buffer_end()
|
||||
while (y, x) < end and self.xy_char(x, y) not in WORD_LETTERS:
|
||||
while (y, x) < end and self.xy_char(x, y) not in self.mode.word_letters:
|
||||
if x == len(self.buffer.lines[y]):
|
||||
x = 0
|
||||
y += 1
|
||||
else:
|
||||
x += 1
|
||||
while (y, x) < end and self.xy_char(x, y) in WORD_LETTERS:
|
||||
while (y, x) < end and self.xy_char(x, y) in self.mode.word_letters:
|
||||
if x == len(self.buffer.lines[y]):
|
||||
x = 0
|
||||
y += 1
|
||||
|
@ -360,27 +355,27 @@ class Window(object):
|
|||
p = self.find_right_word()
|
||||
if p is not None:
|
||||
self.goto(p)
|
||||
def get_word_bounds_at_point(self, p, wl=WORD_LETTERS):
|
||||
def get_word_bounds_at_point(self, p):
|
||||
if len(self.buffer.lines[p.y]) == 0:
|
||||
return None
|
||||
elif self.cursor_char() not in wl:
|
||||
return None
|
||||
x1 = x2 = p.x
|
||||
while x1 > 0 and self.xy_char(x1 - 1, p.y) in wl:
|
||||
while x1 > 0 and self.xy_char(x1 - 1, p.y) in self.mode.word_letters:
|
||||
x1 -= 1
|
||||
while x2 < len(self.buffer.lines[p.y]) and self.xy_char(x2, p.y) in wl:
|
||||
x2 += 1
|
||||
return (Point(x1, p.y), Point(x2, p.y))
|
||||
def get_word_at_point(self, p, wl=WORD_LETTERS):
|
||||
bounds = self.get_word_bounds_at_point(p, wl)
|
||||
def get_word_at_point(self, p):
|
||||
bounds = self.get_word_bounds_at_point(p)
|
||||
if bounds is None:
|
||||
return None
|
||||
else:
|
||||
return self.buffer.get_substring(bounds[0], bounds[1])
|
||||
def get_word_bounds(self, wl=WORD_LETTERS):
|
||||
return self.get_word_bounds_at_point(self.logical_cursor(), wl)
|
||||
def get_word(self, wl=WORD_LETTERS):
|
||||
return self.get_word_at_point(self.logical_cursor(), wl)
|
||||
def get_word_bounds(self):
|
||||
return self.get_word_bounds_at_point(self.logical_cursor())
|
||||
def get_word(self):
|
||||
return self.get_word_at_point(self.logical_cursor())
|
||||
|
||||
# page up/down
|
||||
def _pshift_up(self, p, num):
|
||||
|
@ -496,69 +491,111 @@ class Window(object):
|
|||
self.set_mark_point(self.logical_cursor())
|
||||
self.goto(p)
|
||||
|
||||
# deletion
|
||||
def left_delete(self):
|
||||
self.buffer.left_delete(self.logical_cursor())
|
||||
def right_delete(self):
|
||||
self.buffer.right_delete(self.logical_cursor())
|
||||
def delete(self, p1, p2):
|
||||
self.buffer.delete(p1, p2)
|
||||
|
||||
# killing
|
||||
def kill_line(self):
|
||||
return self.copy_line(kill=True)
|
||||
def kill_region(self):
|
||||
return self.copy_region(kill=True)
|
||||
def kill_left_word(self):
|
||||
p1 = self.find_left_word()
|
||||
p2 = self.logical_cursor()
|
||||
if p1 == p2:
|
||||
return
|
||||
return self.kill(p1, p2)
|
||||
def kill_right_word(self):
|
||||
p1 = self.logical_cursor()
|
||||
p2 = self.find_right_word()
|
||||
if p1 == p2:
|
||||
return
|
||||
return self.kill(p1, p2)
|
||||
def copy_line(self, kill=False):
|
||||
# finding (used by deletion, killing, and copying)
|
||||
def get_line(self):
|
||||
(x, y) = self.logical_cursor().xy()
|
||||
lines = self.buffer.lines
|
||||
if y < len(lines) - 1:
|
||||
return (Point(0, y), Point(0, y + 1))
|
||||
elif y > 0:
|
||||
return (Point(len(lines[y - 1]), y - 1), Point(len(lines[y]), y))
|
||||
else:
|
||||
return (None, None)
|
||||
def get_line_left(self):
|
||||
cursor = self.logical_cursor()
|
||||
(x, y) = cursor.xy()
|
||||
lines = self.buffer.lines
|
||||
if (x > 0) and not regex.whitespace.match(lines[y][:x]):
|
||||
return (Point(0, y), cursor)
|
||||
elif y > 0:
|
||||
return (Point(len(lines[y - 1]), y - 1), cursor)
|
||||
else:
|
||||
return (None, None)
|
||||
def get_line_right(self):
|
||||
cursor = self.logical_cursor()
|
||||
(x, y) = cursor.xy()
|
||||
lines = self.buffer.lines
|
||||
if (x < len(lines[y]) and not regex.whitespace.match(lines[y][x:])):
|
||||
limit = Point(len(lines[y]), y)
|
||||
return (cursor, Point(len(lines[y]), y))
|
||||
elif y < len(lines) - 1:
|
||||
limit = Point(0, y + 1)
|
||||
return (cursor, Point(0, y + 1))
|
||||
else:
|
||||
return
|
||||
if kill:
|
||||
return self.kill(cursor, limit)
|
||||
else:
|
||||
return self.copy(cursor, limit)
|
||||
def copy_region(self, kill=False):
|
||||
return (None, None)
|
||||
def get_region(self):
|
||||
cursor = self.logical_cursor()
|
||||
p1, p2 = None, None
|
||||
if cursor < self.mark:
|
||||
p1 = cursor
|
||||
p2 = self.mark
|
||||
elif self.mark < cursor:
|
||||
p1 = self.mark
|
||||
p2 = cursor
|
||||
return (p1, p2)
|
||||
def get_left_word(self):
|
||||
p1 = self.find_left_word()
|
||||
p2 = self.logical_cursor()
|
||||
if p1 == p2:
|
||||
return (None, None)
|
||||
else:
|
||||
self.input_line = "Empty kill region"
|
||||
return
|
||||
if kill:
|
||||
return self.kill(p1, p2)
|
||||
return (p1, p2)
|
||||
def get_right_word(self):
|
||||
p1 = self.logical_cursor()
|
||||
p2 = self.find_right_word()
|
||||
if p1 == p2:
|
||||
return (None, None)
|
||||
else:
|
||||
return self.copy(p1, p2)
|
||||
return (p1, p2)
|
||||
|
||||
# deletion
|
||||
def delete(self, p1, p2):
|
||||
self.buffer.delete(p1, p2)
|
||||
def delete_line(self):
|
||||
(p1, p2) = self.get_line_right()
|
||||
if p1 is not None: self.delete(p1, p2)
|
||||
def delete_region(self):
|
||||
(p1, p2) = self.get_region()
|
||||
if p1 is not None: self.delete(p1, p2)
|
||||
def delete_left_word(self):
|
||||
(p1, p2) = self.get_left_word()
|
||||
if p1 is not None: self.delete(p1, p2)
|
||||
def delete_right_word(self):
|
||||
(p1, p2) = self.get_right_word()
|
||||
if p1 is not None: self.delete(p1, p2)
|
||||
def left_delete(self):
|
||||
self.buffer.left_delete(self.logical_cursor())
|
||||
def right_delete(self):
|
||||
self.buffer.right_delete(self.logical_cursor())
|
||||
|
||||
# killing
|
||||
def kill(self, p1, p2):
|
||||
killed = self.buffer.get_substring(p1, p2)
|
||||
self.buffer.delete(p1, p2)
|
||||
self.application.push_kill(killed)
|
||||
return killed
|
||||
def kill_line(self):
|
||||
(p1, p2) = self.get_line_right()
|
||||
if p1 is not None: self.kill(p1, p2)
|
||||
def kill_region(self):
|
||||
(p1, p2) = self.get_region()
|
||||
if p1 is not None: self.kill(p1, p2)
|
||||
def kill_left_word(self):
|
||||
(p1, p2) = self.get_left_word()
|
||||
if p1 is not None: self.kill(p1, p2)
|
||||
def kill_right_word(self):
|
||||
(p1, p2) = self.get_right_word()
|
||||
if p1 is not None: self.kill(p1, p2)
|
||||
|
||||
# copying
|
||||
def copy(self, p1, p2):
|
||||
copied = self.buffer.get_substring(p1, p2)
|
||||
self.application.push_kill(copied)
|
||||
return copied
|
||||
def copy_line(self):
|
||||
(p1, p2) = self.get_line_right()
|
||||
if p1 is not None: return self.copy(p1, p2)
|
||||
def copy_region(self, kill=False):
|
||||
(p1, p2) = self.get_region()
|
||||
if p1 is not None: return self.copy(p1, p2)
|
||||
|
||||
# overwriting
|
||||
def overwrite_char_at_cursor(self, c):
|
||||
|
@ -610,31 +647,6 @@ class Window(object):
|
|||
else:
|
||||
return self.buffer.lines[y][x]
|
||||
|
||||
# hiding stuff
|
||||
def hide(self, y1, y2):
|
||||
if y2 == 0:
|
||||
return
|
||||
for (py1, py2) in self.hidden_ranges.itervalues():
|
||||
if ((y1 >= py1 and y1 < py2) or
|
||||
(y2 >= py1 and y2 < py2) or
|
||||
(y1 <= py1 and y2 >= py2)):
|
||||
return
|
||||
for i in range(y1, y2):
|
||||
self.hidden_lines[i] = y2
|
||||
self.hidden_ranges[y2] = (y1, y2)
|
||||
def ishidden(self, y):
|
||||
return self.hidden_lines.setdefault(y, False)
|
||||
def hiddenindicator(self, y):
|
||||
return y in self.hidden_ranges
|
||||
def unhide(self, y):
|
||||
py2 = self.ishidden(y)
|
||||
if not py2:
|
||||
return
|
||||
py1 = self.hidden_ranges[py2][0]
|
||||
del self.hidden_ranges[py2]
|
||||
for i in range(py1, py2):
|
||||
self.hidden_lines[i] = False
|
||||
|
||||
# undo/redo
|
||||
def undo(self):
|
||||
p = self.buffer.undo()
|
||||
|
|
Loading…
Reference in New Issue