--HG--
branch : pmacs2
This commit is contained in:
moculus 2007-06-05 04:49:24 +00:00
parent 3e1c2ef3c6
commit 99dfb30e3e
11 changed files with 333 additions and 274 deletions

View File

@ -10,7 +10,7 @@ from point2 import Point
#import mode, mode_c, mode_mini, mode_python, mode_nasm, mode_perl, mode_search #import mode, mode_c, mode_mini, mode_python, mode_nasm, mode_perl, mode_search
#import mode_replace, mode_xml, mode_console, mode_sh, mode_text, mode_which #import mode_replace, mode_xml, mode_console, mode_sh, mode_text, mode_which
#import mode_mutt, mode_sql, mode_javascript, mode_diff, mode_blame, mode_tt #import mode_mutt, mode_sql, mode_javascript, mode_diff, mode_blame, mode_tt
import mode2, mode_mini2 import mode2, mode_mini, mode_python, mode_perl
def run(buffers, jump_to_line=None, init_mode=None): def run(buffers, jump_to_line=None, init_mode=None):
# save terminal state so we can restore it when the program exits # save terminal state so we can restore it when the program exits
@ -78,19 +78,15 @@ class Application:
# initialize our modes # initialize our modes
self.modes = { self.modes = {
'fundamental': mode2.Fundamental,
'mini': mode_mini2.Mini,
}
# self.modes = {
# 'blame': mode_blame.Blame, # 'blame': mode_blame.Blame,
# 'c': mode_c.C, # 'c': mode_c.C,
# 'console': mode_console.Console, # 'console': mode_console.Console,
# 'diff': mode_diff.Diff, # 'diff': mode_diff.Diff,
# 'fundamental': mode.Fundamental, 'fundamental': mode2.Fundamental,
# 'mini': mode_mini.Mini, 'mini': mode_mini.Mini,
# 'nasm': mode_nasm.Nasm, # 'nasm': mode_nasm.Nasm,
# 'perl': mode_perl.Perl, 'perl': mode_perl.Perl,
# 'python': mode_python.Python, 'python': mode_python.Python,
# 'replace': mode_replace.Replace, # 'replace': mode_replace.Replace,
# 'search': mode_search.Search, # 'search': mode_search.Search,
# 'sh': mode_sh.Sh, # 'sh': mode_sh.Sh,
@ -101,7 +97,7 @@ class Application:
# 'sql': mode_sql.Sql, # 'sql': mode_sql.Sql,
# 'javascript': mode_javascript.Javascript, # 'javascript': mode_javascript.Javascript,
# 'template': mode_tt.Template, # 'template': mode_tt.Template,
# } }
# these are used in this order to determine which mode to open certain # these are used in this order to determine which mode to open certain
# kinds of files # kinds of files
@ -114,10 +110,10 @@ class Application:
#'.profile': 'sh', #'.profile': 'sh',
} }
self.mode_extensions = { self.mode_extensions = {
# '.py': 'python', '.py': 'python',
# '.pl': 'perl', '.pl': 'perl',
# '.pm': 'perl', '.pm': 'perl',
# '.t': 'perl', '.t': 'perl',
# '.c': 'c', # '.c': 'c',
# '.txt': 'text', # '.txt': 'text',
# '.s': 'nasm', # '.s': 'nasm',
@ -132,8 +128,8 @@ class Application:
# '.tt': 'template' # '.tt': 'template'
} }
self.mode_detection = { self.mode_detection = {
# 'python': 'python', 'python': 'python',
# 'perl': 'perl', 'perl': 'perl',
# 'sh': 'sh', # 'sh': 'sh',
# 'bash': 'sh', # 'bash': 'sh',
} }
@ -281,7 +277,7 @@ class Application:
f.close() f.close()
b = buffer2.FileBuffer(path) b = buffer2.FileBuffer(path)
b.open() b.open()
self.add_window_to_buffer(b, self.active_slot) #self.add_window_to_buffer(b, self.active_slot)
self.add_buffer(b) self.add_buffer(b)
if switch_to: if switch_to:
self.switch_buffer(b) self.switch_buffer(b)
@ -292,7 +288,7 @@ class Application:
b = buffer2.DataBuffer(name, data) b = buffer2.DataBuffer(name, data)
if modename is not None: if modename is not None:
b.modename = modename b.modename = modename
self.add_window_to_buffer(b, self.active_slot) #self.add_window_to_buffer(b, self.active_slot)
self.add_buffer(b) self.add_buffer(b)
if switch_to: if switch_to:
self.switch_buffer(b) self.switch_buffer(b)
@ -318,10 +314,11 @@ class Application:
def switch_buffer(self, b): def switch_buffer(self, b):
assert self.has_buffer_name(b.name()), "buffer %s does not exist" % (b.name()) assert self.has_buffer_name(b.name()), "buffer %s does not exist" % (b.name())
assert 0 <= self.active_slot and self.active_slot < len(self.bufferlist.slots) assert 0 <= self.active_slot and self.active_slot < len(self.bufferlist.slots)
self.add_window_to_buffer(b, self.active_slot) #self.add_window_to_buffer(b, self.active_slot)
self.bufferlist.set_slot(self.active_slot, b) self.bufferlist.set_slot(self.active_slot, b)
def add_window_to_buffer(self, b, slotname): def add_window_to_buffer(self, b, slotname):
# XYZ
if not b.has_window(slotname): if not b.has_window(slotname):
slot = self.bufferlist.slots[slotname] slot = self.bufferlist.slots[slotname]
window2.Window(b, self, height=slot.height, width=slot.width) window2.Window(b, self, height=slot.height, width=slot.width)
@ -445,34 +442,6 @@ class Application:
self.hide_cursor() self.hide_cursor()
curses.doupdate() curses.doupdate()
# debugging
def dump(self):
w = self.window()
ll = len(w.buffer.lines)
pl = len(w.get_physical_lines())
vl = len(w.visible_lines())
first = w.first
last = w.last
cursor = w.logical_cursor()
vcursor = w.visible_cursor()
s = ""
s += "width: %d\n" % (w.width)
s += "height: %d\n" % (w.height)
s += "len logical lines: %d\n" % (ll)
s += "logical first: %s\n" % (first)
s += "logical last: %s\n" % (last)
s += "logical cursor: %s\n" % (cursor)
s += "len physical lines: %d\n" % (pl)
s += "physical first: %s\n" % (w.physical_point(first))
s += "physical last: %s\n" % (w.physical_point(last))
s += "physical cursor: %s\n" % (w.physical_point(cursor))
s += "len visible lines: %d\n" % (vl)
s += "visible first: %s\n" % ("n/a")
s += "visible last: %s\n" % ("n/a")
s += "visible cursor: %s\n" % (vcursor)
return s
# sub-drawing methods # sub-drawing methods
def draw_slots(self): def draw_slots(self):
self.win.erase() self.win.erase()
@ -486,6 +455,7 @@ class Application:
if slot.window is None: if slot.window is None:
return return
w = slot.window w = slot.window
modename = w.mode.name()
redattr = color.build_attr(color.pairs('red', 'default')) redattr = color.build_attr(color.pairs('red', 'default'))
@ -497,15 +467,42 @@ class Application:
(px, py) = (None, None) (px, py) = (None, None)
while count < slot.height: while count < slot.height:
if y >= len(lines): if y >= len(lines):
self.win.addstr(slot.offset + count, 0, '~' + ' ' * (slot.width - 1), redattr) self.win.addstr(slot.offset + count, 0, '~', redattr)
else: else:
# let's find the cursor
if cy == y and cx >= x and cx < x + slot.width: if cy == y and cx >= x and cx < x + slot.width:
px = cx - x px = cx - x
py = count py = count
line = lines[y] line = lines[y]
subline = line[x:x + slot.width] if modename in w.buffer.highlights:
if len(subline) < slot.width: group = w.buffer.highlights[modename].tokens[y]
subline += ' ' * (slot.width - len(subline)) j = 0
for token in group:
assert token.y == y
if token.x < x:
continue
elif token.x >= x + slot.width:
break
c = w.mode.colors.get(token.name, w.mode.default_color)
# c = w.mode.default_color
# name_parts = token.name.split('.')
# for i in range(0, len(name_parts)):
# name = '.'.join(name_parts[i:])
# if name in w.mode.colors:
# c = w.mode.colors[name]
# break
if DARK_BACKGROUND:
c |= curses.A_BOLD
if token.x + len(token.string) >= x + slot.width:
n = len(token.string) - x - slot.width + token.x
s = token.string[:n]
self.win.addstr(slot.offset + count, token.x - x, s, c)
else:
self.win.addstr(slot.offset + count, token.x - x, token.string, c)
else:
self.win.addstr(slot.offset + count, 0, line[x:x + slot.width]) self.win.addstr(slot.offset + count, 0, line[x:x + slot.width])
if x + slot.width >= len(line): if x + slot.width >= len(line):

