closes#137
- right arrow consumed the escape sequence without forwarding it, so the
cursor couldn't move back right after moving left (60149a2)
- p10k's instant prompt redirects stdout to a temp file that exec iris
inherits, sending the overlay there instead of the terminal and looking
like a dead keyboard. Reopens /dev/tty when stdout isn't a terminal
(7ebbb0c)
- zsh/bash autostart lacked the interactivity check fish already had, so
agentic tools sourcing your rc file spawned a rogue iris that seized
/dev/tty (5fe58be)
currently, every command that doesn't have a completion spec is assumed
to be a cobra cli and it gets ran with a `__complete` argument. for non
cobra clis this can cause problems if those non-cobra clis have
sideeffects even when ran with the `__complete` argument, and there is
no way to disable this.
one of these problems was solved at #111, but a full solution would
probably require actual sandboxing which is i think is an overkill just
for attempting to get suggestions for unrecognized commands. instead of
sandboxing, this pr adds a config option for allowing only selected
commands to be probed and disallowing the rest.
currently the default is still allowing all (`["*"]`) so default
behavior is the same, but it might be better to just have a long list of
known cobra clis as the default instead.
here's a demo of a side effect caused by the probing, in this case
"deleting" a file with rmtrash without actually trying to run the
command:
https://github.com/user-attachments/assets/5256d363-5291-42e8-bb4f-cf7467927246
---------
Co-authored-by: shemishtamesh <shemishtamail@gmail.com>
closes#91
3 mode config atuin history
```toml
[core]
# 0 = off, 1 = atuin history only, 2 = atuin history + default history
atuin-history = 0
```
Default is Mode 0 (turn off), who uses atuin history has to config it
manually
Mode 1 = atuin only (as you can see only 11 commands):
<img width="1285" height="466" alt="image"
src="https://github.com/user-attachments/assets/ca520ec7-fb45-4403-8087-a4951ba8dba0"
/>
Mode 2 = combine shell history + atuin history (prefer atuin):
<img width="1261" height="469" alt="image"
src="https://github.com/user-attachments/assets/1558ad3e-38f3-4d6e-bc8e-cfc00ea9cb4b"
/>
Mode 0 = turn off atuin
---
Custom atuin db path if anyone's using their own path (leave empty to
use default from atuin)
```toml
atuin-db-path = ""
```
---
I also handled the search menu overlay of Atuin, IRIS won't show in this
mode, but you have to change the keybind between 2 tool cuz they're
using same keybind Ctrl + R, but I think using IRIS make it unnecessary
to use Atuin search mode (82b180c9610f75d41008a54dfde474c7f2cce015)
<img width="70%" alt="image"
src="https://github.com/user-attachments/assets/e0c62050-7e6e-4e37-a1cc-2bfb63e1e984"
/>
<i><b>Before (Menu layout completely broken)</b></i>
<img width="50%" alt="image"
src="https://github.com/user-attachments/assets/1e6d8de9-cde8-473d-8a42-4748c480c812"
/>
<i ><b>After handling (not shows anymore)</b></i>
closes#130
- CHANGELOG.md file for people who can view changelog from github
---
`iris changelog` command:
`iris changelog [version]` (e.g. iris changelog v0.5.1)
`iris changelog -n 3` (see changelog of 3 latest releaseas)
=> `iris changelog` looks just like CHANGELOG.md, grouped headers and
all. It only stops looking that way if we personally overwrite that
release's description with something else
=> With 1-hour local cache (invalidated on updater-channel change),
`--refresh` flag to bypass, graceful fallback to stale cache on GitHub
rate-limiting
---
- New auto update config
```toml
# 0 = off (default, notify only), 1 = auto-install, 2 = always confirm first
auto-update = 1
```
- New just debug-changelog and just debug-autoupdate recipes (fully
offline, mocked HTTP servers, no real network/config touched)
Fixes#124.
Since #78 the shell reports `IRIS_CWD` on `chpwd`, but the wrapper only
passes it to
`spec.SetCWD` for suggestions. Its own working directory never moves, so
tools that
read the pane's foreground process to locate the shell resolve the wrong
path after a
`cd`. I hit this with herdr, which stopped detecting the git repository
of a pane once
IRIS was in it. tmux uses the same lookup for `pane_current_path`.
The absolute path check matches what `spec.SetCWD` already does, so both
treat a
malformed value the same way. The `os.Chdir` error is dropped because
the path comes
from the shell integration, the user cannot act on the failure, and
keeping the last
known directory is better than stopping the loop.
`go test ./...` passes. I tested this end to end on macOS only: the
wrapper followed
the `cd`, and herdr picked the repository back up.
One limitation: the outer launcher process keeps its start directory,
only the wrapper
running `runWrapper` follows. That was enough for herdr, which reads the
wrapper.
closes#62
when you open a new Zellij pane, the shell inherits Iris’s environment
variables, so it thinks Iris is already running. But the pane doesn't
inherit the underlying connection (FD 13), so suggestions silently fail
into a dead pipe
the old code only checked for `tmux` by process name, ignoring Zellij
completely
- Fixed:
instead of checking for specific app names, Iris now tracks the active
terminal device (`IRIS_TTY`)
if a new shell detects that it's on a different `TTY` than Iris, it
clears the stale environment variables so Iris can start fresh. The
`IRIS_PID != PPID` check prevents Iris from trying to re-exec itself
when spawning sub-shells.
```sh
if [ -n "$IRIS_PID" ] && [ "$IRIS_PID" != "$PPID" ] && [ "${TTY:-$(tty 2>/dev/null)}" != "$IRIS_TTY" ]; then
unset IRIS_PID IRIS_IS_CHILD IRIS_FD IRIS_TTY
fi
```
closes#122
please read the conversation to understand this change
The bug was that the reset-mode-to-config-default logic already existed
in the code (activeMode = loadMode()) but sat in a switch case that
could never execute, the bytes it matched (\r, \n, Ctrl+C, Ctrl+U) were
already intercepted and handled earlier in the same loop iteration with
an unconditional continue, so control never reached that switch
After released v0.5.0, I saw that v0.5.0 showed only 1 commit changelog
instead of the real 16 commits since v0.4.21
Nightly builds tag every push to main, so a nightly tag can land on the
exact same commit as a stable release tag
GoReleaser picked that nearby nightly as the `previous release` when
building the changelog
Fixes:
- `.goreleaser.yaml`: added `git.ignore_tags`: ["*-nightly.*"] so
changelog diffing skips nightly tags entirely
- `nightly.yml`: the cleanup step deleted a tag named `nightly`, but
each run tags as `v<version>-nightly.<sha>`, so it never actually
deleted anything and nightly tags piled up unbounded. Now deletes all
previous `v*-nightly.*` tags/releases before creating the new one
Nightly updates correctly detected the newest version, but the installer
always queried GitHub’s `/releases/latest` endpoint. Since that endpoint
only returns the latest stable release, `iris update` downloaded the
stable binary even when the nightly channel was configured.
This change passes the selected nightly tag to the installer through
`IRIS_RELEASE_TAG`. When set, the installer queries
`/releases/tags/<tag>`, locates that nightly release’s assets, and
installs the correct binary. Stable updates continue to use
`/releases/latest` unchanged.
closes#112
Replace `os.UserConfigDir()` with explicit `~/.config` fallback to align
macOS, Linux, and other platforms on same config location
Respects `XDG_CONFIG_HOME` if set, otherwise uses `~/.config/iris/`
## Summary
Closes#108
This PR fixes two issues related to terminal interaction and rendering:
- Make Right Arrow ghost acceptance configurable instead of hard-coded.
- Correct overlay positioning when the shell prompt wraps across
terminal lines.
## Changes
### Right Arrow configuration
- Add a new `navigate-right` keybinding to the configuration.
- Add `navigate-right = "right"` to the default configuration to
preserve existing behavior.
- Update the wrapper to use the configured binding instead of a
hard-coded Right Arrow check.
- Forward the Right Arrow escape sequence to the PTY when
`navigate-right` is unset, allowing the shell or terminal to handle it
normally.
### Overlay positioning
- Compute the cursor's current column from the total visual width
instead of using the accumulated width directly.
- Correctly handle wrapped prompts by calculating the cursor column
modulo the terminal width.
- Clamp the overlay position so it never extends beyond the terminal
width.
- Extend debug logging with the computed cursor position to aid
troubleshooting.
## Why
Right Arrow ghost acceptance was previously implemented as a hard-coded
behavior, making it impossible to disable or remap through
configuration. This change makes it consistent with the existing
configurable keybindings while preserving the default behavior.
Overlay positioning assumed that the prompt length represented the
cursor's current column. When the prompt wrapped onto a new terminal
line, this assumption caused the suggestion overlay to be positioned
incorrectly. Computing the cursor column from the wrapped position
ensures the overlay is aligned with the actual cursor.
## Testing
- [x] Default configuration retains Right Arrow ghost acceptance.
- [x] Setting `navigate-right = ""` forwards Right Arrow to the shell.
- [x] Existing keybindings continue to function as before.
- [x] Overlay is correctly positioned for both short and wrapped
prompts.
- [x] Overlay remains within terminal bounds.
run the `__complete` probe subprocess in its own session so that a
cobra-incompatible binary that ignores `__complete` can't mess with the
user's controlling terminal.
tested on both macos and nixos.
encountered the problem while trying to use
[visidata](https://www.visidata.org/).
---------
Co-authored-by: shemishtamesh <shemishtamail@gmail.com>
Fixes#88
## Root cause
`MatchKey` treated `Ctrl+M` and the Enter key as the same raw byte
(`0x0d`). After editing the generated config, a `ctrl+m` binding could
shadow Enter, causing Return to toggle mode instead of executing the
selected command.
While investigating this, I also found that `MatchKey` only recognized
raw control bytes for `ctrl+<letter>` bindings. In Fish and terminals
that use the Kitty keyboard protocol (e.g. Kitty and Foot), those key
combinations may instead be sent as CSI sequences such as `\x1b[106;5u`,
preventing navigation bindings like `ctrl+j` / `ctrl+k` from being
matched.
## Changes
* `internal/config/keys.go`
* Reserve the Enter byte (`0x0d`) so it cannot be claimed by a `ctrl+m`
keybinding.
* Add `matchKittyCtrl()` to support Kitty keyboard protocol CSI
sequences for `ctrl+<letter>` bindings when the Ctrl modifier is
present.
* `root/wrapper.go`
* Extract `handleNavKey()` to remove duplicated navigation handling
logic.
* `internal/config/config_test.go`
* Add regression tests covering the Enter/`ctrl+m` fix and Kitty
keyboard protocol key sequences.
## Tested
* `go test ./...` — 201 passed
* Verified that Enter is no longer shadowed by `ctrl+m` after editing
the generated config.
* Verified that `ctrl+j` / `ctrl+k` navigation works correctly in Fish.
---------
Co-authored-by: verse91 <versedev.store@proton.me>
Co-authored-by: VERSE <sunnyone0901@gmail.com>
closes#57
IRIS now automatically read and suggest internal configuration aliases
for Git (`.gitconfig`, `.git/config`) and Cargo (`.cargo/config.toml`)
- Added the `Provider` interface and extended registry for CLI tools
that define aliases
- Git: parse aliases via `git config --show-scope`, supporting raw
tab/space separation and scope differentiation
- Cargo: traverse the directory tree upwards to root to read the
`.cargo/config.toml` configuration
- 0ms hot-path caching: key caching is calculated entirely via `os.Stat`
mtime (no subprocess spawn) combined with a 2-second TTL window to
ensure 0ms latency when typing
- Lookup integration: display alias suggestions at the subcommand level
and automatically expand aliases as the user enters further arguments
(ignore shell pipeline commands starting with `!`)
Commit `efc49ba` (feat: upgrade to lipgloss v2, #94) changed
`go.mod`/`go.sum` (lipgloss v1 → v2, ~24 dependency version bumps) but
did not update `vendorHash` in `flake.nix`.
As a result `nix build .#iris` (and any consumer) fails with a
fixed-output derivation hash mismatch:
```
error: hash mismatch in fixed-output derivation 'iris-<rev>-go-modules.drv':
specified: sha256-kBSMhUsuCKIjAXjGfl1WSjCX+tlGi9BTnkRu9ScW6M0=
got: sha256-KQNloP/Aj283YQ4d5LFu/2Pbb2HbVTZPhLK1fs4xvGw=
```
This one-line change updates `vendorHash` to the hash actually produced
by the module set at HEAD. Verified: `nix build .#iris` succeeds with
the corrected hash.
Run `nix flake update` afterwards to regenerate `flake.lock`.
Hi!
I upgraded lipgloss to v2 and also took the opportunity to migrate some
of the raw escape sequence handling to x/ansi. Feel free to cherry pick
whatever is helpful from this!
closes#71, #84, #86
- AUR
- Homebrew
- Nix
- Debian (.deb)
- RPM (.rpm)
- Aqua
- ASDF
This is my first time doing this, so there might be mistakes. If you
can't download it through any pkg manager, please leave a comment or
open an issue
---------
Co-authored-by: use-the-fork <23747916+use-the-fork@users.noreply.github.com>
closes#82
Also added a `HISTFILE` so it always reads the correct file that the
shell is pointing to
Is there a `HISTFILE`? If so, use it
If it's Zsh: Is there a `ZDOTDIR`? Use `ZDOTDIR/.zsh_history`
If it's Fish: Is there an `XDG_DATA_HOME`? Use
`XDG_DATA_HOME/fish/fish_history`
If none of them are present, revert to the default `$HOME/...`