pyqt-code-editor 0.0.12__tar.gz → 0.0.14__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 (73) hide show
  1. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/PKG-INFO +2 -2
  2. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/__init__.py +1 -1
  3. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/app.py +2 -2
  4. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/check.py +3 -2
  5. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/complete.py +28 -5
  6. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/file_link.py +11 -1
  7. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/syntax_highlighters/languages/generic.py +21 -16
  8. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/widgets/tabbed_editor.py +3 -1
  9. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/readme.md +1 -1
  10. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/COPYING +0 -0
  11. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyproject.toml +0 -0
  12. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/_settings.py +0 -0
  13. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/code_editors/__init__.py +0 -0
  14. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/code_editors/code_editors.py +0 -0
  15. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/code_editors/languages/__init__.py +0 -0
  16. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/code_editors/languages/generic.py +0 -0
  17. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/code_editors/languages/markdown.py +0 -0
  18. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/code_editors/languages/python.py +0 -0
  19. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/code_editors/languages/text.py +0 -0
  20. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/components/__init__.py +0 -0
  21. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/components/editor_panel.py +0 -0
  22. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/components/find_in_files.py +0 -0
  23. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/components/jupyter_console.py +0 -0
  24. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/components/project_explorer.py +0 -0
  25. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/components/settings_panel.py +0 -0
  26. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/components/sigmund.py +0 -0
  27. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/components/workspace_explorer.py +0 -0
  28. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/__init__.py +0 -0
  29. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/auto_indent.py +0 -0
  30. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/auto_pair.py +0 -0
  31. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/base.py +0 -0
  32. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/comment.py +0 -0
  33. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/execute.py +0 -0
  34. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/line_number.py +0 -0
  35. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/python_auto_indent.py +0 -0
  36. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/search_replace.py +0 -0
  37. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/shortcuts.py +0 -0
  38. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/smart_backspace_delete.py +0 -0
  39. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/symbols.py +0 -0
  40. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/theme.py +0 -0
  41. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/widgets/__init__.py +0 -0
  42. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/mixins/zoom.py +0 -0
  43. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/python_utils.py +0 -0
  44. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/signal_router.py +0 -0
  45. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/syntax_highlighters/__init__.py +0 -0
  46. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/syntax_highlighters/languages/__init__.py +0 -0
  47. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/syntax_highlighters/languages/python.py +0 -0
  48. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/syntax_highlighters/syntax_highlighter.py +0 -0
  49. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/themes.py +0 -0
  50. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/utils.py +0 -0
  51. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/watchdog.py +0 -0
  52. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/widgets/__init__.py +0 -0
  53. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/widgets/calltip_widget.py +0 -0
  54. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/widgets/completion_popup.py +0 -0
  55. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/widgets/dock.py +0 -0
  56. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/widgets/quick_open_dialog.py +0 -0
  57. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/widgets/quick_open_file_dialog.py +0 -0
  58. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/widgets/quick_symbol_dialog.py +0 -0
  59. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/widgets/search_replace_frame.py +0 -0
  60. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/widgets/tab_splitter.py +0 -0
  61. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/worker/__init__.py +0 -0
  62. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/worker/languages/__init__.py +0 -0
  63. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/worker/languages/generic.py +0 -0
  64. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/worker/languages/python.py +0 -0
  65. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/worker/manager.py +0 -0
  66. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/worker/process.py +0 -0
  67. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/worker/providers/__init__.py +0 -0
  68. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/worker/providers/codestral.py +0 -0
  69. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/worker/providers/jedi.py +0 -0
  70. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/worker/providers/ruff.py +0 -0
  71. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/worker/providers/sigmund.py +0 -0
  72. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/pyqt_code_editor/worker/providers/symbol.py +0 -0
  73. {pyqt_code_editor-0.0.12 → pyqt_code_editor-0.0.14}/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.12
3
+ Version: 0.0.14
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>
@@ -28,7 +28,7 @@ Copyright 2025 Sebastiaan Mathôt
28
28
 
29
29
  ## About
30
30
 
31
- Sigmund Analyst is a powerful code editor (also: Integrated Development Environment or IDE) focused on AI-assisted data analysis with Python
31
+ Sigmund Analyst is a powerful code editor (also: Integrated Development Environment or IDE) focused on AI-assisted data analysis with Python. It is composed of a set of powerful PyQt/ PySide widgets that can also be used in other applications.
32
32
 
33
33
  Features:
34
34
 
