hiiro 0.1.383 → 0.1.385
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -13
- data/README.md +1 -1
- data/bin/h-herdr +126 -0
- data/bin/h-js +21 -0
- data/bin/h-plist +214 -0
- data/bin/hh +4 -0
- data/doc/AGENTS_md.html +898 -0
- data/doc/AppTest/MockApp.html +192 -0
- data/doc/AppTest/MockEnvironment.html +192 -0
- data/doc/AppTest/MockGit.html +157 -0
- data/doc/AppTest/MockItem.html +178 -0
- data/doc/AppTest/MockMatcher.html +200 -0
- data/doc/AppTest/MockResult.html +235 -0
- data/doc/AppTest.html +401 -0
- data/doc/Asarfile/Appfile.html +4219 -0
- data/doc/Asarfile.html +1445 -0
- data/doc/BackgroundTest.html +388 -0
- data/doc/BinsTest.html +245 -0
- data/doc/BranchManager.html +373 -804
- data/doc/BranchTest/MockGit.html +272 -0
- data/doc/BranchTest.html +621 -0
- data/doc/CHANGELOG_md.html +771 -0
- data/doc/CLAUDE_md.html +310 -1092
- data/doc/ClaudeTest.html +323 -0
- data/doc/CommitTest.html +271 -0
- data/doc/ConfigTest.html +407 -0
- data/doc/ContextBundleManager.html +811 -0
- data/doc/CurrentTaskTest.html +325 -0
- data/doc/Directory.html +63 -770
- data/doc/EnvFile.html +397 -0
- data/doc/EnvironmentTest.html +610 -0
- data/doc/FilesystemEffectsTest.html +478 -0
- data/doc/FuzzyfindTest.html +382 -0
- data/doc/Gemfile.html +309 -669
- data/doc/Gemfile_lock.html +336 -691
- data/doc/GitBranchTest.html +428 -0
- data/doc/GitBranchesTest.html +428 -0
- data/doc/GitEffectsTest.html +381 -0
- data/doc/GitPrTest.html +581 -0
- data/doc/GitRemoteTest.html +519 -0
- data/doc/GitWorktreeTest.html +576 -0
- data/doc/GitWorktreesTest.html +712 -0
- data/doc/Globber.html +593 -0
- data/doc/HerdrEffectsTest.html +464 -0
- data/doc/HerdrPluginTest.html +344 -0
- data/doc/HerdrWorkspaceTest.html +230 -0
- data/doc/Hiiro/AnyStruct.html +78 -835
- data/doc/Hiiro/AppFiles.html +88 -882
- data/doc/Hiiro/AppRecord.html +233 -0
- data/doc/Hiiro/Args.html +82 -855
- data/doc/Hiiro/Assignment.html +232 -0
- data/doc/Hiiro/Background.html +287 -0
- data/doc/Hiiro/Bins.html +70 -818
- data/doc/Hiiro/Branch.html +416 -0
- data/doc/Hiiro/Capture.html +314 -0
- data/doc/Hiiro/CheckRun.html +261 -0
- data/doc/Hiiro/Config.html +178 -830
- data/doc/Hiiro/CurrentTask.html +254 -0
- data/doc/Hiiro/DB/JSON.html +200 -0
- data/doc/Hiiro/DB.html +440 -0
- data/doc/Hiiro/Effects/Executor/Filesystem/NullFilesystem.html +642 -0
- data/doc/Hiiro/Effects/Executor/Filesystem.html +750 -0
- data/doc/Hiiro/Effects/Executor/NullExecutor.html +436 -0
- data/doc/Hiiro/Effects/Executor.html +509 -0
- data/doc/Hiiro/Effects.html +121 -0
- data/doc/Hiiro/Error.html +127 -0
- data/doc/Hiiro/FallbackTarget/App.html +308 -0
- data/doc/Hiiro/FallbackTarget/Environment.html +777 -0
- data/doc/Hiiro/FallbackTarget.html +1748 -0
- data/doc/Hiiro/Fuzzyfind.html +70 -818
- data/doc/Hiiro/Git/Branch.html +106 -975
- data/doc/Hiiro/Git/Branches.html +128 -1084
- data/doc/Hiiro/Git/Pr.html +2575 -1115
- data/doc/Hiiro/Git/Remote.html +106 -971
- data/doc/Hiiro/Git/Worktree.html +90 -899
- data/doc/Hiiro/Git/Worktrees.html +129 -1085
- data/doc/Hiiro/Git.html +306 -1413
- data/doc/Hiiro/Glob.html +58 -757
- data/doc/Hiiro/Herdr/Collection/Workspace/Workspaces/Tab/Tabs/Pane/Panes.html +5289 -0
- data/doc/Hiiro/Herdr/Collection/Workspace/Workspaces/Tab/Tabs/Pane.html +5470 -0
- data/doc/Hiiro/Herdr/Collection/Workspace/Workspaces/Tab/Tabs.html +2292 -0
- data/doc/Hiiro/Herdr/Collection/Workspace/Workspaces/Tab.html +2619 -0
- data/doc/Hiiro/Herdr/Collection/Workspace/Workspaces.html +1339 -0
- data/doc/Hiiro/Herdr/Collection/Workspace.html +2337 -0
- data/doc/Hiiro/Herdr/Collection.html +2190 -0
- data/doc/Hiiro/Herdr.html +125 -0
- data/doc/Hiiro/InputFile.html +550 -0
- data/doc/Hiiro/Invocation.html +356 -0
- data/doc/Hiiro/InvocationResolution.html +218 -0
- data/doc/Hiiro/Link.html +507 -0
- data/doc/Hiiro/Matcher/Item.html +60 -777
- data/doc/Hiiro/Matcher/PathResult.html +106 -979
- data/doc/Hiiro/Matcher/Result.html +110 -1001
- data/doc/Hiiro/Matcher.html +147 -1138
- data/doc/Hiiro/Notification.html +159 -953
- data/doc/Hiiro/Options/Args/Definition.html +557 -0
- data/doc/Hiiro/Options/Args.html +1301 -1020
- data/doc/Hiiro/Options.html +155 -963
- data/doc/Hiiro/PaneHome.html +312 -0
- data/doc/Hiiro/Paths/Symlink.html +102 -946
- data/doc/Hiiro/Paths.html +75 -838
- data/doc/Hiiro/PinRecord.html +309 -0
- data/doc/Hiiro/PinnedPRManager.html +1388 -0
- data/doc/Hiiro/PinnedPr.html +2261 -0
- data/doc/Hiiro/Project.html +233 -0
- data/doc/Hiiro/Projects.html +437 -0
- data/doc/Hiiro/PsProcess.html +770 -0
- data/doc/Hiiro/Queue/Prompt.html +177 -927
- data/doc/Hiiro/Queue.html +963 -1622
- data/doc/Hiiro/Rbenv.html +197 -988
- data/doc/Hiiro/RegistryEntry/Hiiro.html +176 -0
- data/doc/Hiiro/RegistryEntry.html +842 -0
- data/doc/Hiiro/Reminder.html +238 -0
- data/doc/Hiiro/Result.html +462 -0
- data/doc/Hiiro/RunnerTool.html +106 -956
- data/doc/Hiiro/Runners/Bin.html +98 -939
- data/doc/Hiiro/Runners/Subcommand.html +100 -956
- data/doc/Hiiro/Runners.html +150 -1043
- data/doc/Hiiro/ServiceManager.html +251 -1283
- data/doc/Hiiro/Shell.html +226 -772
- data/doc/Hiiro/ShellCommand.html +277 -0
- data/doc/Hiiro/SparseGroups.html +64 -784
- data/doc/Hiiro/Tag.html +543 -0
- data/doc/Hiiro/Tags.html +117 -906
- data/doc/Hiiro/Task.html +203 -982
- data/doc/Hiiro/TaskCli/Commands/Error.html +137 -0
- data/doc/Hiiro/TaskCli/Commands.html +3128 -0
- data/doc/Hiiro/TaskCli.html +220 -0
- data/doc/Hiiro/TaskManager/Config.html +110 -876
- data/doc/Hiiro/TaskManager.html +530 -1372
- data/doc/Hiiro/TaskRecord.html +511 -0
- data/doc/Hiiro/TaskResource.html +176 -0
- data/doc/Hiiro/TaskSessions/Error.html +131 -0
- data/doc/Hiiro/TaskSessions.html +247 -0
- data/doc/Hiiro/Tasks.html +289 -776
- data/doc/Hiiro/TestHarness.html +1105 -0
- data/doc/Hiiro/TodoItem.html +184 -1165
- data/doc/Hiiro/TodoManager.html +163 -1185
- data/doc/Hiiro/Tree.html +123 -898
- data/doc/Hiiro/Tui/ListScreen.html +672 -0
- data/doc/Hiiro/Tui/Terminal.html +488 -0
- data/doc/Hiiro/Tui.html +121 -0
- data/doc/Hiiro.html +631 -1851
- data/doc/HiiroAddCmdTest.html +366 -0
- data/doc/HiiroAddDefaultTest.html +384 -0
- data/doc/HiiroRunnersBinTest.html +363 -0
- data/doc/HiiroRunnersSubcommandTest.html +430 -0
- data/doc/HiiroSetup.html +190 -0
- data/doc/HiiroTest.html +533 -0
- data/doc/HomeDirs.html +528 -0
- data/doc/JsTest.html +187 -0
- data/doc/LICENSE.html +309 -669
- data/doc/LinkManager/Link.html +86 -885
- data/doc/LinkManager.html +224 -1007
- data/doc/LinkTest/MockLinkManager.html +331 -0
- data/doc/LinkTest.html +198 -0
- data/doc/MatcherItemTest.html +167 -0
- data/doc/MatcherResultTest.html +375 -0
- data/doc/MatcherTest.html +908 -0
- data/doc/MockHiiro.html +346 -0
- data/doc/NotificationTest/MockHiiroForNotify.html +180 -0
- data/doc/NotificationTest.html +592 -0
- data/doc/Notify.html +77 -828
- data/doc/NotifyPluginTest.html +421 -0
- data/doc/Object.html +7684 -1547
- data/doc/ObsidianNotes.html +599 -0
- data/doc/OptionsDefinitionTest.html +348 -0
- data/doc/OptionsTest.html +1047 -0
- data/doc/PaneTest/MockHerdr.html +1113 -0
- data/doc/PaneTest.html +415 -0
- data/doc/Pins/Pin.html +355 -1062
- data/doc/Pins.html +73 -815
- data/doc/PinsPinTest/MockHiiro.html +178 -0
- data/doc/PinsPinTest.html +514 -0
- data/doc/PluginTest.html +388 -0
- data/doc/PortfolioApi.html +311 -0
- data/doc/Project.html +84 -941
- data/doc/ProjectPluginTest.html +507 -0
- data/doc/ProjectTest.html +249 -0
- data/doc/QueueHerdrTest.html +181 -0
- data/doc/README_md.html +557 -741
- data/doc/Rakefile.html +309 -669
- data/doc/ReminderManager/Reminder.html +626 -0
- data/doc/ReminderManager.html +469 -0
- data/doc/RequirePathsTest.html +168 -0
- data/doc/RubyGems/Version/Git/Claude.html +251 -0
- data/doc/RubyGems/Version/Git/RubyGem.html +214 -0
- data/doc/RubyGems/Version/Git.html +1175 -0
- data/doc/RubyGems/Version.html +379 -0
- data/doc/RubyGems.html +251 -0
- data/doc/SaveTest.html +352 -0
- data/doc/ServiceManagerHerdrTest.html +187 -0
- data/doc/SessionTest/MockHerdr.html +699 -0
- data/doc/SessionTest.html +343 -0
- data/doc/ShaTest.html +343 -0
- data/doc/ShellTest.html +430 -0
- data/doc/String.html +58 -757
- data/doc/SystemCallCapture.html +267 -0
- data/doc/TODO_md.html +311 -672
- data/doc/TaskCommandTest.html +2416 -0
- data/doc/TaskManager.html +1554 -1599
- data/doc/TaskManagerConfigTest.html +451 -0
- data/doc/TaskManagerFilterTasksTest.html +421 -0
- data/doc/TaskManagerFromWorktreeTest.html +308 -0
- data/doc/TaskTest.html +545 -0
- data/doc/TaskToggleTui.html +224 -0
- data/doc/TestHarnessEffectsTest.html +562 -0
- data/doc/TestHelpers.html +231 -0
- data/doc/TodoItemTest.html +983 -0
- data/doc/TodoManagerTest.html +1172 -0
- data/doc/TodoTest/MockTodoManager.html +398 -0
- data/doc/TodoTest.html +243 -0
- data/doc/TreeTest.html +477 -0
- data/doc/WindowTest/MockHerdr.html +746 -0
- data/doc/WindowTest.html +343 -0
- data/doc/WtreeTest.html +566 -0
- data/doc/bin/h-_config.html +362 -0
- data/doc/bin/h-dsstore-read.html +358 -0
- data/doc/css/fonts.css +167 -0
- data/doc/css/rdoc.css +328 -1600
- data/doc/demo_sh.html +314 -674
- data/doc/docs/README_md.html +477 -736
- data/doc/docs/coupling-and-extraction-plan_txt.html +1589 -0
- data/doc/docs/docker-testing-guide_md.html +668 -865
- data/doc/docs/h-app_md.html +615 -0
- data/doc/docs/h-bg_md.html +420 -0
- data/doc/docs/h-bin_md.html +475 -0
- data/doc/docs/h-branch_md.html +1035 -0
- data/doc/docs/h-claude_md.html +1121 -0
- data/doc/docs/h-commit_md.html +417 -0
- data/doc/docs/h-config_md.html +522 -0
- data/doc/docs/h-cpr_md.html +399 -0
- data/doc/docs/h-db_md.html +555 -0
- data/doc/docs/h-file_md.html +422 -0
- data/doc/docs/h-herdr_md.html +470 -0
- data/doc/docs/h-img_md.html +430 -0
- data/doc/docs/h-link_md.html +619 -0
- data/doc/docs/h-misc_md.html +435 -0
- data/doc/docs/h-notify_md.html +510 -0
- data/doc/docs/h-pane_md.html +405 -784
- data/doc/docs/h-plugin_md.html +382 -705
- data/doc/docs/h-pm_md.html +549 -0
- data/doc/docs/h-pr-monitor_md.html +458 -0
- data/doc/docs/h-pr_md.html +795 -0
- data/doc/docs/h-project_md.html +522 -0
- data/doc/docs/h-queue_md.html +744 -0
- data/doc/docs/h-registry_md.html +542 -0
- data/doc/docs/h-run_md.html +493 -0
- data/doc/docs/h-save_md.html +453 -0
- data/doc/docs/h-service_md.html +654 -0
- data/doc/docs/h-session_md.html +370 -762
- data/doc/docs/h-sha_md.html +461 -0
- data/doc/docs/h-sparse_md.html +493 -0
- data/doc/docs/h-subtask_md.html +359 -0
- data/doc/docs/h-tags_md.html +417 -0
- data/doc/docs/h-task_md.html +447 -0
- data/doc/docs/h-title_md.html +400 -0
- data/doc/docs/h-todo_md.html +617 -0
- data/doc/docs/h-window_md.html +356 -785
- data/doc/docs/h-wtree_md.html +539 -0
- data/doc/docs/h_md.html +605 -0
- data/doc/docs/t_md.html +659 -0
- data/doc/docs/why-t_md.html +698 -0
- data/doc/fonts/Lato-Light.ttf +0 -0
- data/doc/fonts/Lato-LightItalic.ttf +0 -0
- data/doc/fonts/Lato-Regular.ttf +0 -0
- data/doc/fonts/Lato-RegularItalic.ttf +0 -0
- data/doc/fonts/SourceCodePro-Bold.ttf +0 -0
- data/doc/fonts/SourceCodePro-Regular.ttf +0 -0
- data/doc/h-tmux-plugins_tmux.html +309 -669
- data/doc/herdr-plugin/herdr-plugin_toml.html +375 -0
- data/doc/hiiro_gemspec.html +621 -0
- data/doc/images/add.png +0 -0
- data/doc/images/arrow_up.png +0 -0
- data/doc/images/brick.png +0 -0
- data/doc/images/brick_link.png +0 -0
- data/doc/images/bug.png +0 -0
- data/doc/images/bullet_black.png +0 -0
- data/doc/images/bullet_toggle_minus.png +0 -0
- data/doc/images/bullet_toggle_plus.png +0 -0
- data/doc/images/date.png +0 -0
- data/doc/images/delete.png +0 -0
- data/doc/images/find.png +0 -0
- data/doc/images/loadingAnimation.gif +0 -0
- data/doc/images/macFFBgHack.png +0 -0
- data/doc/images/package.png +0 -0
- data/doc/images/page_green.png +0 -0
- data/doc/images/page_white_text.png +0 -0
- data/doc/images/page_white_width.png +0 -0
- data/doc/images/plugin.png +0 -0
- data/doc/images/ruby.png +0 -0
- data/doc/images/tag_blue.png +0 -0
- data/doc/images/tag_green.png +0 -0
- data/doc/images/transparent.png +0 -0
- data/doc/images/wrench.png +0 -0
- data/doc/images/wrench_orange.png +0 -0
- data/doc/images/zoom.png +0 -0
- data/doc/index.html +313 -667
- data/doc/js/darkfish.js +120 -0
- data/doc/js/search.js +110 -0
- data/doc/merge.html +353 -0
- data/doc/notes.html +328 -688
- data/doc/obsidian_slides_md.html +353 -687
- data/doc/record-demo_sh.html +313 -673
- data/doc/script/compare.html +310 -670
- data/doc/script/install.html +309 -669
- data/doc/script/sync.html +312 -672
- data/doc/script/test.html +309 -669
- data/doc/script/update.html +323 -667
- data/doc/side-effect-separation-plan_md.html +439 -0
- data/doc/slides_md.html +374 -727
- data/doc/table_of_contents.html +10197 -0
- data/docs/h-herdr.md +21 -8
- data/lib/hiiro/version.rb +1 -1
- data/script/publish +1 -1
- metadata +230 -3
- data/.DS_Store +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1877449a8336392c36f54f38f1ea86792b736f6d8af25bea8bb98f1f62081328
|
|
4
|
+
data.tar.gz: 495465e2395a43cc24464922aa60e24283e97bf715f7492f7be182e8936629c6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0d1c6e96f27300ab32b675f10b2d00c207792a0534859bbbfaa02f72d855b3af33572422842474cdfddf3a18cd5146eb93060349b03671232b4b4485c262079d
|
|
7
|
+
data.tar.gz: 0db00cb34ddc01b743a1a3f039e80308619134ce722e9f316cc483f36c1db1579d749218be66ab30e31b664996f6eeb9e89a6ffacff6c1763ce8d47dc8193e7e
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- `h herdr` and `hh` pane controls for Vim-style focus, two-pane reflow, resize, swap, and zoom
|
|
7
|
+
- `prefix+shift+h/j/k/l` reflows a two-pane tab toward an edge; `prefix+alt+h/j/k/l` resizes the current pane
|
|
8
|
+
|
|
9
|
+
## [0.1.384] - 2026-09-23
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- `h plist` command for working with property lists
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- publish script now requires hiiro unconditionally at startup instead of only when falling back to local version
|
|
16
|
+
|
|
3
17
|
## [0.1.381] - 2026-09-20
|
|
4
18
|
|
|
5
19
|
### Added
|
|
@@ -14,8 +28,6 @@
|
|
|
14
28
|
- `h save` subcommands: `ls`/`list`, `dir`, `show`/`cat`, `copy`, `open`, `edit`, `rm`/`remove` for managing saved files
|
|
15
29
|
- `t path`, `t cd`, `t start`, and `t switch` accept optional `APP` argument to select a configured relative directory beneath the task root
|
|
16
30
|
- APP resolves by exact name or unique case-sensitive prefix; fails when ambiguous or missing
|
|
17
|
-
|
|
18
|
-
### Added
|
|
19
31
|
- `t switch` / `t workspace` and `t cd` accept an optional APP positional (or `--app`) resolving through the apps registry by exact name or unique prefix; the workspace or pane cd targets the app directory under the task worktree, e.g. `t switch aldi cpm` opens `~/work/aldi/main/retailer-tools/content-page-migrator`
|
|
20
32
|
|
|
21
33
|
## [0.1.376] - 2026-09-14
|
|
@@ -143,14 +155,4 @@
|
|
|
143
155
|
|
|
144
156
|
### Removed
|
|
145
157
|
- Remove tmux paste-buffer, jumplist, task-color, focus-hook, and arbitrary-layout features that Herdr 0.8.2 does not support.
|
|
146
|
-
- Remove the old `Hiiro::Tmux` adapter and tmux-specific command tests.
|
|
147
|
-
|
|
148
|
-
### Fixed
|
|
149
|
-
- Strip the desktop notifier executable path and run notifications and sounds as detached processes instead of creating persistent Herdr tabs.
|
|
150
|
-
- Preserve `add_cmd` declaration locations and argument metadata in generated help; allow command groups to pass arguments and help through to child commands.
|
|
151
|
-
- Make undeclared `add_cmd opts:` entries boolean flags without consuming positional arguments; preserve explicit options and reserve conflicting short aliases.
|
|
152
|
-
- Show selected command options for `add_cmd -h`/`--help` without executing the command block.
|
|
153
|
-
- Focus the exact Herdr pane through the socket API and read the CLI's plain-text pane output without JSON parsing.
|
|
154
|
-
- Restore the missing `Hiiro::Bins` helper so `require "hiiro"` boots and commands like `h jumplist record` dispatch correctly.
|
|
155
|
-
- Make Hiiro's Ruby requirement explicit as Ruby 3.2+ and have rbenv-wide gem installs skip incompatible Ruby versions.
|
|
156
|
-
- Update the publish script to preserve the Ruby support constant, run only on supported Ruby, and install releases only into compatible rbenv versions.
|
|
158
|
+
- Remove the old `Hiiro::Tmux` adapter and tmux-specific command tests.
|
data/README.md
CHANGED
|
@@ -152,7 +152,7 @@ See the [task command reference](docs/t.md) for all commands and the [workflow i
|
|
|
152
152
|
| `h setup` | Install plugins and subcommands to system paths |
|
|
153
153
|
| `h edit` | Open the h script in your editor |
|
|
154
154
|
| `h alert` | macOS desktop notifications via terminal-notifier |
|
|
155
|
-
| `h herdr` | Herdr
|
|
155
|
+
| `h herdr` | Herdr task popups plus Vim-style pane focus, movement, resize, swap, and zoom controls (`h herdr install`) |
|
|
156
156
|
| `h task` | Same program as `t`: task records, todos, worktrees (`t NAME tree new`), and Herdr workspaces |
|
|
157
157
|
|
|
158
158
|
### External Subcommands
|
data/bin/h-herdr
CHANGED
|
@@ -10,6 +10,16 @@ require 'fileutils'
|
|
|
10
10
|
|
|
11
11
|
PLUGIN_ID = 'hiiro'
|
|
12
12
|
ACTIONS = %w[switch todo-add todos shell nvim].freeze
|
|
13
|
+
PANE_DIRECTIONS = {
|
|
14
|
+
'h' => 'left',
|
|
15
|
+
'j' => 'down',
|
|
16
|
+
'k' => 'up',
|
|
17
|
+
'l' => 'right',
|
|
18
|
+
'left' => 'left',
|
|
19
|
+
'down' => 'down',
|
|
20
|
+
'up' => 'up',
|
|
21
|
+
'right' => 'right',
|
|
22
|
+
}.freeze
|
|
13
23
|
INSTALL_DIR = Hiiro::Config.config_dir('herdr-plugin')
|
|
14
24
|
SOURCE_DIR = File.expand_path('../herdr-plugin', File.dirname(File.realpath(__FILE__)))
|
|
15
25
|
KEYS_SNIPPET = <<~TOML
|
|
@@ -43,6 +53,56 @@ KEYS_SNIPPET = <<~TOML
|
|
|
43
53
|
type = "plugin_action"
|
|
44
54
|
command = "hiiro.nvim"
|
|
45
55
|
description = "task notes in nvim"
|
|
56
|
+
|
|
57
|
+
# Vim-style pane layout controls. Herdr already uses prefix+h/j/k/l for focus.
|
|
58
|
+
# Uppercase rotates a two-pane tab so the current pane lands on that edge.
|
|
59
|
+
[[keys.command]]
|
|
60
|
+
key = "prefix+shift+h"
|
|
61
|
+
type = "shell"
|
|
62
|
+
command = "h herdr move left"
|
|
63
|
+
description = "move current pane to the left"
|
|
64
|
+
|
|
65
|
+
[[keys.command]]
|
|
66
|
+
key = "prefix+shift+j"
|
|
67
|
+
type = "shell"
|
|
68
|
+
command = "h herdr move down"
|
|
69
|
+
description = "move current pane to the bottom"
|
|
70
|
+
|
|
71
|
+
[[keys.command]]
|
|
72
|
+
key = "prefix+shift+k"
|
|
73
|
+
type = "shell"
|
|
74
|
+
command = "h herdr move up"
|
|
75
|
+
description = "move current pane to the top"
|
|
76
|
+
|
|
77
|
+
[[keys.command]]
|
|
78
|
+
key = "prefix+shift+l"
|
|
79
|
+
type = "shell"
|
|
80
|
+
command = "h herdr move right"
|
|
81
|
+
description = "move current pane to the right"
|
|
82
|
+
|
|
83
|
+
[[keys.command]]
|
|
84
|
+
key = "prefix+alt+h"
|
|
85
|
+
type = "shell"
|
|
86
|
+
command = "h herdr resize left"
|
|
87
|
+
description = "resize current pane left"
|
|
88
|
+
|
|
89
|
+
[[keys.command]]
|
|
90
|
+
key = "prefix+alt+j"
|
|
91
|
+
type = "shell"
|
|
92
|
+
command = "h herdr resize down"
|
|
93
|
+
description = "resize current pane down"
|
|
94
|
+
|
|
95
|
+
[[keys.command]]
|
|
96
|
+
key = "prefix+alt+k"
|
|
97
|
+
type = "shell"
|
|
98
|
+
command = "h herdr resize up"
|
|
99
|
+
description = "resize current pane up"
|
|
100
|
+
|
|
101
|
+
[[keys.command]]
|
|
102
|
+
key = "prefix+alt+l"
|
|
103
|
+
type = "shell"
|
|
104
|
+
command = "h herdr resize right"
|
|
105
|
+
description = "resize current pane right"
|
|
46
106
|
TOML
|
|
47
107
|
|
|
48
108
|
def herdr_bin
|
|
@@ -55,6 +115,45 @@ def source_dir
|
|
|
55
115
|
gem_root && File.join(gem_root, 'herdr-plugin')
|
|
56
116
|
end
|
|
57
117
|
|
|
118
|
+
def pane_direction!(value)
|
|
119
|
+
PANE_DIRECTIONS.fetch(value.to_s) do
|
|
120
|
+
raise Hiiro::Error, 'Direction must be h, j, k, l, left, down, up, or right'
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def pane_ratio!(value)
|
|
125
|
+
return nil if value.nil?
|
|
126
|
+
ratio = Float(value, exception: false)
|
|
127
|
+
raise Hiiro::Error, 'Ratio must be greater than 0 and less than 1' unless ratio && ratio.positive? && ratio < 1
|
|
128
|
+
ratio
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def move_current_pane(direction, ratio = nil)
|
|
132
|
+
current = herdr_client.current_pane
|
|
133
|
+
raise Hiiro::Error, 'No current Herdr pane' unless current
|
|
134
|
+
panes = herdr_client.panes(workspace: current.workspace_id).select { |pane| pane.tab_id == current.tab_id }
|
|
135
|
+
raise Hiiro::Error, "Move requires exactly two panes in the current tab; found #{panes.length}" unless panes.length == 2
|
|
136
|
+
other = panes.find { |pane| pane.id != current.id }
|
|
137
|
+
|
|
138
|
+
if %w[left up].include?(direction)
|
|
139
|
+
source, target = other, current
|
|
140
|
+
split = direction == 'left' ? 'right' : 'down'
|
|
141
|
+
move_ratio = ratio && 1.0 - ratio
|
|
142
|
+
focus = '--no-focus'
|
|
143
|
+
else
|
|
144
|
+
source, target = current, other
|
|
145
|
+
split = direction
|
|
146
|
+
move_ratio = ratio
|
|
147
|
+
focus = '--focus'
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
detached = system(herdr_bin, 'pane', 'move', source.id, '--new-tab', '--no-focus')
|
|
151
|
+
raise Hiiro::Error, 'Herdr could not detach the pane for reflow' unless detached
|
|
152
|
+
args = ['pane', 'move', source.id, '--tab', target.tab_id, '--target-pane', target.id, '--split', split]
|
|
153
|
+
args += ['--ratio', move_ratio.to_s] if move_ratio
|
|
154
|
+
raise Hiiro::Error, 'Herdr could not reflow the pane' unless system(herdr_bin, *args, focus)
|
|
155
|
+
end
|
|
156
|
+
|
|
58
157
|
Hiiro.run(*ARGV, external_commands: false) do
|
|
59
158
|
add_cmd(:install) do
|
|
60
159
|
no_args = opts.args.empty?
|
|
@@ -81,6 +180,33 @@ Hiiro.run(*ARGV, external_commands: false) do
|
|
|
81
180
|
|
|
82
181
|
add_cmd(:actions) { ACTIONS.each { |name| puts "hiiro.#{name}" } }
|
|
83
182
|
|
|
183
|
+
add_cmd(:focus, args: %i[direction]) do
|
|
184
|
+
direction = pane_direction!(opts.args.first)
|
|
185
|
+
raise Hiiro::Error, 'Herdr could not focus the pane' unless system(herdr_bin, 'pane', 'focus', '--current', '--direction', direction)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
add_cmd(:resize, args: %i[direction amount?]) do
|
|
189
|
+
direction = pane_direction!(opts.args.shift)
|
|
190
|
+
amount = opts.args.shift
|
|
191
|
+
args = ['pane', 'resize', '--current', '--direction', direction]
|
|
192
|
+
args += ['--amount', amount] if amount
|
|
193
|
+
raise Hiiro::Error, 'Herdr could not resize the pane' unless system(herdr_bin, *args)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
add_cmd(:swap, args: %i[direction]) do
|
|
197
|
+
direction = pane_direction!(opts.args.first)
|
|
198
|
+
raise Hiiro::Error, 'Herdr could not swap the pane' unless system(herdr_bin, 'pane', 'swap', '--current', '--direction', direction)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
add_cmd(:move, :layout, :arrange, args: %i[direction ratio?]) do
|
|
202
|
+
move_current_pane(pane_direction!(opts.args.shift), pane_ratio!(opts.args.shift))
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
add_cmd(:zoom) do
|
|
206
|
+
raise Hiiro::Error, 'h herdr zoom takes no arguments' unless opts.args.empty?
|
|
207
|
+
raise Hiiro::Error, 'Herdr could not zoom the pane' unless system(herdr_bin, 'pane', 'zoom', '--current', '--toggle')
|
|
208
|
+
end
|
|
209
|
+
|
|
84
210
|
# Headless: bound to a key, opens the popup with the chosen action.
|
|
85
211
|
add_cmd(:action, args: %i[name]) do
|
|
86
212
|
name = opts.args.first
|
data/bin/h-js
CHANGED
|
@@ -5,6 +5,27 @@ require 'hiiro'
|
|
|
5
5
|
# sed -n '/scripts.*[{]/,/[}]/p' package.json
|
|
6
6
|
|
|
7
7
|
Hiiro.run do
|
|
8
|
+
add_cmd :add, args: ['NAME', 'COMMAND...'] do
|
|
9
|
+
abort 'Usage: h-js add NAME COMMAND... (use -- before command flags)' unless opts.args.length >= 2
|
|
10
|
+
name, *command_args = opts.args
|
|
11
|
+
abort 'Script name cannot be blank' if name.strip.empty?
|
|
12
|
+
command = command_args.length == 1 ? command_args.first : Shellwords.join(command_args)
|
|
13
|
+
abort 'Script command cannot be blank' if command.strip.empty?
|
|
14
|
+
abort 'No package.json in the current directory' unless File.file?('package.json')
|
|
15
|
+
|
|
16
|
+
package = JSON.parse(File.read('package.json'))
|
|
17
|
+
abort 'package.json must contain an object' unless package.is_a?(Hash)
|
|
18
|
+
package['scripts'] = {} unless package.key?('scripts')
|
|
19
|
+
abort 'package.json scripts must be an object' unless package['scripts'].is_a?(Hash)
|
|
20
|
+
abort "Script #{name.inspect} already exists" if package['scripts'].key?(name)
|
|
21
|
+
|
|
22
|
+
package['scripts'][name] = command
|
|
23
|
+
File.write('package.json', JSON.pretty_generate(package) + "\n")
|
|
24
|
+
puts "Added script #{name.inspect} to package.json"
|
|
25
|
+
rescue JSON::ParserError => error
|
|
26
|
+
abort "Invalid package.json: #{error.message}"
|
|
27
|
+
end
|
|
28
|
+
|
|
8
29
|
add_cmd :pkg do
|
|
9
30
|
file, *_other = Dir.glob('package.json')
|
|
10
31
|
|
data/bin/h-plist
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'hiiro'
|
|
4
|
+
require 'open3'
|
|
5
|
+
require 'json'
|
|
6
|
+
|
|
7
|
+
PLIST_TYPES = %w[bool integer float date string data xml json dictionary array].freeze
|
|
8
|
+
PLIST_FORMATS = %w[xml1 binary1 json swift objc].freeze
|
|
9
|
+
|
|
10
|
+
def require_plist(path)
|
|
11
|
+
unless path && !path.empty?
|
|
12
|
+
STDERR.puts 'A plist path is required.'
|
|
13
|
+
exit 1
|
|
14
|
+
end
|
|
15
|
+
expanded = File.expand_path(path)
|
|
16
|
+
unless File.file?(expanded)
|
|
17
|
+
STDERR.puts "Plist not found: #{expanded}"
|
|
18
|
+
exit 1
|
|
19
|
+
end
|
|
20
|
+
expanded
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def run_plutil(*arguments, allow_failure: false)
|
|
24
|
+
stdout, stderr, status = Open3.capture3('plutil', *arguments)
|
|
25
|
+
unless status.success? || allow_failure
|
|
26
|
+
STDERR.print(stderr.empty? ? stdout : stderr)
|
|
27
|
+
exit status.exitstatus
|
|
28
|
+
end
|
|
29
|
+
[stdout, stderr, status]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def print_plutil(*arguments)
|
|
33
|
+
stdout, stderr, = run_plutil(*arguments)
|
|
34
|
+
STDOUT.print(stdout)
|
|
35
|
+
STDERR.print(stderr)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def validate_type(type)
|
|
39
|
+
return type if PLIST_TYPES.include?(type)
|
|
40
|
+
STDERR.puts "Unknown type #{type.inspect}. Use: #{PLIST_TYPES.join(', ')}"
|
|
41
|
+
exit 1
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def mutation_arguments(verb, key, type, values)
|
|
45
|
+
args = [verb, key, "-#{validate_type(type)}"]
|
|
46
|
+
unless %w[dictionary array].include?(type)
|
|
47
|
+
if values.empty?
|
|
48
|
+
STDERR.puts "A value is required for type #{type}."
|
|
49
|
+
exit 1
|
|
50
|
+
end
|
|
51
|
+
args << values.join(' ')
|
|
52
|
+
end
|
|
53
|
+
args
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
Hiiro.run(*ARGV) do
|
|
57
|
+
add_subcmd(:show, :print) do |path=nil|
|
|
58
|
+
print_plutil('-p', '--', require_plist(path))
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
add_subcmd(:get) do |path=nil, key=nil, format='raw'|
|
|
62
|
+
unless key
|
|
63
|
+
STDERR.puts 'Usage: h plist get <file> <keypath> [raw|json|xml1|binary1]'
|
|
64
|
+
exit 1
|
|
65
|
+
end
|
|
66
|
+
unless %w[raw json xml1 binary1].include?(format)
|
|
67
|
+
STDERR.puts 'Format must be raw, json, xml1, or binary1.'
|
|
68
|
+
exit 1
|
|
69
|
+
end
|
|
70
|
+
print_plutil('-extract', key, format, '-o', '-', '--', require_plist(path))
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
add_subcmd(:keys) do |path=nil, key=nil|
|
|
74
|
+
plist = require_plist(path)
|
|
75
|
+
stdout, = if key
|
|
76
|
+
run_plutil('-extract', key, 'json', '-expect', 'dictionary', '-o', '-', '--', plist)
|
|
77
|
+
else
|
|
78
|
+
run_plutil('-convert', 'json', '-o', '-', '--', plist)
|
|
79
|
+
end
|
|
80
|
+
value = JSON.parse(stdout)
|
|
81
|
+
unless value.is_a?(Hash)
|
|
82
|
+
STDERR.puts(key ? "Not a dictionary: #{key}" : 'The plist root is not a dictionary.')
|
|
83
|
+
exit 1
|
|
84
|
+
end
|
|
85
|
+
puts value.keys.sort
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
add_subcmd(:type) do |path=nil, key=nil|
|
|
89
|
+
unless key
|
|
90
|
+
STDERR.puts 'Usage: h plist type <file> <keypath>'
|
|
91
|
+
exit 1
|
|
92
|
+
end
|
|
93
|
+
print_plutil('-type', key, '--', require_plist(path))
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
add_subcmd(:lint) do |*paths|
|
|
97
|
+
if paths.empty?
|
|
98
|
+
STDERR.puts 'Usage: h plist lint <file...>'
|
|
99
|
+
exit 1
|
|
100
|
+
end
|
|
101
|
+
expanded = paths.map { |path| require_plist(path) }
|
|
102
|
+
print_plutil('-lint', '--', *expanded)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
add_subcmd(:set) do |path=nil, key=nil, *arguments|
|
|
106
|
+
unless key
|
|
107
|
+
STDERR.puts 'Usage: h plist set <file> <keypath> [type] <value>'
|
|
108
|
+
exit 1
|
|
109
|
+
end
|
|
110
|
+
type = PLIST_TYPES.include?(arguments.first) ? arguments.shift : 'string'
|
|
111
|
+
values = arguments
|
|
112
|
+
plist = require_plist(path)
|
|
113
|
+
_, _, status = run_plutil('-type', key, '--', plist, allow_failure: true)
|
|
114
|
+
verb = status.success? ? '-replace' : '-insert'
|
|
115
|
+
print_plutil(*mutation_arguments(verb, key, type, values), '--', plist)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
add_subcmd(:add, :insert) do |path=nil, key=nil, *arguments|
|
|
119
|
+
unless key
|
|
120
|
+
STDERR.puts 'Usage: h plist add <file> <keypath> [type] <value>'
|
|
121
|
+
exit 1
|
|
122
|
+
end
|
|
123
|
+
type = PLIST_TYPES.include?(arguments.first) ? arguments.shift : 'string'
|
|
124
|
+
values = arguments
|
|
125
|
+
print_plutil(*mutation_arguments('-insert', key, type, values), '--', require_plist(path))
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
add_subcmd(:rm, :remove, :delete) do |path=nil, key=nil|
|
|
129
|
+
unless key
|
|
130
|
+
STDERR.puts 'Usage: h plist rm <file> <keypath>'
|
|
131
|
+
exit 1
|
|
132
|
+
end
|
|
133
|
+
print_plutil('-remove', key, '--', require_plist(path))
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
add_subcmd(:convert) do |path=nil, format=nil, output=nil|
|
|
137
|
+
plist = require_plist(path)
|
|
138
|
+
unless PLIST_FORMATS.include?(format)
|
|
139
|
+
STDERR.puts "Usage: h plist convert <file> <#{PLIST_FORMATS.join('|')}> [output]"
|
|
140
|
+
exit 1
|
|
141
|
+
end
|
|
142
|
+
args = ['-convert', format]
|
|
143
|
+
args.concat(['-o', File.expand_path(output)]) if output
|
|
144
|
+
print_plutil(*args, '--', plist)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
add_subcmd(:json) do |path=nil|
|
|
148
|
+
print_plutil('-convert', 'json', '-r', '-o', '-', '--', require_plist(path))
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
add_subcmd(:xml) do |path=nil|
|
|
152
|
+
print_plutil('-convert', 'xml1', '-o', '-', '--', require_plist(path))
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
add_subcmd(:create) do |path=nil, format='xml1'|
|
|
156
|
+
unless path
|
|
157
|
+
STDERR.puts 'Usage: h plist create <file> [xml1|binary1|json]'
|
|
158
|
+
exit 1
|
|
159
|
+
end
|
|
160
|
+
unless %w[xml1 binary1 json].include?(format)
|
|
161
|
+
STDERR.puts 'Create format must be xml1, binary1, or json.'
|
|
162
|
+
exit 1
|
|
163
|
+
end
|
|
164
|
+
expanded = File.expand_path(path)
|
|
165
|
+
if File.exist?(expanded)
|
|
166
|
+
STDERR.puts "Refusing to overwrite existing file: #{expanded}"
|
|
167
|
+
exit 1
|
|
168
|
+
end
|
|
169
|
+
print_plutil('-create', format, expanded)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
add_subcmd(:edit) do |path=nil|
|
|
173
|
+
exec('safe_nvim', require_plist(path))
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
add_subcmd(:help) do
|
|
177
|
+
puts <<~HELP
|
|
178
|
+
h-plist — inspect and modify Apple property lists with plutil
|
|
179
|
+
|
|
180
|
+
READ:
|
|
181
|
+
h plist <file> Pretty-print a plist
|
|
182
|
+
h plist show <file> Pretty-print a plist
|
|
183
|
+
h plist get <file> <keypath> [format] Extract a value
|
|
184
|
+
h plist keys <file> [dict-keypath] List dictionary keys
|
|
185
|
+
h plist type <file> <keypath> Print a value's type
|
|
186
|
+
h plist lint <file...> Validate plist syntax
|
|
187
|
+
h plist json <file> Emit readable JSON
|
|
188
|
+
h plist xml <file> Emit XML
|
|
189
|
+
|
|
190
|
+
WRITE:
|
|
191
|
+
h plist set <file> <keypath> [type] <value> Insert or replace
|
|
192
|
+
h plist add <file> <keypath> [type] <value> Insert only
|
|
193
|
+
h plist rm <file> <keypath> Remove a value
|
|
194
|
+
h plist convert <file> <format> [output] Convert in place or copy
|
|
195
|
+
h plist create <file> [format] Create without overwrite
|
|
196
|
+
h plist edit <file> Open with safe_nvim
|
|
197
|
+
|
|
198
|
+
TYPES:
|
|
199
|
+
bool, integer, float, date, string (default), data, xml, json,
|
|
200
|
+
dictionary, array
|
|
201
|
+
|
|
202
|
+
Key paths use plutil syntax. Numeric components address array indexes.
|
|
203
|
+
Quote values containing spaces. Mutating commands edit the file in place.
|
|
204
|
+
HELP
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
add_default do |path=nil|
|
|
208
|
+
if path
|
|
209
|
+
print_plutil('-p', '--', require_plist(path))
|
|
210
|
+
else
|
|
211
|
+
run_subcmd(:help)
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|