@@ -177,6 +177,10 @@ def _load_ui(self) -> None:
177177 - 1 ,
178178 )
179179
180+ # Permanent status bar label — lives on the right, never overwritten by showMessage()
181+ self ._cursor_label = QLabel ("Ln 1, Col 1 | 0 chars" )
182+ self .ui .statusBar ().addPermanentWidget (self ._cursor_label )
183+
180184 def _setup_file_tree (self ) -> None :
181185 """Configure QFileSystemModel rooted at the user's home directory."""
182186 self ._fs_model = QFileSystemModel (self .ui )
@@ -239,6 +243,9 @@ def _connect_signals(self) -> None:
239243 lambda _ : self ._update_title ()
240244 )
241245
246+ # Cursor position: update permanent label on every cursor move
247+ self ._plain_text_edit .cursorPositionChanged .connect (self ._update_cursor_label )
248+
242249 # Keyboard shortcuts not present in the .ui file.
243250 # (Ctrl+S/O/Q/Shift+S are already wired via QAction shortcuts in main_window.ui.)
244251 # ApplicationShortcut context: fires even when a child widget holds focus,
@@ -378,6 +385,14 @@ def _update_title(self) -> None:
378385 suffix = " *" if modified else ""
379386 self .ui .setWindowTitle (f"TextTools — { name } { suffix } " if name else "TextTools" )
380387
388+ def _update_cursor_label (self ) -> None :
389+ """Update the permanent cursor position label in the status bar."""
390+ cursor = self ._plain_text_edit .textCursor ()
391+ line = cursor .blockNumber () + 1
392+ col = cursor .columnNumber () + 1
393+ chars = len (self ._plain_text_edit .toPlainText ())
394+ self ._cursor_label .setText (f"Ln { line } , Col { col } | { chars :,} chars" )
395+
381396 # ------------------------------------------ ViewModel signal handlers
382397
383398 def _on_document_loaded (self , content : str ) -> None :
0 commit comments