@@ -2,4 +2,4 @@
2
2
 
3
3
  from ._settings import settings
4
4
 
5
- __version__ = '0.0.12'
5
+ __version__ = '0.0.14'
@@ -14,7 +14,7 @@ from .components.jupyter_console import JupyterConsole
14
14
  from .components.workspace_explorer import WorkspaceExplorer
15
15
  from .components.sigmund import Sigmund
16
16
  from .components.settings_panel import SettingsPanel
17
- from . import settings, watchdog
17
+ from . import settings, watchdog, __version__
18
18
  from pyqt_code_editor.signal_router import signal_router
19
19
 
20
20
  logging.basicConfig(level=logging.INFO, force=True)
@@ -29,7 +29,7 @@ class MainWindow(QMainWindow):
29
29
  if not root_path:
30
30
  root_path = settings.current_folder
31
31
 
32
- self.setWindowTitle("Sigmund Analyst")
32
+ self.setWindowTitle(f"Sigmund Analyst {__version__}")
33
33
  # The editor panel provides splittable editor tabs
34
34
  self._editor_panel = EditorPanel()
35
35
  self._editor_panel.open_folder_requested.connect(self._open_folder)
@@ -79,10 +79,11 @@ class Check:
79
79
  symbol = '➜'
80
80
  else:
81
81
  symbol = '❌'