View File

@ -1,5 +1,5 @@
import md5, os, sets, shutil import md5, os, sets, shutil
import aes, regex import aes, regex, highlight2
from point2 import Point from point2 import Point
# undo/redo stack constants # undo/redo stack constants
@ -39,7 +39,7 @@ class Buffer(object):
self.stack_limit = stack_limit self.stack_limit = stack_limit
self.nl = nl self.nl = nl
self.modified = False self.modified = False
self.modes = {} self.highlights = {}
# basic file operation stuff # basic file operation stuff
def _open_file_r(self, path): def _open_file_r(self, path):
@ -99,19 +99,35 @@ class Buffer(object):
def add_window(self, w): def add_window(self, w):
if w not in self.windows: if w not in self.windows:
self.windows.append(w) self.windows.append(w)
modename = w.mode.name()
if modename not in self.highlights and w.mode.lexer is not None:
self.highlights[modename] = highlight2.Highlighter(w.mode.lexer)
self.highlights[modename].highlight(self.lines)
def remove_window(self, w): def remove_window(self, w):
if w in self.windows: if w in self.windows:
self.windows.remove(w) self.windows.remove(w)
modename = w.mode.name()
found = False
for w2 in self.windows:
if w2.mode.name() == modename:
found = True
break
if not found:
del self.highlights[modename]
def _region_add(self, p1, p2, lines, act): def _region_add(self, p1, p2, lines, act):
move = DelMove(self, p1, p2) move = DelMove(self, p1, p2)
self.add_to_stack(move, act) self.add_to_stack(move, act)
for w in self.windows: for w in self.windows:
w.region_added(p1, lines) w.region_added(p1, lines)
for name in self.highlights:
self.highlights[name].relex_add(self.lines, p1.y, p1.x, lines)
def _region_del(self, p1, p2, lines, act): def _region_del(self, p1, p2, lines, act):
move = AddMove(self, p1, lines) move = AddMove(self, p1, lines)
self.add_to_stack(move, act) self.add_to_stack(move, act)
for w in self.windows: for w in self.windows:
w.region_removed(p1, p2) w.region_removed(p1, p2)
for name in self.highlights:
self.highlights[name].relex_del(self.lines, p1.y, p1.x, p2.y, p2.x)
# internal validation # internal validation
def _validate_point(self, p): def _validate_point(self, p):

View File

