Commit graph

105 commits

Author SHA1 Message Date
vrubelroman
e4514028ef fix: PKGBUILD pkgver was still pinned to 0.2.6
All checks were successful
CI / test (push) Successful in 9m41s
grep for the version bump missed this file since it has no extension.
makepkg pulls sources from the tag named after pkgver, so Arch builds
were still fetching v0.2.6 despite main/the v0.2.7 tag being current.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-03 21:14:47 +00:00
vrubelroman
0ab59ad7c3 chore: bump version to v0.2.7
Some checks failed
CI / test (push) Has been cancelled
Release / release (push) Failing after 2s
Release / test (push) Successful in 9m39s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-03 21:06:34 +00:00
vrubelroman
135f5e0d19 fix: harden copy/move/delete transfers, add CI, dead code cleanup
All checks were successful
CI / test (push) Successful in 10m0s
Audited every copy/move/delete path (local, remote same-host, cross-host)
and fixed:

- Shell command injection in same-host remote cp/mv (unescaped paths
  interpolated into exec strings); added remote.ShellQuote.
- Missing guard against copying/moving a directory into its own
  subdirectory, locally and on same-host remote transfers (unbounded
  recursion / disk fill). New regression tests in ops_test.go.
- Remote-to-remote same-path file copy silently truncating the source
  file via Create() before it finished being read.
- Overwrite warning ("N existing target(s)") never shown for remote
  destinations, only local ones.
- Remote same-host server-side cp never advancing the file-done counter
  (waited on -v output that was never requested).
- Removed a dead "plan-then-confirm" subsystem (5 functions, 2 message
  types, 2 unreachable Update() cases) superseded by the current design.
- Remote delete (SFTP) now runs as a cancellable job with the same
  progress modal as local delete, instead of a single blocking call.

Also add a CI workflow that runs build/vet/test on every push and PR,
since previously they only ran on release tags.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-03 20:36:00 +00:00
vrubelroman
c15ade247a fix: verify SSH host keys, support ssh-agent, fix remote dir walk bugs
- Replace ssh.InsecureIgnoreHostKey() with TOFU verification against
  ~/.ssh/known_hosts (accept-new for unknown hosts, hard reject on a
  changed key) to close a MITM hole on every SFTP connection.
- Actually connect to a running ssh-agent (SSH_AUTH_SOCK) for auth
  instead of only scanning default key files on disk; give a clear
  error when an explicit IdentityFile is passphrase-protected.
- Fix SSHClient.walk()/DirectorySize: the internal filepathSkipDir
  sentinel leaked out as a real error on stat/ReadDir failures instead
  of being swallowed, aborting size calculation on the first
  unreadable subdirectory instead of skipping it.
- Skip symlink-to-directory entries in remote directory copies instead
  of failing the whole transfer trying to Open() them as regular files.
- Consolidate 5 duplicated sudo-aware home-dir lookups into
  internal/homedir, adding a missing os.Geteuid()==0 check before
  trusting SUDO_USER.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-03 15:31:32 +00:00
