QScintilla/TypingCompleters/CompleterRuby.py

changeset 0
de9c2efb9d02
child 12
1d8dd9706f46
equal deleted inserted replaced
-1:000000000000 0:de9c2efb9d02
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2007 - 2009 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a typing completer for Ruby.
8 """
9
10 from PyQt4.QtCore import QObject, SIGNAL, QRegExp
11 from PyQt4.Qsci import QsciLexerRuby
12
13 from CompleterBase import CompleterBase
14
15 import Preferences
16
17 class CompleterRuby(CompleterBase):
18 """
19 Class implementing typing completer for Ruby.
20 """
21 def __init__(self, editor, parent = None):
22 """
23 Constructor
24
25 @param editor reference to the editor object (QScintilla.Editor)
26 @param parent reference to the parent object (QObject)
27 """
28 CompleterBase.__init__(self, editor, parent)
29
30 self.__beginRX = QRegExp(r"""^=begin """)
31 self.__beginNlRX = QRegExp(r"""^=begin\r?\n""")
32 self.__hereRX = QRegExp(r"""<<-?['"]?(\w*)['"]?\r?\n""")
33
34 self.readSettings()
35
36 def readSettings(self):
37 """
38 Public slot called to reread the configuration parameters.
39 """
40 self.setEnabled(Preferences.getEditorTyping("Ruby/EnabledTypingAids"))
41 self.__insertClosingBrace = \
42 Preferences.getEditorTyping("Ruby/InsertClosingBrace")
43 self.__indentBrace = \
44 Preferences.getEditorTyping("Ruby/IndentBrace")
45 self.__skipBrace = \
46 Preferences.getEditorTyping("Ruby/SkipBrace")
47 self.__insertQuote = \
48 Preferences.getEditorTyping("Ruby/InsertQuote")
49 self.__insertBlank = \
50 Preferences.getEditorTyping("Ruby/InsertBlank")
51 self.__insertHereDoc = \
52 Preferences.getEditorTyping("Ruby/InsertHereDoc")
53 self.__insertInlineDoc = \
54 Preferences.getEditorTyping("Ruby/InsertInlineDoc")
55
56 def charAdded(self, charNumber):
57 """
58 Public slot called to handle the user entering a character.
59
60 @param charNumber value of the character entered (integer)
61 """
62 char = unichr(charNumber)
63 if char not in ['(', ')', '{', '}', '[', ']', ',', "'", '"', '\n', ' ']:
64 return # take the short route
65
66 line, col = self.editor.getCursorPosition()
67
68 if self.__inComment(line, col) or \
69 self.__inDoubleQuotedString() or \
70 self.__inSingleQuotedString() or \
71 self.__inHereDocument() or \
72 self.__inInlineDocument():
73 return
74
75 # open parenthesis
76 # insert closing parenthesis and self
77 if char == '(':
78 txt = self.editor.text(line)[:col]
79 if self.__insertClosingBrace:
80 self.editor.insert(')')
81
82 # closing parenthesis
83 # skip matching closing parenthesis
84 elif char in [')', '}', ']']:
85 if char == self.editor.text(line)[col]:
86 if self.__skipBrace:
87 self.editor.setSelection(line, col, line, col + 1)
88 self.editor.removeSelectedText()
89
90 # space
91 # complete inline documentation
92 elif char == ' ':
93 txt = self.editor.text(line)[:col]
94 if self.__insertInlineDoc and self.__beginRX.exactMatch(txt):
95 self.editor.insert('=end')
96
97 # comma
98 # insert blank
99 elif char == ',':
100 if self.__insertBlank:
101 self.editor.insert(' ')
102 self.editor.setCursorPosition(line, col + 1)
103
104 # open curly brace
105 # insert closing brace
106 elif char == '{':
107 if self.__insertClosingBrace:
108 self.editor.insert('}')
109
110 # open bracket
111 # insert closing bracket
112 elif char == '[':
113 if self.__insertClosingBrace:
114 self.editor.insert(']')
115
116 # double quote
117 # insert double quote
118 elif char == '"':
119 if self.__insertQuote:
120 self.editor.insert('"')
121
122 # quote
123 # insert quote
124 elif char == '\'':
125 if self.__insertQuote:
126 self.editor.insert('\'')
127
128 # new line
129 # indent to opening brace, complete inline documentation
130 elif char == '\n':
131 txt = self.editor.text(line - 1)
132 if self.__insertInlineDoc and self.__beginNlRX.exactMatch(txt):
133 self.editor.insert('=end')
134 elif self.__insertHereDoc and self.__hereRX.exactMatch(txt):
135 self.editor.insert(self.__hereRX.cap(1))
136 elif self.__indentBrace and re.search(":\r?\n", txt) is None:
137 openCount = len(re.findall("[({[]", txt))
138 closeCount = len(re.findall("[)}\]]", txt))
139 if openCount > closeCount:
140 openCount = 0
141 closeCount = 0
142 openList = list(re.finditer("[({[]", txt))
143 index = len(openList) - 1
144 while index > -1 and openCount == closeCount:
145 lastOpenIndex = openList[index].start()
146 txt2 = txt[lastOpenIndex:]
147 openCount = len(re.findall("[({[]", txt2))
148 closeCount = len(re.findall("[)}\]]", txt2))
149 index -= 1
150 if openCount > closeCount and lastOpenIndex > col:
151 self.editor.insert(' ' * (lastOpenIndex - col + 1))
152 self.editor.setCursorPosition(line, lastOpenIndex + 1)
153
154 def __inComment(self, line, col):
155 """
156 Private method to check, if the cursor is inside a comment
157
158 @param line current line (integer)
159 @param col current position within line (integer)
160 @return flag indicating, if the cursor is inside a comment (boolean)
161 """
162 txt = self.editor.text(line)
163 while col >= 0:
164 if txt[col] == "#":
165 return True
166 col -= 1
167 return False
168
169 def __inDoubleQuotedString(self):
170 """
171 Private method to check, if the cursor is within a double quoted string.
172
173 @return flag indicating, if the cursor is inside a double
174 quoted string (boolean)
175 """
176 return self.editor.currentStyle() == QsciLexerRuby.DoubleQuotedString
177
178 def __inSingleQuotedString(self):
179 """
180 Private method to check, if the cursor is within a single quoted string.
181
182 @return flag indicating, if the cursor is inside a single
183 quoted string (boolean)
184 """
185 return self.editor.currentStyle() == QsciLexerRuby.SingleQuotedString
186
187 def __inHereDocument(self):
188 """
189 Private method to check, if the cursor is within a here document.
190
191 @return flag indicating, if the cursor is inside a here document (boolean)
192 """
193 return self.editor.currentStyle() == QsciLexerRuby.HereDocument
194
195 def __inInlineDocument(self):
196 """
197 Private method to check, if the cursor is within an inline document.
198
199 @return flag indicating, if the cursor is inside an inline document (boolean)
200 """
201 return self.editor.currentStyle() == QsciLexerRuby.POD

eric ide

mercurial