Wed, 25 Oct 2017 21:00:48 +0200
Fallback option for using QScintilla if no auto completion found by plug-ins.
--- a/Preferences/ConfigurationPages/EditorAutocompletionPage.py Tue Oct 24 19:09:09 2017 +0200 +++ b/Preferences/ConfigurationPages/EditorAutocompletionPage.py Wed Oct 25 21:00:48 2017 +0200 @@ -29,7 +29,7 @@ self.setObjectName("EditorAutocompletionPage") # set initial values - self.acEnabledCheckBox.setChecked( + self.acEnabledGroupBox.setChecked( Preferences.getEditor("AutoCompletionEnabled")) self.acCaseSensitivityCheckBox.setChecked( Preferences.getEditor("AutoCompletionCaseSensitivity")) @@ -39,12 +39,16 @@ Preferences.getEditor("AutoCompletionReplaceWord")) self.acThresholdSlider.setValue( Preferences.getEditor("AutoCompletionThreshold")) + self.acScintillaCheckBox.setChecked( + Preferences.getEditor("AutoCompletionScintillaOnFail")) self.acTimeoutSpinBox.setValue( Preferences.getEditor("AutoCompletionTimeout")) self.acCacheSizeSpinBox.setValue( Preferences.getEditor("AutoCompletionCacheSize")) self.acCacheTimeSpinBox.setValue( Preferences.getEditor("AutoCompletionCacheTime")) + self.acWatchdogDoubleSpinBox.setValue( + Preferences.getEditor("AutoCompletionWatchdogTime") / 1000.0) def save(self): """ @@ -52,7 +56,7 @@ """ Preferences.setEditor( "AutoCompletionEnabled", - self.acEnabledCheckBox.isChecked()) + self.acEnabledGroupBox.isChecked()) Preferences.setEditor( "AutoCompletionCaseSensitivity", self.acCaseSensitivityCheckBox.isChecked()) @@ -67,6 +71,9 @@ "AutoCompletionThreshold", self.acThresholdSlider.value()) Preferences.setEditor( + "AutoCompletionScintillaOnFail", + self.acScintillaCheckBox.isChecked()) + Preferences.setEditor( "AutoCompletionTimeout", self.acTimeoutSpinBox.value()) Preferences.setEditor( @@ -75,6 +82,9 @@ Preferences.setEditor( "AutoCompletionCacheTime", self.acCacheTimeSpinBox.value()) + Preferences.setEditor( + "AutoCompletionWatchdogTime", + self.acWatchdogDoubleSpinBox.value() * 1000) def create(dlg):
--- a/Preferences/ConfigurationPages/EditorAutocompletionPage.ui Tue Oct 24 19:09:09 2017 +0200 +++ b/Preferences/ConfigurationPages/EditorAutocompletionPage.ui Wed Oct 25 21:00:48 2017 +0200 @@ -32,23 +32,7 @@ </widget> </item> <item> - <widget class="QCheckBox" name="acEnabledCheckBox"> - <property name="toolTip"> - <string>Select this to enable autocompletion</string> - </property> - <property name="whatsThis"> - <string><b>Autocompletion Enabled</b><p>Select to enable autocompletion. In order to get autocompletion from alternative autocompletion providers (if installed), these have to be enabled on their respective configuration page. Only one alternative provider might be enabled.</p></string> - </property> - <property name="text"> - <string>Automatic Completion Enabled</string> - </property> - </widget> - </item> - <item> <widget class="QGroupBox" name="groupBox"> - <property name="enabled"> - <bool>false</bool> - </property> <property name="title"> <string>General</string> </property> @@ -83,6 +67,24 @@ </property> </widget> </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="acEnabledGroupBox"> + <property name="toolTip"> + <string>Select this to enable autocompletion</string> + </property> + <property name="whatsThis"> + <string><b>Autocompletion Enabled</b><p>Select to enable autocompletion. In order to get autocompletion from alternative autocompletion providers (if installed), these have to be enabled on their respective configuration page. Only one alternative provider might be enabled.</p></string> + </property> + <property name="title"> + <string>Automatic Completion Enabled</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <layout class="QGridLayout" name="gridLayout_4"> <item row="2" column="0"> <widget class="QLabel" name="textLabel1_2"> <property name="text"> @@ -90,7 +92,14 @@ </property> </widget> </item> - <item row="2" column="1" colspan="3"> + <item row="3" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Time to start completion:</string> + </property> + </widget> + </item> + <item row="2" column="1"> <layout class="QHBoxLayout" name="horizontalLayout"> <item> <widget class="QSlider" name="acThresholdSlider"> @@ -129,15 +138,20 @@ </item> </layout> </item> - <item row="3" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Time to wait until completion:</string> + <item row="3" column="1"> + <widget class="QSpinBox" name="acTimeoutSpinBox"> + <property name="minimumSize"> + <size> + <width>70</width> + <height>0</height> + </size> </property> - </widget> - </item> - <item row="3" column="1" colspan="2"> - <widget class="QSpinBox" name="acTimeoutSpinBox"> + <property name="maximumSize"> + <size> + <width>70</width> + <height>16777215</height> + </size> + </property> <property name="toolTip"> <string>Enter the time in milliseconds after which a list with completion proposals shall be shown</string> </property> @@ -154,110 +168,197 @@ <number>0</number> </property> <property name="maximum"> - <number>999</number> + <number>1000</number> + </property> + <property name="singleStep"> + <number>50</number> + </property> + </widget> + </item> + </layout> + <zorder>textLabel1_2</zorder> + <zorder>textLabel1_2</zorder> + <zorder></zorder> + <zorder>label</zorder> + <zorder>acTimeoutSpinBox</zorder> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_3"> + <property name="title"> + <string>Plug-In Behavior</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QCheckBox" name="acScintillaCheckBox"> + <property name="toolTip"> + <string>Select to show QScintilla provided completions, if the selected plug-ins fail</string> + </property> + <property name="whatsThis"> + <string>Qscintilla provided completions are shown, if this option is enabled and completions shall be provided by plug-ins (see completions sub-page of the plug-in) and the plugin-ins don't deliver any completions.</string> + </property> + <property name="text"> + <string>Show QScintilla completions, if plug-ins fail</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Maximum time to wait:</string> + </property> + </widget> + </item> + <item> + <widget class="QDoubleSpinBox" name="acWatchdogDoubleSpinBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="minimumSize"> + <size> + <width>70</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>70</width> + <height>16777215</height> + </size> + </property> + <property name="toolTip"> + <string>Enter the time in seconds after which QSintilla should be used</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="accelerated"> + <bool>true</bool> + </property> + <property name="correctionMode"> + <enum>QAbstractSpinBox::CorrectToNearestValue</enum> + </property> + <property name="suffix"> + <string> s</string> + </property> + <property name="decimals"> + <number>1</number> + </property> + <property name="maximum"> + <double>10.000000000000000</double> + </property> + <property name="singleStep"> + <double>0.500000000000000</double> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Completions Cache</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Size:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="acCacheSizeSpinBox"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Enter the maximum number of entries to be kept in the completions cache</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="correctionMode"> + <enum>QAbstractSpinBox::CorrectToNearestValue</enum> + </property> + <property name="suffix"> + <string> entries</string> + </property> + <property name="minimum"> + <number>0</number> + </property> + <property name="maximum"> + <number>1000</number> </property> <property name="singleStep"> <number>10</number> </property> </widget> </item> - <item row="3" column="3"> - <spacer name="horizontalSpacer"> + <item row="0" column="2"> + <spacer name="horizontalSpacer_2"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> - <width>192</width> + <width>271</width> <height>20</height> </size> </property> </spacer> </item> - <item row="4" column="0" colspan="4"> - <widget class="QGroupBox" name="groupBox_2"> - <property name="title"> - <string>Completions Cache</string> + <item row="1" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Timeout:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="acCacheTimeSpinBox"> + <property name="toolTip"> + <string>Enter the time in seconds after which a cached completion entry should be removed from the completions cache</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Size:</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QSpinBox" name="acCacheSizeSpinBox"> - <property name="toolTip"> - <string>Enter the maximum number of entries to be kept in the completions cache</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - <property name="correctionMode"> - <enum>QAbstractSpinBox::CorrectToNearestValue</enum> - </property> - <property name="suffix"> - <string> entries</string> - </property> - <property name="minimum"> - <number>0</number> - </property> - <property name="maximum"> - <number>999</number> - </property> - <property name="singleStep"> - <number>10</number> - </property> - </widget> - </item> - <item row="0" column="2"> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>271</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_3"> - <property name="text"> - <string>Timeout:</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QSpinBox" name="acCacheTimeSpinBox"> - <property name="toolTip"> - <string>Enter the time in seconds after which a cached completion entry should be removed from the completions cache</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - <property name="correctionMode"> - <enum>QAbstractSpinBox::CorrectToNearestValue</enum> - </property> - <property name="suffix"> - <string> s</string> - </property> - <property name="minimum"> - <number>0</number> - </property> - <property name="maximum"> - <number>3600</number> - </property> - <property name="singleStep"> - <number>60</number> - </property> - </widget> - </item> - </layout> + <property name="correctionMode"> + <enum>QAbstractSpinBox::CorrectToNearestValue</enum> + </property> + <property name="suffix"> + <string> s</string> + </property> + <property name="minimum"> + <number>0</number> + </property> + <property name="maximum"> + <number>3600</number> + </property> + <property name="singleStep"> + <number>60</number> + </property> </widget> </item> </layout> @@ -279,12 +380,16 @@ </layout> </widget> <tabstops> - <tabstop>acEnabledCheckBox</tabstop> <tabstop>acCaseSensitivityCheckBox</tabstop> <tabstop>acReplaceWordCheckBox</tabstop> <tabstop>acReversedCheckBox</tabstop> + <tabstop>acEnabledGroupBox</tabstop> <tabstop>acThresholdSlider</tabstop> <tabstop>acTimeoutSpinBox</tabstop> + <tabstop>acScintillaCheckBox</tabstop> + <tabstop>acWatchdogDoubleSpinBox</tabstop> + <tabstop>acCacheSizeSpinBox</tabstop> + <tabstop>acCacheTimeSpinBox</tabstop> </tabstops> <resources/> <connections> @@ -295,28 +400,28 @@ <slot>display(int)</slot> <hints> <hint type="sourcelabel"> - <x>304</x> - <y>114</y> + <x>442</x> + <y>161</y> </hint> <hint type="destinationlabel"> - <x>465</x> - <y>116</y> + <x>485</x> + <y>162</y> </hint> </hints> </connection> <connection> - <sender>acEnabledCheckBox</sender> + <sender>acScintillaCheckBox</sender> <signal>toggled(bool)</signal> - <receiver>groupBox</receiver> + <receiver>acWatchdogDoubleSpinBox</receiver> <slot>setEnabled(bool)</slot> <hints> <hint type="sourcelabel"> - <x>103</x> - <y>43</y> + <x>30</x> + <y>237</y> </hint> <hint type="destinationlabel"> - <x>114</x> - <y>64</y> + <x>155</x> + <y>259</y> </hint> </hints> </connection>
--- a/Preferences/__init__.py Tue Oct 24 19:09:09 2017 +0200 +++ b/Preferences/__init__.py Wed Oct 25 21:00:48 2017 +0200 @@ -416,18 +416,21 @@ "AutoCompletionShowSingle": False, "AutoCompletionSource": QsciScintilla.AcsDocument, "AutoCompletionThreshold": 2, + # timeout in ms before auto-completion is started "AutoCompletionTimeout": 200, - # timeout in ms before auto-completion is started "AutoCompletionFillups": False, + # show QScintilla completions, if plug-in fails + "AutoCompletionScintillaOnFail": False, "AutoCompletionReversedList": False, "AutoCompletionCacheSize": 100, "AutoCompletionCacheTime": 300, # 5 minutes + "AutoCompletionWatchdogTime": 3000, # ms "CallTipsEnabled": False, "CallTipsVisible": 0, "CallTipsStyle": QsciScintilla.CallTipsNoContext, + # show QScintilla calltips, if plug-in fails "CallTipsScintillaOnFail": False, - # show QScintilla calltips, if plug-in fails "AutoCheckSyntax": True, "OnlineSyntaxCheck": True, @@ -2075,12 +2078,13 @@ "CaretWidth", "AutoCompletionSource", "AutoCompletionThreshold", "AutoCompletionTimeout", "AutoCompletionCacheSize", "AutoCompletionCacheTime", - "CallTipsVisible", "CallTipsStyle", - "MarkOccurrencesTimeout", "AutoSpellCheckChunkSize", - "SpellCheckingMinWordSize", "PostScriptLevel", "EOLMode", - "ZoomFactor", "WhitespaceSize", "OnlineSyntaxCheckInterval", - "OnlineChangeTraceInterval", "WrapLongLinesMode", - "WrapVisualFlag", "CallTipsPosition", "VirtualSpaceOptions"]: + "AutoCompletionWatchdogTime", "CallTipsVisible", + "CallTipsStyle", "MarkOccurrencesTimeout", + "AutoSpellCheckChunkSize", "SpellCheckingMinWordSize", + "PostScriptLevel", "EOLMode", "ZoomFactor", "WhitespaceSize", + "OnlineSyntaxCheckInterval", "OnlineChangeTraceInterval", + "WrapLongLinesMode", "WrapVisualFlag", "CallTipsPosition", + "VirtualSpaceOptions"]: return int(prefClass.settings.value( "Editor/" + key, prefClass.editorDefaults[key])) elif key in ["AdditionalOpenFilters", "AdditionalSaveFilters", @@ -2098,10 +2102,6 @@ elif value in ["false", "False"]: value = 0 return QsciLexerPython.IndentationWarning(int(value)) - elif key == "AutoCompletionScintillaOnFail": - # This is obsolete, return default value for backward compatibility - # with old plug-ins. - return False else: return toBool(prefClass.settings.value( "Editor/" + key, prefClass.editorDefaults[key]))
--- a/QScintilla/Editor.py Tue Oct 24 19:09:09 2017 +0200 +++ b/QScintilla/Editor.py Wed Oct 25 21:00:48 2017 +0200 @@ -388,6 +388,7 @@ self.__acContext = True self.__acText = "" self.__acCompletions = set() + self.__acCompletionsFinished = 0 self.__acCache = E5Cache( size=Preferences.getEditor("AutoCompletionCacheSize")) self.__acCache.setMaximumCacheTime( @@ -398,6 +399,12 @@ Preferences.getEditor("AutoCompletionTimeout")) self.__acTimer.timeout.connect(self.__autoComplete) + self.__acWatchdog = QTimer(self) + self.__acWatchdog.setSingleShot(True) + self.__acWatchdog.setInterval( + Preferences.getEditor("AutoCompletionWatchdogTime")) + self.__acWatchdog.timeout.connect(self.autoCompleteQScintilla) + self.__completionListHookFunctions = {} self.__completionListAsyncHookFunctions = {} self.__setAutoCompletion() @@ -4456,6 +4463,11 @@ """ Public method to perform an autocompletion using QScintilla methods. """ + self.__acText = ' ' # Prevent long running ACs to add results + self.__acWatchdog.stop() + if self.__acCompletions: + return + acs = Preferences.getEditor("AutoCompletionSource") if acs == QsciScintilla.AcsDocument: self.autoCompleteFromDocument() @@ -4673,6 +4685,7 @@ else: self.__acText = self.getWordLeft(line, col) self.__acCompletions.clear() + self.__acCompletionsFinished = 0 # Suppress empty completions if auto and self.__acText == '': @@ -4697,6 +4710,9 @@ completions = self.__completionListHookFunctions[key]( self, context) self.completionsListReady(completions, self.__acText) + + if Preferences.getEditor("AutoCompletionScintillaOnFail"): + self.__acWatchdog.start() # TODO: document this hook in chapter 6.2 of plug-in document def completionsListReady(self, completions, acText): @@ -4712,10 +4728,22 @@ if acText == self.__acText and bool(completions): # process the list only, if not already obsolete or completions # are not empty + self.__acCompletions.update(set(completions)) + + self.__acCompletionsFinished += 1 + # Got all results from auto completer? + if self.__acCompletionsFinished >= len( + self.__completionListAsyncHookFunctions): + self.__acWatchdog.stop() + + # Autocomplete with QScintilla if no results present + if (Preferences.getEditor("AutoCompletionScintillaOnFail") + and not self.__acCompletions): + self.autoCompleteQScintilla() + return if self.isListActive(): self.cancelList() - self.__acCompletions.update(set(completions)) if self.__acCompletions: self.__acCache.add(acText, set(self.__acCompletions)) self.__showCompletionsList(self.__acCompletions)