settle

Settle is a Zettelkasten note manager. All notes are written in Markdown and are
stored locally.

Note that settle does not edit the files it handles directly. Therefore,
you're probably going to want to use (or write) a plugin for your favourite
editor, such as settle.vim for Vim and
Neovim.

Table of contents

  - Synopsis
  - Options
  - Commands
      - the query command
          - examples
      - the sync command
          - examples
  - Configuration
  - Templates
      - Template placeholders
  - Setting up shell autocompletion
      - bash
      - zsh
      - fish
  - License and credits

Synopsis

settle [--help | -h | --version | -v]
settle {sync | -S} [-p | -c | -u | -g | -m | -n]
settle {query | -Q} [-t | -p | -g | -x | -l | -b | -o | -f | -s | --graph]
settle ls ['tags' | 'projects' | 'ghosts' | 'path']

Options

  - -h, --help - Print usage information

  - -V, --version - Print version information

Commands

  - help - print usage information broadly or, if a subcommand is given, usage
    information for said subcommand

  - compl <SHELL> - generate autocompletion file for a certain shell (currently
    supported: zsh, bash, fish) (see: section on shell
    autocompletion)

  - ls <OBJECT> - list things that don't directly involve notes. Possible
    arguments:
    
      - path -  print the path to the Zettelkasten
      - tags -  print all existing tags
      - projects - print all existing projects
      - ghosts - print notes that have links pointed to them, but don't exist

  - query or -Q (described below)

  - sync or -S (described below)

All warnings and errors are printed to stderr, so you can suppress them (e.g.
2>/dev/null).

A short briefing on regular expressions (REGEX)

Regex is a useful tool that settle has support for, because it provides
wildcards and patterns which allow matching multiple strings. See this regular
expression specification for
all supported patterns. But here are a few of the most useful characters you're
going to use:

  - . - match any single character
  - * - match the previous character zero or more times
  - + - match the previous character one or more times

If you wanted to match a literal ., * or +, you'd have to escape them with
a backslash: \., \* and \+ respectively.

Here are some examples:

  - .* matches anything, even empty strings
  - f+ matches the character f one or more times
  - .*foo.* matches any string containing the word foo

The query command

The query command is used for getting information related to the notes in the
Zettelkasten - most of the time, by returning those that match a given set of
criteria.

Note that the various options listed here all compound - that is to say, every
option acts as a criteria for querying. settle query --title "Foo.*" --tag "bar" will only return notes whose titles starts with Foo AND have the tag
bar, not notes whose titles start with Foo OR have the tag bar. By
default, when no filter parameter is applied (that is to say, settle query is
ran without options), all notes are returned.

Here are the query flags:

  - -t | --title <REGEX> - keep Zettel whose title matches <REGEX>

  - -p | --project <REGEX> - keep Zettel that are in projects that match <REGEX>

  - -g | --tag <REGEX> - keep Zettel that have at least one tag that matches <REGEX>

  - -x | --text <REGEX> - keep Zettel whose text contents match <REGEX>. Note
    that this unlocks the %a format option (see below)

  - -l | --links <REGEX> - keep Zettel to which the notes whose titles match
    <REGEX> have links pointing to

  - -b | --backlinks <REGEX> - keep Zettel which have a link pointing to the
    notes whose title match <REGEX>

  - -o | --loners - keep Zettel that have no links pointing to other notes AND
    have no links pointing to them.

  - -e | --exact - disable ALL regular expressions and make every match literal

  - -f | --format <FORMAT> - print according to <FORMAT>, which has the
    following flags:
    
      - %t - the title of the note
      - %p - the project [name] of the note
      - %P - the absolute path to the Zettel
      - %l - the (forward) links of the Zettel
      - %b - the backlinks of the Zettel; note that since settle only stores
        forward links in the database, fetching backlinks is a little bit more
        time consuming
      - %a - the first match that settle found while filtering the Zettel with
        the --text option. This may not be that useful for exact matches, but
        it's extremely useful when using regex. Note that, when your query is
        enclosed with two .* on both ends, such as ".*example.*", the entire
        matched line is printed; the practical application is giving your
        queries a (somewhat limited) context.

  - -s | --link_sep <SEPARATOR> - specify the separator used between both forward
    links and backlinks, when several have to be printed consequently. Default
    value is |

  - --graph - transform the output into [DOT
    format](https://en.wikipedia.org/wiki/DOT_(graph_description_language),
    where the nodes are the individual Zettel titles and the edges are links.
    You can then run the file through e.g. Graphviz or xdot (or anything that
    can read DOT for that matter) to render the graph into an image, or, rather,
    explore the graph interactively.
    
    NOTE: all direct (immediate) links that the notes in the query results have
    will appear on the graph.

Examples of the query command

  - settle query --text "sample" --loners returns all notes that contain sample
    in their text and that aren't linked with any other note in the
    Zettelkasten.

  - settle query --project "" --title ".*word.*" returns all notes that are in
    the main Zettelkasten (the empty-string project) and have the word word
    within their title.

  - settle query --project main --title ".*word.*" is exactly the same as above,
    but uses the project-alias main.

  - settle query --formatting "[%p] %t" --link_sep " | " is the same as the
    default format. Note that, since no links are printed, the separator is
    actually never used for this format.

  - settle query --tag "literature" --links "Neurons" returns all notes that
    have the literature tag and link to a note called precisely Neurons
    (note the absence of regex wildcards)

  - settle query --format "[%P]\t%l" --link_sep "\t" --title "Note.*" takes
    every Zettel whose title starts with Note and prints their absolute path
    between square brackets, but also their forward links, which are separated
    with tabs.

  - settle query --graph 1>graph.gv prints DOT output of the entire Zettelkasten
    to a file called graph.gv

  - settle query --graph --tag "neurology" prints a DOT graph of all Zettel
    who have the neurology tag.

  - settle query --text ".*search.*" --format "%t (%a)" not only prints every
    Zettel that contains the word search in it, but it also prints every line
    containing that word.

The sync command

The sync command is used for changing things related to notes - be it creating
new ones, updating their metadata in the database, moving them from a project to
another project, or renaming them.

Note that, unlike the query command, the options that do take arguments here
don't work with regex (except --move). Matches here need to be exact, since
we're dealing with more or less precise database changes. Also, unless
specified otherwise, most/all options are mutually exclusive.

Here are the options for this command:

  - -p | --project <PROJECT> - specify project (NOTE: by itself, this option
    doesn't do anything)

  - -c | --create <TITLE> - create a new Zettel with the provided title. If the
    --project flag is provided, then make it part of that project; if not,
    then add it to the main Zettelkasten project. This operation may only fail
    if there is already an entry in the database with the same title.

  - -u | --update <PATH> - update a note's metadata, given its path (relative or
    absolute) on the filesystem. If the file is not part of the Zettelkasten or
    doesn't exist, then an error is returned.

  - -g | --generate - generate the entire database; that is to say, every
    Zettel's metadata is updated (or added, if they weren't in the database
    already)

  - -m | --move <REGEX> - move all Zettel whose title matches <REGEX> to the
    project specified by the --project option

  - -n | --rename <FROM> <TO> - rename <FROM> to <TO>, preserving the
    project and making all the links that pointed to the old title point to the
    new one instead. If there is no Zettel with <FROM> as title, or if there
    already is a note with <TO> as a title, then an error is returned.