vrubelroman
3cf9582147 chore: remove accidentally committed release tarball from repo
src/vcom-0.2.5/ and its .tar.gz were a stale extracted release
snapshot (including its own vendor/ tree) checked in by mistake in
1577ee5. Not referenced by any build script; just repo bloat.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-03 15:31:17 +00:00
vrubelroman
9c5ad363a4 feat: unified install script, RPM packaging, bump to v0.2.6 2026-05-15 09:45:24 +03:00
vrubelroman
44db42da1e fix: text-input modals (mkdir/rename/SSH) confirm only on Enter, not y 2026-05-14 01:04:26 +03:00
vrubelroman
1577ee5525 fix: use Recommends instead of Depends for ueberzugpp in deb, add Ubuntu install guide 2026-05-13 13:47:38 +03:00
vrubelroman
915b695e88 fix: remaining 0.2.4 → 0.2.5 in deb filenames 2026-05-13 13:41:39 +03:00
vrubelroman
a468e33e82 chore: bump version to v0.2.5 2026-05-13 13:40:09 +03:00
vrubelroman
fae53d6fd3 feat: remote image preview — detect via magic bytes, download to temp for overlay 2026-05-13 13:28:19 +03:00
vrubelroman
2d6ec2e445 fix: Ctrl+R refresh now properly reloads remote/archive panes via SFTP 2026-05-13 12:57:17 +03:00
vrubelroman
7128e58692 refactor: remove auto-refresh timer — panes already refresh on nav and after ops 2026-05-13 12:50:40 +03:00
vrubelroman
c598350fc5 fix: skip local PathExists check when target is remote (SFTP copy) 2026-05-13 12:43:03 +03:00
vrubelroman
7d2a2dd547 fix: broken background between Background/b and Cancel/c in progress modals 2026-05-13 01:34:00 +03:00
vrubelroman
fd2aa80894 feat: same-host SSH optimization (Exec cp/mv), per-file progress for all remote copies
- SSHClient.Exec() and ExecWithProgress() for server-side commands
- SSHHost.SameAs() and SSHClient.SameHostAs() for host comparison
- Same-host copy uses ExecWithProgress('cp -rv') with per-line progress
- Same-host move uses Exec('mv'), instant server-side rename
- CopyDirFromRemote/ToRemote/BetweenRemotes with per-file progress callbacks
- Context cancellation support for all remote copy operations
- Two-phase remote copy: count files first, then transfer with progress bar
- Fix: consistent modal colors (Enter=Accent, Cancel=CancelButton, Background=Accent)
2026-05-13 01:11:55 +03:00
vrubelroman
8352441bda perf: skip plan phases for copy/delete, remove size tracking, show file count only
- Delete: skip remoteDeletePlanCmd and trashPlanCmd, show dialog immediately
- Copy: skip copyPlanCmd and remoteCopyPlanCmd, show dialog immediately
- CopyStats: no lstat per file, count files via WalkDir only
- Copy: two-phase (count first, then copy with known total + progress bar)
- Progress: file-based ratio, remove Size/Speed display
- Stage: Counting files... → Coping files... (no empty stage)
2026-05-12 17:39:22 +03:00
vrubelroman
bd157b41b0 fix: fallback to home dir on startup, skip session save of SSH remote paths
- Use os.UserHomeDir() as fallback instead of os.Getwd()
- In saveSession(), skip saving pane path when pane is in remote mode
- In applyPaneSession(), verify directory is readable (not just exists)
2026-05-12 15:18:44 +03:00
vrubelroman
288325c2a1 fix: bump PKGBUILD and flake.nix version to v0.2.4 2026-05-04 15:23:22 +03:00
vrubelroman
2cf198cea8 chore: bump version to v0.2.4 2026-05-04 01:37:10 +03:00
vrubelroman
cb40a1d008 fix: remote directory size calculation via SFTP Walk on Space key 2026-05-04 01:27:06 +03:00
vrubelroman
f3b2fe59c4 feat: auto-refresh directory listing, enabled by default every 5s 2026-05-04 01:07:22 +03:00
vrubelroman
a9ccff8635 fix: reset cursor on enter dir and persist full cursor memory across sessions 2026-05-04 00:36:34 +03:00
vrubelroman
d5569ecdd0 fix: reset scroll offset when preserveKey changes cursor to avoid hidden top entries on go-parent 2026-05-04 00:29:04 +03:00
vrubelroman
152d45c7af feat: persist session state (folder, cursor, active pane) on exit and restore on launch 2026-05-04 00:16:44 +03:00
vrubelroman
b31fffbce4 chore: bump version to v0.2.3 2026-04-29 16:49:43 +03:00
vrubelroman
be7addcb2a chore: bump version to v0.2.2 2026-04-29 16:47:13 +03:00
vrubelroman
c4707d9300 fix: help dialog cleanup + theme selector polish
Help dialog (F1):
- Rename title 'Keyboard and Mouse Help' → 'Keyboard Help'
- Remove entire 'Dialogs and Transfers' section
  (all keys r, a, n, x shown in footer bar)
- Remove 'o', 's', 'q' entries (shown in footer as F9/o, F12/s, F10/q)
- Update 't' from 'cycle theme' → 'select theme'

Theme selector dialog (t):
- Move navigation hint to bottom of dialog
- Color 'Enter' green / 'Esc' red via renderModalHintTokens
2026-04-29 16:26:40 +03:00
vrubelroman
92e72bc8c6 feat: theme selector dialog with live preview (t key)
Replace the simple cycleTheme() with a modal dialog that shows all
19 themes with color swatches, live preview on Up/Down navigation,
and commit/revert on Enter/Esc.

