perl mode features

--HG--
branch : pmacs2
This commit is contained in:
moculus 2008-05-12 20:16:53 +00:00
parent 25cd253693
commit 510e98dc92
2 changed files with 60 additions and 7 deletions

View File

@ -2,6 +2,7 @@
import curses, curses.ascii, getpass, os, re, string, sys, termios, time import curses, curses.ascii, getpass, os, re, string, sys, termios, time
import traceback import traceback
from subprocess import Popen, PIPE, STDOUT from subprocess import Popen, PIPE, STDOUT
from collections import defaultdict
import buffer, bufferlist, color, completer, keyinput, method, minibuffer, mode import buffer, bufferlist, color, completer, keyinput, method, minibuffer, mode
import util, window import util, window
@ -42,6 +43,7 @@ class Application(object):
# initialize some basic stuff # initialize some basic stuff
# a highlighted_range contains three things: (window, start_p, end_p) # a highlighted_range contains three things: (window, start_p, end_p)
self.state = defaultdict(lambda: {})
self.config = {} self.config = {}
self.highlighted_ranges = [] self.highlighted_ranges = []
self.mini_active = False self.mini_active = False

View File

@ -1,4 +1,4 @@
import re, sets, string, sys import os, re, sets, string, sys
import color, commands, completer, context, default, method, mode, regex, tab import color, commands, completer, context, default, method, mode, regex, tab
from point import Point from point import Point
from lex import Grammar, PatternRule, ContextPatternRule, RegionRule, OverridePatternRule, PatternGroupRule from lex import Grammar, PatternRule, ContextPatternRule, RegionRule, OverridePatternRule, PatternGroupRule
@ -91,7 +91,7 @@ class PerlGrammar(Grammar):
# some more basic stuff # some more basic stuff
PatternRule(r'package', r"(?<=package )(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*"), PatternRule(r'package', r"(?<=package )(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*"),
PatternRule(r'sub', r"(?<=sub )[a-zA-Z_][a-zA-Z_0-9]*"), PatternRule(r'sub', r"(?<=sub )(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*"),
PatternRule(r'use', r"(?<=use )(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*"), PatternRule(r'use', r"(?<=use )(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*"),
PatternRule(r'require', r"(?<=require )(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*"), PatternRule(r'require', r"(?<=require )(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*"),
PatternRule(r'perl_label', r'[a-zA-Z_][a-zA-Z0-9_]*:(?!:)'), PatternRule(r'perl_label', r'[a-zA-Z_][a-zA-Z0-9_]*:(?!:)'),
@ -487,6 +487,31 @@ class PerlWrapParagraph(method.WrapParagraph):
else: else:
w.set_error("did not detect comment or pod lines") w.set_error("did not detect comment or pod lines")
class PerlOpenModule(method.Method):
args = [Argument("module", type=type(""), prompt="Open Perl Module: ")]
def _execute(self, w, **vargs):
path = w.mode.find_module(vargs['module'])
if path:
w.application.methods['open-file'].execute(w, filename=path)
else:
w.set_error("Could not find module %r" % vargs['module'])
class PerlOpenModuleWord(method.Method):
def _execute(self, w, **vargs):
word = pkg = w.get_token().string
path = None
while True:
path = w.mode.find_module(pkg)
if path:
break
parent = pkg.rsplit('::')[0]
if parent == pkg:
break
parent = pkg
if path:
w.application.methods['open-file'].execute(w, filename=path)
else:
w.set_error("Could not find module related to %r" % pkg)
class PerlFunctionCompleter(completer.Completer): class PerlFunctionCompleter(completer.Completer):
def get_candidates(self, s, w=None): def get_candidates(self, s, w=None):
old_window = w.buffer.method.old_window old_window = w.buffer.method.old_window
@ -516,9 +541,9 @@ class PerlContext(context.Context):
if t.name in m.opentokens and t.string in m.opentags: if t.name in m.opentokens and t.string in m.opentags:
stack.append(t.string) stack.append(t.string)
elif t.name in m.closetokens and t.string in m.closetags: elif t.name in m.closetokens and t.string in m.closetags:
assert stack[-1] == m.closetags[t.string] if stack[-1] == m.closetags[t.string]:
stack.pop(-1) stack.pop(-1)
if not stack: if t.string == '}' and not stack:
curr = None curr = None
class Perl(mode.Fundamental): class Perl(mode.Fundamental):
@ -627,7 +652,7 @@ class Perl(mode.Fundamental):
actions = [PerlSetLib, PerlCheckSyntax, PerlHashCleanup, actions = [PerlSetLib, PerlCheckSyntax, PerlHashCleanup,
PerlViewModulePerldoc, PerlViewWordPerldoc, PerlWrapParagraph, PerlViewModulePerldoc, PerlViewWordPerldoc, PerlWrapParagraph,
PerlInitFunctions, PerlGotoFunction, PerlWhichFunction, PerlInitFunctions, PerlGotoFunction, PerlWhichFunction,
PerlListFunctions] PerlListFunctions, PerlOpenModule, PerlOpenModuleWord]
completers = { completers = {
'perlfunction': PerlFunctionCompleter(), 'perlfunction': PerlFunctionCompleter(),
} }
@ -664,6 +689,32 @@ class Perl(mode.Fundamental):
self.functions = None self.functions = None
self.funclines = None self.funclines = None
def find_module(self, module):
parts = module.split('::')
parts[-1] += '.pm'
relpath = os.path.join(*parts)
path = None
for d in self.get_inc():
path2 = os.path.join(d, relpath)
if os.path.exists(path2):
path = path2
break
return path
def get_inc(self):
a = self.window.application
if 'inc' not in a.state['perl']:
perllib = a.config.get('perl.lib')
if perllib:
cmd = "PERL5LIB=%r perl -e 'print join(\"\\n\", @INC);'" % perllib
else:
cmd = "perl -e 'print join(\"\\n\", @INC);'"
(status, data) = commands.getstatusoutput(cmd)
if status != 0:
raise Exception, "%r failed" % cmd
a.state['perl']['inc'] = data.split('\n')
return a.state['perl']['inc']
def get_functions(self): def get_functions(self):
return self.context.get_names() return self.context.get_names()
def get_function_names(self): def get_function_names(self):