Examples of the sync command

  - settle sync --generate (re)generates the database from the notes in the
    Zettelkasten directory

  - settle sync --create "My super interesting note" creates a note called My super interesting note inside the main Zettelkasten project

  - settle sync --create "A novel idea" --project "inbox" creates a note called
    A novel idea inside the inbox project

  - assuming that the Zettelkasten directory is at $HOME/zettelkasten, then
    settle sync --update "$HOME/zettelkasten/My super interesting note" updates
    the metadata of My super interesting note in the database

  - settle sync --move "My super interesting note" --project "inbox" moves the
    note My super interesting note to the inbox project

  - settle sync --rename "My super interesting note" "My less interesting note"
    renames My super interesting note to My less interesting note

Configuration

The location of the configuration file may be influenced by environment
variables:

1.  if $SETTLE_CONFIG is set: $SETTLE_CONFIG
2.  if $XDG_CONFIG_HOME is set: $XDG_CONFIG_HOME/settle/settle.yaml
3.  default: $HOME/.config/settle/settle.yaml

A generic configuration file is automatically created when settle is ran with
any command (except compl), if it doesn't already exist.

Configuration properties

  - zettelkasten - directory where the notes are stored
    
    If you don't specify an absolute path, e.g. notes, it's assumed you want
    your Zettelkasten to be at ~/notes. You can also use paths containing
    environment variables or paths starting with a tilde (~)

  - template - path to Zettel template
    
    If empty, or if the path is invalid, then templates won't be used. You can
    use paths containing environment variables, or a leading tilde (~).

Templates

Template files are used when creating new Zettel. The text they contain gets put
inside said new note, replacing variables.

Template placeholders

  - ${TITLE} - replaced with the title of the note
  - ${DATE} - replaced with the output of date +%Y-%m-%d

Example template

# ${TITLE}



### References

- ${DATE}:

Shell autocompletion

Shell completions can be generated by the user at runtime, by using the compl
subcommand. In most cases, you'll need to create a directory for user-defined
completions, then add settle's output to it.

If you want XDG compliance, you probably know what you're doing, so just replace
a few things here and there.

bash

Add the following text to the ~/.bash_completion file:

for comp_file in ~/.bash_completion.d/*; do
    [[ -f "${comp_file}" ]] && . "${comp_file}"
done

And then run the following commands:

mkdir ~/.bash_completion.d
settle compl bash >~/.bash_completion.d/settle

zsh

In your terminal, run:

mkdir ~/.zsh_completion.d
settle compl zsh >~/.zsh_completion.d/_settle

Then add this line in your zshrc:

fpath=(${HOME}/.zsh_completion.d $fpath)

fish

Run the following commands:

mkdir -p ~/.config/fish/completions
settle compl fish >~/.config/fish/completions/settle.fish

nushell

From inside nushell, you can generate the completion file by running:

settle compl nu | save ~/.config/nushell/settle.nu

(Note that settle compl nushell also works; nushell is just an alias for
nu)

And then you'll need to add the following line to your config.nu, so that the
completions are sourced on every shell startup:

source ~/.config/nushell/settle.nu

License & Credits

Licensed under MIT

Written by xylous <xylous.e@gmail.com>
