Package pallavi :: Package plugins :: Module Lexing
[hide private]
[frames] | no frames]

Source Code for Module pallavi.plugins.Lexing

  1  # Copyright (c) 2006 Dusty Phillips 
  2   
  3  # Permission is hereby granted, free of charge, to any person obtaining a 
  4  # copy of this software and associated documentation files (the "Software"), 
  5  # to deal in the Software without restriction, including without limitation 
  6  # the rights to use, copy, modify, merge, publish, distribute, sublicense, 
  7  # and/or sell copies of the Software, and to permit persons to whom the 
  8  # Software is furnished to do so, subject to the following conditions: 
  9   
 10  # The above copyright notice and this permission notice shall be included in 
 11  # all copies or substantial portions of the Software. 
 12   
 13  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 14  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 15  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
 16  # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 17  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 18  # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 19  # DEALINGS IN THE SOFTWARE. 
 20   
 21  '''This plugin listens for events that change the text buffer and changes 
 22  the buffer lexing styles if they needs to be changed. 
 23   
 24  This plugin provides the following actions: 
 25  GetLexerItem (itemname, callback) 
 26          Get an arbitrary item from the lexer for the focused TextView, 
 27          variable name and callback function to return the item to.       
 28   
 29  This plugin listens for the following events. 
 30  NewFileCreated 
 31  FileOpened 
 32  BufferSwitched 
 33  TextViewAdded 
 34  FileSaved 
 35  FileClosed 
 36          Adjusts the syntax highlighting on a buffer when event occurs.''' 
 37  from wx import stc 
 38  import os, os.path 
 39  from pallavi.EventActionManager import Action 
 40   
 41  lexers = {} 
 42   
43 -def setup():
44 '''Sets up the event listeners and arranges for lexing on all textviews''' 45 eventBus.AddListener("NewFileCreated", AdjustLexing) 46 eventBus.AddListener("FileOpened", AdjustLexing) 47 eventBus.AddListener("BufferSwitched", AdjustLexing) 48 eventBus.AddListener("TextViewAdded", AdjustLexing) 49 eventBus.AddListener("FileSaved", AdjustLexingAll) 50 eventBus.AddListener("FileClosed", AdjustLexingAll) 51 actions.AddAction(Action("GetLexerItem", GetLexerItem)) 52 # Ensure we always have a plain lexer to return 53 lexers["plain"] = LexerInfo({"extensions": ["txt"], "shebangs": [], "lexer": "null", "keywords": ""}) 54 # Load the preconfigured lexers followed by the user's lexers. User settings override preconfigured settings 55 for path_prefix in (config.share, config.config_dir): 56 if os.path.isdir(path_prefix + "/lexing_languages"): 57 for filename in filter(lambda x: x.endswith(".py"), os.listdir(path_prefix + "/lexing_languages")): 58 lexername = filename[0:-3] 59 # Allows user settings to overide specific system settings with other settings as defaults 60 if lexers.has_key(lexername): 61 lx = lexers[lexername] 62 locals = lx.__dict__ 63 else: 64 locals = {} 65 execfile(path_prefix + "/lexing_languages/" + filename, globals(), locals) 66 lexers[lexername] = LexerInfo(locals)
67
68 -def GetLexerItem(itemname, callback):
69 '''Get an arbitrary item stored on a per-mode basis and call the callback with the value of that item''' 70 try: 71 textView = pallavi.focusedView.focusedTextView 72 lexer = MatchLexer(textView.filename, textView.GetLine(0)) 73 callback(lexer.dictionary[itemname]) 74 except: 75 callback(None)
76
77 -def AdjustLexing(eventName, data):
78 '''Adjusts the lexing on the textview passed as data or 79 the currently focused textview.''' 80 if type(data) == type(pallavi.focusedView.focusedTextView): 81 textView = data 82 else: 83 textView = pallavi.focusedView.focusedTextView 84 85 lexerInfo = MatchLexer(textView.filename, textView.GetLine(0)) 86 for style in config.styles: #@TODO: make each lexer have its own styles 87 textView.StyleSetSpec(style, config.styles[style]) 88 textView.SetKeyWords(0, lexerInfo.keywords) 89 if lexerInfo.lexer != "null": 90 textView.SetLexerLanguage(lexerInfo.lexer) 91 else: textView.SetLexer(stc.STC_LEX_NULL) 92 textView.Colourise(0, textView.GetLength())
93 94
95 -def AdjustLexingAll(eventName, data):
96 '''Adjust the lexing on all textviews in all views''' 97 for view in pallavi.views: 98 for textView in view.textViews: 99 AdjustLexing(eventName, textView)
100
101 -class LexerInfo(object):
102 '''Class collects information about a specific lexing mode, including information for 103 syntax parsing as well as possibly info for code folding, autoindent, and other 104 features. 105 106 Contains a list of extensions to be associated with files of that type, a match 107 for shebang lines (first line is #! ....), the lexer to use, the list of keywords 108 to match, and other features. 109 '''
110 - def __init__(self, dictionary):
111 self.dictionary = dictionary 112 # Any item can be placed in the dictionary (so other plugins can look 113 # things up on a lexer-specific basis, but these four are used internally 114 self.extensions = dictionary['extensions'] 115 self.shebangs = dictionary['shebangs'] 116 self.keywords = dictionary['keywords'] 117 self.lexer = dictionary['lexer']
118
119 - def __getitem__(self, key):
120 '''Get an arbitrary item from the dictionary''' 121 try: 122 return self.dictionary[key] 123 except: 124 return None
125
126 - def MatchesFilename(self, filename):
127 '''Determine if this lexer is fit to parse a particular file based on its filename.''' 128 for ext in self.extensions: 129 if filename.endswith(ext): 130 return True 131 return False
132
133 - def MatchesShebang(self, firstline):
134 '''Determine if this lexer is fit to parse a particular file based on its first line.''' 135 for bang in self.shebangs: 136 if firstline.startswith("#!") and firstline.find(bang) > 0: 137 return True 138 return False
139
140 - def Matches(self, filename, firstline):
141 return self.MatchesFilename(filename) or self.MatchesShebang(firstline)
142
143 -def MatchLexer(filename, firstline):
144 for lexer in lexers.values(): 145 if lexer.Matches(filename, firstline): 146 return lexer 147 return lexers["plain"]
148