pmacs3/mode/shellmini.py

160 lines
5.4 KiB
Python

import code, os, re, string, StringIO, sys, traceback
import buffer, 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 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
if(i == 0) and '/' not in curr_t.string:
# we are completing a command
candidates = []
else:
# we are completing a path
cwd = os.getcwd()
if not cwd.endswith('/'):
cwd += '/'
path = cwd + curr_t.string
(d, name) = os.path.split(path)
names = []
for x in os.listdir(d):
if os.path.isdir(os.path.join(d, x)):
names.append(x + '/')
else:
names.append(x)
candidates = [x for x in names if x.startswith(name)]
s = completer.find_common_string(candidates)[len(name):]
w.insert_string_at_cursor(s)
mode.mini.use_completion_window(a, name, 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.PipeBuffer('/bin/bash', [], name="*Shell*", term='xterm')
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 ShellMini(mode.Fundamental):
modename = 'ShellMini'
actions = [ShellExec, ShellClear, ShellCancel,
ShellHistoryPrev, ShellHistoryNext,
ShellTab,
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',))
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