Thu, 26 Oct 2017 19:07:55 +0200
Merged with changes from Tobias.
--- a/Preferences/ConfigurationPages/EditorAutocompletionPage.py Thu Oct 26 19:06:20 2017 +0200 +++ b/Preferences/ConfigurationPages/EditorAutocompletionPage.py Thu Oct 26 19:07:55 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 Thu Oct 26 19:06:20 2017 +0200 +++ b/Preferences/ConfigurationPages/EditorAutocompletionPage.ui Thu Oct 26 19:07:55 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 Thu Oct 26 19:06:20 2017 +0200 +++ b/Preferences/__init__.py Thu Oct 26 19:07:55 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 Thu Oct 26 19:06:20 2017 +0200 +++ b/QScintilla/Editor.py Thu Oct 26 19:07:55 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)