GitHub - Sambigeara/fuzzynote
source link: https://github.com/Sambigeara/fuzzynote
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Fuzzynote (fzn)
Follow me on Twitter for the latest fzn
updates and announcements, or just to watch me talk to myself.
Terminal-based, hyper-fast, CRDT-backed, collaborative note-taking tool
Simple, powerful, extremely fast search
fzn
is local-first; remote-second. It acts on local in-memory data, meaning no expensive I/O and native speeds.
Instant search (over large datasets) via any number of full or fuzzy match groups.
Zoom in using common prefixes.
Things the user does in this gif :
- Opens
fzn
- Fuzzy searches for
shopping
, highlights matching lines withCtrl-s
, and zooms on common prefix withEnter
(=
denotes a full string match). - Adds new line (with auto-prepended
shopping
prefix) - Presses
Escape
to go to search line - Fuzzy searches for
impo
, highlights and zooms onimportant project
- Focuses on line
write `hello` script
, and opens a note buffer (in vim) withCtrl-o
- Adds the script, then saves and closes the vim buffer, thus attaching the note to the line
- Fuzzy matches on
fzn
, focuses on a line with a URL, and pressesCtrl-_
to match the URL and open in default browser
Real time collaboration
Backed by a CRDT-based, append-only, mergeable text database.
Collaborate on a list live, or make changes offline and sync later, with guaranteed and consistent output.
Rather than collaborating on multiple documents, fzn
will sync lines matching specific terms to different remotes. Remotes can have any number of "collaborators" with access.
In short, you can collaborate on multiple "documents" from the same view at the same time.
Frodo (left) and Joe (right) only share lines with match term important project
. Non-matched lines remain private. NOTE: Frodo and Joe are using the web support to manage their remotes, and for real time collaboration.
Remotes
A "remote" is a remote target where we sync lists.
- Sync all lines, or specify match terms to sync only some. A remote can be a full or partial view.
- Add any number of collaborators who will have access to each remote.
Web (quickstart)
- Simple remote management
- Real time collaboration
- Managed cloud data store, easy data sync across different computers (simply
fzn login
and startfzn
)
Note: for full transparency, if the project takes off, I'll integrate a paid subscription system to enable me to support the infrastructure and the project on an ongoing basis. I'll be proactive in communicating this and will acknowledge any support from early users when making any decisions! Consider this an N-month free trial with "early-release" user status.
S3 (quickstart)
Configure an S3 bucket yourself and share between collaborators for near real-time collaboration and backup.
Installation
Compile locally (requires Go):
git clone [email protected]:Sambigeara/fuzzynote.git cd fuzzynote make build # Installs binary to `/bin/fzn`
Or download the binary direct from the releases page.
Quickstart
Basic usage
- Install
fzn
- Start
./fzn
Web sign-up, terminal login
- Install
fzn
- Sign up here
- Login and follow prompts
./fzn login
- Start
./fzn
Add a "remote"
In this example, Frodo creates a remote for important project
- Open the interactive menu
./fzn cfg
- Select
Add new remote...
# Example output ? Select action: Remote: main (1748937357) ▸ Add new remote... Exit
- Specify the name, Frodo chooses
important project
✔ Add new remote... ✔ Specify name for new remote: important project
- Select newly created remote
? Select action: Remote: main (1748937357) ▸ Remote: important project (8934754397) Add new remote... Exit
- Set the "match term"
- All lines that match this term will sync with the remote
- Setting to an empty string will mean that ALL lines will be sync'd and all collaborators will have access
- Note: this includes lines that previously matched the term, but no longer do (e.g. if you delete the particular matching substring from the line)
# Select "Match" ? Remote: important project (8934754397): Manage collaborators... Name: important project ▸ Match: UPDATE ME 2596996162 IsActive: true Delete? (for all collaborators) Exit # Enter new match term and press Enter ✔ Enter new value: important project
Add a collaborator
Joe is invited to the important project
remote:
# Select "Manage collaborators..." ? Remote: important project (8934754397): ▸ Manage collaborators... Name: important project Match: important project IsActive: true Delete? (for all collaborators) Exit # Select "Add new collaborator..." ? Manage collaborators: ▸ Add new collaborator... Exit # Add email address, and press Enter ✔ Enter email address: [email protected]
Accept an invitation
Joe responds to the invite above
- Open the interactive menu
./fzn cfg
- Select the newly added remote - all invited remotes will start with
INVITE:
? Select action: Remote: main (6782346574) ▸ Remote: INVITE: important project (8934754397) Add new remote... Exit
- (Optional) update the name
# Select "Name" ? Remote: INVITE: important project (8934754397): ▸ Name: INVITE: important project Match: UPDATE ME 7398574395 IsActive: false Delete? Exit # Enter new name and press Enter ✔ Enter new value: important project
- Update the match term (this can be anything, and does not need to be consistent with other collaborator's match terms - but keeping them consistent is more predictable).
# Select "Match" ? Remote: important project (8934754397): Name: important project ▸ Match: UPDATE ME 7398574395 IsActive: false Delete? Exit # Enter new match term and press Enter ✔ Enter new value: important project
- Activate the remote (it's
false
by default to prevent accidental sharing of your personal notes)
# Select "IsActive" and choose "true" ? Remote: important project (8934754397): Name: important project Match: important project ▸ IsActive: false Delete? Exit
- Start the app - the sync will occur in the background and you can start collaborating on the remote
./fzn
Setup an S3 remote
-
Configure an S3 bucket with access via access key/secret - link to AWS docs.
-
Create a file called
config.yml
in thefzn
root directory. By default, this is at$HOME/.fzn/
on*nix
systems, or%USERPROFILE%\.fzn
on Windows. If you've already runfzn
, the root directory will have aprimary.db
and one or morewal_*.db
files, for reference. -
Add the following to the file, using key/secret from above:
s3: - key: {AWS_ACCESS_KEY} secret: {AWS_SECRET} bucket: bucket_name prefix: some_prefix
- Optional: specify the "match term" to only sync matching lines:
s3: - key: {AWS_ACCESS_KEY} secret: {AWS_SECRET} bucket: bucket_name prefix: some_prefix match: some match term # Add this to only sync matching lines
-
Optional: set the
sync
intervals (via envvar or inline flag on startup). The default interval is 10 seconds, meaningfzn
will flush local changes to the remote every 10 seconds. Likewise, in a separate thread,fzn
will retrieve new changes from the remote every 10 seconds.If you want nearer real-time sync (perhaps for collaboration?), you can reduce the interval via an envvar, e.g.:
export FZN_SYNC_FREQUENCY_MS=1000
or in-line:
./fzn --sync-frequency-ms=1000
Each of the above will set to the interval to 1000ms (1 second).
Note: extensive I/O to S3 can be more expensive than expected, albeit only pennies in the beginning - worth keeping an eye out if you favour short sync intervals.
-
Start the app, if you haven't already
./fzn
Other remote platforms?
At present fzn
only supports S3 as a remote target. However, it is easily extensible, so if there is demand for additional platforms, then please make a request via a new issue!
Controls
Navigation
- General navigation:
Arrow keys
- Go to start of line:
Ctrl-a
- Go to end of line:
Ctrl-e
- Go to search line:
ESCAPE
- Exit:
Double ESCAPE
Search (top line)
Any number of tab-separated search groups are applied to the lists independently. Use full, fuzzy, or inverse string matching.
- Full string match: start the search group with
=
- Inverse string match (full strings), start the search group with
=!
- Separate search groups:
TAB
foo # matches "fobo" =foo # will not match "fobo" =!foo # will ignore any lines with "foo" in it
List items (lines)
- Add new line (prepending search line text to new line):
Enter
- Delete line:
Ctrl-d
- Undo/Redo last operation:
Ctrl-u/Ctrl-r
- Moves current item up or down:
Alt-]/Alt-[
- Open note on the currently selected list item in selected terminal editor (default is Vim). Save in editor saves to list item:
Ctrl-o
- Copy current item into buffer:
Ctrl-c
- Paste current item from buffer:
Ctrl-p
Group operations
- Select item under cursor:
Ctrl-s
- Set common prefix string to search line:
Enter
- Clear selected items:
Escape
Visibility
- Toggle global visibility:
Ctrl-i (top line)
- Toggle list item visibility:
Ctrl-i
Handy functions
- Open first URL in list item:
Ctrl-_
- Copy first URL from list item into the system clipboard:
Ctrl-c
Token operators
The following character combinations will parse to different useful outputs:
{d}
: A date in the formMon, Jan 2, 2006
Configuration
fzn --help
will print out the configurable options.
> fzn --help
Usage: fzn [options] [arguments]
OPTIONS
--root/$FZN_ROOT <string>
--colour/$FZN_COLOUR <string> (default: light)
--editor/$FZN_EDITOR <string> (default: vim)
--sync-frequency-ms/$FZN_SYNC_FREQUENCY_MS <uint> (default: 10000)
--gather-frequency-ms/$FZN_GATHER_FREQUENCY_MS <uint> (default: 30000)
--help/-h
display this help messageshell
editor
: specifies the terminal editor which is used when opening notes on list items.vim
,emacs
andnano
all appear to work. Others may too.sync-frequency-ms
/gather-frequency-ms
: these can be ignored for nowroot
: (mostly for testing and can be ignored for general use) specifies the directory thatfzn
will treat as it's root. By default, this is at$HOME/.fzn/
on*nix
systems, or%USERPROFILE%\.fzn
on Windows.
Future plans
- Web-app (Wasm)
- E2E encryption
Issues/Considerations
The terminal client is fully functioning, however given the early stages of the project, and the (at points) rapid development, there are likely to be some bugs hanging around. Things to look out for:
- If
fzn
is left idle for some time, it might ungracefully error (usually due to some web connection issue) and exit. Under very rare circumstances, it might hang and require the user to kill the process manually (viakill
commands). Due to the nature of the app, your data will almost certainly be unaffected. - Sometimes the sync algorithm gets confused. Usually, all that is needed is just to add or delete a line or character (adding additional events to the WAL will trigger a flush and get things moving). If that doesn't work, turning it off and on again usually does the trick.
- Notice something wrong? Please do open an issue!
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK