feat: export command

This commit is contained in:
Jnyandeep 2026-07-30 11:05:26 +05:30
parent cf086b057d
commit e6bce5c9a5
12 changed files with 397 additions and 46 deletions

5
Cargo.lock generated
View File

@ -797,9 +797,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.149"
version = "1.0.151"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
dependencies = [
"itoa",
"memchr",
@ -1171,6 +1171,7 @@ dependencies = [
"rstest",
"rstest_reuse",
"serde",
"serde_json",
"tempfile",
"time",
"which",

View File

@ -18,8 +18,8 @@ maintenance = { status = "actively-developed" }
[dependencies]
anyhow = "1.0.32"
askama = { version = "0.16.0", default-features = false, features = [
"derive",
"std",
"derive",
"std",
] }
bincode = "1.3.1"
clap = { version = "4.3.0", features = ["derive"] }
@ -30,7 +30,12 @@ fastrand = "2.0.0"
glob = "0.3.0"
ouroboros = "0.18.3"
serde = { version = "1.0.116", features = ["derive"] }
time = { version = "0.3.47", default-features = false, features = ["parsing", "macros", "std"] }
serde_json = "1.0.151"
time = { version = "0.3.47", default-features = false, features = [
"parsing",
"macros",
"std",
] }
[target.'cfg(windows)'.dependencies]
which = "8.0.2"
@ -60,46 +65,46 @@ strip = true
[package.metadata.deb]
assets = [
[
"target/release/zoxide",
"usr/bin/",
"755",
],
[
"contrib/completions/zoxide.bash",
"usr/share/bash-completion/completions/zoxide",
"644",
],
[
"contrib/completions/zoxide.fish",
"usr/share/fish/vendor_completions.d/",
"664",
],
[
"contrib/completions/_zoxide",
"usr/share/zsh/vendor-completions/",
"644",
],
[
"man/man1/*",
"usr/share/man/man1/",
"644",
],
[
"README.md",
"usr/share/doc/zoxide/",
"644",
],
[
"CHANGELOG.md",
"usr/share/doc/zoxide/",
"644",
],
[
"LICENSE",
"usr/share/doc/zoxide/",
"644",
],
[
"target/release/zoxide",
"usr/bin/",
"755",
],
[
"contrib/completions/zoxide.bash",
"usr/share/bash-completion/completions/zoxide",
"644",
],
[
"contrib/completions/zoxide.fish",
"usr/share/fish/vendor_completions.d/",
"664",
],
[
"contrib/completions/_zoxide",
"usr/share/zsh/vendor-completions/",
"644",
],
[
"man/man1/*",
"usr/share/man/man1/",
"644",
],
[
"README.md",
"usr/share/doc/zoxide/",
"644",
],
[
"CHANGELOG.md",
"usr/share/doc/zoxide/",
"644",
],
[
"LICENSE",
"usr/share/doc/zoxide/",
"644",
],
]
extended-description = """\
zoxide is a smarter cd command, inspired by z and autojump. It remembers which \

View File

@ -94,6 +94,50 @@ _arguments "${_arguments_options[@]}" : \
;;
esac
;;
(export)
_arguments "${_arguments_options[@]}" : \
'-h[Print help]' \
'--help[Print help]' \
'-V[Print version]' \
'--version[Print version]' \
":: :_zoxide__subcmd__export_commands" \
"*::: :->export" \
&& ret=0
case $state in
(export)
words=($line[1] "${words[@]}")
(( CURRENT += 1 ))
curcontext="${curcontext%:*:*}:zoxide-export-command-$line[1]:"
case $line[1] in
(csv)
_arguments "${_arguments_options[@]}" : \
'-h[Print help]' \
'--help[Print help]' \
'-V[Print version]' \
'--version[Print version]' \
&& ret=0
;;
(json)
_arguments "${_arguments_options[@]}" : \
'-h[Print help]' \
'--help[Print help]' \
'-V[Print version]' \
'--version[Print version]' \
&& ret=0
;;
(text)
_arguments "${_arguments_options[@]}" : \
'-h[Print help]' \
'--help[Print help]' \
'-V[Print version]' \
'--version[Print version]' \
&& ret=0
;;
esac
;;
esac
;;
(import)
_arguments "${_arguments_options[@]}" : \
'--merge[Merge into existing database]' \
@ -219,6 +263,7 @@ _zoxide_commands() {
local commands; commands=(
'add:Add a new directory or increment its rank' \
'edit:Edit the database' \
'export:Export entries from the database' \
'import:Import entries from another application' \
'init:Generate shell configuration' \
'query:Search for a directory in the database' \
@ -261,6 +306,30 @@ _zoxide__subcmd__edit__subcmd__reload_commands() {
local commands; commands=()
_describe -t commands 'zoxide edit reload commands' commands "$@"
}
(( $+functions[_zoxide__subcmd__export_commands] )) ||
_zoxide__subcmd__export_commands() {
local commands; commands=(
'csv:' \
'json:' \
'text:' \
)
_describe -t commands 'zoxide export commands' commands "$@"
}
(( $+functions[_zoxide__subcmd__export__subcmd__csv_commands] )) ||
_zoxide__subcmd__export__subcmd__csv_commands() {
local commands; commands=()
_describe -t commands 'zoxide export csv commands' commands "$@"
}
(( $+functions[_zoxide__subcmd__export__subcmd__json_commands] )) ||
_zoxide__subcmd__export__subcmd__json_commands() {
local commands; commands=()
_describe -t commands 'zoxide export json commands' commands "$@"
}
(( $+functions[_zoxide__subcmd__export__subcmd__text_commands] )) ||
_zoxide__subcmd__export__subcmd__text_commands() {
local commands; commands=()
_describe -t commands 'zoxide export text commands' commands "$@"
}
(( $+functions[_zoxide__subcmd__import_commands] )) ||
_zoxide__subcmd__import_commands() {
local commands; commands=(

View File

@ -27,6 +27,7 @@ Register-ArgumentCompleter -Native -CommandName 'zoxide' -ScriptBlock {
[CompletionResult]::new('--version', '--version', [CompletionResultType]::ParameterName, 'Print version')
[CompletionResult]::new('add', 'add', [CompletionResultType]::ParameterValue, 'Add a new directory or increment its rank')
[CompletionResult]::new('edit', 'edit', [CompletionResultType]::ParameterValue, 'Edit the database')
[CompletionResult]::new('export', 'export', [CompletionResultType]::ParameterValue, 'Export entries from the database')
[CompletionResult]::new('import', 'import', [CompletionResultType]::ParameterValue, 'Import entries from another application')
[CompletionResult]::new('init', 'init', [CompletionResultType]::ParameterValue, 'Generate shell configuration')
[CompletionResult]::new('query', 'query', [CompletionResultType]::ParameterValue, 'Search for a directory in the database')
@ -81,6 +82,37 @@ Register-ArgumentCompleter -Native -CommandName 'zoxide' -ScriptBlock {
[CompletionResult]::new('--version', '--version', [CompletionResultType]::ParameterName, 'Print version')
break
}
'zoxide;export' {
[CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('-V', '-V ', [CompletionResultType]::ParameterName, 'Print version')
[CompletionResult]::new('--version', '--version', [CompletionResultType]::ParameterName, 'Print version')
[CompletionResult]::new('csv', 'csv', [CompletionResultType]::ParameterValue, 'csv')
[CompletionResult]::new('json', 'json', [CompletionResultType]::ParameterValue, 'json')
[CompletionResult]::new('text', 'text', [CompletionResultType]::ParameterValue, 'text')
break
}
'zoxide;export;csv' {
[CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('-V', '-V ', [CompletionResultType]::ParameterName, 'Print version')
[CompletionResult]::new('--version', '--version', [CompletionResultType]::ParameterName, 'Print version')
break
}
'zoxide;export;json' {
[CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('-V', '-V ', [CompletionResultType]::ParameterName, 'Print version')
[CompletionResult]::new('--version', '--version', [CompletionResultType]::ParameterName, 'Print version')
break
}
'zoxide;export;text' {
[CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('-V', '-V ', [CompletionResultType]::ParameterName, 'Print version')
[CompletionResult]::new('--version', '--version', [CompletionResultType]::ParameterName, 'Print version')
break
}
'zoxide;import' {
[CompletionResult]::new('--merge', '--merge', [CompletionResultType]::ParameterName, 'Merge into existing database')
[CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help')

View File

@ -22,6 +22,9 @@ _zoxide() {
zoxide,edit)
cmd="zoxide__subcmd__edit"
;;
zoxide,export)
cmd="zoxide__subcmd__export"
;;
zoxide,import)
cmd="zoxide__subcmd__import"
;;
@ -46,6 +49,15 @@ _zoxide() {
zoxide__subcmd__edit,reload)
cmd="zoxide__subcmd__edit__subcmd__reload"
;;
zoxide__subcmd__export,csv)
cmd="zoxide__subcmd__export__subcmd__csv"
;;
zoxide__subcmd__export,json)
cmd="zoxide__subcmd__export__subcmd__json"
;;
zoxide__subcmd__export,text)
cmd="zoxide__subcmd__export__subcmd__text"
;;
zoxide__subcmd__import,atuin)
cmd="zoxide__subcmd__import__subcmd__atuin"
;;
@ -71,7 +83,7 @@ _zoxide() {
case "${cmd}" in
zoxide)
opts="-h -V --help --version add edit import init query remove"
opts="-h -V --help --version add edit export import init query remove"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@ -176,6 +188,62 @@ _zoxide() {
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
zoxide__subcmd__export)
opts="-h -V --help --version csv json text"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
zoxide__subcmd__export__subcmd__csv)
opts="-h -V --help --version"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
zoxide__subcmd__export__subcmd__json)
opts="-h -V --help --version"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
zoxide__subcmd__export__subcmd__text)
opts="-h -V --help --version"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
zoxide__subcmd__import)
opts="-h -V --merge --help --version atuin autojump fasd z z.lua zsh-z"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then

View File

@ -24,6 +24,7 @@ set edit:completion:arg-completer[zoxide] = {|@words|
cand --version 'Print version'
cand add 'Add a new directory or increment its rank'
cand edit 'Edit the database'
cand export 'Export entries from the database'
cand import 'Import entries from another application'
cand init 'Generate shell configuration'
cand query 'Search for a directory in the database'
@ -71,6 +72,33 @@ set edit:completion:arg-completer[zoxide] = {|@words|
cand -V 'Print version'
cand --version 'Print version'
}
&'zoxide;export'= {
cand -h 'Print help'
cand --help 'Print help'
cand -V 'Print version'
cand --version 'Print version'
cand csv 'csv'
cand json 'json'
cand text 'text'
}
&'zoxide;export;csv'= {
cand -h 'Print help'
cand --help 'Print help'
cand -V 'Print version'
cand --version 'Print version'
}
&'zoxide;export;json'= {
cand -h 'Print help'
cand --help 'Print help'
cand -V 'Print version'
cand --version 'Print version'
}
&'zoxide;export;text'= {
cand -h 'Print help'
cand --help 'Print help'
cand -V 'Print version'
cand --version 'Print version'
}
&'zoxide;import'= {
cand --merge 'Merge into existing database'
cand -h 'Print help'

View File

@ -28,6 +28,7 @@ complete -c zoxide -n "__fish_zoxide_needs_command" -s h -l help -d 'Print help'
complete -c zoxide -n "__fish_zoxide_needs_command" -s V -l version -d 'Print version'
complete -c zoxide -n "__fish_zoxide_needs_command" -f -a "add" -d 'Add a new directory or increment its rank'
complete -c zoxide -n "__fish_zoxide_needs_command" -f -a "edit" -d 'Edit the database'
complete -c zoxide -n "__fish_zoxide_needs_command" -f -a "export" -d 'Export entries from the database'
complete -c zoxide -n "__fish_zoxide_needs_command" -f -a "import" -d 'Import entries from another application'
complete -c zoxide -n "__fish_zoxide_needs_command" -f -a "init" -d 'Generate shell configuration'
complete -c zoxide -n "__fish_zoxide_needs_command" -f -a "query" -d 'Search for a directory in the database'
@ -49,6 +50,17 @@ complete -c zoxide -n "__fish_zoxide_using_subcommand edit; and __fish_seen_subc
complete -c zoxide -n "__fish_zoxide_using_subcommand edit; and __fish_seen_subcommand_from increment" -s V -l version -d 'Print version'
complete -c zoxide -n "__fish_zoxide_using_subcommand edit; and __fish_seen_subcommand_from reload" -s h -l help -d 'Print help'
complete -c zoxide -n "__fish_zoxide_using_subcommand edit; and __fish_seen_subcommand_from reload" -s V -l version -d 'Print version'
complete -c zoxide -n "__fish_zoxide_using_subcommand export; and not __fish_seen_subcommand_from csv json text" -s h -l help -d 'Print help'
complete -c zoxide -n "__fish_zoxide_using_subcommand export; and not __fish_seen_subcommand_from csv json text" -s V -l version -d 'Print version'
complete -c zoxide -n "__fish_zoxide_using_subcommand export; and not __fish_seen_subcommand_from csv json text" -f -a "csv"
complete -c zoxide -n "__fish_zoxide_using_subcommand export; and not __fish_seen_subcommand_from csv json text" -f -a "json"
complete -c zoxide -n "__fish_zoxide_using_subcommand export; and not __fish_seen_subcommand_from csv json text" -f -a "text"
complete -c zoxide -n "__fish_zoxide_using_subcommand export; and __fish_seen_subcommand_from csv" -s h -l help -d 'Print help'
complete -c zoxide -n "__fish_zoxide_using_subcommand export; and __fish_seen_subcommand_from csv" -s V -l version -d 'Print version'
complete -c zoxide -n "__fish_zoxide_using_subcommand export; and __fish_seen_subcommand_from json" -s h -l help -d 'Print help'
complete -c zoxide -n "__fish_zoxide_using_subcommand export; and __fish_seen_subcommand_from json" -s V -l version -d 'Print version'
complete -c zoxide -n "__fish_zoxide_using_subcommand export; and __fish_seen_subcommand_from text" -s h -l help -d 'Print help'
complete -c zoxide -n "__fish_zoxide_using_subcommand export; and __fish_seen_subcommand_from text" -s V -l version -d 'Print version'
complete -c zoxide -n "__fish_zoxide_using_subcommand import; and not __fish_seen_subcommand_from atuin autojump fasd z z.lua zsh-z" -l merge -d 'Merge into existing database'
complete -c zoxide -n "__fish_zoxide_using_subcommand import; and not __fish_seen_subcommand_from atuin autojump fasd z z.lua zsh-z" -s h -l help -d 'Print help'
complete -c zoxide -n "__fish_zoxide_using_subcommand import; and not __fish_seen_subcommand_from atuin autojump fasd z z.lua zsh-z" -s V -l version -d 'Print version'

View File

@ -43,6 +43,27 @@ module completions {
--version(-V) # Print version
]
# Export entries from the database
export extern "zoxide export" [
--help(-h) # Print help
--version(-V) # Print version
]
export extern "zoxide export csv" [
--help(-h) # Print help
--version(-V) # Print version
]
export extern "zoxide export json" [
--help(-h) # Print help
--version(-V) # Print version
]
export extern "zoxide export text" [
--help(-h) # Print help
--version(-V) # Print version
]
# Import entries from another application
export extern "zoxide import" [
--merge # Merge into existing database

View File

@ -111,6 +111,61 @@ const completion: Fig.Spec = {
},
],
},
{
name: "export",
description: "Export entries from the database",
subcommands: [
{
name: "csv",
options: [
{
name: ["-h", "--help"],
description: "Print help",
},
{
name: ["-V", "--version"],
description: "Print version",
},
],
},
{
name: "json",
options: [
{
name: ["-h", "--help"],
description: "Print help",
},
{
name: ["-V", "--version"],
description: "Print version",
},
],
},
{
name: "text",
options: [
{
name: ["-h", "--help"],
description: "Print help",
},
{
name: ["-V", "--version"],
description: "Print version",
},
],
},
],
options: [
{
name: ["-h", "--help"],
description: "Print help",
},
{
name: ["-V", "--version"],
description: "Print version",
},
],
},
{
name: "import",
description: "Import entries from another application",

View File

@ -43,6 +43,7 @@ https://github.com/ajeetdsouza/zoxide
pub enum Cmd {
Add(Add),
Edit(Edit),
Export(Export),
Import(Import),
Init(Init),
Query(Query),
@ -88,6 +89,24 @@ pub enum EditCommand {
Reload,
}
/// Export entries from the database
#[derive(Debug, Parser)]
#[clap(
author,
help_template = HelpTemplate,
)]
pub struct Export {
#[clap(subcommand)]
pub cmd: ExportCommand,
}
#[derive(Clone, Debug, Subcommand)]
pub enum ExportCommand {
Csv,
Json,
Text,
}
/// Import entries from another application
#[derive(Debug, Parser)]
#[clap(

39
src/cmd/export.rs Normal file
View File

@ -0,0 +1,39 @@
use std::io::{self, Write};
use serde_json::to_writer_pretty;
use crate::{
cmd::{Export, ExportCommand, Run},
db::Database,
error::BrokenPipeHandler,
};
impl Run for Export {
fn run(&self) -> anyhow::Result<()> {
let db = Database::open()?;
let dirs = db.dirs();
let out = &mut io::stdout().lock();
match &self.cmd {
ExportCommand::Csv => {
writeln!(out, "path,rank,last_accessed").pipe_exit("stdout")?;
for dir in dirs {
writeln!(out, "{},{},{}", dir.path, dir.rank, dir.last_accessed)
.pipe_exit("stdout")?;
}
}
ExportCommand::Json => {
to_writer_pretty(&mut *out, dirs)?;
writeln!(out).pipe_exit("stdout")?;
}
ExportCommand::Text => {
for dir in dirs {
writeln!(out, "{}|{}|{}", dir.path, dir.rank, dir.last_accessed)
.pipe_exit("stdout")?;
}
}
}
Ok(())
}
}

View File

@ -1,6 +1,7 @@
mod add;
mod cmd;
mod edit;
mod export;
mod import;
mod init;
mod query;
@ -20,6 +21,7 @@ impl Run for Cmd {
Cmd::Add(cmd) => cmd.run(),
Cmd::Edit(cmd) => cmd.run(),
Cmd::Import(cmd) => cmd.run(),
Cmd::Export(cmd) => cmd.run(),
Cmd::Init(cmd) => cmd.run(),
Cmd::Query(cmd) => cmd.run(),
Cmd::Remove(cmd) => cmd.run(),