82
- description = '\n'.join([
82
+ description = '\n'.join({
83
83
  str(annotation['code']) + ': ' + annotation['message']
84
+ if annotation['code'] else annotation['message']
84
85
  for annotation in annotations
85
- ])
86
+ })
86
87
  annotation = {
87
88
  'type': 'check',
88
89
  'text': f'{symbol}{line_number}',
@@ -1,6 +1,7 @@
1
1
  import logging
2
2
  from qtpy.QtCore import QTimer, Qt
3
3
  from qtpy.QtGui import QTextCursor
4
+ from qtpy.QtWidgets import QApplication
4
5
  from ..widgets.completion_popup import CompletionPopup
5
6
  from ..widgets.calltip_widget import CalltipWidget
6
7
  from .. import settings
@@ -447,6 +448,7 @@ class Complete:
447
448
  """
448
449
  Display the calltip as a small persistent widget below the cursor line,
449
450
  horizontally aligned with the cursor, so it doesn't obscure typed text.
451
+ If there's not enough space below, show it above the cursor instead.
450
452
  """
451
453
  if self._cm_calltip_widget.isVisible():
452
454
  logger.info("Calltip widget already visible, updating text.")
@@ -460,12 +462,33 @@ class Complete:
460
462
  # the text cursor relative to the editor's viewport.
461
463
  cr = self.cursorRect()
462
464
 
463
- # Convert its bottom-left to global coordinates, then shift down
464
- global_pos = self.mapToGlobal(cr.bottomLeft())
465
- global_pos.setX(global_pos.x() + self.viewportMargins().left())
466
- # global_pos.setY(global_pos.y() + cr.height())
467
-
465
+ # Get the screen geometry to check boundaries
466
+ screen = QApplication.primaryScreen()
467
+ screen_rect = screen.availableGeometry()
468
+
469
+ # Calculate the calltip size
470
+ self._cm_calltip_widget.adjustSize()
471
+ calltip_height = self._cm_calltip_widget.height()
472
+
473
+ # Convert cursor bottom-left to global coordinates
474
+ global_bottom_left = self.mapToGlobal(cr.bottomLeft())
475
+ global_bottom_left.setX(global_bottom_left.x() + self.viewportMargins().left())
476
+
477
+ # Check if calltip would fit below the cursor
478
+ if global_bottom_left.y() + calltip_height > screen_rect.bottom():
479
+ # Not enough space below, show above cursor instead
480
+ global_pos = self.mapToGlobal(cr.topRight())
481
+ global_pos.setX(global_pos.x() + self.viewportMargins().left())
482
+ global_pos.setY(global_pos.y() - calltip_height)
483
+ logger.info("Positioning calltip above cursor due to screen boundaries.")
484
+ else:
485
+ # Enough space below, use bottom-left position
486
+ global_pos = global_bottom_left
487
+ logger.info("Positioning calltip below cursor.")
488
+
489
+ print(f'intended position: {global_pos}')
468
490
  self._cm_calltip_widget.move(global_pos)
491
+ print(f'actual position: {self._cm_calltip_widget.pos()}')
469
492
  self._cm_calltip_widget.show()
470
493
 
471
494
  def closeEvent(self, event):
@@ -165,7 +165,17 @@ class FileLink:
165
165
  if reply == QMessageBox.Yes:
166
166
  # Reload file
167
167
  logger.info("Reloading file after external change.")
168
- self.open_file(changed_path, encoding=self.code_editor_encoding)
168
+ try:
169
+ self.open_file(changed_path,
170
+ encoding=self.code_editor_encoding)
171
+ except FileNotFoundError:
172
+ # When an open file is renamed, it may not exist anymore
173
+ old_path = self.code_editor_file_path
174
+ self.code_editor_file_path = None
175
+ self.file_name_changed.emit(self, old_path,
176
+ self.code_editor_file_path)
177
+ self.set_modified(True)
178
+ return
169
179
  else:
170
180
  logger.info("User chose not to reload. Re-watching file anyway.")
171
181
  # Re-add the file to watcher so we keep listening for future changes
@@ -45,7 +45,8 @@ class SyntaxHighlighter(QSyntaxHighlighter):
45
45
  for token_type, token_text in tokens:
46
46
  length = len(token_text)
47
47
  fmt = self._get_format(token_type)
48
- self.setFormat(index, length, fmt)
48
+ if fmt:
49
+ self.setFormat(index, length, fmt)
49
50
  index += length
50
51
 
51
52
 
@@ -56,21 +57,25 @@ class SyntaxHighlighter(QSyntaxHighlighter):
56
57
  if token_type in self._token_formats:
57
58
  return self._token_formats[token_type]
58
59
 
59
- fmt = QTextCharFormat()
60
- style_defs = self._style.style_for_token(token_type)
61
-
62
- if style_defs['color']:
63
- color_str = style_defs['color']
64
- fmt.setForeground(self._make_brush(color_str))
65
- if style_defs['bgcolor']:
66
- bg_color_str = style_defs['bgcolor']
67
- fmt.setBackground(self._make_brush(bg_color_str))
68
- if style_defs['bold']:
69
- fmt.setFontWeight(QFont.Bold)
70
- if style_defs['italic']:
71
- fmt.setFontItalic(True)
72
- if style_defs['underline']:
73
- fmt.setUnderlineStyle(QTextCharFormat.SingleUnderline)
60
+ try:
61
+ style_defs = self._style.style_for_token(token_type)
62
+ except KeyError:
63
+ logger.error(f"style not found for token type {token_type}")
64
+ fmt = None
65
+ else:
66
+ fmt = QTextCharFormat()
67
+ if style_defs['color']:
68
+ color_str = style_defs['color']
69
+ fmt.setForeground(self._make_brush(color_str))
70
+ if style_defs['bgcolor']:
71
+ bg_color_str = style_defs['bgcolor']
72
+ fmt.setBackground(self._make_brush(bg_color_str))
73
+ if style_defs['bold']:
74
+ fmt.setFontWeight(QFont.Bold)
75
+ if style_defs['italic']:
76
+ fmt.setFontItalic(True)
77
+ if style_defs['underline']:
78
+ fmt.setUnderlineStyle(QTextCharFormat.SingleUnderline)
74
79
 
75
80
  self._token_formats[token_type] = fmt
76
81
  return fmt
@@ -235,10 +235,12 @@ class TabbedEditor(QTabWidget):
235
235
  """
236
236
  from_language = utils.guess_language_from_path(from_path)
237
237
  to_language = utils.guess_language_from_path(to_path)
238
+ index = self.indexOf(editor)
238
239
  if from_language == to_language:
240
+ title = self._synonym(editor.code_editor_file_path)
241
+ self.setTabText(index, title)
239
242
  return
240
243
  logger.info(f'language changed from {from_language} to {to_language}')
241
- index = self.indexOf(editor)
242
244
  self.removeTab(index)
243
245
  self.add_code_editor(to_path, index=index)
244
246
 
@@ -5,7 +5,7 @@ Copyright 2025 Sebastiaan Mathôt
5
5
 
6
6
  ## About
7
7
 
8
- Sigmund Analyst is a powerful code editor (also: Integrated Development Environment or IDE) focused on AI-assisted data analysis with Python
8
+ Sigmund Analyst is a powerful code editor (also: Integrated Development Environment or IDE) focused on AI-assisted data analysis with Python. It is composed of a set of powerful PyQt/ PySide widgets that can also be used in other applications.
9
9
 
10
10
  Features:
11
11