A TUI/CLI reference manager based on Zotero, built with pyzotero and featuring an fzf-based selector.
Project description
Refero
A smarter, lighter scholarly workflow for Zotero — right from your terminal.
Getting Started • Features • Usage • Picker Styles • Keybindings • Contributing • License
Overview
- TUI/CLI client of Zotero.
- Collecting, organizing, annotating, citing, and sharing research for local (desktop) and web Zotero via
pyzotero+fzfpicker. - Modes:
local: A faster, lag-free viewer/exporter, switch to Web Mode automatically when creating, editing, or deleting items.web: Full features(view/create/edit/delete/export). No installation of Zotero client needed.
- Scope: browse/view/export/edit plus add-by-identifier (DOI/arXiv).
System Support
MacOS– SupportedLinux– SupportedWindows– Supported
Features
- Interactive fuzzy picker (fzf): fast search with presets (
compact,aligned,colored,preview,title-preview), configurable preview window, and rich keybindings. - Local + Web backends: browse offline via Zotero Local API(pyzotero); switch to Zotero Web API for full create/edit/delete.
- Search & filters: query by title/author/year/tags/collections; supports grouping by collection path.
- Smart open: open best attachment (PDF → HTML → URL/DOI), or a specific type; open directly in Zotero.
- Export: generate bibliographies (e.g., BibTeX), including to files named by citekey.
- Add by identifier: create items from DOI/arXiv; apply tags and collections; dry‑run to preview Zotero JSON.
- Edit metadata (web): update fields and content fields (Note, Abstract, Extra); Markdown note editor supported.
- Label editor: manage Tags and Collections together or individually; interactive picker-based flows.
- Attachment management: attach/remove PDFs; bulk remove all PDF attachments from an item.
- Safe deletes: move to Trash with confirmation; optional no‑prompt and permanent variants.
- Configurable: tune
fzfheader/match formats, preview pane, and extra flags to fit your workflow.
Getting Started
Prerequisite
## MacOS
brew install fzf # version >=0.55
## Linux
sudo apt install fzf # Debian/Ubuntu
sudo dnf install fzf # Fedora
sudo pacman -S fzf # Arch
sudo apt install xclip # Debian/Ubuntu
sudo dnf install xclip # Fedora
sudo pacman -S xclip # Arch
Install
Method 1:
pip install refero
Method 2 (direct from Git):
pip install git+git://github.com/chu-/Refero.git@main
Method 3 (editable):
git clone https://github.com/chu-/Refero
cd ./ref
pip install -e .
Configure
Create ~/.config/ref/config.yaml:
fzf-binary: fzf
fzf-extra-flags: ["--ansi", "--multi", "-i", "--delimiter= :: "]
fzf-extra-bindings: [
"ctrl-s:jump",
"ctrl-r:execute(open zotero://select/library/items/{5})",
"ctrl-o:execute(ref open {5})",
"ctrl-e:execute(ref edit {5})",
"ctrl-t:execute(ref label {+5} --pick)",
"ctrl-l:execute(ref relate {5} --pick)",
#"ctrl-t:execute(ref tag {+5} --pick)",
#"ctrl-t:execute(ref collection {+5})",
"ctrl-k:execute(ref note {5})",
#"ctrl-k:execute(ref abstract {5})",
#"ctrl-k:execute(ref extra {5})",
"ctrl-a:execute(ref export {5} --format bibtex --out {6}.bib)",
"ctrl-d:execute(ref delete {+5})+abort",
# "ctrl-d:execute(ref delete -y {+5})", # skip confirmation
# macOS defaults to pbcopy; Linux uses xclip -selection clipboard automatically
"alt-y:execute-silent(echo -n {5} | pbcopy)+abort"
]
fzf-header-format: "{doc[title]:<70.70} :: {doc[author]} :: «{doc[year]}» :: :{doc[tags]} :: {doc[key]} :: {doc[citekey]}"
match-format: "{doc[title]} :: {doc[author]} :: {doc[year]} :: :{doc[tags]}"
# Default note editor mode: text | markdown
note_editor: markdown
# Diff display style for concurrent edits: table | inline | pairwise
diff_style: inline
zotero:
mode: local # local | web
local_api: http://localhost:23119/api # Zotero desktop local API
endpoint: null # optional override; if set, takes precedence over local_api
library_id: 0 # required when mode: web (your numeric Zotero user id)
library_type: user
api_key: null # required when mode: web (Zotero Web API key)
storage_dir: ~/Zotero/storage # local Zotero storage path for attachments
Linux:
refdetects Linux at runtime and swaps the default picker bindings to usexdg-openfor Zotero links andxclip -selection clipboardfor clipboard actions. Installxclipfirst (for example,sudo apt install xclip) to enable thealt-yclipboard binding.Windows: bindings fall back to PowerShell (
Start-Process) for opening Zotero links and the built-incliputility for clipboard actions.
Usage
Basic help:
ref -h
ref --help
ref list -h
ref pick -h
ref view -h
ref export -h
ref label -h
ref tag -h
ref collection -h
ref coll -h
ref set -h
ref add -h
ref delete -h
Quick search (default subcommand is list, -q implied with positional args):
ref "graph neural"
ref smith
ref keyword1 keyword2 keyword3
ref keyword --author chu
ref --year 2025 keyword1 keyword2
Filters and collections:
ref -q graph --limit 10
ref --tag nlp
ref --author chu
ref -c ABCD1234
ref -c "Reading List"
ref --title transformer
ref --year 2021 --title "transformer"
Picker (interactive with fzf; default subcommand is -q for ref pick):
ref pick "graph neural" --limit 10
ref pick --tag nlp
ref pick -c "NLP"
ref pick --author smith --year 2021
Open best attachment / specific types:
ref open <KEY> # best: PDF -> HTML -> URL/DOI
ref open --pdf <KEY>
ref open --html <KEY>
ref open --url <KEY>
View metadata:
ref view <KEY>
ref preview <KEY>
Export:
ref export <KEY>... --format bibtex
ref export <KEY>... --format bibtex --out out.bib
Add by identifier (web mode only):
# requires zotero.api_key and zotero.library_id
ref add --doi xx.xxxx/xx -c "Reading List,AI" # collections by name or key
ref add --arxiv xx.xxxx/xx --tag "ml,arxiv"
ref add --doi xx.xxxx/xx --dry-run # show Zotero JSON only
Edit metadata (web mode only):
# requires zotero.api_key and zotero.library_id
ref edit <KEY>
Label editor (tags and collections):
# Editor mode: opens a temp file to edit collections and tags
ref label <KEY>
# Interactive mode: pick tags, then collections via fzf
# Use Tab to selected/unselected labels, Type+Enter to add new tags, then Enter/Esc to confirm/cancel selection"),
ref label <KEY> --pick
ref label <KEY> --pick -l 100
Edit tags only:
ref tag <KEY>
ref tag <KEY> --pick
ref tag <KEY> --pick -l 100
Edit collections only:
ref collection <KEY>
ref coll <KEY> --pick
ref coll <KEY> --pick -l 100
Set metadata (web mode only):
# requires zotero.api_key and zotero.library_id
# add tags
ref set <KEY> -g ml -g reading
ref set <KEY> --tag "ml,reading,arxiv"
# add to collections (by key or name; partial names supported)
ref set <KEY> -c ABCD1234 -c "Reading List"
ref set <KEY> --collection "AI,Reading List"
# attach a local PDF as a linked-file attachment
ref set <KEY> --pdf ~/Downloads/paper.pdf
# remove from collections / remove tags
ref set <KEY> --collection-rm "Reading List" --tag-rm ml
# remove all PDF attachments
ref set <KEY> --pdf-rm
# combine
ref set <KEY> -g nlp -c "Reading List" --pdf ./paper.pdf
Delete (web mode only):
ref delete <KEY>... # confirm once, moves to Trash
ref delete -y <KEY>... # no prompt
ref delete --permanent <KEY> # moves to Trash; empty Trash to purge
Content Fields Editing:
Edit text-based fields on an item:
ref note <KEY> # Edit or create a child Note
# use Markdown editor mode for notes (requires deps: markdown, markdownify)
ref note <KEY> --note-editor markdown
# or set config: note_editor: markdown|text, and markdown is default
ref abstract <KEY> # Edit the abstractNote field
ref extra <KEY> # Edit the Extra field
Editing concurrency
ref edit/extra/abstract/note <KEY>- When editing, if changed remotely after you opened the editor, ref detects it and shows a three‑way diff of base → remote → yours.
- Actions:
- [y]ours: overwrite the remote note with your edited text.
- [r]emote: reload the latest remote content into the editor and let you re‑edit.
- [m]erge: merge the remote note with your edited text, only in
ref edit <KEY> - [a]bort: cancel without saving.
- The diff display is controlled by
diff_styleinconfig.yaml(table|inline|pairwise). - Note editor mode is controlled by
note_editorinconfig.yaml(defaultmarkdown) or--note-editorper‑command.
Diff style for concurrent edits
When editing text fields and a newer remote version exists, ref shows a diff before you choose an action. Control the display via diff_style in config.yaml:
- table: concise summary showing values for base, yours, remote
- inline: single-line bracketed inline diff like
[base → remote → yours] - pairwise: compact inline diff using the C++ Diff Match Patch engine via
fast-diff-match-patch. Deletions are shown in red; remote insertions(base→remote) in blue; local insertions(base→yours) in green.
Example:
diff_style: inline # table | inline | pairwise
More examples
# list (explicit)
ref list -q "graph neural"
ref list --tag nlp
ref list -d 7b00316
ref list --doi 7b00316
ref list --author smith
ref list -c ABCD1234
ref list -c "Reading List"
ref list --title transformer
ref list --year 2021
ref list -a smith -y 2021
ref list --author smith --year 2021
ref list --title transformer --tag nlp
ref list --author "smith" --title "transformer"
ref list --year 2021 --title "transformer"
# group by collection path
ref list --group-by-collection # groups items under "Parent -> Child"
# pick (explicit)
ref pick -q graph
ref pick -d 7b00316
ref pick --doi 7b00316
ref pick -a smith
ref pick --title transformer
Picker Styles
You can quickly change how items are rendered in the picker using the fzf-style preset. Supported values: compact, aligned, colored, preview, title-preview.
Minimal example:
fzf-style: aligned # compact | aligned | colored | preview | title-preview
Preset details:
- aligned: padded columns for title/author/year
- compact: shorter columns (good for narrow terminals)
- colored: ANSI-colored title/author/year (requires
--ansi), set color_scheme in config:calm|bright|minimal|contrast - preview: adds a right-side preview pane with colored JSON using
jqif available - title-preview: colored title line + compact metadata preview
Preview preset sets (simplified):
fzf-extra-flags:
- --ansi
- --delimiter
- " :: "
- --preview
- "sh -c 'if command -v jq >/dev/null 2>&1; then ref view \"$1\" | jq -C .; else ref view \"$1\" | cat; fi' sh {5}"
- --preview-window
- right,60,border
You can override the preview window regardless of preset:
fzf-preview-window: up,60,border
# or:
fzf-preview-window: up,1,wrap
fzf-preview-window: down,1,wrap
Keybindings
Press Ctrl-h in any picker to show a dynamic help overlay derived from your fzf-extra-bindings in config.yaml. If no bindings are configured, a concise default help is shown.
In the pick view:
- ctrl-n/p: navigate items
- Tab: toggle select/unselect (multi-select)
- ctrl-r: open in Zotero (
zotero://select/library/items/{key}) - ctrl-s: jump to target item
- ctrl-o: open best attachment (such as
ref open {key}) - ctrl-e: edit metadata (web mode; such as
ref edit {key}) - ctrl-t: edit Label, Tags or Collections (such as
ref label {key} --pick) - ctrl-l: relate items (such as
ref relate {key} --pick) - ctrl-k: edit Content Fields: Note, Extra or Abstract with default Markdown editor
- ctrl-a: export to BibTeX as
{citekey}.bib - ctrl-d: delete selected items (
ref delete {+5}; add-yto skip confirmation) - alt-y: copy field of item (clipboard command defaults to
pbcopyon macOS,xclip -selection clipboardon Linux, orclipon Windows). Use {1},{2},{3}... to select different field item.
Notes
- With
zotero.mode: local,refuseszotero.local_api(defaulthttp://localhost:23119/api). - For the Zotero Web API, set
zotero.mode: weband providezotero.api_keyandzotero.library_id. Optionally setzotero.endpoint. fzfmatches displayed fields; include fields infzf-header-formatto broaden matching.
Contributing
Issues and PRs are welcome.
License
This project is licensed under the terms of the MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file refero-0.1.0.tar.gz.
File metadata
- Download URL: refero-0.1.0.tar.gz
- Upload date:
- Size: 82.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
315cc141b399d98e6f46283f38579a093b363716883a036d9ce6d6a27f085a25
|
|
| MD5 |
060eefe59a4f59ef1f05982deda10edf
|
|
| BLAKE2b-256 |
d1e2dd25bba66a4b46ff1e9291558d76cec199c4059ca8e49aaee80195237d9a
|
File details
Details for the file Refero-0.1.0-py3-none-any.whl.
File metadata
- Download URL: Refero-0.1.0-py3-none-any.whl
- Upload date:
- Size: 76.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a330e571bdd40929f119fa552b561c6e81235937ad677b931787ce16cc235228
|
|
| MD5 |
3045bce6639abdf145e37e190b0d5f92
|
|
| BLAKE2b-256 |
f606c756e232ad1df30855b3527543aa9f65d1201c73502b7e4ada167f2922a7
|