pmacs3/mode/shellmini.py

171 lines
6.0 KiB
Python

import code, os, re, string, StringIO, sys, traceback
import buffer, buffer.pipe, buffer.emul
import color, completer, lex, method, mode, window
from lex import Grammar, PatternRule, RegionRule
from point import Point
from method import Method
from subprocess import Popen, PIPE, STDOUT
class ShellMiniGrammar(Grammar):
rules = [
PatternRule('word', r'(?:(?:\\.|[^\n\\\'" ])+|"(?:\\.|[^\\\"])*"|\'(?:\\.|[^\\\'])*\')+'),
PatternRule('spaces', r' +'),
PatternRule('eol', r'\n'),
]
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")
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
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
s1 = curr_t.string
if(curr_i == 0) and '/' not in s1:
completer = completer.get_completer['command']
else:
completer = completer.get_completer['path']
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)
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*'):
#b = buffer.pipe.PipeBuffer('/bin/bash', [], name="*Shell*", term='xterm')
b = buffer.emul.XTermBuffer(a, '/bin/bash', [], name="*Shell*")
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')
class OpenShellRaw(Method):
'''Evaluate sh expressions'''
def execute(self, w, **vargs):
a = w.application
if not a.has_buffer_name('*Shell*'):
#b = buffer.pipe.PipeBuffer('/bin/bash', [], name="*Shell*", term='xterm')
b = buffer.emul.XTermBuffer(a, '/bin/bash', [], name="*Shell*")
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)
class ShellMini(mode.Fundamental):
modename = 'ShellMini'
actions = [ShellExec, ShellClear, ShellCancel,
ShellHistoryPrev, ShellHistoryNext,
ShellTab,
ShellPageUp, ShellPageDown, ShellGotoBeginning, ShellGotoEnd,
OpenShell, OpenShellRaw]
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',))
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