Changes:
- Add modalThemeSelect kind to modalKind enum
- Add themeSelectorState struct + field to Model
- Add openThemeSelector() replacing cycleTheme() call
- Add handleModalKey case for modalThemeSelect (Up/Down/Enter/Esc)
- Add applyThemePreview() and finalizeTheme() helper methods
- Add renderThemeSelectModal() with aligned theme names + swatches
- Update renderModal() dispatch and widen modal for theme selector
- Update help text: 't' now shows 'select theme'
2026-04-29 16:13:29 +03:00
vrubelroman
cd877ab584 feat: mirror pane (p), cursor memory, clean up help dialog
- Add Mirror pane keybinding p (for 'Pane'), SSH restored on s
- Add session-scoped cursor memory per directory
- Fix cursor memory bug: DisplayName() adds trailing / for directories
- Fix remote mirror: use active.Path instead of mount.RemotePath
- Remove F-key/Mouse/b/c entries from F1 help dialog
- Remove Mirror from ShortHelp footer (F-keys only)
- Add missing letter-key bindings to help: p, s, a, n, x
2026-04-29 16:03:34 +03:00
vrubelroman
c8d6976030 refactor: remove Edit key binding, rename ExtractArchive -> Unpack
- Remove unused Edit key binding (no keys assigned, duplicated Enter)
- Rename ExtractArchive to Unpack across KeyMap struct, DefaultKeyMap(),
  ShortHelp(), FullHelp(), and Model.Update() handler
- Rename handleExtractArchive() -> handleUnpack()
- Update help text, status messages, and dialog titles to 'unpack'
2026-04-29 15:20:53 +03:00
vrubelroman
3b9eb4afa5 fix: add cancel button support for extraction; feat: delete progress dialog
- ExtractArchiveToDir now accepts context.Context for cancellation
- extractZipArchive/extractTarArchive check ctx.Done() in extraction loops
- startExtractJob creates context with cancel (C/c now works for extraction)
- Added startDeleteJob method with per-file progress reporting
- Local delete (trash/permanent) now shows progress dialog with B/b and C/c
- renderArchiveProgressModal handles 'delete' kind (file-based progress, no speed)
- archiveDoneMsg handles 'delete' completion (reload panes, clear marks)
2026-04-29 14:12:11 +03:00
vrubelroman
42c51f0ef5 feat: add extraction progress dialog (F11/e)
- ExtractArchiveToDir now accepts progress callback for file-by-file reporting
- Added countArchiveEntries/countZipEntries/countTarEntries helpers
- Added startExtractJob method following startArchiveJob pattern
- archiveJobState now has kind field ('archive'/'extract')
- archiveDoneMsg handler reloads only passive pane for extraction
- renderArchiveProgressModal shows file-based progress for extraction (no size/speed)
- Removed old synchronous extractArchiveCmd() and opExtractArchive case in opMsg
2026-04-29 14:01:36 +03:00
vrubelroman
3229d9b263 feat: merge F8/x delete with F11 archive extraction
- Delete mode toggle ('d') inside existing confirm dialog instead of separate modal
- F11/e shows confirm dialog before extracting archive to opposite pane
- deleteKind field toggles between 'permanent' and 'trash'
- Active pane reloads after extraction so files appear immediately
2026-04-29 13:42:59 +03:00
vrubelroman
8589187a10 cursor: move up on delete, hide size/modified columns in SSH host list, parent '..' empty modified, SSH keepalive 30s 2026-04-29 13:04:47 +03:00
vrubelroman
278b90e5bd Fix log.Printf format verbs to match actual types (vet errors) 2026-04-29 11:53:35 +03:00
vrubelroman
7cd7a24642 Show F11 (permanent delete) in footer bar between F10 and F12 2026-04-29 03:16:18 +03:00
vrubelroman
1ed2d3defb SSH connection status indicators
- Add Connected bool field to vfs.Entry and RemoteMount
- Track connection status in sshState.connectedHosts
- Show status icon (connected/disconnected) in pane header when browsing remote host
- Async SSH connection test with cancel support for Add Host dialog
- Colored labels and styled help text in SSH dialogs
- Confirmation dialog when deleting manually-added SSH hosts
2026-04-29 03:11:53 +03:00
vrubelroman
df4df6b8f6 fix: file type handling on Enter - extensions checked before executable bit
- Reorder Category() to check known extensions (text, config, image,
  pdf, audio, video, archive) before the executable bit check.
  Fixes video/audio/image files with executable bit being opened in
  editor instead of system default application.
- Remove 'executable' from isEditableEntry() - executables are now
  launched via handleExecute() instead of opened in Neovim.
