context header v0.1

--HG--
branch : pmacs2
This commit is contained in:
moculus 2009-02-05 15:21:24 +00:00
parent ace50bbb85
commit 7c1d0a9330
7 changed files with 110 additions and 57 deletions

View File

@ -783,10 +783,10 @@ class Application(object):
modename = w.mode.name() modename = w.mode.name()
# draw the header # draw the header
rstrs = w.mode.get_header(w) rstrs = w.mode.get_header()
assert len(rstrs) >= w.mode.header assert len(rstrs) >= w.mode.header
for j in range(0, w.mode.header): for j in range(0, w.mode.header):
rstrs[j].draw(self.win, slot.y_offset + j, slot.x_offset) rstrs[j].draw(self.win, slot.y_offset + j, slot.x_offset, slot.width)
# draw the actual slot # draw the actual slot
self._draw_slot(i) self._draw_slot(i)

View File

@ -368,14 +368,11 @@ class Buffer(object):
self.delete(p1, p2, act, force) self.delete(p1, p2, act, force)
# random # random
def is_whitespace(self, y):
return regex.whitespace.match(self.lines[y])
def count_leading_whitespace(self, y): def count_leading_whitespace(self, y):
line = self.lines[y] m = regex.leading_whitespace.match(self.lines[y])
m = regex.leading_whitespace.match(line)
if m:
return m.end() return m.end()
else:
# should not happen
raise Exception, "iiiijjjj"
# generic window functionality # generic window functionality
def forward(self, p): def forward(self, p):

View File

@ -13,9 +13,11 @@ class Slot(object):
self.x_offset = x_offset self.x_offset = x_offset
if self.window is not None: if self.window is not None:
self.window.set_size(self.width, self.height) self.window.set_size(self.width, self.height)
def reset(self):
self.window.set_size(self.width, self.height)
def set(self, w): def set(self, w):
self.window = w self.window = w
self.resize(self.height, self.width, self.y_offset, self.x_offset) #self.resize(self.height, self.width, self.y_offset, self.x_offset)
w.set_size(self.width, self.height) w.set_size(self.width, self.height)
def unset(self): def unset(self):
if not self.is_empty(): if not self.is_empty():
@ -57,11 +59,13 @@ class BufferList(object):
self.width = width self.width = width
self.fit_slots() self.fit_slots()
def is_window_visible(self, w): def find_window_slot(self, w):
for slot in self.slots: for slot in self.slots:
if w is slot.window: if w is slot.window:
return True return slot
return False return None
def is_window_visible(self, w):
return self.find_window_slot(w) is not None
def is_buffer_visible(self, b): def is_buffer_visible(self, b):
for slot in self.slots: for slot in self.slots:
if slot.window is not None and b is slot.window.buffer: if slot.window is not None and b is slot.window.buffer:

View File

