pyqt-code-editor 0.0.55__tar.gz → 0.0.56__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/PKG-INFO +16 -3
  2. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/__init__.py +1 -1
  3. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/app.py +20 -0
  4. pyqt_code_editor-0.0.56/pyqt_code_editor/components/jupyter_console/__init__.py +1 -0
  5. pyqt_code_editor-0.0.56/pyqt_code_editor/components/jupyter_console/jupyter_console.py +198 -0
  6. pyqt_code_editor-0.0.55/pyqt_code_editor/components/jupyter_console.py → pyqt_code_editor-0.0.56/pyqt_code_editor/components/jupyter_console/jupyter_console_tab.py +84 -261
  7. pyqt_code_editor-0.0.56/pyqt_code_editor/components/jupyter_console/kernel_spec_manager.py +21 -0
  8. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/components/sigmund/sigmund_analyst_widget.py +36 -9
  9. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/readme.md +15 -2
  10. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/COPYING +0 -0
  11. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyproject.toml +0 -0
  12. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/_settings.py +0 -0
  13. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/code_editors/__init__.py +0 -0
  14. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/code_editors/code_editors.py +0 -0
  15. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/code_editors/languages/__init__.py +0 -0
  16. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/code_editors/languages/generic.py +0 -0
  17. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/code_editors/languages/javascript.py +0 -0
  18. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/code_editors/languages/markdown.py +0 -0
  19. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/code_editors/languages/python.py +0 -0
  20. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/code_editors/languages/text.py +0 -0
  21. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/components/__init__.py +0 -0
  22. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/components/editor_panel.py +0 -0
  23. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/components/find_in_files.py +0 -0
  24. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/components/project_explorer.py +0 -0
  25. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/components/settings_panel.py +0 -0
  26. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/components/sigmund/__init__.py +0 -0
  27. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/components/sigmund/confirm_run_code_dialog.py +0 -0
  28. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/components/sigmund/editor_workspace.py +0 -0
  29. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/components/sigmund/sigmund.py +0 -0
  30. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/components/sigmund/sigmund_analyst_chat_widget.py +0 -0
  31. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/components/workspace_explorer.py +0 -0
  32. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/environment_manager.py +0 -0
  33. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/__init__.py +0 -0
  34. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/auto_indent.py +0 -0
  35. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/auto_pair.py +0 -0
  36. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/base.py +0 -0
  37. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/check.py +0 -0
  38. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/comment.py +0 -0
  39. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/complete.py +0 -0
  40. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/execute.py +0 -0
  41. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/file_link.py +0 -0
  42. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/highlight_matching_brackets.py +0 -0
  43. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/line_number.py +0 -0
  44. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/merge_undo_actions.py +0 -0
  45. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/python_auto_indent.py +0 -0
  46. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/search_replace.py +0 -0
  47. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/shortcuts.py +0 -0
  48. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/smart_backspace_delete.py +0 -0
  49. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/symbols.py +0 -0
  50. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/theme.py +0 -0
  51. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/widgets/__init__.py +0 -0
  52. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/mixins/zoom.py +0 -0
  53. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/sigmund-analyst.png +0 -0
  54. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/signal_router.py +0 -0
  55. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/syntax_highlighters/__init__.py +0 -0
  56. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/syntax_highlighters/languages/__init__.py +0 -0
  57. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/syntax_highlighters/languages/generic.py +0 -0
  58. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/syntax_highlighters/languages/python.py +0 -0
  59. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/syntax_highlighters/syntax_highlighter.py +0 -0
  60. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/themes.py +0 -0
  61. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/utils/__init__.py +0 -0
  62. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/utils/languages/__init__.py +0 -0
  63. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/utils/languages/python/__init__.py +0 -0
  64. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/utils/languages/python/_auto_indent.py +0 -0
  65. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/utils/languages/python/_extract_cells.py +0 -0
  66. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/utils/languages/python/_mask_str_in_code.py +0 -0
  67. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/watchdog.py +0 -0
  68. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/widgets/__init__.py +0 -0
  69. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/widgets/calltip_widget.py +0 -0
  70. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/widgets/completion_popup.py +0 -0
  71. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/widgets/dock.py +0 -0
  72. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/widgets/quick_open_dialog.py +0 -0
  73. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/widgets/quick_open_file_dialog.py +0 -0
  74. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/widgets/quick_symbol_dialog.py +0 -0
  75. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/widgets/search_replace_frame.py +0 -0
  76. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/widgets/tab_splitter.py +0 -0
  77. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/widgets/tabbed_editor.py +0 -0
  78. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/worker/__init__.py +0 -0
  79. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/worker/languages/__init__.py +0 -0
  80. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/worker/languages/generic.py +0 -0
  81. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/worker/languages/python.py +0 -0
  82. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/worker/manager.py +0 -0
  83. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/worker/process.py +0 -0
  84. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/worker/providers/__init__.py +0 -0
  85. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/worker/providers/codestral.py +0 -0
  86. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/worker/providers/jedi.py +0 -0
  87. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/worker/providers/ruff.py +0 -0
  88. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/worker/providers/sigmund.py +0 -0
  89. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/worker/providers/symbol.py +0 -0
  90. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/worker/providers/tree_sitter.py +0 -0
  91. {pyqt_code_editor-0.0.55 → pyqt_code_editor-0.0.56}/pyqt_code_editor/worker/settings.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyqt_code_editor