- Add handleExecute() method that runs executable files in the
  terminal via tea.ExecProcess.
- Update handleOpenSelected() to route: text/config -> editor,
  executable -> launch, everything else -> system default (xdg-open).
- Bump version to v0.2.1
2026-04-27 23:18:48 +03:00
vrubelroman
c0df75c57e add Cyrillic→Latin keyboard layout translation for Russian users (ЙЦУКЕН→QWERTY) 2026-04-27 20:30:11 +03:00
vrubelroman
d38945f595 remove duplicate theme aliases (gruvbox, nord-frost); add 4 new themes: one-dark, everforest, github-dark, catppuccin-macchiato 2026-04-27 20:19:43 +03:00
vrubelroman
c35fbad5e3 chore: bump version to v0.2.0 2026-04-27 19:43:49 +03:00
vrubelroman
a483267bd9 feat: extended preview for PDF, audio, video via external utilities
Add rich preview support for three new file categories by leveraging
external CLI tools with graceful fallback when tools are missing.

- PDF: text extraction via pdftotext, page count via pdfinfo
- Audio: metadata via ffprobe (duration, bitrate, codec, sample rate, channels)
- Video: metadata via ffprobe (duration, bitrate, video/audio codec, resolution)
- New PreviewKind constants: PDF, Audio, Video
- New Metadata fields for extended preview data
- New extension maps and Category() entries for pdf/audio/video
- Icons: PDF (󰷉), audio (󰋋), video (󰋲) in preview header

Closes #5
2026-04-27 19:25:03 +03:00
vrubelroman
813c40a41e fix: cursor position on Enter for '..' now lands on source folder (same as Backspace); feat: permanent delete via F11/d; fix: footer F-key order (F1-F11) 2026-04-27 18:56:20 +03:00
vrubelroman
7a55fb289e feat: directory history (Alt+Left/Alt+Right), filter fixes (sticky per-pane, navigation, Shift+select, offset, Esc clear) 2026-04-27 18:11:19 +03:00
vrubelroman
08c095e74f feat: add interactive file search/filter (feature #1)
Pressing / opens a filter bar at the bottom of the screen. As the user
types, the active pane's entries are filtered in real-time using
case-insensitive substring matching. The .. entry is always preserved.

Key bindings:
  /       - open filter input (re-opens with previous query if active)
  Esc     - clear filter and restore full list
  Enter   - commit filter (keeps filtering active, closes input bar)
  Up/Down - navigate the filtered list while typing
  PgUp/Dn - scroll the filtered list

Filter is automatically cleared when navigating to a different directory
(Enter on a folder, Backspace to parent, opening an archive).

Modified files:
  - internal/ui/keymap.go: added Filter key binding (/)
  - internal/ui/model.go: filterMode, filterQuery, filterInput fields;
    filteredPane() helper for View rendering; filter handling in Update();
    renderFilterBar() for the bottom bar UI; clearFilter() helper;
    adjustCursorForFilter() to keep cursor in bounds

Created files:
  - plans/feature-roadmap.md
2026-04-27 17:14:48 +03:00
vrubelroman
bba8783f10 Fix directory preview layout to exactly match browser pane columns
Root cause: renderPreviewPane() was stuffing directory entries into the
viewport model via SetContent(), then rendering through
renderPreviewContent() which wraps the viewport in an additional
border+padding box. This reduced the effective content width by 4
characters compared to the browser pane's innerWidth (width-2), causing
column misalignment where the date column would wrap to the next line.

Fix: For directory previews, directly render entries using the same
renderPaneRows() and renderColumnsHeader() functions as the browser
pane, at the same innerWidth. A temporary BrowserPane is created with
the directory entries, and renderPaneRows() is called with active=false,
producing pixel-identical output to the main file browser.

Removed renderDirectoryPreviewBody() which is no longer needed.
2026-04-27 16:52:44 +03:00
vrubelroman
db5eaba409 feat: show program version in F1 help dialog footer 2026-04-27 16:26:01 +03:00
vrubelroman
68f340ee7d docs: reorder README sections — screenshots before build, font after installation 2026-04-27 16:13:47 +03:00
vrubelroman
c2ca689814 chore: bump version to v0.1.9
- Update README with all 17 built-in themes
- Add font installation instructions for NixOS and Arch Linux
- Add terminal font config for Foot, WezTerm, and Windows Terminal
- Bump version references from v0.1.8 to v0.1.9
2026-04-27 16:09:31 +03:00