side-vim 0.1.0__tar.gz → 0.1.1__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.
- {side_vim-0.1.0 → side_vim-0.1.1}/PKG-INFO +1 -18
- {side_vim-0.1.0 → side_vim-0.1.1}/README.md +0 -17
- {side_vim-0.1.0 → side_vim-0.1.1}/pyproject.toml +1 -1
- {side_vim-0.1.0 → side_vim-0.1.1}/pyproject.toml.orig +1 -1
- {side_vim-0.1.0 → side_vim-0.1.1}/side_vim/vim.py +32 -19
- {side_vim-0.1.0 → side_vim-0.1.1}/LICENSE +0 -0
- {side_vim-0.1.0 → side_vim-0.1.1}/side_vim/__init__.py +0 -0
- {side_vim-0.1.0 → side_vim-0.1.1}/side_vim/__main__.py +0 -0
- {side_vim-0.1.0 → side_vim-0.1.1}/side_vim/_unicode_data.py +0 -0
- {side_vim-0.1.0 → side_vim-0.1.1}/side_vim/caret.py +0 -0
- {side_vim-0.1.0 → side_vim-0.1.1}/side_vim/edits.py +0 -0
- {side_vim-0.1.0 → side_vim-0.1.1}/side_vim/keys.py +0 -0
- {side_vim-0.1.0 → side_vim-0.1.1}/side_vim/layouts.py +0 -0
- {side_vim-0.1.0 → side_vim-0.1.1}/side_vim/mode.py +0 -0
- {side_vim-0.1.0 → side_vim-0.1.1}/side_vim/motions.py +0 -0
- {side_vim-0.1.0 → side_vim-0.1.1}/side_vim/notation.py +0 -0
- {side_vim-0.1.0 → side_vim-0.1.1}/side_vim/parser.py +0 -0
- {side_vim-0.1.0 → side_vim-0.1.1}/side_vim/scroll.py +0 -0
- {side_vim-0.1.0 → side_vim-0.1.1}/side_vim/search.py +0 -0
- {side_vim-0.1.0 → side_vim-0.1.1}/side_vim/text.py +0 -0
- {side_vim-0.1.0 → side_vim-0.1.1}/side_vim/unicode.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: side-vim
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: Vim mode for PySide6's QPlainTextEdit
|
|
5
5
|
Author: sprytnyk.dev
|
|
6
6
|
License-Expression: MIT
|
|
@@ -191,22 +191,5 @@ Set these up by hand before the first tag:
|
|
|
191
191
|
goes into GitHub. See the [PyPI setup guide](https://docs.pypi.org/trusted-publishers/creating-a-project-through-oidc/)
|
|
192
192
|
and [GitHub approval guide](https://docs.github.com/en/actions/how-tos/deploy/configure-and-manage-deployments/review-deployments).
|
|
193
193
|
|
|
194
|
-
For each release:
|
|
195
|
-
|
|
196
|
-
1. On `main`, check the README and run `make check`. If key handling changed,
|
|
197
|
-
run `make mac-keys` on a Mac.
|
|
198
|
-
2. Run `uv version X.Y.Z`. Write the dated `CHANGELOG.md` section from the commits
|
|
199
|
-
since the previous release, using only sections with entries: Breaking,
|
|
200
|
-
Highlights, Fixes, Changes and Removed. Review it before committing.
|
|
201
|
-
3. Build and test the wheel in a temporary environment. Make the signed
|
|
202
|
-
`chore(release): vX.Y.Z` commit and signed `vX.Y.Z` tag with key
|
|
203
|
-
`0xC00C0F0D647BD3C6`. Push `main` and that tag to `origin`.
|
|
204
|
-
4. The release workflow runs CI, checks that the tag matches the package version,
|
|
205
|
-
and builds the wheel and source distribution. Review the run and approve the
|
|
206
|
-
`pypi` job. It publishes those files using
|
|
207
|
-
[uv trusted publishing](https://docs.astral.sh/uv/guides/integration/github/#publishing-to-pypi).
|
|
208
|
-
5. Confirm the version is on PyPI, then create a GitHub release using just the
|
|
209
|
-
changelog section as its notes. Attach no files.
|
|
210
|
-
|
|
211
194
|
The project [release skill](https://github.com/sprytnyk/side-vim/blob/main/.claude/skills/release/SKILL.md)
|
|
212
195
|
has the command sequence and approval points.
|
|
@@ -179,22 +179,5 @@ Set these up by hand before the first tag:
|
|
|
179
179
|
goes into GitHub. See the [PyPI setup guide](https://docs.pypi.org/trusted-publishers/creating-a-project-through-oidc/)
|
|
180
180
|
and [GitHub approval guide](https://docs.github.com/en/actions/how-tos/deploy/configure-and-manage-deployments/review-deployments).
|
|
181
181
|
|
|
182
|
-
For each release:
|
|
183
|
-
|
|
184
|
-
1. On `main`, check the README and run `make check`. If key handling changed,
|
|
185
|
-
run `make mac-keys` on a Mac.
|
|
186
|
-
2. Run `uv version X.Y.Z`. Write the dated `CHANGELOG.md` section from the commits
|
|
187
|
-
since the previous release, using only sections with entries: Breaking,
|
|
188
|
-
Highlights, Fixes, Changes and Removed. Review it before committing.
|
|
189
|
-
3. Build and test the wheel in a temporary environment. Make the signed
|
|
190
|
-
`chore(release): vX.Y.Z` commit and signed `vX.Y.Z` tag with key
|
|
191
|
-
`0xC00C0F0D647BD3C6`. Push `main` and that tag to `origin`.
|
|
192
|
-
4. The release workflow runs CI, checks that the tag matches the package version,
|
|
193
|
-
and builds the wheel and source distribution. Review the run and approve the
|
|
194
|
-
`pypi` job. It publishes those files using
|
|
195
|
-
[uv trusted publishing](https://docs.astral.sh/uv/guides/integration/github/#publishing-to-pypi).
|
|
196
|
-
5. Confirm the version is on PyPI, then create a GitHub release using just the
|
|
197
|
-
changelog section as its notes. Attach no files.
|
|
198
|
-
|
|
199
182
|
The project [release skill](https://github.com/sprytnyk/side-vim/blob/main/.claude/skills/release/SKILL.md)
|
|
200
183
|
has the command sequence and approval points.
|
|
@@ -177,6 +177,7 @@ class VimMode(QObject):
|
|
|
177
177
|
self._want_at: tuple[int, Version] | None = None
|
|
178
178
|
self._block_on = False
|
|
179
179
|
self._plain_width = editor.cursorWidth()
|
|
180
|
+
self._plain_overwrite = editor.overwriteMode()
|
|
180
181
|
# The undo steps vim knows, newest last: Qt's steps from the top of the
|
|
181
182
|
# document's stack, and the few only vim has. Valid while _version() is still
|
|
182
183
|
# _synced.
|
|
@@ -274,7 +275,7 @@ class VimMode(QObject):
|
|
|
274
275
|
self._set_mode(Mode.NORMAL)
|
|
275
276
|
self._on_cursor_moved()
|
|
276
277
|
else:
|
|
277
|
-
self.
|
|
278
|
+
self._update_cursor()
|
|
278
279
|
|
|
279
280
|
def detach(self) -> None:
|
|
280
281
|
"""Take vim off the editor for good."""
|
|
@@ -325,12 +326,12 @@ class VimMode(QObject):
|
|
|
325
326
|
self._saved_flags = None
|
|
326
327
|
if self._mode is Mode.INSERT and self._read_only():
|
|
327
328
|
self._leave_insert()
|
|
328
|
-
self.
|
|
329
|
+
self._update_cursor()
|
|
329
330
|
if kind in (QEvent.Type.FocusIn, QEvent.Type.FocusOut):
|
|
330
331
|
self._caret.restart_blink()
|
|
331
332
|
if kind == QEvent.Type.FontChange:
|
|
332
333
|
# the editor lays out the text again first
|
|
333
|
-
QTimer.singleShot(0, self, self.
|
|
334
|
+
QTimer.singleShot(0, self, self._update_cursor)
|
|
334
335
|
return False
|
|
335
336
|
|
|
336
337
|
def _token(self, event: QKeyEvent) -> str | None:
|
|
@@ -452,7 +453,7 @@ class VimMode(QObject):
|
|
|
452
453
|
cursor = self._editor.textCursor()
|
|
453
454
|
cursor.setPosition(self._to_qt(lines, pos))
|
|
454
455
|
self._editor.setTextCursor(cursor)
|
|
455
|
-
self.
|
|
456
|
+
self._update_cursor()
|
|
456
457
|
|
|
457
458
|
def _put(self, lines: Lines, pos: Pos) -> None:
|
|
458
459
|
"""Go to pos, kept on a character of a line that exists, as Normal mode wants."""
|
|
@@ -602,7 +603,7 @@ class VimMode(QObject):
|
|
|
602
603
|
if self._mouse_down:
|
|
603
604
|
self._adopt_selection(cursor)
|
|
604
605
|
else:
|
|
605
|
-
self.
|
|
606
|
+
self._update_cursor()
|
|
606
607
|
return
|
|
607
608
|
lines = self._lines()
|
|
608
609
|
pos = self._from_qt(lines, cursor.position())
|
|
@@ -610,32 +611,44 @@ class VimMode(QObject):
|
|
|
610
611
|
if self._to_qt(lines, fixed) != cursor.position():
|
|
611
612
|
self._go(lines, fixed)
|
|
612
613
|
else:
|
|
613
|
-
self.
|
|
614
|
+
self._update_cursor()
|
|
614
615
|
|
|
615
|
-
def
|
|
616
|
+
def _update_cursor(self) -> None:
|
|
616
617
|
"""A block cursor in Normal mode, the editor's own cursor in Insert mode. In
|
|
617
|
-
Visual mode the editor's cursor is hidden and the Caret draws vim's.
|
|
618
|
+
Visual mode the editor's cursor is hidden and the Caret draws vim's.
|
|
619
|
+
|
|
620
|
+
Qt draws a wide cursor by inverting what's under it, so a dim character, like a
|
|
621
|
+
comment, stays dim on the block. In overwrite mode Qt draws the character in
|
|
622
|
+
the background colour on the block, as vim does, so overwrite mode is on
|
|
623
|
+
outside Insert mode. Typing doesn't change, since vim takes the keys there."""
|
|
618
624
|
visual = self._enabled and self._mode in VISUAL_MODES and self._end is not None
|
|
619
625
|
if self._enabled and self._mode is not Mode.INSERT:
|
|
620
626
|
if not self._block_on:
|
|
621
627
|
self._plain_width = self._editor.cursorWidth()
|
|
628
|
+
self._plain_overwrite = self._editor.overwriteMode()
|
|
622
629
|
self._block_on = True
|
|
623
|
-
|
|
630
|
+
width = 0 if visual else char_width(self._editor, self._position())
|
|
631
|
+
self._set_cursor(width, overwrite=True)
|
|
624
632
|
elif self._block_on:
|
|
625
633
|
self._block_on = False
|
|
626
|
-
self.
|
|
634
|
+
self._set_cursor(self._plain_width, self._plain_overwrite)
|
|
627
635
|
self._hide_editor_cursor(visual)
|
|
628
636
|
# a read-only editor draws no cursor of its own
|
|
629
637
|
no_cursor = not self._editor.textInteractionFlags() & DRAWS_CURSOR
|
|
630
638
|
normal = self._enabled and self._mode is Mode.NORMAL and no_cursor
|
|
631
639
|
self._caret.show_at(self._position() if visual or normal else None)
|
|
632
640
|
|
|
633
|
-
def
|
|
634
|
-
"""Qt repaints only the cursor's new area when its width changes,
|
|
635
|
-
turning into Insert mode's line left
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
641
|
+
def _set_cursor(self, width: int, overwrite: bool) -> None:
|
|
642
|
+
"""Qt repaints only the cursor's new area when its width changes, and nothing
|
|
643
|
+
when overwrite mode changes, so the block turning into Insert mode's line left
|
|
644
|
+
the rest of the block on screen. Both areas are repainted here; the old one is
|
|
645
|
+
read first, since overwrite mode makes it wider."""
|
|
646
|
+
editor = self._editor
|
|
647
|
+
if (editor.cursorWidth(), editor.overwriteMode()) != (width, overwrite):
|
|
648
|
+
editor.viewport().update(editor.cursorRect())
|
|
649
|
+
editor.setOverwriteMode(overwrite)
|
|
650
|
+
editor.setCursorWidth(width)
|
|
651
|
+
editor.viewport().update(editor.cursorRect())
|
|
639
652
|
|
|
640
653
|
def _hide_editor_cursor(self, hide: bool) -> None:
|
|
641
654
|
"""Width 0 doesn't hide the editor's cursor everywhere: on a screen scaled by a
|
|
@@ -815,7 +828,7 @@ class VimMode(QObject):
|
|
|
815
828
|
self._editor.setTextCursor(cursor)
|
|
816
829
|
finally:
|
|
817
830
|
self._busy = False
|
|
818
|
-
self.
|
|
831
|
+
self._update_cursor()
|
|
819
832
|
|
|
820
833
|
def _adopt_selection(self, cursor: QTextCursor) -> None:
|
|
821
834
|
"""Visual mode for a selection the mouse or the app made: the same characters,
|
|
@@ -847,7 +860,7 @@ class VimMode(QObject):
|
|
|
847
860
|
and not self._mouse_down
|
|
848
861
|
)
|
|
849
862
|
if valid and self._qt_selection(self._lines()) == (cursor.anchor(), cursor.position()):
|
|
850
|
-
self.
|
|
863
|
+
self._update_cursor()
|
|
851
864
|
elif cursor.hasSelection():
|
|
852
865
|
self._adopt_selection(cursor)
|
|
853
866
|
else:
|
|
@@ -1329,7 +1342,7 @@ class VimMode(QObject):
|
|
|
1329
1342
|
def _set_mode(self, mode: Mode) -> None:
|
|
1330
1343
|
changed = mode is not self._mode
|
|
1331
1344
|
self._mode = mode
|
|
1332
|
-
self.
|
|
1345
|
+
self._update_cursor()
|
|
1333
1346
|
if changed:
|
|
1334
1347
|
self.mode_changed.emit(mode)
|
|
1335
1348
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|