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()
# draw the header
rstrs = w.mode.get_header(w)
rstrs = w.mode.get_header()
assert len(rstrs) >= 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
self._draw_slot(i)

View File

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

View File

@ -13,9 +13,11 @@ class Slot(object):
self.x_offset = x_offset
if self.window is not None:
self.window.set_size(self.width, self.height)
def reset(self):
self.window.set_size(self.width, self.height)
def set(self, 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)
def unset(self):
if not self.is_empty():
@ -57,11 +59,13 @@ class BufferList(object):
self.width = width
self.fit_slots()
def is_window_visible(self, w):
def find_window_slot(self, w):
for slot in self.slots:
if w is slot.window:
return True
return False
return slot
return None
def is_window_visible(self, w):
return self.find_window_slot(w) is not None
def is_buffer_visible(self, b):
for slot in self.slots:
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"
## margins
def get_header(self): return self.get_setting('header')
def set_header(self, value): return self.set_setting('header', value)
header = property(get_header, set_header)
def get_footer(self): return self.get_setting('footer')
def set_footer(self, value): return self.set_setting('footer', value)
footer = property(get_footer, set_footer)
def get_lmargin(self): return self.get_setting('lmargin')
def set_lmargin(self, value): return self.set_setting('lmargin', value)
lmargin = property(get_lmargin, set_lmargin)
def get_rmargin(self): return self.get_setting('rmargin')
def set_rmargin(self, value): return self.set_setting('rmargin', value)
rmargin = property(get_rmargin, set_rmargin)
def _get_header(self): return self.get_setting('header')
def _set_header(self, value): return self.set_setting('header', value)
header = property(_get_header, _set_header)
def _get_footer(self): return self.get_setting('footer')
def _set_footer(self, value): return self.set_setting('footer', value)
footer = property(_get_footer, _set_footer)
def _get_lmargin(self): return self.get_setting('lmargin')
def _set_lmargin(self, value): return self.set_setting('lmargin', value)
lmargin = property(_get_lmargin, _set_lmargin)
def _get_rmargin(self): return self.get_setting('rmargin')
def _set_rmargin(self, value): return self.set_setting('rmargin', value)
rmargin = property(_get_rmargin, _set_rmargin)
def install(cls, app):
app.setmode(cls.modename.lower(), cls, paths=cls.paths,
@ -286,11 +286,23 @@ class Fundamental(Handler):
# header
def showing_header(self):
return self.header != 0
def enable_header(self):
def _enable_header(self):
self.header = 1
def disable_header(self):
def _disable_header(self):
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
def showing_line_numbers(self):
return self.lmargin != 0
@ -301,10 +313,10 @@ class Fundamental(Handler):
self.lmargin = 0
# headers and margins
def get_header(self, w):
def get_header(self):
fg, bg = "default", "red"
return [RenderString(s='header', attrs=color.build(fg, bg))]
def get_footer(self, w):
def get_footer(self):
fg, bg = "default", "red"
return [RenderString(s='footer', attrs=color.build(fg, bg))]
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 color, completer, context, default, mode, method, regex, tab, method.introspect
from point import Point
from render import RenderString
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule
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
# also a continued line
if self.continued:
self._opt_append('cont', currlvl)
self._opt_append('cont', currlvl, y)
else:
self._opt_append('cont', currlvl + w)
self._opt_append('cont', currlvl + w, y)
elif fqname == 'string.start':
# 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':
# since we're done with the string, resume our indentation level
self._opt_pop('string')
@ -183,25 +184,25 @@ class PythonTabber(tab.StackTabber):
self.popped = True
elif token.string in self.startlevel_names and self.is_leftmost_token(y, i):
# 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):
# 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'):
self._pop_until('if', 'elif')
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):
# we know we'll unindent at least to the first try
if not self.popped and not self.last_popped:
self._pop_until('try')
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):
# we know we'll unindent at least to the first try/except
if not self.popped and not self.last_popped:
self._pop_until('try', 'except')
currlvl = self.get_curr_level()
self._append(token.string, currlvl + w)
self._append(token.string, currlvl + w, y)
return currlvl
class PythonCheckSyntax(method.Method):
@ -575,6 +576,39 @@ class Python(mode.Fundamental):
names['first'] = self.window.first.xy()
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):
mode.Fundamental.__init__(self, w)
self.add_bindings('close-paren', (')',))

View File

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