@ -101,18 +101,18 @@ class Fundamental(Handler):
format = "%(flag)s %(bname)-18s (%(mname)s) %(indent)s %(cursor)s/%(mark)s %(perc)s" format = "%(flag)s %(bname)-18s (%(mname)s) %(indent)s %(cursor)s/%(mark)s %(perc)s"
## margins ## margins
def get_header(self): return self.get_setting('header') def _get_header(self): return self.get_setting('header')
def set_header(self, value): return self.set_setting('header', value) def _set_header(self, value): return self.set_setting('header', value)
header = property(get_header, set_header) header = property(_get_header, _set_header)
def get_footer(self): return self.get_setting('footer') def _get_footer(self): return self.get_setting('footer')
def set_footer(self, value): return self.set_setting('footer', value) def _set_footer(self, value): return self.set_setting('footer', value)
footer = property(get_footer, set_footer) footer = property(_get_footer, _set_footer)
def get_lmargin(self): return self.get_setting('lmargin') def _get_lmargin(self): return self.get_setting('lmargin')
def set_lmargin(self, value): return self.set_setting('lmargin', value) def _set_lmargin(self, value): return self.set_setting('lmargin', value)
lmargin = property(get_lmargin, set_lmargin) lmargin = property(_get_lmargin, _set_lmargin)
def get_rmargin(self): return self.get_setting('rmargin') def _get_rmargin(self): return self.get_setting('rmargin')
def set_rmargin(self, value): return self.set_setting('rmargin', value) def _set_rmargin(self, value): return self.set_setting('rmargin', value)
rmargin = property(get_rmargin, set_rmargin) rmargin = property(_get_rmargin, _set_rmargin)
def install(cls, app): def install(cls, app):
app.setmode(cls.modename.lower(), cls, paths=cls.paths, app.setmode(cls.modename.lower(), cls, paths=cls.paths,
@ -286,11 +286,23 @@ class Fundamental(Handler):
# header # header
def showing_header(self): def showing_header(self):
return self.header != 0 return self.header != 0
def enable_header(self): def _enable_header(self):
self.header = 1 self.header = 1
def disable_header(self): def _disable_header(self):
self.header = 0 self.header = 0
def enable_header(self):
self._enable_header()
self._slot_reset()
def disable_header(self):
self._disable_header()
self._slot_reset()
def _slot_reset(self):
w = self.window
slot = w.application.bufferlist.find_window_slot(w)
assert slot is not None
slot.reset()
# line numbers # line numbers
def showing_line_numbers(self): def showing_line_numbers(self):
return self.lmargin != 0 return self.lmargin != 0
@ -301,10 +313,10 @@ class Fundamental(Handler):
self.lmargin = 0 self.lmargin = 0
# headers and margins # headers and margins
def get_header(self, w): def get_header(self):
fg, bg = "default", "red" fg, bg = "default", "red"
return [RenderString(s='header', attrs=color.build(fg, bg))] return [RenderString(s='header', attrs=color.build(fg, bg))]
def get_footer(self, w): def get_footer(self):
fg, bg = "default", "red" fg, bg = "default", "red"
return [RenderString(s='footer', attrs=color.build(fg, bg))] return [RenderString(s='footer', attrs=color.build(fg, bg))]
def get_rmargin(self, w, y, x, ended=False, cont=False): def get_rmargin(self, w, y, x, ended=False, cont=False):

View File

@ -1,6 +1,7 @@
import commands, os.path, string, sys, traceback import commands, os.path, string, sys, traceback
import color, completer, context, default, mode, method, regex, tab, method.introspect import color, completer, context, default, mode, method, regex, tab, method.introspect
from point import Point from point import Point
from render import RenderString
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule from lex import Grammar, PatternRule, RegionRule, OverridePatternRule
from parse import Any, And, Or, Optional, Name, Match, Matchs from parse import Any, And, Or, Optional, Name, Match, Matchs
@ -157,12 +158,12 @@ class PythonTabber(tab.StackTabber):
# we need to pop the indentation level over, unless last line was # we need to pop the indentation level over, unless last line was
# also a continued line # also a continued line
if self.continued: if self.continued:
self._opt_append('cont', currlvl) self._opt_append('cont', currlvl, y)
else: else:
self._opt_append('cont', currlvl + w) self._opt_append('cont', currlvl + w, y)
elif fqname == 'string.start': elif fqname == 'string.start':
# while inside of a string, there is no indention leve # while inside of a string, there is no indention leve
self._opt_append('string', None) self._opt_append('string', None, y)
elif fqname == 'string.end': elif fqname == 'string.end':
# since we're done with the string, resume our indentation level # since we're done with the string, resume our indentation level
self._opt_pop('string') self._opt_pop('string')
@ -183,25 +184,25 @@ class PythonTabber(tab.StackTabber):
self.popped = True self.popped = True
elif token.string in self.startlevel_names and self.is_leftmost_token(y, i): elif token.string in self.startlevel_names and self.is_leftmost_token(y, i):
# we know we will indent exactly once # we know we will indent exactly once
self._append(token.string, currlvl + w) self._append(token.string, currlvl + w, y)
elif token.string in ('elif', 'else') and self.is_leftmost_token(y, i): elif token.string in ('elif', 'else') and self.is_leftmost_token(y, i):
# we know we'll unindent at least to the first if/elif # we know we'll unindent at least to the first if/elif
if not self.popped and not self.last_popped and self._peek_until('if', 'elif'): if not self.popped and not self.last_popped and self._peek_until('if', 'elif'):
self._pop_until('if', 'elif') self._pop_until('if', 'elif')
currlvl = self.get_curr_level() currlvl = self.get_curr_level()
self._append(token.string, currlvl + w) self._append(token.string, currlvl + w, y)
elif token.string == 'except' and self.is_leftmost_token(y, i): elif token.string == 'except' and self.is_leftmost_token(y, i):
# we know we'll unindent at least to the first try # we know we'll unindent at least to the first try
if not self.popped and not self.last_popped: if not self.popped and not self.last_popped:
self._pop_until('try') self._pop_until('try')
currlvl = self.get_curr_level() currlvl = self.get_curr_level()
self._append(token.string, currlvl + w) self._append(token.string, currlvl + w, y)
elif token.string == 'finally' and self.is_leftmost_token(y, i): elif token.string == 'finally' and self.is_leftmost_token(y, i):
# we know we'll unindent at least to the first try/except # we know we'll unindent at least to the first try/except
if not self.popped and not self.last_popped: if not self.popped and not self.last_popped:
self._pop_until('try', 'except') self._pop_until('try', 'except')
currlvl = self.get_curr_level() currlvl = self.get_curr_level()
self._append(token.string, currlvl + w) self._append(token.string, currlvl + w, y)
return currlvl return currlvl
class PythonCheckSyntax(method.Method): class PythonCheckSyntax(method.Method):
@ -575,6 +576,39 @@ class Python(mode.Fundamental):
names['first'] = self.window.first.xy() names['first'] = self.window.first.xy()
return names return names
# xyz
def _enable_header(self):
self.header = 3
def _disable_header(self):
self.header = 0
def get_header(self):
fg, bg = "default", "red"
w = self.window
y = self.window.first.y
if self.window.first.x > 0:
y += 1
lvl = self.tabber.get_level(y)
markers = self.tabber.record[y]
if w.buffer.is_whitespace(y):
ws = None
else:
ws = w.buffer.count_leading_whitespace(y)
hs = []
i = len(markers) - 1
while i >= 0 and len(hs) < 3:
marker = markers[i]
i -= 1
if marker.y == y:
continue
if ws and marker.level > ws:
continue
s = w.buffer.lines[marker.y][:w.width - 1]
hs.insert(0, RenderString(s=s, attrs=color.build(fg, bg)))
while len(hs) < 3:
hs.insert(0, RenderString(s='', attrs=color.build(fg, bg)))
return hs
def __init__(self, w): def __init__(self, w):
mode.Fundamental.__init__(self, w) mode.Fundamental.__init__(self, w)
self.add_bindings('close-paren', (')',)) self.add_bindings('close-paren', (')',))

View File

@ -29,9 +29,13 @@ class RenderString(object):
self.y = y self.y = y
self.x = x self.x = x
self.attrs = attrs self.attrs = attrs
def draw(self, cwin, y, x): def draw(self, cwin, y, x, x2=None):
try: try:
cwin.addstr(self.y + y, self.x + x, self.string, self.attrs) if x2:
s = '%-*s' % (x2 - x, self.string)
else:
s = self.string
cwin.addstr(self.y + y, self.x + x, s, self.attrs)
except: except:
v = (y, self.x, x, self.string, self.attrs) v = (y, self.x, x, self.string, self.attrs)
raise Exception, "cwin.addstr(%d, %d + %d, %r, %r) failed" % v raise Exception, "cwin.addstr(%d, %d + %d, %r, %r) failed" % v

40
tab.py
View File

@ -2,11 +2,12 @@ import regex, util
from point import Point from point import Point
class Marker(object): class Marker(object):
def __init__(self, name, level): def __init__(self, name, level, y):
self.name = name self.name = name
self.level = level self.level = level
self.y = y
def __repr__(self): def __repr__(self):
return '<Marker(%r, %r)>' % (self.name, self.level) return '<Marker(%r, %r, %r)>' % (self.name, self.level, self.y)
class Tabber(object): class Tabber(object):
wsre = regex.whitespace wsre = regex.whitespace
@ -158,7 +159,7 @@ class StackTabber(Tabber):
level = self.get_curr_level() + self.mode.tabwidth level = self.get_curr_level() + self.mode.tabwidth
else: else:
level = rtoken.x level = rtoken.x
self._append(token.string, level) self._append(token.string, level, y)
return currlvl return currlvl
def _handle_close_token(self, currlvl, y, i): def _handle_close_token(self, currlvl, y, i):
token = self.get_token(y, i) token = self.get_token(y, i)
@ -180,8 +181,8 @@ class StackTabber(Tabber):
return len(self.markers) > 0 return len(self.markers) > 0
def _empty(self): def _empty(self):
return len(self.markers) == 0 return len(self.markers) == 0
def _append(self, name, level): def _append(self, name, level, y=None):
self.markers.append(Marker(name, level)) self.markers.append(Marker(name, level, y))
def _peek(self): def _peek(self):
if self.markers: if self.markers:
return self.markers[-1] return self.markers[-1]
@ -220,22 +221,23 @@ class StackTabber(Tabber):
else: else:
self.markers.pop(-1) self.markers.pop(-1)
def _opt_append(self, name, level): def _opt_append(self, name, level, y=None):
if self.markers and self.markers[-1].name == name: if self.markers and self.markers[-1].name == name:
pass pass
else: else:
self._append(name, level) self._append(name, level, y)
def _opt_pop(self, *names): def _opt_pop(self, *names):
if self.markers and self.markers[-1].name in names: if self.markers and self.markers[-1].name in names:
self.markers.pop(-1) self.markers.pop(-1)
class Marker2(object): class Marker2(object):
def __init__(self, name, type_, level): def __init__(self, name, type_, level, y=None):
self.name = name self.name = name
self.type_ = type_ self.type_ = type_
self.level = level self.level = level
self.y = y
def __repr__(self): def __repr__(self):
return '<Marker2(%r, %r, %r)>' % (self.name, self.type_, self.level) return '<Marker2(%r, %r, %r, %r)>' % (self.name, self.type_, self.level, self.y)
class StackTabber2(Tabber): class StackTabber2(Tabber):
open_tokens = {'delimiter': {'{': '}', '(': ')', '[': ']'}} open_tokens = {'delimiter': {'{': '}', '(': ')', '[': ']'}}
@ -307,9 +309,9 @@ class StackTabber2(Tabber):
while self._nomatch(*names): while self._nomatch(*names):
self.stack.pop() self.stack.pop()
def _append(self, name, type_, level): def _append(self, name, type_, level, y=None):
self.stack.append(Marker2(name, type_, level)) self.stack.append(Marker2(name, type_, level))
def _append_unless(self, name, type_, level): def _append_unless(self, name, type_, level, y=None):
if self._nomatch(name): if self._nomatch(name):
self.stack.append(Marker2(name, type_, level)) self.stack.append(Marker2(name, type_, level))
def _peek(self): def _peek(self):
@ -387,7 +389,7 @@ class StackTabber2(Tabber):
if d is None or d != 1 and s not in d: if d is None or d != 1 and s not in d:
if s not in self.close_scope_tokens.get(name, set()): if s not in self.close_scope_tokens.get(name, set()):
nextlvl = self._get_next_level() nextlvl = self._get_next_level()
self._append_unless('continue', name, nextlvl) self._append_unless('continue', name, nextlvl, y)
#XYZYZYXYXY #XYZYZYXYXY
def _is_open_token(self, t): def _is_open_token(self, t):
@ -405,20 +407,20 @@ class StackTabber2(Tabber):
level = self._get_next_level() level = self._get_next_level()
else: else:
level = tokens[i + 1].x + 1 level = tokens[i + 1].x + 1
self._append(t.string, t.name, level) self._append(t.string, t.name, level, y)
def _handle_other_token(self, y, tokens, start, end, i, t): def _handle_other_token(self, y, tokens, start, end, i, t):
name, s = t.fqname(), t.string name, s = t.fqname(), t.string
# handle "free" tokens (strings, heredocs, etc) # handle "free" tokens (strings, heredocs, etc)
if name in self.start_free_tokens: if name in self.start_free_tokens:
self._append('free', name, None) self._append('free', name, None, y)
return return
elif name in self.end_free_tokens: elif name in self.end_free_tokens:
self._pop('free') self._pop('free')
# handle macros # handle macros
if name in self.start_macro_tokens: if name in self.start_macro_tokens:
self._append('macro', name, 0) self._append('macro', name, 0, y)
if i == 0: if i == 0:
self._save_curr_level() self._save_curr_level()
return return
@ -439,17 +441,17 @@ class StackTabber2(Tabber):
not top)): not top)):
if self.continue_tokens: if self.continue_tokens:
if s in self.continue_tokens.get(name, {}): if s in self.continue_tokens.get(name, {}):
self._append_unless('continue', name, self._get_next_level()) self._append_unless('continue', name, self._get_next_level(), y)
elif self.nocontinue_tokens: elif self.nocontinue_tokens:
d = self.nocontinue_tokens.get(name) d = self.nocontinue_tokens.get(name)
if d is None or d != 1 and s not in d: if d is None or d != 1 and s not in d:
self._append_unless('continue', name, self._get_next_level()) self._append_unless('continue', name, self._get_next_level(), y)
if name == 'continuation': if name == 'continuation':
# handle explicit continuation # handle explicit continuation
self._append_unless('continue', name, self._get_next_level()) self._append_unless('continue', name, self._get_next_level(), y)
elif s in self.control_tokens.get(name, {}): elif s in self.control_tokens.get(name, {}):
# handle control keywords # handle control keywords
if i == start: if i == start:
self._save_curr_level() self._save_curr_level()
self._append_unless('control', name, self._get_next_level()) self._append_unless('control', name, self._get_next_level(), y)