pmacs3/mode/shellmini.py

159 lines
5.5 KiB
Python
Raw Normal View History

2008-09-12 09:31:48 -04:00
import code, os, re, string, StringIO, sys, traceback
2008-11-03 09:30:06 -05:00
import buffer, buffer.pipe, buffer.emul
2008-10-29 00:02:50 -04:00
import color, completer, lex, method, mode, window
2008-09-19 15:57:00 -04:00
from lex import Grammar, PatternRule, RegionRule
2008-09-12 09:31:48 -04:00
from point import Point
from method import Method
from subprocess import Popen, PIPE, STDOUT
2008-10-29 11:43:15 -04:00
class ShellMiniGrammar(Grammar):
rules = [
PatternRule('word', r'(?:(?:\\.|[^\n\\\'" ])+|"(?:\\.|[^\\\"])*"|\'(?:\\.|[^\\\'])*\')+'),
PatternRule('spaces', r' +'),
PatternRule('eol', r'\n'),
]
2008-09-12 09:31:48 -04:00
class ShellExec(Method):
def _execute(self, w, **vargs):
a = w.application
if a.completion_window_is_open():
a.close_completion_buffer()
s = w.buffer.make_string()
w.mode.history[-1] = s
w.mode.history.append('')
w.buffer.set_data('')
w.mode.hindex = len(w.mode.history) - 1
if not a.has_buffer_name('*Shell*'):
raise Exception, "No shell found!"
b = a.bufferlist.get_buffer_by_name('*Shell*')
if a.window().buffer is not b:
a.switch_buffer(b)
b.pipe_write(s + "\n")
2008-09-12 09:31:48 -04:00
class ShellCancel(Method):
def execute(self, w, **vargs):
w.application.close_mini_buffer()
if w.application.completion_window_is_open():
w.application.close_completion_buffer()
class ShellClear(Method):
def execute(self, w, **vargs):
a = w.application
if not a.has_buffer_name('*Shell*'):
raise Exception, "No shell found!"
b = a.bufferlist.get_buffer_by_name('*Shell*')
class ShellHistoryPrev(Method):
def execute(self, w, **vargs):
if w.mode.hindex <= 0:
w.mode.hindex = 0
return
elif w.mode.hindex == len(w.mode.history) - 1:
w.mode.history[-1] = w.buffer.make_string()
w.mode.hindex -= 1
w.buffer.set_data(w.mode.history[w.mode.hindex])
class ShellHistoryNext(Method):
def execute(self, w, **vargs):
if w.mode.hindex == len(w.mode.history) - 1:
return
w.mode.hindex += 1
w.buffer.set_data(w.mode.history[w.mode.hindex])
class ShellTab(Method):
def execute(self, w, **vargs):
a = w.application
s = w.buffer.make_string()
x = w.logical_cursor().x
if not s or s[:x].isspace():
w.insert_string_at_cursor(' ' * w.mode.tabwidth)
return
2008-09-19 15:57:00 -04:00
l = lex.Lexer(w.mode, ShellMiniGrammar)
tokens = list(l.lex([s]))
curr_t = None
curr_i = None
for i in range(0, len(tokens)):
t = tokens[i]
if t.x < x and t.end_x() >= x:
curr_i = i
curr_t = t
if curr_t is None:
return
2008-10-29 11:43:15 -04:00
s1 = curr_t.string
if(curr_i == 0) and '/' not in s1:
completer = method.DATATYPES['command']
2008-09-19 15:57:00 -04:00
else:
2008-10-29 11:43:15 -04:00
completer = method.DATATYPES['path']
2008-09-19 15:57:00 -04:00
2008-10-29 11:43:15 -04:00
s2, exists, complete = completer.tab_string(s1, w)
w.delete(Point(curr_t.x, curr_t.y), Point(curr_t.end_x(), curr_t.y))
w.insert_string_at_cursor(s2)
candidates = completer.get_candidates(s1, w)
mode.mini.use_completion_window(a, s2, candidates)
2008-09-12 09:31:48 -04:00
class ShellBaseMethod(Method):
subcls = Method
subbuf = '*Shell*'
def __init__(self):
Method.__init__(self)
self.submethod = self.subcls()
def _execute(self, w, **vargs):
a = w.application
if not a.has_buffer_name(self.subbuf):
raise Exception, "No shell found!"
w2 = a.bufferlist.get_buffer_by_name(self.subbuf).windows[0]
self.submethod.execute(w2, **vargs)
class ShellPageUp(ShellBaseMethod):
subcls = method.move.PageUp
class ShellPageDown(ShellBaseMethod):
subcls = method.move.PageDown
class ShellGotoBeginning(ShellBaseMethod):
subcls = method.move.GotoBeginning
class ShellGotoEnd(ShellBaseMethod):
subcls = method.move.GotoEnd
class OpenShell(Method):
'''Evaluate sh expressions'''
def execute(self, w, **vargs):
a = w.application
if not a.has_buffer_name('*Shell*'):
2008-11-03 09:30:06 -05:00
#b = buffer.pipe.PipeBuffer('/bin/bash', [], name="*Shell*", term='xterm')
2008-11-08 10:30:04 -05:00
b = buffer.emul.XTermBuffer(a, '/bin/bash', [], name="*Shell*")
2008-09-12 09:31:48 -04:00
a.add_buffer(b)
window.Window(b, a)
b = a.bufferlist.get_buffer_by_name('*Shell*')
if a.window().buffer is not b:
a.switch_buffer(b)
f = lambda x: None
w.application.open_mini_buffer('>>> ', f, self, None, 'shellmini')
2008-09-12 09:31:48 -04:00
class ShellMini(mode.Fundamental):
modename = 'ShellMini'
actions = [ShellExec, ShellClear, ShellCancel,
ShellHistoryPrev, ShellHistoryNext,
ShellTab,
2008-09-12 09:31:48 -04:00
ShellPageUp, ShellPageDown, ShellGotoBeginning, ShellGotoEnd,
OpenShell]
def __init__(self, w):
mode.Fundamental.__init__(self, w)
self.saved_input = ""
self.history = ['']
self.hindex = 0
self.add_bindings('shell-exec', ('RETURN',))
self.add_bindings('shell-clear', ('C-l',))
self.add_bindings('shell-cancel', ('C-]', 'C-g'))
self.add_bindings('shell-history-prev', ('C-p', 'UP'))
self.add_bindings('shell-history-next', ('C-n', 'DOWN'))
self.add_bindings('shell-tab', ('TAB',))
2008-09-12 09:31:48 -04:00
self.add_bindings('shell-page-up', ('M-v',))
self.add_bindings('shell-page-down', ('C-v',))
self.add_bindings('shell-goto-beginning', ('M-<',))
self.add_bindings('shell-goto-end', ('M->',))
install = ShellMini.install