Mon, 23 Aug 2021 17:59:09 +0200
Finished implementing an extension to the debug/run/... start dialog.
--- a/eric7/Debugger/DebugUI.py Sun Aug 22 19:59:18 2021 +0200 +++ b/eric7/Debugger/DebugUI.py Mon Aug 23 17:59:09 2021 +0200 @@ -88,6 +88,8 @@ # read the saved debug info values self.lastUsedVenvName = Preferences.Prefs.settings.value( 'DebugInfo/VirtualEnvironment', '') + self.scriptsHistory = Preferences.toList( + Preferences.Prefs.settings.value('DebugInfo/ScriptsHistory')) self.argvHistory = Preferences.toList( Preferences.Prefs.settings.value('DebugInfo/ArgumentsHistory')) self.wdHistory = Preferences.toList( @@ -634,13 +636,9 @@ self.debugActGrp.setEnabled(False) self.dbgSetBpActGrp.setEnabled(False) - self.runAct.setEnabled(False) self.runProjectAct.setEnabled(False) - self.profileAct.setEnabled(False) self.profileProjectAct.setEnabled(False) - self.coverageAct.setEnabled(False) self.coverageProjectAct.setEnabled(False) - self.debugAct.setEnabled(False) self.debugProjectAct.setEnabled(False) self.restartAct.setEnabled(False) self.stopAct.setEnabled(False) @@ -731,6 +729,28 @@ return [starttb, debugtb] + def setScriptsHistory(self, scriptName, clearHistories=False, + history=None): + """ + Public slot to initialize the scripts history. + + @param scriptName script name + @type str + @param clearHistories flag indicating, that the list should + be cleared (defaults to False) + @type bool (optional) + @param history list of history entries to be set (defaults to None) + @type list of str (optional) + """ + if clearHistories: + del self.scriptsHistory[1:] + elif history is not None: + self.scriptsHistory = history[:] + else: + if scriptName in self.scriptsHistory: + self.scriptsHistory.remove(scriptName) + self.scriptsHistory.insert(0, scriptName) + def setArgvHistory(self, argsStr, clearHistories=False, history=None): """ Public slot to initialize the argv history. @@ -852,10 +872,6 @@ Private slot to handle the closeProgram signal. """ self.editorOpen = False - self.debugAct.setEnabled(False) - self.runAct.setEnabled(False) - self.profileAct.setEnabled(False) - self.coverageAct.setEnabled(False) self.debugActGrp.setEnabled(False) self.dbgSetBpActGrp.setEnabled(False) self.lastAction = -1 @@ -886,11 +902,6 @@ elif editor.isRubyFile(): cap = self.debugServer.getClientCapabilities('Ruby') - if not self.passive: - self.runAct.setEnabled(cap & HasInterpreter) - self.coverageAct.setEnabled(cap & HasCoverage) - self.profileAct.setEnabled(cap & HasProfiler) - self.debugAct.setEnabled(cap & HasDebugger) self.dbgSetBpActGrp.setEnabled(cap & HasDebugger) if editor.curLineHasBreakpoint(): self.dbgEditBpAct.setEnabled(True) @@ -903,10 +914,6 @@ self.dbgNextBpAct.setEnabled(False) self.dbgPrevBpAct.setEnabled(False) else: - self.runAct.setEnabled(False) - self.coverageAct.setEnabled(False) - self.profileAct.setEnabled(False) - self.debugAct.setEnabled(False) self.dbgSetBpActGrp.setEnabled(False) def __cursorChanged(self, editor): @@ -963,12 +970,15 @@ """ Public method to clear the various debug histories. """ + self.scriptsHistory = [] self.argvHistory = [] self.wdHistory = [] self.envHistory = [] self.multiprocessNoDebugHistory = [] Preferences.Prefs.settings.setValue( + 'DebugInfo/ScriptsHistory', self.scriptsHistory) + Preferences.Prefs.settings.setValue( 'DebugInfo/ArgumentsHistory', self.argvHistory) Preferences.Prefs.settings.setValue( 'DebugInfo/WorkingDirectoryHistory', self.wdHistory) @@ -985,6 +995,7 @@ Public method to perform shutdown actions. """ # Just save the 10 most recent entries + del self.scriptsHistory[10:] del self.argvHistory[10:] del self.wdHistory[10:] del self.envHistory[10:] @@ -992,6 +1003,8 @@ Preferences.Prefs.settings.setValue( 'DebugInfo/VirtualEnvironment', self.lastUsedVenvName) Preferences.Prefs.settings.setValue( + 'DebugInfo/ScriptsHistory', self.scriptsHistory) + Preferences.Prefs.settings.setValue( 'DebugInfo/ArgumentsHistory', self.argvHistory) Preferences.Prefs.settings.setValue( 'DebugInfo/WorkingDirectoryHistory', self.wdHistory) @@ -1689,21 +1702,24 @@ """ Private slot to handle the coverage of script action. """ - self.__doCoverage(False) + self.doCoverage(False) def __coverageProject(self): """ Private slot to handle the coverage of project action. """ self.__compileChangedProjectFiles() - self.__doCoverage(True) + self.doCoverage(True) - def __doCoverage(self, runProject): + def doCoverage(self, runProject, script=""): """ - Private method to handle the coverage actions. + Public method to handle the coverage actions. @param runProject flag indicating coverage of the current project (True) or script (false) + @type bool + @param script name of a script (optional) + @type str """ from .StartDialog import StartDialog @@ -1717,14 +1733,24 @@ if runProject else self.tr("Coverage of Script") ) + if runProject: + scriptName = self.project.getMainScript(True) + elif script: + scriptName = script + elif self.lastDebuggedFile: + scriptName = self.lastDebuggedFile + else: + scriptName = "" dlg = StartDialog( cap, self.lastUsedVenvName, self.argvHistory, self.wdHistory, self.envHistory, self.exceptions, self.ui, 2, autoClearShell=self.autoClearShell, - configOverride=self.overrideGlobalConfig) + configOverride=self.overrideGlobalConfig, + forProject=runProject, scriptName=scriptName, + scriptsList=self.scriptsHistory) if dlg.exec() == QDialog.DialogCode.Accepted: - (lastUsedVenvName, argv, wd, env, exceptions, clearShell, - console) = dlg.getData() + (lastUsedVenvName, scriptName, argv, wd, env, exceptions, + clearShell, console) = dlg.getData() configOverride = dlg.getGlobalOverrideData() eraseCoverage = dlg.getCoverageData() @@ -1755,20 +1781,25 @@ self.lastStartAction = 6 self.clientType = self.project.getProjectLanguage() else: - editor = self.viewmanager.activeWindow() - if editor is None: - return - - if ( - not self.viewmanager.checkDirty( - editor, Preferences.getDebugger("Autosave")) or - editor.getFileName() is None - ): - return + if scriptName: + fn = scriptName + self.clientType = "Python3" + else: + # run current editor + editor = self.viewmanager.activeWindow() + if editor is None: + return - fn = editor.getFileName() + if ( + not self.viewmanager.checkDirty( + editor, Preferences.getDebugger("Autosave")) or + editor.getFileName() is None + ): + return + + fn = editor.getFileName() + self.clientType = editor.determineFileType() self.lastStartAction = 5 - self.clientType = editor.determineFileType() # save the filename for use by the restart method self.lastDebuggedFile = fn @@ -1779,6 +1810,7 @@ # This moves any previous occurrence of these arguments to the head # of the list. + self.setScriptsHistory(scriptName) self.setArgvHistory(argv) self.setWdHistory(wd) self.setEnvHistory(env) @@ -1820,12 +1852,15 @@ self.stopAct.setEnabled(True) if dlg.clearHistories(): + self.setScriptsHistory("", clearHistories=True) self.setArgvHistory("", clearHistories=True) self.setWdHistory("", clearHistories=True) self.setEnvHistory("", clearHistories=True) self.setMultiprocessNoDebugHistory("", clearHistories=True) elif dlg.historiesModified(): - argvHistory, wdHistory, envHistory, _ = dlg.getHistories() + (scriptsHistory, argvHistory, wdHistory, envHistory, + _) = dlg.getHistories() + self.setScriptsHistory("", history=scriptsHistory) self.setArgvHistory("", history=argvHistory) self.setWdHistory("", history=wdHistory) self.setEnvHistory("", history=envHistory) @@ -1834,21 +1869,24 @@ """ Private slot to handle the profile script action. """ - self.__doProfile(False) + self.doProfile(False) def __profileProject(self): """ Private slot to handle the profile project action. """ self.__compileChangedProjectFiles() - self.__doProfile(True) + self.doProfile(True) - def __doProfile(self, runProject): + def doProfile(self, runProject, script=""): """ - Private method to handle the profile actions. + Public method to handle the profile actions. @param runProject flag indicating profiling of the current project (True) or script (False) + @type bool + @param script name of a script (optional) + @type str """ from .StartDialog import StartDialog @@ -1862,14 +1900,24 @@ if runProject else self.tr("Profile of Script") ) + if runProject: + scriptName = self.project.getMainScript(True) + elif script: + scriptName = script + elif self.lastDebuggedFile: + scriptName = self.lastDebuggedFile + else: + scriptName = "" dlg = StartDialog( cap, self.lastUsedVenvName, self.argvHistory, self.wdHistory, self.envHistory, self.exceptions, self.ui, 3, autoClearShell=self.autoClearShell, - configOverride=self.overrideGlobalConfig) + configOverride=self.overrideGlobalConfig, + forProject=runProject, scriptName=scriptName, + scriptsList=self.scriptsHistory) if dlg.exec() == QDialog.DialogCode.Accepted: - (lastUsedVenvName, argv, wd, env, exceptions, clearShell, - console) = dlg.getData() + (lastUsedVenvName, scriptName, argv, wd, env, exceptions, + clearShell, console) = dlg.getData() configOverride = dlg.getGlobalOverrideData() eraseTimings = dlg.getProfilingData() @@ -1900,20 +1948,25 @@ self.lastStartAction = 8 self.clientType = self.project.getProjectLanguage() else: - editor = self.viewmanager.activeWindow() - if editor is None: - return - - if ( - not self.viewmanager.checkDirty( - editor, Preferences.getDebugger("Autosave")) or - editor.getFileName() is None - ): - return + if scriptName: + fn = scriptName + self.clientType = "Python3" + else: + # run current editor + editor = self.viewmanager.activeWindow() + if editor is None: + return - fn = editor.getFileName() + if ( + not self.viewmanager.checkDirty( + editor, Preferences.getDebugger("Autosave")) or + editor.getFileName() is None + ): + return + + fn = editor.getFileName() + self.clientType = editor.determineFileType() self.lastStartAction = 7 - self.clientType = editor.determineFileType() # save the filename for use by the restart method self.lastDebuggedFile = fn @@ -1924,6 +1977,7 @@ # This moves any previous occurrence of these arguments to the head # of the list. + self.setScriptsHistory(scriptName) self.setArgvHistory(argv) self.setWdHistory(wd) self.setEnvHistory(env) @@ -1965,12 +2019,15 @@ self.stopAct.setEnabled(True) if dlg.clearHistories(): + self.setScriptsHistory("", clearHistories=True) self.setArgvHistory("", clearHistories=True) self.setWdHistory("", clearHistories=True) self.setEnvHistory("", clearHistories=True) self.setMultiprocessNoDebugHistory("", clearHistories=True) elif dlg.historiesModified(): - argvHistory, wdHistory, envHistory, _ = dlg.getHistories() + (scriptsHistory, argvHistory, wdHistory, envHistory, + _) = dlg.getHistories() + self.setScriptsHistory("", history=scriptsHistory) self.setArgvHistory("", history=argvHistory) self.setWdHistory("", history=wdHistory) self.setEnvHistory("", history=envHistory) @@ -1979,21 +2036,24 @@ """ Private slot to handle the run script action. """ - self.__doRun(False) + self.doRun(False) def __runProject(self): """ Private slot to handle the run project action. """ self.__compileChangedProjectFiles() - self.__doRun(True) + self.doRun(True) - def __doRun(self, runProject): + def doRun(self, runProject, script=""): """ - Private method to handle the run actions. + Public method to handle the run actions. @param runProject flag indicating running the current project (True) or script (False) + @type bool + @param script name of a script (optional) + @type str """ from .StartDialog import StartDialog @@ -2007,14 +2067,24 @@ if runProject else self.tr("Run Script") ) + if runProject: + scriptName = self.project.getMainScript(True) + elif script: + scriptName = script + elif self.lastDebuggedFile: + scriptName = self.lastDebuggedFile + else: + scriptName = "" dlg = StartDialog( cap, self.lastUsedVenvName, self.argvHistory, self.wdHistory, self.envHistory, self.exceptions, self.ui, 1, autoClearShell=self.autoClearShell, - configOverride=self.overrideGlobalConfig) + configOverride=self.overrideGlobalConfig, + forProject=runProject, scriptName=scriptName, + scriptsList=self.scriptsHistory) if dlg.exec() == QDialog.DialogCode.Accepted: - (lastUsedVenvName, argv, wd, env, exceptions, clearShell, - console) = dlg.getData() + (lastUsedVenvName, scriptName, argv, wd, env, exceptions, + clearShell, console) = dlg.getData() configOverride = dlg.getGlobalOverrideData() if runProject: @@ -2044,22 +2114,27 @@ self.lastStartAction = 4 self.clientType = self.project.getProjectLanguage() else: - editor = self.viewmanager.activeWindow() - if editor is None: - return - - if ( - not self.viewmanager.checkDirty( - editor, - Preferences.getDebugger("Autosave")) or - editor.getFileName() is None - ): - return + if scriptName: + fn = scriptName + self.clientType = "Python3" + else: + # run current editor + editor = self.viewmanager.activeWindow() + if editor is None: + return - fn = editor.getFileName() + if ( + not self.viewmanager.checkDirty( + editor, + Preferences.getDebugger("Autosave")) or + editor.getFileName() is None + ): + return + + fn = editor.getFileName() + self.clientType = editor.determineFileType() self.lastStartAction = 3 - self.clientType = editor.determineFileType() - + # save the filename for use by the restart method self.lastDebuggedFile = fn self.restartAct.setEnabled(True) @@ -2069,6 +2144,7 @@ # This moves any previous occurrence of these arguments to the head # of the list. + self.setScriptsHistory(scriptName) self.setArgvHistory(argv) self.setWdHistory(wd) self.setEnvHistory(env) @@ -2106,12 +2182,15 @@ self.stopAct.setEnabled(True) if dlg.clearHistories(): + self.setScriptsHistory("", clearHistories=True) self.setArgvHistory("", clearHistories=True) self.setWdHistory("", clearHistories=True) self.setEnvHistory("", clearHistories=True) self.setMultiprocessNoDebugHistory("", clearHistories=True) elif dlg.historiesModified(): - argvHistory, wdHistory, envHistory, _ = dlg.getHistories() + (scriptsHistory, argvHistory, wdHistory, envHistory, + _) = dlg.getHistories() + self.setScriptsHistory("", history=scriptsHistory) self.setArgvHistory("", history=argvHistory) self.setWdHistory("", history=wdHistory) self.setEnvHistory("", history=envHistory) @@ -2120,21 +2199,24 @@ """ Private slot to handle the debug script action. """ - self.__doDebug(False) + self.doDebug(False) def __debugProject(self): """ Private slot to handle the debug project action. """ self.__compileChangedProjectFiles() - self.__doDebug(True) + self.doDebug(True) - def __doDebug(self, debugProject): + def doDebug(self, debugProject, script=""): """ - Private method to handle the debug actions. + Public method to handle the debug actions. @param debugProject flag indicating debugging the current project (True) or script (False) + @type bool + @param script name of a script (optional) + @type str """ from .StartDialog import StartDialog @@ -2148,6 +2230,14 @@ if debugProject else self.tr("Debug Script") ) + if debugProject: + scriptName = self.project.getMainScript(True) + elif script: + scriptName = script + elif self.lastDebuggedFile: + scriptName = self.lastDebuggedFile + else: + scriptName = "" dlg = StartDialog( cap, self.lastUsedVenvName, self.argvHistory, self.wdHistory, self.envHistory, self.exceptions, self.ui, 0, @@ -2155,10 +2245,12 @@ autoContinue=self.autoContinue, enableMultiprocess=self.enableMultiprocess, multiprocessNoDebugHistory=self.multiprocessNoDebugHistory, - configOverride=self.overrideGlobalConfig) + configOverride=self.overrideGlobalConfig, + forProject=debugProject, scriptName=scriptName, + scriptsList=self.scriptsHistory) if dlg.exec() == QDialog.DialogCode.Accepted: - (lastUsedVenvName, argv, wd, env, exceptions, clearShell, - console) = dlg.getData() + (lastUsedVenvName, scriptName, argv, wd, env, exceptions, + clearShell, console) = dlg.getData() configOverride = dlg.getGlobalOverrideData() (tracePython, autoContinue, enableMultiprocess, multiprocessNoDebug) = dlg.getDebugData() @@ -2193,20 +2285,25 @@ self.lastStartAction = 2 self.clientType = self.project.getProjectLanguage() else: - editor = self.viewmanager.activeWindow() - if editor is None: - return - - if ( - not self.viewmanager.checkDirty( - editor, Preferences.getDebugger("Autosave")) or - editor.getFileName() is None - ): - return + if scriptName: + fn = scriptName + self.clientType = "Python3" + else: + # debug current editor + editor = self.viewmanager.activeWindow() + if editor is None: + return - fn = editor.getFileName() + if ( + not self.viewmanager.checkDirty( + editor, Preferences.getDebugger("Autosave")) or + editor.getFileName() is None + ): + return + + fn = editor.getFileName() + self.clientType = editor.determineFileType() self.lastStartAction = 1 - self.clientType = editor.determineFileType() # save the filename for use by the restart method self.lastDebuggedFile = fn @@ -2217,6 +2314,7 @@ # This moves any previous occurrence of these arguments to the head # of the list. + self.setScriptsHistory(scriptName) self.setArgvHistory(argv) self.setWdHistory(wd) self.setEnvHistory(env) @@ -2282,13 +2380,15 @@ self.stopAct.setEnabled(True) if dlg.clearHistories(): + self.setScriptsHistory("", clearHistories=True) self.setArgvHistory("", clearHistories=True) self.setWdHistory("", clearHistories=True) self.setEnvHistory("", clearHistories=True) self.setMultiprocessNoDebugHistory("", clearHistories=True) elif dlg.historiesModified(): - (argvHistory, wdHistory, envHistory, + (scriptsHistory, argvHistory, wdHistory, envHistory, noDebugHistory) = dlg.getHistories() + self.setScriptsHistory("", history=scriptsHistory) self.setArgvHistory("", history=argvHistory) self.setWdHistory("", history=wdHistory) self.setEnvHistory("", history=envHistory)
--- a/eric7/Debugger/StartDialog.py Sun Aug 22 19:59:18 2021 +0200 +++ b/eric7/Debugger/StartDialog.py Mon Aug 23 17:59:09 2021 +0200 @@ -32,7 +32,7 @@ tracePython=False, autoClearShell=True, autoContinue=True, enableMultiprocess=False, multiprocessNoDebugHistory=None, configOverride=None, - forProject=False, lastUsedScriptName="", scriptsList=None): + forProject=False, scriptName="", scriptsList=None): """ Constructor @@ -82,7 +82,7 @@ @param forProject flag indicating to get the parameters for a run/debug/... action for a project @type bool - @param lastUsedScriptName name of the most recently used script + @param scriptName name of the script @type str @param scriptsList history list of script names @type list of str @@ -132,7 +132,6 @@ self.ui.workdirPicker.setSizeAdjustPolicy( QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon) - # TODO: extend these History actions self.clearButton = self.ui.buttonBox.addButton( self.tr("Clear Histories"), QDialogButtonBox.ButtonRole.ActionRole) self.editButton = self.ui.buttonBox.addButton( @@ -159,6 +158,9 @@ self.ui.globalOverrideGroup.setChecked(configOverride["enable"]) self.ui.redirectCheckBox.setChecked(configOverride["redirect"]) + self.ui.scriptnamePicker.addItems(scriptsList) + self.ui.scriptnamePicker.setText(scriptName) + if dialogType == 0: # start debug dialog enableMultiprocessGlobal = Preferences.getDebugger( "MultiProcessEnabled") @@ -199,16 +201,23 @@ """ Public method to retrieve the data entered into this dialog. - @return a tuple of interpreter, argv, workdir, environment, - exceptions flag, clear interpreter flag and run in console flag - @rtype tuple of (str, str, str, str, bool, bool, bool) + @return a tuple of virtual environment, script name, argv, workdir, + environment, exceptions flag, clear interpreter flag and run in + console flag + @rtype tuple of (str, str, str, str, str, bool, bool, bool) """ cmdLine = self.ui.cmdlineCombo.currentText() workdir = self.ui.workdirPicker.currentText(toNative=False) environment = self.ui.environmentCombo.currentText() venvName = self.ui.venvComboBox.currentText() + scriptName = ( + self.ui.scriptnamePicker.currentText() + if self.ui.scriptnamePicker.isEnabled() else + "" + ) return (venvName, + scriptName, cmdLine, workdir, environment, @@ -288,14 +297,18 @@ cmdLine = self.ui.cmdlineCombo.currentText() workdir = self.ui.workdirPicker.currentText() environment = self.ui.environmentCombo.currentText() + scriptName = self.ui.scriptnamePicker.currentText() self.ui.cmdlineCombo.clear() self.ui.workdirPicker.clear() self.ui.environmentCombo.clear() + self.ui.scriptnamePicker.clear() self.ui.cmdlineCombo.addItem(cmdLine) self.ui.workdirPicker.addItem(workdir) self.ui.environmentCombo.addItem(environment) + self.ui.scriptnamePicker.addItem("") + self.ui.scriptnamePicker.setCurrentText(scriptName) if self.dialogType == 0: noDebugList = self.ui.multiprocessNoDebugCombo.currentText() @@ -308,12 +321,14 @@ """ histories = [ "", + self.tr("Script Name"), self.tr("Command Line"), self.tr("Working Directory"), self.tr("Environment"), ] combos = [ None, + self.ui.scriptnamePicker, self.ui.cmdlineCombo, self.ui.workdirPicker, self.ui.environmentCombo, @@ -330,7 +345,9 @@ if ok and historyKind: history = [] historiesIndex = histories.index(historyKind) - if historiesIndex == 2: + if historiesIndex == 1: + history = self.ui.scriptnamePicker.getPathItems() + elif historiesIndex == 3: history = self.ui.workdirPicker.getPathItems() else: combo = combos[historiesIndex] @@ -372,10 +389,10 @@ """ Public method to get the lists of histories. - @return tuple containing the histories of command line arguments, - working directories, environment settings and no debug programs - lists - @rtype tuple of four list of str + @return tuple containing the histories of script names, command line + arguments, working directories, environment settings and no debug + programs lists + @rtype tuple of five list of str """ noDebugHistory = ( [ @@ -386,6 +403,7 @@ None ) return ( + self.ui.scriptnamePicker.getPathNames(), [self.ui.cmdlineCombo.itemText(index) for index in range( self.ui.cmdlineCombo.count())], self.ui.workdirPicker.getPathItems(),
--- a/eric7/Sessions/SessionFile.py Sun Aug 22 19:59:18 2021 +0200 +++ b/eric7/Sessions/SessionFile.py Mon Aug 23 17:59:09 2021 +0200 @@ -7,6 +7,7 @@ Module implementing a class representing the session JSON file. """ +import contextlib import json import time @@ -145,6 +146,10 @@ # step 5: debug info if self.__isGlobal: + if len(dbg.scriptsHistory): + dbgScriptName = dbg.scriptsHistory[0] + else: + dbgScriptName = "" if len(dbg.argvHistory): dbgCmdline = dbg.argvHistory[0] else: @@ -165,6 +170,7 @@ dbgMultiprocessNoDebug = "" sessionDict["DebugInfo"] = { "VirtualEnv": dbg.lastUsedVenvName, + "ScriptName": dbgScriptName, "CommandLine": dbgCmdline, "WorkingDirectory": dbgWd, "Environment": dbgEnv, @@ -181,6 +187,7 @@ else: sessionDict["DebugInfo"] = { "VirtualEnv": project.dbgVirtualEnv, + "ScriptName": "", "CommandLine": project.dbgCmdline, "WorkingDirectory": project.dbgWd, "Environment": project.dbgEnv, @@ -331,6 +338,8 @@ } dbg.lastUsedVenvName = debugInfoDict["VirtualEnv"] + with contextlib.suppress(KeyError): + dbg.setScriptsHistory(debugInfoDict["ScriptName"]) dbg.setArgvHistory(debugInfoDict["CommandLine"]) dbg.setWdHistory(debugInfoDict["WorkingDirectory"]) dbg.setEnvHistory(debugInfoDict["Environment"])