From 3d06125ed556e2c4fe5a71f75bbf24c12d765e9b Mon Sep 17 00:00:00 2001 From: moculus Date: Thu, 23 Apr 2009 15:47:54 +0000 Subject: [PATCH] emacs/vi mode autodetection --HG-- branch : pmacs2 --- regex.py | 30 +++++++++++++++++------------- window.py | 37 ++++++++++++++++++++++--------------- 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/regex.py b/regex.py index 59d89c3..7b51f9d 100644 --- a/regex.py +++ b/regex.py @@ -1,5 +1,9 @@ import re +# mode stuff (emacs/vi) +auto_mode_emacs = re.compile(r'-\*- ([^ ]+) -\*-') +auto_mode_vi = re.compile('(?:vim|vi|ex):.+?(?:syntax|syn)=([^ ]+)') + # lexing reserved_token_names = re.compile(r'^(?:rules|null|start|end|middle[0-9]*)$') valid_token_name = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$') @@ -12,25 +16,25 @@ meta_chars = re.compile(r'([\.\^\$\*\+\?\{\}\(\)\[\]\|\"\'\\,])') shell_command = re.compile(r'^[^ ]+') # whitespace regexes -leading_whitespace = re.compile('^ *') +leading_whitespace = re.compile('^ *') trailing_whitespace = re.compile(' *$') -whitespace = re.compile('^[ \n]*$') -space = re.compile('^ *$') +whitespace = re.compile(r'^[ \n]*$') +space = re.compile('^ *$') leading_whitespace2 = re.compile('^( *?)(.*?)\n?$') # word regexes -word = re.compile('^[A-Za-z0-9_]+$') +word = re.compile('^[A-Za-z0-9_]+$') word_char = re.compile('^[A-Za-z0-9_]$') # perl regexes -perl_base = re.compile("^sub ") -perl_hash_cleanup = re.compile(r"^( *)([^ ]+|'(?:\.|[^'\'])*'|\"(?:\.|[^\\\"]*)\")( *)(=>)( *)([^ ].*)$") -perl_assign_cleanup = re.compile(r"^( *)((?:my |our )?[^ ]+)( *)(=(?!>))( *)([^ ].*)$") -perl_function = re.compile(r"^ *sub ([A-Za-z_][A-Za-z0-9_]*)") +perl_base = re.compile("^sub ") +perl_hash_cleanup = re.compile(r"^( *)([^ ]+|'(?:\.|[^'\'])*'|\"(?:\.|[^\\\"]*)\")( *)(=>)( *)([^ ].*)$") +perl_assign_cleanup = re.compile("^( *)((?:my |our )?[^ ]+)( *)(=(?!>))( *)([^ ].*)$") +perl_function = re.compile("^ *sub ([A-Za-z_][A-Za-z0-9_]*)") # python regexes -python_base = re.compile(r"^[^ ]") -python_dict_cleanup = re.compile(r"^( *)((?:[^'\":]|'(?:\.|[^\'])*'|\"(?:\.|[^\'])*)+?)( *)(:)( *)([^ ].*)$") -python_assign_cleanup = re.compile(r"^( *)([^ ]+)( *)(=)( *)([^ ].*)$") -python_scope = re.compile('^( *)(class|def) ([A-Za-z_][A-Za-z0-9_]*)') -python_indent = re.compile('^( *)') +python_base = re.compile("^[^ ]") +python_dict_cleanup = re.compile(r"^( *)((?:[^'\":]|'(?:\.|[^\'])*'|\"(?:\.|[^\'])*)+?)( *)(:)( *)([^ ].*)$") +python_assign_cleanup = re.compile("^( *)([^ ]+)( *)(=)( *)([^ ].*)$") +python_scope = re.compile('^( *)(class|def) ([A-Za-z_][A-Za-z0-9_]*)') +python_indent = re.compile('^( *)') diff --git a/window.py b/window.py index 538b843..7e38bb5 100644 --- a/window.py +++ b/window.py @@ -45,24 +45,31 @@ class Window(object): basename = os.path.basename(path) ext = self._get_path_ext(path) - if path in self.application.mode_paths: - mode_name = self.application.mode_paths[path] - elif basename in self.application.mode_basenames: - mode_name = self.application.mode_basenames[basename] - elif ext in self.application.mode_extensions: - mode_name = self.application.mode_extensions[ext] - elif len(b.lines) > 0 and \ - b.lines[0].startswith('#!'): + # we don't want to accidentally end up searching binary (or pseudo- + # binary) files. this is kind of a hack + if b.lines and len(b.lines[0]) < 4096: + firstline = b.lines[0] + else: + firstline = '' + + if path in a.mode_paths: + mode_name = a.mode_paths[path] + elif basename in a.mode_basenames: + mode_name = a.mode_basenames[basename] + elif ext in a.mode_extensions: + mode_name = a.mode_extensions[ext] + elif regex.auto_mode_emacs.search(firstline): + mode_name = regex.auto_mode_emacs.search(firstline).group(1) + elif regex.auto_mode_vi.search(firstline): + mode_name = regex.auto_mode_vi.search(firstline).group(1) + elif firstline.startswith('#!'): line = b.lines[0] - for word in self.application.mode_detection: + for word in a.mode_detection: if word in line: - mode_name = self.application.mode_detection[word] + mode_name = a.mode_detection[word] - if mode_name is None: - mode_name = "fundamental" - - m = self.application.modes[mode_name](self) - self.set_mode(m) + cls = a.modes.get(mode_name, a.modes['fundamental']) + self.set_mode(cls(self)) b.add_window(self) # private method used in window constructor