parent
b9d304e2c7
commit
dddfa7a347
|
@ -143,6 +143,7 @@ class Application(object):
|
||||||
# buffer list stuff
|
# buffer list stuff
|
||||||
self.bufferlist = bufferlist.BufferList(height, width)
|
self.bufferlist = bufferlist.BufferList(height, width)
|
||||||
self.active_slot = 0
|
self.active_slot = 0
|
||||||
|
self.complete_slot = None
|
||||||
|
|
||||||
# run user custom code here
|
# run user custom code here
|
||||||
self.rcerror = None
|
self.rcerror = None
|
||||||
|
@ -199,6 +200,70 @@ class Application(object):
|
||||||
curses.nonl()
|
curses.nonl()
|
||||||
curses.def_prog_mode()
|
curses.def_prog_mode()
|
||||||
|
|
||||||
|
def completion_window_is_open(self):
|
||||||
|
n = self.complete_slot
|
||||||
|
if n is None:
|
||||||
|
pass
|
||||||
|
elif n >= len(self.bufferlist.slots):
|
||||||
|
self.complete_slot = None
|
||||||
|
elif self.bufferlist.slots[n].window is None:
|
||||||
|
self.complete_slot = None
|
||||||
|
elif not hasattr(self.bufferlist.slots[n].window.buffer, '_completion'):
|
||||||
|
self.complete_slot = None
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_completion_window(self):
|
||||||
|
return self.bufferlist.slots[self.complete_slot].window
|
||||||
|
|
||||||
|
def open_completion_buffer(self, s, candidates):
|
||||||
|
opened = False
|
||||||
|
previous = None
|
||||||
|
if len(self.bufferlist.slots) == 1:
|
||||||
|
self.add_slot()
|
||||||
|
opened = True
|
||||||
|
|
||||||
|
n = len(self.bufferlist.slots) - 1
|
||||||
|
if self.active_slot == n:
|
||||||
|
n -= 1
|
||||||
|
|
||||||
|
if not opened:
|
||||||
|
previous = self.bufferlist.slots[n].window.buffer
|
||||||
|
|
||||||
|
lines = ["This is a completion buffer:", ""]
|
||||||
|
if len(candidates) > self.bufferlist.slots[n].height:
|
||||||
|
m = len(candidates) - (len(candidates) // 2)
|
||||||
|
mlen = 0
|
||||||
|
for c in candidates[:m]:
|
||||||
|
mlen = max(mlen, len(c))
|
||||||
|
for i in range(0, m):
|
||||||
|
if m + i < len(candidates):
|
||||||
|
c1, c2 = candidates[i * 2], candidates[i * 2 + 1]
|
||||||
|
lines.append("%-*s %-s" % (mlen, c1, c2))
|
||||||
|
else:
|
||||||
|
lines.append(candidates[i * 2])
|
||||||
|
else:
|
||||||
|
lines = list(candidates)
|
||||||
|
data = '\n'.join(lines)
|
||||||
|
|
||||||
|
b = self.data_buffer("*Completions*", data, switch_to=False)
|
||||||
|
b._completion = s
|
||||||
|
b._opened = opened
|
||||||
|
b._previous = previous
|
||||||
|
self.bufferlist.set_slot(n, b)
|
||||||
|
self.complete_slot = n
|
||||||
|
|
||||||
|
def close_completion_buffer(self):
|
||||||
|
w = self.get_completion_window()
|
||||||
|
opened = w.buffer._opened
|
||||||
|
if opened:
|
||||||
|
self.bufferlist.remove_slot(self.complete_slot)
|
||||||
|
else:
|
||||||
|
self.bufferlist.set_slot(self.complete_slot, w.buffer._previous)
|
||||||
|
self.close_buffer(w.buffer)
|
||||||
|
self.complete_slot = None
|
||||||
|
|
||||||
def set_completer(self, datatype, completer):
|
def set_completer(self, datatype, completer):
|
||||||
method.DATATYPES[datatype] = completer
|
method.DATATYPES[datatype] = completer
|
||||||
|
|
||||||
|
@ -246,6 +311,17 @@ class Application(object):
|
||||||
return (slot.height, slot.width)
|
return (slot.height, slot.width)
|
||||||
|
|
||||||
# files and stuff
|
# files and stuff
|
||||||
|
def close_buffer(self, b):
|
||||||
|
self.bufferlist.remove_buffer(b)
|
||||||
|
b.close()
|
||||||
|
active_slot = self.bufferlist.slots[self.active_slot]
|
||||||
|
for i in range(0, len(self.bufferlist.slots)):
|
||||||
|
if self.bufferlist.slots[i].is_empty():
|
||||||
|
if self.bufferlist.hidden_buffers:
|
||||||
|
self.bufferlist.set_slot(i, self.bufferlist.hidden_buffers[0])
|
||||||
|
else:
|
||||||
|
self.bufferlist.set_slot(i, active_slot.window.buffer)
|
||||||
|
|
||||||
def open_path(self, path, binary=False, cipher=None, password=None):
|
def open_path(self, path, binary=False, cipher=None, password=None):
|
||||||
path = os.path.abspath(os.path.realpath(util.expand_tilde(path)))
|
path = os.path.abspath(os.path.realpath(util.expand_tilde(path)))
|
||||||
b = self.get_buffer_by_path(path)
|
b = self.get_buffer_by_path(path)
|
||||||
|
@ -369,6 +445,7 @@ class Application(object):
|
||||||
self.add_buffer(b)
|
self.add_buffer(b)
|
||||||
if switch_to:
|
if switch_to:
|
||||||
self.switch_buffer(b)
|
self.switch_buffer(b)
|
||||||
|
return b
|
||||||
def color_data_buffer(self, name, data, switch_to=True, modename='colortext'):
|
def color_data_buffer(self, name, data, switch_to=True, modename='colortext'):
|
||||||
if self.has_buffer_name(name):
|
if self.has_buffer_name(name):
|
||||||
b = self.bufferlist.buffer_names[name]
|
b = self.bufferlist.buffer_names[name]
|
||||||
|
|
|
@ -125,6 +125,11 @@ class BufferList(object):
|
||||||
if hasattr(b, 'path') and b.path == path:
|
if hasattr(b, 'path') and b.path == path:
|
||||||
return b
|
return b
|
||||||
return None
|
return None
|
||||||
|
def close_buffer(self, b):
|
||||||
|
for i in range(0, len(self.slots)):
|
||||||
|
slot = self.slots[i]
|
||||||
|
if self.slots[i].window is not None and self.slots[i].window.buffer is b:
|
||||||
|
self.unset_slot(i)
|
||||||
def remove_buffer(self, b):
|
def remove_buffer(self, b):
|
||||||
assert b in self.buffers, "buffer %s does not exist" % (b.name())
|
assert b in self.buffers, "buffer %s does not exist" % (b.name())
|
||||||
for i in range(0, len(self.slots)):
|
for i in range(0, len(self.slots)):
|
||||||
|
|
|
@ -809,6 +809,8 @@ class Cancel(Method):
|
||||||
'''Cancel command in-progress, and return to the main buffer'''
|
'''Cancel command in-progress, and return to the main buffer'''
|
||||||
def execute(self, w, **vargs):
|
def execute(self, w, **vargs):
|
||||||
w.application.close_mini_buffer()
|
w.application.close_mini_buffer()
|
||||||
|
if w.application.completion_window_is_open():
|
||||||
|
w.application.close_completion_buffer()
|
||||||
w.set_error('Cancel')
|
w.set_error('Cancel')
|
||||||
|
|
||||||
class SplitWindow(Method):
|
class SplitWindow(Method):
|
||||||
|
|
|
@ -70,10 +70,7 @@ class KillBuffer(Method):
|
||||||
def _doit(self):
|
def _doit(self):
|
||||||
a = self._old_window.application
|
a = self._old_window.application
|
||||||
b = self._to_kill
|
b = self._to_kill
|
||||||
if a.bufferlist.is_buffer_visible(b):
|
a.close_buffer(b)
|
||||||
a.bufferlist.set_slot(a.active_slot, a.bufferlist.hidden_buffers[0])
|
|
||||||
a.bufferlist.remove_buffer(b)
|
|
||||||
b.close()
|
|
||||||
def _callback(self, v):
|
def _callback(self, v):
|
||||||
a = self._old_window.application
|
a = self._old_window.application
|
||||||
if v == 'yes':
|
if v == 'yes':
|
||||||
|
|
61
mode/mini.py
61
mode/mini.py
|
@ -1,25 +1,70 @@
|
||||||
import method, mode
|
import string
|
||||||
|
import buffer, method, mode, window
|
||||||
|
|
||||||
|
class MiniInsertString(method.InsertString):
|
||||||
|
_is_method = False
|
||||||
|
def __init__(self, s):
|
||||||
|
method.InsertString.__init__(self, s)
|
||||||
|
self.name = "mini-insert-string-%s" % s
|
||||||
|
def _execute(self, w, **vargs):
|
||||||
|
try:
|
||||||
|
app = w.application
|
||||||
|
w.insert_string_at_cursor(self.string)
|
||||||
|
if app.completion_window_is_open():
|
||||||
|
app.close_completion_buffer()
|
||||||
|
except buffer.ReadOnlyError:
|
||||||
|
w.set_error('Buffer is read-only')
|
||||||
|
|
||||||
|
class MiniInsertSpace(method.Method):
|
||||||
|
def _execute(self, w, **vargs):
|
||||||
|
try:
|
||||||
|
app = w.application
|
||||||
|
w.insert_string_at_cursor(' ')
|
||||||
|
if app.completion_window_is_open():
|
||||||
|
app.close_completion_buffer()
|
||||||
|
except buffer.ReadOnlyError:
|
||||||
|
w.set_error('Buffer is read-only')
|
||||||
|
|
||||||
class MiniCallback(method.Method):
|
class MiniCallback(method.Method):
|
||||||
def execute(self, window, **vargs):
|
def execute(self, w, **vargs):
|
||||||
window.buffer.do_callback()
|
app = w.application
|
||||||
|
if app.completion_window_is_open():
|
||||||
|
app.close_completion_buffer()
|
||||||
|
w.buffer.do_callback()
|
||||||
|
|
||||||
class MiniTabComplete(method.Method):
|
class MiniTabComplete(method.Method):
|
||||||
def execute(self, window, **vargs):
|
def execute(self, w, **vargs):
|
||||||
b = window.buffer
|
app = w.application
|
||||||
|
b = w.buffer
|
||||||
if b.tabber is None:
|
if b.tabber is None:
|
||||||
window.application.set_error("No tab completion")
|
w.application.set_error("No tab completion")
|
||||||
return
|
return
|
||||||
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, w)
|
||||||
b.set_data(s2)
|
b.set_data(s2)
|
||||||
|
|
||||||
|
if app.completion_window_is_open():
|
||||||
|
w2 = app.get_completion_window()
|
||||||
|
if w2.last_is_visible():
|
||||||
|
w2.goto_beginning()
|
||||||
|
else:
|
||||||
|
w2.page_down()
|
||||||
|
else:
|
||||||
|
candidates = sorted(b.tabber.get_candidates(s1))
|
||||||
|
if len(candidates) > 1:
|
||||||
|
app.open_completion_buffer(s2, candidates)
|
||||||
|
|
||||||
class Mini(mode.Fundamental):
|
class Mini(mode.Fundamental):
|
||||||
modename = 'Mini'
|
modename = 'Mini'
|
||||||
actions = [MiniCallback, MiniTabComplete]
|
actions = [MiniCallback, MiniTabComplete, MiniInsertSpace]
|
||||||
def __init__(self, w):
|
def __init__(self, w):
|
||||||
mode.Fundamental.__init__(self, w)
|
mode.Fundamental.__init__(self, w)
|
||||||
self.add_bindings('mini-callback', ('RETURN',))
|
self.add_bindings('mini-callback', ('RETURN',))
|
||||||
self.add_bindings('mini-tab-complete', ('TAB',))
|
self.add_bindings('mini-tab-complete', ('TAB',))
|
||||||
|
|
||||||
|
# create all the insert actions for the basic text input
|
||||||
|
for c in string.letters + string.digits + string.punctuation:
|
||||||
|
self.add_action_and_bindings(MiniInsertString(c), (c,))
|
||||||
|
self.add_bindings('mini-insert-space', ('SPACE',))
|
||||||
|
|
||||||
install = Mini.install
|
install = Mini.install
|
||||||
|
|
|
@ -73,7 +73,7 @@ def find(r, w, move=False, direction='next', start=None, end=None):
|
||||||
break
|
break
|
||||||
if newc:
|
if newc:
|
||||||
w.goto(newc[0])
|
w.goto(newc[0])
|
||||||
else:
|
elif ranges:
|
||||||
i = 0
|
i = 0
|
||||||
if direction == 'next':
|
if direction == 'next':
|
||||||
i = -1
|
i = -1
|
||||||
|
|
Loading…
Reference in New Issue