Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zi automatically selects only initial result #1022

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ When calling `zoxide init`, the following flags are available:
- `--cmd j` would change the commands to (`j`, `ji`).
- `--cmd cd` would replace the `cd` command.
- `--hook <HOOK>`

- Changes how often zoxide increments a directory's score:

| Hook | Description |
Expand All @@ -414,6 +415,7 @@ Environment variables[^2] can be used for configuration. They must be set before
`zoxide init` is called.

- `_ZO_DATA_DIR`

- Specifies the directory in which the database is stored.
- The default value varies across OSes:

Expand All @@ -427,6 +429,7 @@ Environment variables[^2] can be used for configuration. They must be set before
- When set to 1, `z` will print the matched directory before navigating to
it.
- `_ZO_EXCLUDE_DIRS`

- Excludes the specified directories from the database.
- This is provided as a list of [globs][glob], separated by OS-specific
characters:
Expand All @@ -437,6 +440,7 @@ Environment variables[^2] can be used for configuration. They must be set before
| Windows | `;` | `$HOME;$HOME/private/*` |

- By default, this is set to `"$HOME"`.

- `_ZO_FZF_OPTS`
- Custom options to pass to [fzf] during interactive selection. See
[`man fzf`][fzf-man] for the list of options.
Expand All @@ -447,6 +451,10 @@ Environment variables[^2] can be used for configuration. They must be set before
- `_ZO_RESOLVE_SYMLINKS`
- When set to 1, `z` will resolve symlinks before adding directories to the
database.
- `_ZO_ZI_ONLY_RESULT`
- When set to 1, `zi foo` will automatically select the only result `fzf` returns.
- However, if only one result is available during selection in the `fzf` menu,
it will not be automatically selected.

## Third-party integrations

Expand Down
1 change: 1 addition & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use cmd::Cmd;
fn main() -> io::Result<()> {
// Since we are generating completions in the package directory, we need to
// set this so that Cargo doesn't rebuild every time.
println!("cargo:rustc-check-cfg=cfg(test)");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=src/");
println!("cargo:rerun-if-changed=templates/");
Expand Down
3 changes: 2 additions & 1 deletion src/cmd/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ https://github.com/ajeetdsouza/zoxide
{tab}<bold>_ZO_EXCLUDE_DIRS</bold> {tab}List of directory globs to be excluded
{tab}<bold>_ZO_FZF_OPTS</bold> {tab}Custom flags to pass to fzf
{tab}<bold>_ZO_MAXAGE</bold> {tab}Maximum total age after which entries start getting deleted
{tab}<bold>_ZO_RESOLVE_SYMLINKS</bold>{tab}Resolve symlinks when storing paths").into_resettable()
{tab}<bold>_ZO_RESOLVE_SYMLINKS</bold>{tab}Resolve symlinks when storing paths
{tab}<bold>_ZO_ZI_ONLY_RESULT</bold>{tab}Automatically select only result after fzf initialization (but not while fuzzy finding)").into_resettable()
}
}

Expand Down
49 changes: 46 additions & 3 deletions src/cmd/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ impl Query {
let now = util::current_time()?;
let mut stream = self.get_stream(db, now)?;

if self.interactive {
if self.interactive && config::zi_only_result() {
self.query_interactive_only_result(&mut stream, now)
} else if self.interactive {
self.query_interactive(&mut stream, now)
} else if self.list {
self.query_list(&mut stream, now)
Expand All @@ -33,13 +35,54 @@ impl Query {
let mut fzf = Self::get_fzf()?;
let selection = loop {
match stream.next() {
Some(dir) if Some(dir.path.as_ref()) == self.exclude.as_deref() => continue,
Some(dir) if Some(dir.path.as_ref()) == self.exclude.as_deref() => {
continue;
}
Some(dir) => {
if let Some(selection) = fzf.write(dir, now)? {
break selection;
}
}
None => break fzf.wait()?,
None => {
break fzf.wait()?;
}
}
};

if self.score {
print!("{selection}");
} else {
let path = selection.get(7..).context("could not read selection from fzf")?;
print!("{path}");
}
Ok(())
}

fn query_interactive_only_result(&self, stream: &mut Stream, now: Epoch) -> Result<()> {
let mut fzf = Self::get_fzf()?;
let mut stream_length = 0;
let mut last_dir: Option<String> = None;
let selection = loop {
match stream.next() {
Some(dir) if Some(dir.path.as_ref()) == self.exclude.as_deref() => {
stream_length += 1;
last_dir = Some(format!("{}\n", dir.display().with_score(now)));
continue;
}
Some(dir) => {
stream_length += 1;
last_dir = Some(format!("{}\n", dir.display().with_score(now)));
if let Some(selection) = fzf.write(dir, now)? {
break selection;
}
}
None if stream_length == 1 => {
fzf.close()?;
break last_dir.unwrap();
}
None => {
break fzf.wait()?;
}
}
};

Expand Down
4 changes: 4 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,7 @@ pub fn maxage() -> Result<Rank> {
pub fn resolve_symlinks() -> bool {
env::var_os("_ZO_RESOLVE_SYMLINKS").is_some_and(|var| var == "1")
}

pub fn zi_only_result() -> bool {
env::var_os("_ZO_ZI_ONLY_RESULT").is_some_and(|var| var == "1")
}
4 changes: 4 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ impl FzfChild {
_ => bail!("fzf returned an unknown error"),
}
}

pub fn close(&mut self) -> Result<()> {
self.0.kill().map_err(|err| err.into())
}
}

/// Similar to [`fs::write`], but atomic (best effort on Windows).
Expand Down
Loading