rufio 1.3.0 → 1.4.0

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.
data/docs/guide.md ADDED
@@ -0,0 +1,410 @@
1
+ # rufio User Guide
2
+
3
+ [日本語](./guide_ja.md) | **English**
4
+
5
+ This guide covers rufio 1.3 and later. For installation and an overview, see the [README](../README.md).
6
+ Inside rufio, press `?` to open the help menu at any time.
7
+
8
+ ## Contents
9
+
10
+ - [Screen and Modes](#screen-and-modes)
11
+ - [Navigation](#navigation)
12
+ - [Preview](#preview)
13
+ - [File Operations](#file-operations)
14
+ - [ZIP Archives](#zip-archives)
15
+ - [Filter and Search](#filter-and-search)
16
+ - [Global Search (G mode)](#global-search-g-mode)
17
+ - [Bookmarks and History](#bookmarks-and-history)
18
+ - [Command Mode](#command-mode)
19
+ - [Scripts](#scripts)
20
+ - [DSL Commands](#dsl-commands)
21
+ - [Jobs and Logs](#jobs-and-logs)
22
+ - [Config Mode](#config-mode)
23
+ - [Shell Integration](#shell-integration)
24
+ - [Configuration](#configuration)
25
+ - [External Tools](#external-tools)
26
+ - [Command-line Options](#command-line-options)
27
+ - [Native Engine](#native-engine)
28
+
29
+ ## Screen and Modes
30
+
31
+ Files mode shows the current path on the top row, the bookmark list, the file list on the left and a preview on the right. The bottom row shows the mode tabs.
32
+
33
+ | Key | Mode |
34
+ |-----|------|
35
+ | (start) | **Files** – browse and operate on files |
36
+ | `C` | **Config** – browse `~/.config/rufio/` with the same controls as Files |
37
+ | `G` | **Search** – search names or contents across all bookmarks |
38
+ | `L` | **Logs** – browse command execution logs |
39
+ | `J` | **Jobs** – background commands, scripts and ZIP jobs |
40
+ | `?` | **Help** – floating help menu over the current screen |
41
+
42
+ `ESC` leaves the current mode. In modes other than Files and Config, `Shift+Tab` switches to the previous mode.
43
+
44
+ ## Navigation
45
+
46
+ | Key | Action |
47
+ |-----|--------|
48
+ | `j` / `Down` | Move down |
49
+ | `k` / `Up` | Move up |
50
+ | `h` / `Left` | Parent directory |
51
+ | `l` / `Right` / `Enter` | Enter directory |
52
+ | `g` | First entry |
53
+ | `}` | Last entry |
54
+ | `R` | Refresh |
55
+ | `0` | Back to the directory rufio started in |
56
+ | `q` | Quit (with confirmation) |
57
+ | `T` | Quit and move the shell to the current directory (see [Shell Integration](#shell-integration)) |
58
+
59
+ The mouse also works: click to select, and scroll the list or the preview.
60
+
61
+ ## Preview
62
+
63
+ The right pane previews the selected file. Code is highlighted when `bat` is installed. `.zip` files show their entry list (size, method, modified time, name) without extracting them.
64
+
65
+ | Key | Action |
66
+ |-----|--------|
67
+ | `P` | Fullscreen preview (hides the file list) |
68
+ | `j` / `k` | Scroll |
69
+ | `Ctrl+D` / `Ctrl+U` | Page down / up |
70
+ | `ESC` | Back to the file list |
71
+
72
+ ## File Operations
73
+
74
+ | Key | Action |
75
+ |-----|--------|
76
+ | `o` | Open the file with its application (see `APPLICATIONS` in [Configuration](#configuration)) |
77
+ | `e` | Open the current directory in the system file explorer |
78
+ | `a` | Create a file |
79
+ | `A` | Create a directory |
80
+ | `r` | Rename |
81
+ | `d` | Delete (with confirmation) |
82
+ | `Space` | Select / unselect the current item |
83
+ | `m` | Move selected items to the current directory |
84
+ | `c` | Copy selected items to the current directory |
85
+ | `x` | Delete selected items (with confirmation) |
86
+
87
+ To move or copy, select items with `Space`, go to the destination directory, then press `m` or `c`.
88
+ When a copied item's name already exists, the copy is numbered (`name_1.txt`, `dir_1`). A move to an existing name is reported as an error.
89
+
90
+ ## ZIP Archives
91
+
92
+ Select items with `Space` and press `z`:
93
+
94
+ - **Every selected item is a `.zip`**: each archive is extracted into `<name>/` in the current directory (`<name> 2/`, `<name> 3/` and so on if the name is taken)
95
+ - **Otherwise**: rufio asks for an archive name and compresses the selection into one `.zip` in the current directory. Press `Enter` to accept the suggested name (`<item>.zip` for one item, `Archive.zip` for several)
96
+
97
+ The work runs as a job. Check progress and cancel it in Jobs mode (`J`, then `x`). A partially extracted folder is removed when extraction fails or is cancelled, and the file list refreshes when the job finishes.
98
+
99
+ Extraction validates the whole archive before writing anything. It rejects path traversal, absolute paths, overlapping entries, and archives over 16 GiB in total, 100,000 entries or a 1000:1 compression ratio (for entries over 1 MiB). Symlink and encrypted entries are skipped, CRC-32 is verified, and existing files are never overwritten. Stored and Deflate entries are supported.
100
+
101
+ With nothing selected, `z` opens zoxide history instead.
102
+
103
+ ## Filter and Search
104
+
105
+ | Key | Action |
106
+ |-----|--------|
107
+ | `f` | Filter the current list as you type (`Enter` keeps the filter, `ESC` clears it) |
108
+ | `s` or `/` | Search file names with fzf |
109
+ | `F` | Search file contents with rga |
110
+ | `G` | Global search across all bookmarks (no external tools needed) |
111
+
112
+ ## Global Search (G mode)
113
+
114
+ `G` searches recursively under every bookmarked directory. Add bookmarks with `b` first.
115
+
116
+ | Key | Action |
117
+ |-----|--------|
118
+ | Type | Literal, case-insensitive search |
119
+ | `Tab` | Switch between **File names** and **Content** |
120
+ | `Up` / `Down`, `Ctrl+J` / `Ctrl+K`, `Ctrl+N` / `Ctrl+P` | Select a result |
121
+ | `Enter` | Go to the file in Files mode |
122
+ | `Ctrl+U` | Clear the query |
123
+ | `ESC` | Return to the previous mode |
124
+
125
+ - Matches are highlighted. Content results show the file, line number and matching text.
126
+ - A yellow `Searching...` indicator animates while scanning and turns into a green `Search complete` when done.
127
+ - Inaccessible directories and directory symlinks are skipped. Plain text is read as UTF-8, and files with NUL bytes in the first 8 KB are treated as binary.
128
+
129
+ ### Documents
130
+
131
+ Content search also reads documents, without Python, Microsoft Office or conversion tools:
132
+
133
+ | File | Searched text | Result location |
134
+ |------|---------------|-----------------|
135
+ | `.pdf` | Extractable text | Page |
136
+ | `.xlsx` | Cell text and saved values | Sheet and cell |
137
+ | `.pptx` | Text in slide shapes and tables | Slide |
138
+
139
+ Extracted text is cached in memory (up to 64 documents, about 16 MiB) and re-extracted when a file changes. Scanned images need OCR, which is not included. Legacy `.xls` / `.ppt` and slide notes are not supported.
140
+
141
+ ### Excluding Extensions
142
+
143
+ Add this to `~/.config/rufio/config.rb` and restart rufio. It applies to both file names and contents:
144
+
145
+ ```ruby
146
+ GLOBAL_SEARCH_EXCLUDED_EXTENSIONS = %w[.png .jpg .zip .tar.gz .log].freeze
147
+ ```
148
+
149
+ Extensions ignore case, the leading dot is optional, and the default `[]` excludes nothing.
150
+
151
+ ## Bookmarks and History
152
+
153
+ | Key | Action |
154
+ |-----|--------|
155
+ | `b` | Bookmark the current directory |
156
+ | `B` | Bookmark menu |
157
+ | `1`–`9` | Jump to bookmark 1–9 |
158
+ | `Tab` / `Shift+Tab` | Next / previous bookmark (Files and Config modes) |
159
+ | `z` | zoxide history (when nothing is selected) |
160
+
161
+ The `B` menu has four items:
162
+
163
+ 1. Add the current directory to bookmarks
164
+ 2. Add the current directory to script paths
165
+ 3. Manage script paths (`d` removes, `Enter` jumps, `ESC` closes)
166
+ 4. View bookmarks
167
+
168
+ ## Command Mode
169
+
170
+ Press `:` to open command mode. `Tab` completes, `Up` / `Down` recalls history, `Enter` runs and `ESC` cancels.
171
+
172
+ | Input | Action |
173
+ |-------|--------|
174
+ | `@name` | Run a script from script paths or the current directory |
175
+ | `rake:task` | Run a task from the `Rakefile` in the current directory |
176
+ | `!command` | Run a shell command in the background |
177
+ | `cd <path>` | Go to a directory |
178
+ | `name` | Run a built-in or DSL command |
179
+
180
+ ```
181
+ :@build # Script (Tab completes the name)
182
+ :rake:test # Rake task (Rakefile, rakefile and Rakefile.rb are supported)
183
+ :!git status # Shell command
184
+ :hello # Built-in sample command
185
+ ```
186
+
187
+ ### Going to a Path
188
+
189
+ Paste a path after `:cd` to jump there:
190
+
191
+ ```
192
+ :cd ~/projects/app # Directory
193
+ :cd '/path/with space/a.txt' # File: opens its folder and selects the file
194
+ :cd sub # Relative to the current directory
195
+ :cd - # Back to the previous directory
196
+ :cd # Home directory
197
+ ```
198
+
199
+ Surrounding quotes, a trailing newline, `\ ` escapes and `file://` URLs from copied paths are accepted. `Tab` completes directory names. If the path does not exist, rufio stays where it is and shows an error.
200
+
201
+ ## Scripts
202
+
203
+ Scripts in registered script paths, and in the directory you are browsing, run with `:@name`. They run in the directory you are browsing.
204
+
205
+ | Extension | Runs with |
206
+ |-----------|-----------|
207
+ | `.rb` | Ruby |
208
+ | `.py` | Python 3 |
209
+ | `.sh` | Shell |
210
+ | `.js` | Node.js |
211
+ | `.ts` | ts-node |
212
+ | `.pl` | Perl |
213
+ | `.ps1` | PowerShell |
214
+
215
+ Script paths are searched in this order, and the first matching name wins:
216
+
217
+ 1. `./rufio.yml` in the project
218
+ 2. `~/.config/rufio/script_paths.yml`
219
+ 3. `/etc/rufio/script_paths.yml`
220
+
221
+ To register a directory, open it in rufio and press `B` then `2`.
222
+
223
+ ## DSL Commands
224
+
225
+ Define your own commands in `~/.config/rufio/commands.rb` (`~/.rufio/commands.rb` also works) and run them with `:name`:
226
+
227
+ ```ruby
228
+ command "hello" do
229
+ ruby { "Hello from rufio!" }
230
+ description "Greeting command"
231
+ end
232
+
233
+ command "status" do
234
+ shell "git status"
235
+ description "Git status"
236
+ end
237
+
238
+ command "build" do
239
+ script "~/.config/rufio/scripts/build.rb"
240
+ description "Run build"
241
+ end
242
+ ```
243
+
244
+ ## Jobs and Logs
245
+
246
+ Shell commands, scripts and ZIP work run in the background while you keep browsing. A notification appears when a job finishes.
247
+
248
+ **Jobs mode (`J`)**
249
+
250
+ | Key | Action |
251
+ |-----|--------|
252
+ | `j` / `k` | Select a job |
253
+ | `g` / `G` | First / last job |
254
+ | `Space` | View the job's log |
255
+ | `x` | Cancel the selected job |
256
+ | `ESC` | Back |
257
+
258
+ **Logs mode (`L`)** lists the execution logs in `~/.config/rufio/logs/`. Press `P` to preview a log, `ESC` to leave the preview and `ESC` again to return to Files.
259
+
260
+ ## Config Mode
261
+
262
+ `C` opens `~/.config/rufio/`, creating it if needed. Navigation, preview and file operations work as in Files mode, so you can edit settings and scripts directly. Leaving the directory returns to Files mode.
263
+
264
+ ## Shell Integration
265
+
266
+ `rufio --shell-init` prints a shell function named `rf`. Launch rufio with `rf` and press `T` to quit and move the shell to the directory you were viewing. `q` quits without moving.
267
+
268
+ ```bash
269
+ # bash / zsh (~/.bashrc or ~/.zshrc)
270
+ eval "$(rufio --shell-init)"
271
+
272
+ # fish (~/.config/fish/config.fish)
273
+ rufio --shell-init fish | source
274
+ ```
275
+
276
+ ```powershell
277
+ # PowerShell ($PROFILE)
278
+ Invoke-Expression (& rufio --shell-init powershell | Out-String)
279
+ ```
280
+
281
+ Without an argument, rufio prints PowerShell on Windows and your login shell (`bash`, `zsh` or `fish`) elsewhere. To avoid starting Ruby with every shell, append the output once instead, for example `rufio --shell-init >> ~/.bashrc`.
282
+
283
+ ## Configuration
284
+
285
+ ```
286
+ ~/.config/rufio/
287
+ ├── config.rb # Main settings (Ruby constants)
288
+ ├── script_paths.yml # Script directories
289
+ ├── bookmarks.yml # Bookmarks
290
+ ├── commands.rb # DSL commands
291
+ ├── scripts/ # Your scripts
292
+ └── logs/ # Execution logs
293
+ ```
294
+
295
+ ### config.rb
296
+
297
+ ```ruby
298
+ # ~/.config/rufio/config.rb
299
+
300
+ # 'en' or 'ja' (the RUFIO_LANG environment variable also works)
301
+ LANGUAGE = 'ja'
302
+
303
+ # Colors (HSL)
304
+ COLORS = {
305
+ directory: { hsl: [220, 80, 60] },
306
+ file: { hsl: [0, 0, 90] },
307
+ executable: { hsl: [120, 70, 50] },
308
+ selected: { hsl: [50, 90, 70] },
309
+ preview: { hsl: [180, 60, 65] }
310
+ }.freeze
311
+
312
+ # Change keys by action name. Each value is a single key.
313
+ KEYBINDS = {
314
+ bottom: 'G',
315
+ global_search: 'S'
316
+ }.freeze
317
+
318
+ # Applications used by `o`, by extension
319
+ APPLICATIONS = {
320
+ %w[txt md rb py js json yml] => 'code',
321
+ :default => 'open'
322
+ }.freeze
323
+
324
+ # Extensions excluded from G mode search
325
+ GLOBAL_SEARCH_EXCLUDED_EXTENSIONS = %w[.log].freeze
326
+ ```
327
+
328
+ Action names for `KEYBINDS`:
329
+
330
+ | Group | Actions (default key) |
331
+ |-------|-----------------------|
332
+ | Navigation | `move_up` (k), `move_down` (j), `navigate_parent` (h), `navigate_enter` (l), `top` (g), `bottom` (}), `refresh` (R) |
333
+ | Files | `open_file` (o), `preview` (P), `rename` (r), `delete` (d), `create_file` (a), `create_dir` (A), `move_selected` (m), `copy_selected` (c), `delete_selected` (x), `open_explorer` (e) |
334
+ | Selection and search | `select` (Space), `filter` (f), `fzf_search` (s), `fzf_search_alt` (/), `rga_search` (F) |
335
+ | Bookmarks | `add_bookmark` (b), `bookmark_menu` (B), `zoxide` (z), `start_dir` (0) |
336
+ | Modes | `job_mode` (J), `global_search` (G), `config_mode` (C), `help` (?), `log_viewer` (L), `command_mode` (:), `quit` (q), `quit_cd` (T) |
337
+
338
+ ### script_paths.yml and bookmarks.yml
339
+
340
+ ```yaml
341
+ # ~/.config/rufio/script_paths.yml
342
+ - ~/.config/rufio/scripts
343
+ - ~/bin
344
+ ```
345
+
346
+ ```yaml
347
+ # ~/.config/rufio/bookmarks.yml
348
+ - path: ~/Documents
349
+ name: Documents
350
+ - path: ~/projects
351
+ name: Projects
352
+ ```
353
+
354
+ ### Project Settings
355
+
356
+ Place `rufio.yml` in a project root to add script paths for that project:
357
+
358
+ ```yaml
359
+ # ./rufio.yml
360
+ script_paths:
361
+ - ./scripts
362
+ - ./bin
363
+ ```
364
+
365
+ ## External Tools
366
+
367
+ All tools are optional. Without them, rufio disables the feature or falls back to built-in behavior. Run `rufio -c` to check what is detected.
368
+
369
+ | Tool | Used for | Key |
370
+ |------|----------|-----|
371
+ | fzf | File name search | `s`, `/` |
372
+ | rga | File content search | `F` |
373
+ | zoxide | Directory history | `z` |
374
+ | bat | Syntax highlighting in the preview | — |
375
+
376
+ ```bash
377
+ # macOS
378
+ brew install fzf bat rga zoxide
379
+
380
+ # Ubuntu/Debian
381
+ apt install fzf bat zoxide
382
+ # rga: https://github.com/phiresky/ripgrep-all
383
+ ```
384
+
385
+ ## Command-line Options
386
+
387
+ ```bash
388
+ rufio [DIRECTORY] # Start in DIRECTORY (default: current directory)
389
+ rufio -c # Check dependencies (--check-health)
390
+ rufio --shell-init [SHELL] # Print the rf shell function
391
+ rufio --yjit # Enable YJIT (Ruby 3.1+)
392
+ rufio --zjit # Enable ZJIT (Ruby 3.4+)
393
+ rufio --native # Experimental native directory scanner
394
+ rufio --test # Show an FPS counter
395
+ rufio -h # Help
396
+ ```
397
+
398
+ ## Native Engine
399
+
400
+ The gem bundles a Zig library for macOS (arm64/x86_64), Linux (x86_64/aarch64, glibc 2.17+ or musl) and Windows (x64/arm64). Other platforms use the Ruby implementation automatically.
401
+
402
+ - **G mode content search**: parallel scanning with an in-memory file cache. Repeated searches are about 10x faster than `rg`. Queries with non-ASCII cased letters use the Ruby search. Set `RUFIO_NATIVE_SEARCH=0` to disable it.
403
+ - **ZIP**: decompresses entries and compresses files of 1 MiB or more in parallel (about 4.6x faster to compress and 3.2x faster to extract than Ruby on 8 × 64 MB files with 4 CPUs). Archive validation always stays in Ruby. Set `RUFIO_NATIVE_ZIP=0` to disable it.
404
+
405
+ To rebuild the bundled binaries (requires Zig 0.17):
406
+
407
+ ```bash
408
+ bundle exec rake native:build # all platforms
409
+ bundle exec rake native:check # verify bundled binaries
410
+ ```