eric6/QScintilla/TypingCompleters/CompleterRuby.py

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

eric ide

mercurial