@ -303,25 +303,25 @@ class PerlGrammar(Grammar):
pattern=r"(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*", pattern=r"(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*",
), ),
# nested regions # # nested regions
RegionRule( # RegionRule(
name=r'paren', # name=r'paren',
start=r'\(', # start=r'\(',
grammar=None, # grammar=None,
end=r'\)', # end=r'\)',
), # ),
RegionRule( # RegionRule(
name=r'brace', # name=r'brace',
start=r'{', # start=r'{',
grammar=None, # grammar=None,
end=r'}', # end=r'}',
), # ),
RegionRule( # RegionRule(
name=r'bracket', # name=r'bracket',
start=r'\[', # start=r'\[',
grammar=None, # grammar=None,
end=r'\]', # end=r'\]',
), # ),
# some basic stuff # some basic stuff
PatternRule( PatternRule(

View File

@ -1,5 +1,6 @@
import os, commands, popen2, re import os, commands, popen2, re
import buffer, default, point, regex, util, window import buffer2, default, regex, util, window2
from point2 import Point
DATATYPES = { DATATYPES = {
"path": None, "path": None,
@ -204,10 +205,9 @@ class OpenFile(Method):
i += 1 i += 1
auxname = '%s/%d' % (name, i) auxname = '%s/%d' % (name, i)
name = auxname name = auxname
b = buffer.FileBuffer(path, name=name) b = buffer2.FileBuffer(path, name=name)
b.open() b.open()
(height, width) = a.get_window_height_width(a.active_slot) window2.Window(b, a, height=0, width=0)
window.Window(b, a, height=height, width=width, slot=a.active_slot)
w.application.add_buffer(b) w.application.add_buffer(b)
SwitchBuffer().execute(w, buffername=b.name()) SwitchBuffer().execute(w, buffername=b.name())
class OpenAesFile(Method): class OpenAesFile(Method):
@ -221,10 +221,9 @@ class OpenAesFile(Method):
path = os.path.abspath(os.path.realpath(util.expand_tilde(path))) path = os.path.abspath(os.path.realpath(util.expand_tilde(path)))
a = w.application a = w.application
if not w.application.has_buffer_name(path): if not w.application.has_buffer_name(path):
b = buffer.AesBuffer(path, password) b = buffer2.AesBuffer(path, password)
b.open() b.open()
(height, width) = a.get_window_height_width(a.active_slot) window.Window(b, a, height=0, width=0)
window.Window(b, a, height=height, width=width, slot=a.active_slot)
w.application.add_buffer(b) w.application.add_buffer(b)
SwitchBuffer().execute(w, buffername=path) SwitchBuffer().execute(w, buffername=path)
class SwitchBuffer(Method): class SwitchBuffer(Method):
@ -297,11 +296,12 @@ class SaveBuffer(Method):
class RelexBuffer(Method): class RelexBuffer(Method):
'''Relex the buffer; this resets syntax highlighting''' '''Relex the buffer; this resets syntax highlighting'''
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
if w.mode.lexer is not None: h = w.get_highlighter()
w.mode.highlighter.invalidate_tokens() if h is None:
w.application.set_error("Buffer relexed.")
else:
w.application.set_error("No lexer for buffer.") w.application.set_error("No lexer for buffer.")
else:
h.highlight(w.buffer.lines)
w.application.set_error("Buffer relexed.")
class ToggleWindow(Method): class ToggleWindow(Method):
'''Move between visible windows''' '''Move between visible windows'''
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
@ -395,8 +395,8 @@ class DeleteLeft(Method):
cursor = w.logical_cursor() cursor = w.logical_cursor()
line = w.buffer.lines[cursor.y] line = w.buffer.lines[cursor.y]
if cursor.x >= 4 and line[0:cursor.x].isspace(): if cursor.x >= 4 and line[0:cursor.x].isspace():
w.kill(point.Point(cursor.x-4, cursor.y), w.kill(Point(cursor.x-4, cursor.y),
point.Point(cursor.x, cursor.y)) Point(cursor.x, cursor.y))
else: else:
w.left_delete() w.left_delete()
class DeleteRight(Method): class DeleteRight(Method):
@ -405,8 +405,8 @@ class DeleteRight(Method):
cursor = w.logical_cursor() cursor = w.logical_cursor()
line = w.buffer.lines[cursor.y] line = w.buffer.lines[cursor.y]
if len(line[cursor.x:]) >= 4 and line[:cursor.x + 4].isspace(): if len(line[cursor.x:]) >= 4 and line[:cursor.x + 4].isspace():
w.kill(point.Point(cursor.x, cursor.y), w.kill(Point(cursor.x, cursor.y),
point.Point(cursor.x + 4, cursor.y)) Point(cursor.x + 4, cursor.y))
else: else:
w.right_delete() w.right_delete()
class DeleteLeftWord(Method): class DeleteLeftWord(Method):
@ -496,24 +496,25 @@ class InsertTab(Method):
'''Insert tab into buffer, or tabbify line, depending on mode''' '''Insert tab into buffer, or tabbify line, depending on mode'''
def _execute(self, window, **vargs): def _execute(self, window, **vargs):
cursor = window.logical_cursor() cursor = window.logical_cursor()
i = window.mode.get_indentation_level(cursor.y) #i = window.mode.get_indentation_level(cursor.y)
i = None
if i is None: if i is None:
window.insert_string_at_cursor(' ') window.insert_string_at_cursor(' ')
else: else:
j = window.buffer.count_leading_whitespace(cursor.y) j = window.buffer.count_leading_whitespace(cursor.y)
if i != j: if i != j:
KillWhitespace().execute(window) KillWhitespace().execute(window)
window.insert(point.Point(0, cursor.y), ' ' * i) window.insert(Point(0, cursor.y), ' ' * i)
else: else:
window.goto(point.Point(j, cursor.y)) window.goto(Point(j, cursor.y))
class KillWhitespace(Method): class KillWhitespace(Method):
'''Delete leading whitespace on current line''' '''Delete leading whitespace on current line'''
def _execute(self, window, **vargs): def _execute(self, window, **vargs):
cursor = window.logical_cursor() cursor = window.logical_cursor()
i = window.buffer.count_leading_whitespace(cursor.y) i = window.buffer.count_leading_whitespace(cursor.y)
if i > 0: if i > 0:
window.kill(point.Point(0, cursor.y), window.kill(Point(0, cursor.y),
point.Point(i, cursor.y)) Point(i, cursor.y))
# tabification # tabification
class TabBuffer(Method): class TabBuffer(Method):
@ -541,7 +542,7 @@ class CommentRegion(Method):
window.input_line = "Empty kill region" window.input_line = "Empty kill region"
return return
for y in range(p1.y, p2.y): for y in range(p1.y, p2.y):
window.buffer.insert_string_at_cursor(point.Point(0, y), "#") window.buffer.insert_string_at_cursor(Point(0, y), "#")
class UncommentRegion(Method): class UncommentRegion(Method):
'''Remove a comment from every line in the current buffer''' '''Remove a comment from every line in the current buffer'''
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
@ -557,7 +558,7 @@ class UncommentRegion(Method):
return return
for y in range(p1.y, p2.y): for y in range(p1.y, p2.y):
if w.buffer.lines[y].startswith("#"): if w.buffer.lines[y].startswith("#"):
w.buffer.delete_string(point.Point(0, y), point.Point(1, y)) w.buffer.delete_string(Point(0, y), Point(1, y))
# wrapping/justifying/etc # wrapping/justifying/etc
class WrapLine(Method): class WrapLine(Method):
@ -580,7 +581,7 @@ class WrapLine(Method):
move_old_cursor = False move_old_cursor = False
old_cursor.x -= j + 1 old_cursor.x -= j + 1
old_cursor.y += 1 old_cursor.y += 1
window.goto(point.Point(j, i)) window.goto(Point(j, i))
window.right_delete() window.right_delete()
window.insert_string_at_cursor('\n') window.insert_string_at_cursor('\n')
i += 1 i += 1
@ -589,7 +590,7 @@ class WrapLine(Method):
if l > old_cursor.x: if l > old_cursor.x:
window.goto(old_cursor) window.goto(old_cursor)
else: else:
window.goto(point.Point(l, old_cursor.y)) window.goto(Point(l, old_cursor.y))
class WrapParagraph(Method): class WrapParagraph(Method):
limit = 80 limit = 80
wrapper = WrapLine wrapper = WrapLine
@ -658,7 +659,7 @@ class JustifyLeft(Method):
return return
if this_line[i] != ' ': if this_line[i] != ' ':
return return
window.buffer.delete_string(point.Point(i, cursor.y), cursor) window.buffer.delete_string(Point(i, cursor.y), cursor)
# undo/redo # undo/redo
class Undo(Method): class Undo(Method):
@ -766,8 +767,8 @@ class UnindentBlock(Method):
for i in range(0, len(lines)): for i in range(0, len(lines)):
if lines[i].startswith(' '): if lines[i].startswith(' '):
lines[i] = lines[i][4:] lines[i] = lines[i][4:]
w.buffer.delete_string(point.Point(0, p1.y), point.Point(0, p2.y)) w.buffer.delete_string(Point(0, p1.y), Point(0, p2.y))
w.buffer.insert_string_at_cursor(point.Point(0, p1.y), '\n'.join(lines) + '\n') w.buffer.insert_string_at_cursor(Point(0, p1.y), '\n'.join(lines) + '\n')
class IndentBlock(Method): class IndentBlock(Method):
'''Add 4 spaces to each line in region''' '''Add 4 spaces to each line in region'''
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
@ -784,8 +785,8 @@ class IndentBlock(Method):
lines = w.buffer.lines[p1.y:p2.y] lines = w.buffer.lines[p1.y:p2.y]
for i in range(0, len(lines)): for i in range(0, len(lines)):
lines[i] = ' ' + lines[i] lines[i] = ' ' + lines[i]
w.buffer.delete_string(point.Point(0, p1.y), point.Point(0, p2.y)) w.buffer.delete_string(Point(0, p1.y), Point(0, p2.y))
w.buffer.insert_string_at_cursor(point.Point(0, p1.y), '\n'.join(lines) + '\n') w.buffer.insert_string_at_cursor(Point(0, p1.y), '\n'.join(lines) + '\n')
class CodeComplete(Method): class CodeComplete(Method):
'''Complete based on tokenized strings''' '''Complete based on tokenized strings'''
@ -844,7 +845,7 @@ class OpenConsole(Method):
def execute(self, w, **vargs): def execute(self, w, **vargs):
a = w.application a = w.application
if not a.has_buffer_name('*Console*'): if not a.has_buffer_name('*Console*'):
a.add_buffer(buffer.ConsoleBuffer()) a.add_buffer(buffer2.ConsoleBuffer())
b = a.bufferlist.get_buffer_by_name('*Console*') b = a.bufferlist.get_buffer_by_name('*Console*')
if a.window().buffer is not b: if a.window().buffer is not b:
a.switch_buffer(b) a.switch_buffer(b)
@ -1343,7 +1344,7 @@ class CloseTag(Method):
assert len(tag_stack) == 0, "no match for %r found" % (tag_stack[0]) assert len(tag_stack) == 0, "no match for %r found" % (tag_stack[0])
p = w.logical_point(point.Point(region[0], j)) p = w.logical_point(Point(region[0], j))
w.set_active_point(p, msg='match found on line %(y)d, at character %(x)d') w.set_active_point(p, msg='match found on line %(y)d, at character %(x)d')
class CloseParen(CloseTag): class CloseParen(CloseTag):

View File

@ -155,7 +155,6 @@ class Fundamental(Handler):
# initialize the default colors, highlighter, etc. # initialize the default colors, highlighter, etc.
self.default_color = color.pairs('default', 'default') self.default_color = color.pairs('default', 'default')
self.colors = {} self.colors = {}
self.highlighter = highlight.Highlighter(self)
# get mode name # get mode name
def name(self): def name(self):
@ -190,34 +189,3 @@ class Fundamental(Handler):
else: else:
err = "%s in mode '%s'" % (e, self.name()) err = "%s in mode '%s'" % (e, self.name())
self.window.application.set_error(err) self.window.application.set_error(err)
def invalidate(self):
if self.lexer is not None:
self.highlighter.invalidate_regions()
def get_regions(self):
if self.lexer is not None:
return self.highlighter.tokens
else:
raise Exception, ""
regions = []
for i in range(0, len(self.window.buffer.lines)):
l = self.window.buffer.lines[i]
regions.append([lex2.Token('line', '', i, 0, l)])
return regions
def visible_regions(self):
i = self.window.visible_offset()
regions = self.get_regions()
return regions[i:i+self.window.height]
def region_added(self, p, newlines):
if self.lexer is not None:
self.highlighter.relex_add(lines, p.y, p.x, newlines)
def region_removed(self, p1, p2):
if self.lexer is not None:
self.highlighter.relex_del(lines, p1, p2)
def get_indentation_level(self, y):
return None

View File

@ -1,11 +1,9 @@
import sets, string import method, mode2
import color, highlight, method, minibuffer, mode, point class Mini(mode2.Fundamental):
class Mini(mode.Fundamental):
'''This is the default mode''' '''This is the default mode'''
def __init__(self, w): def __init__(self, w):
mode.Fundamental.__init__(self, w) mode2.Fundamental.__init__(self, w)
# delete actions relating to multiple lines # delete actions relating to multiple lines
self.del_action('center-view') self.del_action('center-view')
@ -41,8 +39,3 @@ class MiniTabComplete(method.Method):
s1 = b.make_string() s1 = b.make_string()
s2, exists, complete = b.tabber.tab_string(s1, window) s2, exists, complete = b.tabber.tab_string(s1, window)
b.set_data(s2) b.set_data(s2)
#class MiniCancel(method.Method):
# def execute(self, window, **vargs):
# window.application.close_mini_buffer()
# window.application.error_string = "Cancel"

View File

@ -1,41 +0,0 @@
import method, mode2
class Mini(mode2.Fundamental):
'''This is the default mode'''
def __init__(self, w):
mode2.Fundamental.__init__(self, w)
# delete actions relating to multiple lines
self.del_action('center-view')
self.del_action('next-line')
self.del_action('previous-line')
self.del_action('page-down')
self.del_action('page-up')
self.del_action('goto-beginning')
self.del_action('goto-end')
self.del_action('switch-buffer')
# add some new actions for the minibuffer
self.add_action_and_bindings(MiniCallback(), ('RETURN',))
self.add_action_and_bindings(MiniTabComplete(), ('TAB',))
#self.add_action_and_bindings(MiniCancel(), ('C-]',))
def name(self):
return "Mini"
class MiniCallback(method.Method):
def execute(self, window, **vargs):
window.buffer.do_callback()
class MiniTabComplete(method.Method):
def __init__(self):
self.name = "tab-complete"
self.args = []
def execute(self, window, **vargs):
b = window.buffer
if b.tabber is None:
window.application.set_error("No tab completion")
return
s1 = b.make_string()
s2, exists, complete = b.tabber.tab_string(s1, window)
b.set_data(s2)

View File

@ -1,13 +1,14 @@
import re, sets, string, sys import re, sets, string, sys
import color, commands, default, lex, lex_perl, method, mode, point, regex, tab_perl import color, commands, default, lex2, lex2_perl, method, mode2, regex, tab_perl
from point2 import Point
class Perl(mode.Fundamental): class Perl(mode2.Fundamental):
def __init__(self, w): def __init__(self, w):
mode.Fundamental.__init__(self, w) mode2.Fundamental.__init__(self, w)
self.tag_matching = True #self.tag_matching = True
self.grammar = lex_perl.PerlGrammar() self.grammar = lex2_perl.PerlGrammar()
self.lexer = lex.Lexer(self.grammar) self.lexer = lex2.Lexer(self.name(), self.grammar)
self.add_action_and_bindings(PerlCheckSyntax(), ('C-c s',)) self.add_action_and_bindings(PerlCheckSyntax(), ('C-c s',))
self.add_action_and_bindings(PerlHashCleanup(), ('C-c h',)) self.add_action_and_bindings(PerlHashCleanup(), ('C-c h',))
@ -24,51 +25,134 @@ class Perl(mode.Fundamental):
self.add_bindings('close-bracket', (']',)) self.add_bindings('close-bracket', (']',))
self.default_color = color.build('default', 'default') self.default_color = color.build('default', 'default')
self.colors = { self.colors = {
'heredoc': color.build('green', 'default'), # basic stuff
'escaped': color.build('magenta', 'default'),
'null': color.build('default', 'default'),
'delimiter': color.build('default', 'default'),
'sub': color.build('cyan', 'default'),
'number': color.build('default', 'default'),
'operator': color.build('default', 'default'),
'endblock': color.build('red', 'default'), 'endblock': color.build('red', 'default'),
'pod': color.build('red', 'default'),
'comment': color.build('red', 'default'),
'string1': color.build('green', 'default'),
'string2': color.build('green', 'default'),
'evalstring': color.build('cyan', 'default'),
'default string': color.build('green', 'default'),
'keyword': color.build('magenta', 'default'), 'keyword': color.build('magenta', 'default'),
'length scalar': color.build('yellow', 'default'),
'system scalar': color.build('yellow', 'default'),
'system array': color.build('yellow', 'default'),
'scalar': color.build('yellow', 'default'), 'scalar': color.build('yellow', 'default'),
'dereference': color.build('yellow', 'default'),
'array': color.build('yellow', 'default'), 'array': color.build('yellow', 'default'),
'deref': color.build('yellow', 'default'),
'hash': color.build('yellow', 'default'), 'hash': color.build('yellow', 'default'),
'hash bareword index': color.build('green', 'default'), 'hash_key': color.build('green', 'default'),
'quoted region': color.build('cyan', 'default'), 'comment': color.build('red', 'default'),
'match regex': color.build('cyan', 'default'), 'function': color.build('cyan', 'default'),
'replace regex': color.build('cyan', 'default'), 'builtin': color.build('magenta', 'default'),
'literal hash bareword index': color.build('green', 'default'), 'method': color.build('cyan', 'default'),
'interpolated scalar': color.build('yellow', 'default'), 'bareword': color.build('default', 'default'),
'interpolated system scalar': color.build('yellow', 'default'),
'interpolated array': color.build('yellow', 'default'),
'interpolated system array': color.build('yellow', 'default'),
'interpolated hash': color.build('yellow', 'default'),
'label': color.build('cyan', 'default'), 'label': color.build('cyan', 'default'),
'package': color.build('cyan', 'default'), 'package': color.build('cyan', 'default'),
'class': color.build('cyan', 'default'),
'use': color.build('cyan', 'default'), 'use': color.build('cyan', 'default'),
'method': color.build('cyan', 'default'), 'method': color.build('cyan', 'default'),
'methodref': color.build('cyan', 'default'),
'method declaration': color.build('cyan', 'default'), # heredoc
'instance method': color.build('cyan', 'default'), 'heredoc1.start': color.build('green', 'default'),
'static method': color.build('cyan', 'default'), 'heredoc1.null': color.build('green', 'default'),
'built-in method': color.build('magenta', 'default'), 'heredoc1.end': color.build('green', 'default'),
'bareword method': color.build('cyan', 'default'), 'heredoc2.start': color.build('green', 'default'),
#'bareword': color.build('yellow', 'magenta'), 'heredoc2.null': color.build('green', 'default'),
'bizzaro': color.build('magenta', 'green') 'heredoc2.end': color.build('green', 'default'),
'eval_heredoc.start': color.build('cyan', 'default'),
'eval_heredoc.null': color.build('cyan', 'default'),
'eval_heredoc.end': color.build('cyan', 'default'),
# pod
'pod.start': color.build('red', 'default'),
'pod.null': color.build('red', 'default'),
'pod.entry': color.build('magenta', 'default'),
'pod.end': color.build('red', 'default'),
# "" strings
'string1.start': color.build('green', 'default'),
'string1.null': color.build('green', 'default'),
'string1.escaped': color.build('magenta', 'default'),
'string1.deref': color.build('yellow', 'default'),
'string1.end': color.build('green', 'default'),
# '' strings
'string2.start': color.build('green', 'default'),
'string2.null': color.build('green', 'default'),
'string2.end': color.build('green', 'default'),
# `` strings
'evalstring': color.build('cyan', 'default'),
# quoted region
'quoted': color.build('cyan', 'default'),
'quoted.start': color.build('cyan', 'default'),
'quoted.null': color.build('cyan', 'default'),
'quoted.end': color.build('cyan', 'default'),
# match regex
'match.start': color.build('cyan', 'default'),
'match.end': color.build('cyan', 'default'),
'match.null': color.build('cyan', 'default'),
# replace regex
'replace.start': color.build('cyan', 'default'),
'replace.middle': color.build('cyan', 'default'),
'replace.end': color.build('cyan', 'default'),
'replace.null': color.build('cyan', 'default'),
# translate regex
'translate.start': color.build('magenta', 'default'),
'translate.middle': color.build('magenta', 'default'),
'translate.end': color.build('magenta', 'default'),
'translate.null': color.build('magenta', 'default'),
} }
# self.colors = {
# 'heredoc': color.build('green', 'default'),
# 'endblock': color.build('red', 'default'),
# 'pod': color.build('red', 'default'),
# 'comment': color.build('red', 'default'),
# 'string1': color.build('green', 'default'),
# 'string2': color.build('green', 'default'),
# 'evalstring': color.build('cyan', 'default'),
# 'default string': color.build('green', 'default'),
# 'keyword': color.build('magenta', 'default'),
# 'length scalar': color.build('yellow', 'default'),
# 'system scalar': color.build('yellow', 'default'),
# 'system array': color.build('yellow', 'default'),
# 'scalar': color.build('yellow', 'default'),
# 'dereference': color.build('yellow', 'default'),
# 'array': color.build('yellow', 'default'),
# 'hash': color.build('yellow', 'default'),
# 'hash bareword index': color.build('green', 'default'),
# 'quoted region': color.build('cyan', 'default'),
# 'match regex': color.build('cyan', 'default'),
# 'replace regex': color.build('cyan', 'default'),
# 'literal hash bareword index': color.build('green', 'default'),
# 'interpolated scalar': color.build('yellow', 'default'),
# 'interpolated system scalar': color.build('yellow', 'default'),
# 'interpolated array': color.build('yellow', 'default'),
# 'interpolated system array': color.build('yellow', 'default'),
# 'interpolated hash': color.build('yellow', 'default'),
# 'label': color.build('cyan', 'default'),
# 'package': color.build('cyan', 'default'),
# 'use': color.build('cyan', 'default'),
# 'method': color.build('cyan', 'default'),
# 'methodref': color.build('cyan', 'default'),
# 'method declaration': color.build('cyan', 'default'),
# 'instance method': color.build('cyan', 'default'),
# 'static method': color.build('cyan', 'default'),
# 'built-in method': color.build('magenta', 'default'),
# 'bareword method': color.build('cyan', 'default'),
# #'bareword': color.build('yellow', 'magenta'),
# 'bizzaro': color.build('magenta', 'green')
# }
#self.highlighter.lex_buffer() #self.highlighter.lex_buffer()
#self.get_regions() #self.get_regions()
self.tabber = tab_perl.PerlTabber(self) #self.tabber = tab_perl.PerlTabber(self)
self.functions = None #self.functions = None
def name(self): def name(self):
return "Perl" return "Perl"
@ -143,8 +227,8 @@ class PerlWrapLine(method.Method):
lines.append(pad + word) lines.append(pad + word)
# remove the old text and add the new # remove the old text and add the new
start_p = point.Point(0, start) start_p = Point(0, start)
end_p = point.Point(len(w.buffer.lines[end-1]), end-1) end_p = Point(len(w.buffer.lines[end-1]), end-1)
w.kill(start_p, end_p) w.kill(start_p, end_p)
w.insert(start_p, '\n'.join(lines)) w.insert(start_p, '\n'.join(lines))
@ -242,7 +326,7 @@ class PerlGotoFunction(method.Method):
functions = w.mode.get_functions() functions = w.mode.get_functions()
if name in functions: if name in functions:
number = functions[name] number = functions[name]
p = point.Point(0, number) p = Point(0, number)
w.goto(p) w.goto(p)
else: else:
w.application.set_error("Function %r was not found" % name) w.application.set_error("Function %r was not found" % name)
@ -342,8 +426,8 @@ class PerlHashCleanup(method.Method):
data += indent_pad + key + key_pad + ' ' + sep + ' ' + value + '\n' data += indent_pad + key + key_pad + ' ' + sep + ' ' + value + '\n'
# remove the old text and add the new # remove the old text and add the new
start_p = point.Point(0, start) start_p = Point(0, start)
end_p = point.Point(0, end + 1) end_p = Point(0, end + 1)
window.kill(start_p, end_p) window.kill(start_p, end_p)
window.insert(start_p, data) window.insert(start_p, data)
@ -443,7 +527,7 @@ class PerlHashCleanup2(method.Method):
data += line + '\n' data += line + '\n'
# remove the old text and add the new # remove the old text and add the new
start_p = point.Point(0, start) start_p = Point(0, start)
end_p = point.Point(0, end + 1) end_p = Point(0, end + 1)
w.kill(start_p, end_p) w.kill(start_p, end_p)
w.insert(start_p, data) w.insert(start_p, data)

View File

@ -1,15 +1,17 @@
import commands, os.path, sets, string, sys import commands, os.path, sets, string, sys
import color, default, mode, lex, lex_python, method, point, regex, tab_python import color, default, mode2, lex2, lex2_python, method, regex, tab_python
import ctag_python, completer import ctag_python, completer
class Python(mode.Fundamental): from point2 import Point
class Python(mode2.Fundamental):
def __init__(self, w): def __init__(self, w):
mode.Fundamental.__init__(self, w) mode2.Fundamental.__init__(self, w)
self.tag_matching = True self.tag_matching = True
self.grammar = lex_python.PythonGrammar() self.grammar = lex2_python.PythonGrammar()
self.lexer = lex.Lexer(self.grammar) self.lexer = lex2.Lexer(self.name(), self.grammar)
self.add_action_and_bindings(PythonCheckSyntax(), ('C-c s',)) self.add_action_and_bindings(PythonCheckSyntax(), ('C-c s',))
self.add_action_and_bindings(PythonDictCleanup(), ('C-c h',)) self.add_action_and_bindings(PythonDictCleanup(), ('C-c h',))
@ -21,30 +23,64 @@ class Python(mode.Fundamental):
self.add_bindings('close-bracket', (']',)) self.add_bindings('close-bracket', (']',))
self.default_color = color.build('default', 'default') self.default_color = color.build('default', 'default')
self.colors = { self.colors = {
'keyword' : color.build('cyan', 'default', 'bold'), 'keyword': color.build('cyan', 'default'),
'pseudo-keyword' : color.build('cyan', 'default', 'bold'), 'builtin_method': color.build('cyan', 'default'),
'built-in method' : color.build('cyan', 'default', 'bold'), 'methodname': color.build('blue', 'default'),
'method declaration' : color.build('blue', 'default', 'bold'), 'classname': color.build('green', 'default'),
'class declaration' : color.build('green', 'default'),
'string4' : color.build('green', 'default'), 'string.start': color.build('green', 'default'),
'string3' : color.build('green', 'default'), 'string.null': color.build('green', 'default'),
'string2' : color.build('green', 'default'), 'string.escaped': color.build('magenta', 'default'),
'string1' : color.build('green', 'default'), 'string.octal': color.build('magenta', 'default'),
'string.format': color.build('yellow', 'default'),
'string.end': color.build('green', 'default'),
'integer': color.build('red', 'default'),
'float': color.build('red', 'default'),
'imaginary': color.build('red', 'default'),
'tq_string.start': color.build('green', 'default'),
'tq_string.null': color.build('green', 'default'),
'tq_string.end': color.build('green', 'default'),
'docstring.start': color.build('green', 'default'),
'docstring.null': color.build('green', 'default'),
'docstring.end': color.build('green', 'default'),
'comment': color.build('red', 'default'), 'comment': color.build('red', 'default'),
'continuation': color.build('red', 'default'), 'continuation': color.build('red', 'default'),
#'operator': color.build('yellow', 'default'), #'operator': color.build('yellow', 'default'),
#'delimiter': color.build('magenta', 'default'), #'delimiter': color.build('magenta', 'default'),
'system_identifier' : color.build('cyan', 'default', 'bold'), 'system_identifier': color.build('cyan', 'default'),
#'bound method' : color.build('yellow', 'default'), #'bound method': color.build(color.build('yellow', 'default'), 'default'),
'import statement' : color.build('magenta', 'green'), 'import': color.build('magenta', 'default'),
'bizzaro' : color.build('magenta', 'green'), #'bizzaro': color.build('magenta', 'default'),
} }
#self.highlighter.lex_buffer() # self.colors = {
#self.get_regions() # 'keyword' : color.build('cyan', 'default', 'bold'),
self.tabber = tab_python.PythonTabber(self) # 'pseudo-keyword' : color.build('cyan', 'default', 'bold'),
self.ctagger = ctag_python.PythonCTagger() # 'built-in method' : color.build('cyan', 'default', 'bold'),
# 'method declaration' : color.build('blue', 'default', 'bold'),
# 'class declaration' : color.build('green', 'default'),
# 'string4' : color.build('green', 'default'),
# 'string3' : color.build('green', 'default'),
# 'string2' : color.build('green', 'default'),
# 'string1' : color.build('green', 'default'),
# 'comment' : color.build('red', 'default'),
# 'continuation' : color.build('red', 'default'),
# #'operator' : color.build('yellow', 'default'),
# #'delimiter' : color.build('magenta', 'default'),
# 'system_identifier' : color.build('cyan', 'default', 'bold'),
# #'bound method' : color.build('yellow', 'default'),
# 'import statement' : color.build('magenta', 'green'),
# 'bizzaro' : color.build('magenta', 'green'),
# }
#self.tabber = tab_python.PythonTabber(self)
#self.ctagger = ctag_python.PythonCTagger()
def name(self): def name(self):
return "Python" return "Python"
@ -138,8 +174,8 @@ class PythonTagComplete(method.Method):
else: else:
newword = completer.find_common_string(candidates) newword = completer.find_common_string(candidates)
w.application.set_error('Ambiguous match: %r' % (candidates)) w.application.set_error('Ambiguous match: %r' % (candidates))
b.delete_string(point.Point(start, cursor.y), point.Point(end, cursor.y)) b.delete_string(Point(start, cursor.y), Point(end, cursor.y))
b.insert_string(point.Point(start, cursor.y), newword) b.insert_string(Point(start, cursor.y), newword)
class PythonDictCleanup(method.Method): class PythonDictCleanup(method.Method):
'''Align assignment blocks and literal dictionaries''' '''Align assignment blocks and literal dictionaries'''
@ -214,7 +250,7 @@ class PythonDictCleanup(method.Method):
data += indent_pad + key + sep + ' ' + key_pad + value + '\n' data += indent_pad + key + sep + ' ' + key_pad + value + '\n'
# remove the old text and add the new # remove the old text and add the new
start_p = point.Point(0, start) start_p = Point(0, start)
end_p = point.Point(0, end + 1) end_p = Point(0, end + 1)
w.kill(start_p, end_p) w.kill(start_p, end_p)
w.insert(start_p, data) w.insert(start_p, data)

View File

@ -1,8 +1,10 @@
LOGICAL = "logical" LOGICAL = "logical"
PHYSICAL = "physical" PHYSICAL = "physical"
class Point: class Point:
def __init__(self, x=0, y=0, t=None): def __init__(self, x=0, y=0, t=None):
raise Exception, "argh!"
assert t is None or \ assert t is None or \
t == LOGICAL or \ t == LOGICAL or \
t == PHYSICAL t == PHYSICAL

View File

@ -15,7 +15,6 @@ class Window(object):
def __init__(self, b, a, height=24, width=80, mode_name=None): def __init__(self, b, a, height=24, width=80, mode_name=None):
self.buffer = b self.buffer = b
self.application = a self.application = a
self.buffer.add_window(self)
self.first = Point(0, 0) self.first = Point(0, 0)
self.last = None self.last = None
@ -59,6 +58,7 @@ class Window(object):
m = self.application.modes[mode_name](self) m = self.application.modes[mode_name](self)
self.set_mode(m) self.set_mode(m)
self.buffer.add_window(self)
# private method used in window constructor # private method used in window constructor
def _get_path_ext(self, path): def _get_path_ext(self, path):
@ -73,6 +73,11 @@ class Window(object):
def set_mode(self, m): def set_mode(self, m):
self.mode = m self.mode = m
#self.redraw() #self.redraw()
def get_highlighter(self):
if self.mode.lexer is None:
return None
else:
return self.buffer.highlights[self.mode.name()]
# this is used to temporarily draw the user's attention to another point # this is used to temporarily draw the user's attention to another point
def set_active_point(self, p, msg='marking on line %(y)d, character %(x)d'): def set_active_point(self, p, msg='marking on line %(y)d, character %(x)d'):
@ -127,7 +132,6 @@ class Window(object):
elif y == p.y and x >= p.x: elif y == p.y and x >= p.x:
self.cursor = Point(x + len(newlines[0]), y) self.cursor = Point(x + len(newlines[0]), y)
self.assure_visible_cursor() self.assure_visible_cursor()
#self.mode.region_added(p, newlines)
# region removed # region removed
def region_removed(self, p1, p2): def region_removed(self, p1, p2):
@ -142,7 +146,6 @@ class Window(object):
else: else:
self.cursor = Point(self.cursor.x, self.cursor.y - p2.y + p1.y) self.cursor = Point(self.cursor.x, self.cursor.y - p2.y + p1.y)
self.assure_visible_cursor() self.assure_visible_cursor()
#self.mode.region_removed(p1, p2)
def point_is_visible(self, p): def point_is_visible(self, p):
return self.first <= p and p <= self.last return self.first <= p and p <= self.last