3
- Version: 0.0.55
3
+ Version: 0.0.56
4
4
  Summary: Fully featured code-editor widgets for PyQt
5
5
  Keywords: code editor,pyqt,ide
6
6
  Author-email: Sebastiaan Mathôt <s.mathot@cogsci.nl>
@@ -30,10 +30,15 @@ Requires-Dist: tree-sitter-yaml
30
30
  Requires-Dist: ruff
31
31
  Project-URL: Source, https://github.com/open-cogsci/sigmund-analyst
32
32
 
33
- # PyQt Code Editor / Sigmund Analyst
33
+ # Sigmund Analyst (PyQt Code Editor)
34
34
 
35
35
  Copyright 2025-2026 Sebastiaan Mathôt
36
36
 
37
+ - [About](#about)
38
+ - [AI integration](#ai-integration)
39
+ - [Installation](#installation)
40
+ - [License](#license)
41
+
37
42
 
38
43
  ## About
39
44
 
@@ -68,7 +73,15 @@ As-you-type code suggestions are provided by Mistral Codestral. To activate Mist
68
73
 
69
74
  ## Installation
70
75
 
71
- ### Linux installer
76
+
77
+ ### Windows
78
+
79
+ The easiest way to install Sigmund Analys on Windows is to install OpenSesame, which include Sigmund Analyst:
80
+
81
+ - <https://osdoc.cogsci.nl/download/>
82
+
83
+
84
+ ### Linux/ Ubuntu
72
85
 
73
86
  The easiest way to install Sigmund Analyst on Linux is to download and run the installer script. This will create a Virtual Environment, pip install Sigmund Analyst and all dependencies into this environment, and add a Desktop file to your system to easily start Sigmund Analyst. To upgrade, simply run the script again.
74
87
 
@@ -2,4 +2,4 @@
2
2
 
3
3
  from ._settings import settings
4
4
 
5
- __version__ = '0.0.55'
5
+ __version__ = '0.0.56'
@@ -456,10 +456,30 @@ class SigmundAnalyst(QMainWindow):
456
456
  )
457
457
  dlg.exec_()
458
458
 
459
+
460
+ def handle_output(text, content):
461
+ print('***')
462
+ print(text)
463
+ # print('---')
464
+ # for part in content['parts']:
465
+ # print(part)
466
+ # print(content)
467
+ print('***')
468
+
459
469
 
460
470
  def launch_app():
461
471
  app = QApplication(sys.argv)
462
472
  settings.set_font_family()
463
473
  window = SigmundAnalyst()
464
474
  window.show()
475
+ window._jupyter_console.execution_complete.connect(handle_output)
476
+ window._toggle_dock_widget(window._jupyter_console)
477
+ # window._jupyter_console.execute_code('''
478
+ # from matplotlib import pyplot as plt
479
+ # plt.plot([1,2,3,4])
480
+ # plt.show()
481
+ # print(10)
482
+ # # int('x')
483
+ # 11
484
+ # ''')
465
485
  sys.exit(app.exec_())
@@ -0,0 +1 @@
1
+ from .jupyter_console import JupyterConsole
@@ -0,0 +1,198 @@
1
+ from qtpy.QtWidgets import (QTabWidget, QWidget, QToolButton, QMenu,
2
+ QAction, QHBoxLayout)
3
+ from qtpy.QtCore import Signal
4
+ import qtawesome as qta
5
+ import sys
6
+ import logging
7
+ from ...environment_manager import environment_manager
8
+ from ...themes import HORIZONTAL_SPACING
9
+ from ...widgets import Dock
10
+ from .jupyter_console_tab import JupyterConsoleTab
11
+ from .kernel_spec_manager import HomeAwareKernelSpecManager
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ class JupyterConsole(Dock):
16
+ """Dockable widget containing tabbed Jupyter consoles"""
17
+
18
+ execution_complete = Signal(str, object)
19
+ workspace_updated = Signal(dict)
20
+
21
+ def __init__(self, parent=None, default_kernel='python3'):
22
+ super().__init__("Jupyter Console", parent)
23
+ self.setObjectName('jupyter_console')
24
+ self.default_kernel = default_kernel
25
+
26
+ # ---------------------------------------------------------------------
27
+ # Kernel cache
28
+ # ---------------------------------------------------------------------
29
+ self.available_kernels = {} # will be filled by refresh_kernel_menu()
30
+
31
+ # ---------------------------------------------------------------------
32
+ # UI setup
33
+ # ---------------------------------------------------------------------
34
+ self.tab_widget = QTabWidget()
35
+ self.tab_widget.setTabsClosable(True)
36
+ self.tab_widget.tabCloseRequested.connect(self.close_tab)
37
+ self.tab_widget.currentChanged.connect(self._on_tab_changed)
38
+ self.setWidget(self.tab_widget)
39
+
40
+ # Corner widget with buttons
41
+ corner_widget = QWidget()
42
+ corner_layout = QHBoxLayout(corner_widget)
43
+ corner_layout.setContentsMargins(0, 0, 0, 0)
44
+ corner_layout.setSpacing(HORIZONTAL_SPACING)
45
+
46
+ self.kernel_button = QToolButton()
47
+ self.kernel_button.setIcon(qta.icon('mdi6.plus'))
48
+ self.kernel_button.setToolTip("Add new kernel")
49
+ self.kernel_button.setPopupMode(QToolButton.InstantPopup)
50
+ self.kernel_button.setAutoRaise(True)
51
+ corner_layout.addWidget(self.kernel_button)
52
+
53
+ self.restart_button = QToolButton()
54
+ self.restart_button.setIcon(qta.icon('mdi6.restart'))
55
+ self.restart_button.setToolTip("Restart current kernel")
56
+ self.restart_button.clicked.connect(self.restart_current_kernel)
57
+ self.restart_button.setAutoRaise(True)
58
+ corner_layout.addWidget(self.restart_button)
59
+
60
+ self.interrupt_button = QToolButton()
61
+ self.interrupt_button.setIcon(qta.icon('mdi6.stop'))
62
+ self.interrupt_button.setToolTip("Interrupt current kernel (Ctrl+C)")
63
+ self.interrupt_button.clicked.connect(self.interrupt_current_kernel)
64
+ self.interrupt_button.setAutoRaise(True)
65
+ corner_layout.addWidget(self.interrupt_button)
66
+
67
+ self.tab_widget.setCornerWidget(corner_widget)
68
+
69
+ # ---------------------------------------------------------------------
70
+ # Kernel menu
71
+ # ---------------------------------------------------------------------
72
+ self.kernel_menu = QMenu(self.kernel_button)
73
+ self.kernel_button.setMenu(self.kernel_menu)
74
+ self.refresh_kernel_menu()
75
+
76
+ # ---------------------------------------------------------------------
77
+ # Start with a default kernel
78
+ # ---------------------------------------------------------------------
79
+ self.add_console_tab(self.default_kernel)
80
+
81
+ # -------------------------------------------------------------------------
82
+ # Helper methods
83
+ # -------------------------------------------------------------------------
84
+ def _on_tab_changed(self, index):
85
+ console_tab = self.tab_widget.widget(index)
86
+ if console_tab:
87
+ console_tab.update_workspace()
88
+ spec = self.available_kernels.get(console_tab.kernel_name, None)
89
+ if spec:
90
+ python_executable = spec['spec']['argv'][0]
91
+ else:
92
+ python_executable = sys.executable
93
+ environment_manager.set_environment(console_tab.kernel_name,
94
+ python_executable,
95
+ 'python')
96
+
97
+ # -------------------------------------------------------------------------
98
+ # Kernel handling
99
+ # -------------------------------------------------------------------------
100
+ def refresh_kernel_menu(self):
101
+ """Refresh the list of available kernels and rebuild the kernel menu."""
102
+ self.kernel_menu.clear()
103
+
104
+ # Get available kernelspecs
105
+ kernel_spec_manager = HomeAwareKernelSpecManager()
106
+ self.available_kernels = kernel_spec_manager.get_all_specs()
107
+ self.fallback_kernel = list(self.available_kernels.keys())[0]
108
+ for spec_name, spec in self.available_kernels.items():
109
+ display_name = spec['spec']['display_name']
110
+ action = QAction(display_name, self)
111
+ action.setData(spec_name)
112
+ action.triggered.connect(self.kernel_menu_triggered)
113
+ self.kernel_menu.addAction(action)
114
+
115
+ def kernel_menu_triggered(self):
116
+ action = self.sender()
117
+ if action:
118
+ self.add_console_tab(action.data())
119
+
120
+ def add_console_tab(self, kernel_name):
121
+ """Add a new console tab with the specified kernel.
122
+ Falls back to the first available kernel if the requested one is invalid.
123
+ """
124
+ if kernel_name not in self.available_kernels:
125
+ if self.available_kernels:
126
+ logger.warning(
127
+ "Requested kernel '%s' not found. "
128
+ "Falling back to '%s'.", kernel_name, self.fallback_kernel
129
+ )
130
+ kernel_name = self.fallback_kernel
131
+ else:
132
+ logger.error("No available kernels found. Cannot create console tab.")
133
+ return None
134
+
135
+ console_tab = JupyterConsoleTab(kernel_name=kernel_name, parent=self)
136
+ console_tab.execution_complete.connect(self.handle_execution_complete)
137
+ console_tab.workspace_updated.connect(self.handle_workspace_updated)
138
+ index = self.tab_widget.addTab(console_tab, kernel_name)
139
+ self.tab_widget.setCurrentIndex(index)
140
+ return console_tab
141
+
142
+ # -------------------------------------------------------------------------
143
+ # Tab / kernel management
144
+ # -------------------------------------------------------------------------
145
+ def close_tab(self, index):
146
+ widget = self.tab_widget.widget(index)
147
+ if widget:
148
+ widget.shutdown_kernel()
149
+ self.tab_widget.removeTab(index)
150
+ if self.tab_widget.count() == 0:
151
+ self.add_console_tab(self.default_kernel)
152
+
153
+ def get_current_console(self):
154
+ return self.tab_widget.currentWidget()
155
+
156
+ def restart_current_kernel(self):
157
+ console = self.get_current_console()
158
+ if console:
159
+ logger.info("Restarting current kernel")
160
+ if console.restart_kernel():
161
+ logger.info("Kernel restart initiated")
162
+ else:
163
+ logger.warning("Failed to restart kernel")
164
+
165
+ def interrupt_current_kernel(self):
166
+ console = self.get_current_console()
167
+ if console:
168
+ logger.info("Interrupting current kernel")
169
+ if console.interrupt_kernel():
170
+ logger.info("Interrupt signal sent to kernel")
171
+ else:
172
+ logger.warning("Failed to interrupt kernel")
173
+
174
+ # -------------------------------------------------------------------------
175
+ # Execution helpers
176
+ # -------------------------------------------------------------------------
177
+ def execute_code(self, code, silent=False):
178
+ console = self.get_current_console()
179
+ if console:
180
+ (console.execute_silently if silent else console.execute_code)(code)
181
+
182
+ def execute_file(self, filepath):
183
+ console = self.get_current_console()
184
+ if console:
185
+ console.execute_file(filepath)
186
+
187
+ def change_directory(self, directory):
188
+ console = self.get_current_console()
189
+ return console.change_directory(directory) if console else False
190
+
191
+ # -------------------------------------------------------------------------
192
+ # Signals
193
+ # -------------------------------------------------------------------------
194
+ def handle_execution_complete(self, output, result):
195
+ self.execution_complete.emit(output, result)
196
+
197
+ def handle_workspace_updated(self, data):
198
+ self.workspace_updated.emit(data)