aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.coveragerc6
-rw-r--r--.gitignore3
-rw-r--r--CHANGELOG.rst161
-rw-r--r--CHANGELOG.txt102
-rw-r--r--CONTRIBUTING.rst93
-rw-r--r--LICENSE2
-rw-r--r--Makefile104
-rw-r--r--Pipfile27
-rw-r--r--README.rst91
-rw-r--r--TODO.txt1
-rw-r--r--docs/Makefile2
-rw-r--r--docs/source/changelog.rst1
-rw-r--r--docs/source/conf.py74
-rw-r--r--docs/source/configuration.rst632
-rw-r--r--docs/source/configuration/colors.rst205
-rw-r--r--docs/source/configuration/genopts.rst157
-rw-r--r--docs/source/configuration/intro.rst3
-rw-r--r--docs/source/configuration/keybindings.rst254
-rw-r--r--docs/source/contributing.rst3
-rw-r--r--docs/source/index.rst37
-rw-r--r--docs/source/nncli-cat.1.rst27
-rw-r--r--docs/source/nncli-create.1.rst22
-rw-r--r--docs/source/nncli-delete.1.rst22
-rw-r--r--docs/source/nncli-dump.1.rst22
-rw-r--r--docs/source/nncli-edit.1.rst22
-rw-r--r--docs/source/nncli-export.1.rst27
-rw-r--r--docs/source/nncli-favorite.1.rst22
-rw-r--r--docs/source/nncli-import.1.rst22
-rw-r--r--docs/source/nncli-list.1.rst22
-rw-r--r--docs/source/nncli-sync.1.rst17
-rw-r--r--docs/source/nncli.1.rst53
-rw-r--r--docs/source/nncli.config.5.rst56
-rw-r--r--docs/source/usage.rst220
-rw-r--r--docs/source/usage/cat-args.rst3
-rw-r--r--docs/source/usage/cat-desc.rst4
-rw-r--r--docs/source/usage/cat-example.rst11
-rw-r--r--docs/source/usage/create-desc.rst3
-rw-r--r--docs/source/usage/create-example.rst7
-rw-r--r--docs/source/usage/delete-args.rst3
-rw-r--r--docs/source/usage/delete-desc.rst1
-rw-r--r--docs/source/usage/dump-args.rst8
-rw-r--r--docs/source/usage/dump-desc.rst6
-rw-r--r--docs/source/usage/edit-args.rst3
-rw-r--r--docs/source/usage/edit-desc.rst2
-rw-r--r--docs/source/usage/export-args.rst8
-rw-r--r--docs/source/usage/export-desc.rst11
-rw-r--r--docs/source/usage/export-example.rst10
-rw-r--r--docs/source/usage/favorite-args.rst3
-rw-r--r--docs/source/usage/favorite-desc.rst1
-rw-r--r--docs/source/usage/genopts.rst24
-rw-r--r--docs/source/usage/import-desc.rst5
-rw-r--r--docs/source/usage/import-example.rst4
-rw-r--r--docs/source/usage/list-args.rst4
-rw-r--r--docs/source/usage/list-desc.rst4
-rw-r--r--docs/source/usage/subopts.rst23
-rw-r--r--docs/source/usage/sync-desc.rst3
-rw-r--r--pyproject.toml108
-rw-r--r--pytest.ini2
-rw-r--r--requirements-dev.txt531
-rw-r--r--requirements.txt37
-rw-r--r--src/nncli/__init__.py (renamed from nncli/__init__.py)2
-rw-r--r--src/nncli/__main__.py (renamed from nncli/__main__.py)0
-rw-r--r--src/nncli/cli.py (renamed from nncli/cli.py)16
-rw-r--r--src/nncli/clipboard.py (renamed from nncli/clipboard.py)0
-rw-r--r--src/nncli/config.py (renamed from nncli/config.py)0
-rw-r--r--src/nncli/gui.py (renamed from nncli/gui.py)0
-rw-r--r--src/nncli/log.py (renamed from nncli/log.py)0
-rw-r--r--src/nncli/nextcloud_note.py (renamed from nncli/nextcloud_note.py)0
-rw-r--r--src/nncli/nncli.py (renamed from nncli/nncli.py)37
-rw-r--r--src/nncli/notes_db.py (renamed from nncli/notes_db.py)4
-rw-r--r--src/nncli/temp.py (renamed from nncli/temp.py)0
-rw-r--r--src/nncli/user_input.py (renamed from nncli/user_input.py)0
-rw-r--r--src/nncli/utils.py (renamed from nncli/utils.py)0
-rw-r--r--src/nncli/view_help.py (renamed from nncli/view_help.py)0
-rw-r--r--src/nncli/view_log.py (renamed from nncli/view_log.py)0
-rw-r--r--src/nncli/view_note.py (renamed from nncli/view_note.py)0
-rw-r--r--src/nncli/view_titles.py (renamed from nncli/view_titles.py)0
-rw-r--r--tox.ini34
78 files changed, 2228 insertions, 1206 deletions
diff --git a/.coveragerc b/.coveragerc
deleted file mode 100644
index 579f18d..0000000
--- a/.coveragerc
+++ /dev/null
@@ -1,6 +0,0 @@
-[run]
-branch = True
-omit = nncli/__main__.py
-
-[report]
-show_missing = True
diff --git a/.gitignore b/.gitignore
index 00a2572..ea34a57 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,4 +7,5 @@ MANIFEST
docs/build/
.tox
htmlcov/
-Pipfile.lock
+docs/html/
+docs/man/
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
new file mode 100644
index 0000000..ad498f4
--- /dev/null
+++ b/CHANGELOG.rst
@@ -0,0 +1,161 @@
+Changelog
+=========
+
+All notable changes to this project will be documented in this file.
+
+The format is based on `Keep a Changelog`_, and this project adheres to
+`Semantic Versioning`_.
+
+`Unreleased`_
+-------------
+Changed
+
+Added
+
+Fixed
+
+Removed
+
+`v0.3.6`_ - 2022-12-30
+----------------------
+Changed
+ - docs: Major refactor to provide manual pages
+ - docs: Change to material theme
+ - README: Add reference to mailing list
+ - Update pyproject.toml
+ - Convert Makefiles to POSIX style
+ - consolidate tool configs in pyproject.toml
+ - update requirements-dev.txt
+ - cli: Modify edit to accept from_stdin flag
+
+Added
+ - Add community guidelines
+ - Add stdin flag to edit subcommand
+ - Add TODO
+
+Fixed
+ - cli: Fix (un)favorite
+ - nncli: Always check do_server_sync before syncing
+
+Removed
+ - docs: Remove CI badge
+ - docs: Don't build PDF
+ - Remove Pipenv in favor of the simpler pip-tools
+
+`v0.3.5`_ - 2021-12-10
+----------------------
+Changed
+ - Update copyright info in docs
+ - Make filtered_notes_sort public
+ - Use $VISUAL instead of $EDITOR
+ - clipboard: Silence calls to 'which'
+ - Smarten up the way we set defaults for cfg_editor
+ - Add mailmap
+ - Allow syncing in Python 3.8 and later
+ - Constrain pytest version
+
+Added
+ - clipboard: Add support for xclip
+ - Add initial hack at a manual
+ - Tox: Add py38 testing
+
+Fixed
+ - Fixed 'nncli create' to work without any arguments (credit: lifesbest23)
+ - clipboard: Fix line continuations
+
+
+`v0.3.4`_ - 2019-03-08
+----------------------
+Changed
+ - Fix crashing bug in view_log.py
+ - Refactor gui.py based on pylint findings
+
+Removed
+ - Pipfile.lock
+
+`v0.3.3`_ - 2019-02-25
+----------------------
+Added
+ - Documentation
+
+ - TODO and CHANGELOG formatting
+ - docutils.conf
+ - sitemap
+ - Canonical URL
+ - robots.txt
+
+Changed
+ - Changed SafeConfigParser to ConfigParser
+ - Reversed test logic in _log_timeout to avoid popping off on an empty
+ stack. This bug was leading to fatal crashes.
+
+`v0.3.2`_ – 2018-12-01
+----------------------
+Added
+ - CHANGELOG.rst
+ - TODO.txt
+ - clear_ids.py contrib script
+
+Changed
+ - References to Github repo changed to point to git.danielmoch.com
+ - Fixed exception in nncli sync
+
+`v0.3.1`_ – 2018-10-30
+----------------------
+Added
+ - Partial unit testing for nncli.py module
+
+Changed
+ - Refactored code (addressing pylint findings)
+ - Fixed bad exception handling in Python 3.4
+
+`v0.3.0`_ – 2018-09-07
+----------------------
+Added
+ - Documentation as PDF format
+
+Changed
+ - Numerous documentation corrections
+
+`v0.2.0`_ – 2018-09-03
+----------------------
+Added
+ - .travis.yml
+ - Pytest, tox, et all added to support automated testing
+ - Both tox and Travis testing back to Python 3.4
+
+`v0.1.2`_ – 2018-08-30
+----------------------
+Added
+ - Support for --version flag
+
+Changed
+ - requirements.txt replaced with Pipfile{,.lock}
+
+`v0.1.1`_ – 2018-08-07
+----------------------
+Added
+ - README content included in PyPI
+
+Changed
+ - README content and formatting
+ - Fix nncli import command
+
+v0.1.0 – 2018-07-31
+-------------------
+Changed
+ - Hard fork of sncli
+
+.. _Keep a Changelog: https://keepachangelog.com/en/1.0.0/
+.. _Semantic Versioning: https://semver.org/spec/v2.0.0.html
+.. _Unreleased: https://git.danielmoch.com/nncli/diff/?id=master&id2=v0.3.6
+.. _v0.3.6: https://git.danielmoch.com/nncli/diff/?id=v0.3.6&id2=v0.3.5
+.. _v0.3.5: https://git.danielmoch.com/nncli/diff/?id=v0.3.5&id2=v0.3.4
+.. _v0.3.4: https://git.danielmoch.com/nncli/diff/?id=v0.3.4&id2=v0.3.3
+.. _v0.3.3: https://git.danielmoch.com/nncli/diff/?id=v0.3.3&id2=v0.3.2
+.. _v0.3.2: https://git.danielmoch.com/nncli/diff/?id=v0.3.2&id2=v0.3.1
+.. _v0.3.1: https://git.danielmoch.com/nncli/diff/?id=v0.3.1&id2=v0.3.0
+.. _v0.3.0: https://git.danielmoch.com/nncli/diff/?id=v0.3.0&id2=v0.2.0
+.. _v0.2.0: https://git.danielmoch.com/nncli/diff/?id=v0.2.0&id2=v0.1.2
+.. _v0.1.2: https://git.danielmoch.com/nncli/diff/?id=v0.1.2&id2=v0.1.1
+.. _v0.1.1: https://git.danielmoch.com/nncli/diff/?id=v0.1.1&id2=v0.1.0
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
deleted file mode 100644
index a353dd6..0000000
--- a/CHANGELOG.txt
+++ /dev/null
@@ -1,102 +0,0 @@
-Changelog
-=========
-
-All notable changes to this project will be documented in this file.
-
-The format is based on Keep a Changelog [1] , and this project adheres to
-Semantic Versioning [2].
-
-Unreleased [3]
-----------
-
-v0.3.4 - 2019-03-08 [4]
--------------------
-Changed
- - Fix crashing bug in view_log.py
- - Refactor gui.py based on pylint findings
-
-Removed
- - Pipfile.lock
-
-v0.3.3 - 2019-02-25 [5]
--------------------
-Added
-- Documentation
- - TODO and CHANGELOG formatting
- - docutils.conf
- - sitemap
- - Canonical URL
- - robots.txt
-
-Changed
-- Changed SafeConfigParser to ConfigParser
-- Reversed test logic in _log_timeout to avoid popping off on an empty
- stack. This bug was leading to fatal crashes.
-
-v0.3.2 – 2018-12-01 [6]
--------------------
-Added
- - CHANGELOG.rst
- - TODO.txt
- - clear_ids.py contrib script
-
-Changed
-- References to Github repo changed to point to git.danielmoch.com
-- Fixed exception in nncli sync
-
-v0.3.1 – 2018-10-30 [7]
--------------------
-Added
-- Partial unit testing for nncli.py module
-
-Changed
-- Refactored code (addressing pylint findings)
-- Fixed bad exception handling in Python 3.4
-
-v0.3.0 – 2018-09-07 [8]
--------------------
-Added
-- Documentation as PDF format
-
-Changed
-- Numerous documentation corrections
-
-v0.2.0 – 2018-09-03 [9]
--------------------
-Added
-- .travis.yml
-- Pytest, tox, et all added to support automated testing
-- Both tox and Travis testing back to Python 3.4
-
-v0.1.2 – 2018-08-30 [10]
--------------------
-Added
-- Support for --version flag
-
-Changed
-- requirements.txt replaced with Pipfile{,.lock}
-
-v0.1.1 – 2018-08-07 [11]
--------------------
-Added
-- README content included in PyPI
-
-Changed
-- README content and formatting
-- Fix nncli import command
-
-v0.1.0 – 2018-07-31
--------------------
-- Hard fork of sncli
-
-[1] - https://keepachangelog.com/en/1.0.0/
-[2] - https://semver.org/spec/v2.0.0.html
-[3] - https://git.danielmoch.com/nncli/diff/?id=master&id2=v0.3.4
-[4] - https://git.danielmoch.com/nncli/diff/?id=v0.3.4&id2=v0.3.3
-[5] - https://git.danielmoch.com/nncli/diff/?id=v0.3.3&id2=v0.3.2
-[6] - https://git.danielmoch.com/nncli/diff/?id=v0.3.2&id2=v0.3.1
-[7] - https://git.danielmoch.com/nncli/diff/?id=v0.3.1&id2=v0.3.0
-[8] - https://git.danielmoch.com/nncli/diff/?id=v0.3.0&id2=v0.2.0
-[9] - https://git.danielmoch.com/nncli/diff/?id=v0.2.0&id2=v0.1.2
-[10] - https://git.danielmoch.com/nncli/diff/?id=v0.1.2&id2=v0.1.1
-[11] - https://git.danielmoch.com/nncli/diff/?id=v0.1.1&id2=v0.1.0
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
new file mode 100644
index 0000000..5dc7bf7
--- /dev/null
+++ b/CONTRIBUTING.rst
@@ -0,0 +1,93 @@
+Contribution Guide
+==================
+
+Thanks for your interest in contributing to nncli(1). This guide
+attempts to document everything you need to know to participate in the
+development community. As with everything else in this repository,
+suggestions are welcome.
+
+Community Guidelines
+--------------------
+
+Given that the nncli(1) community is still in the early stages of
+formation, community guidelines have yet to be rigidly codified. For
+the time being, the following general expectations should be
+considered normative:
+
+- Participants should do their part to make this a welcoming
+ community, free from harassment and discrimination, where everyone
+ feels safe to contribute. Any behavior that threatens this will not
+ be tolerated, and repeated violations will result in expulsion from
+ the community. Anyone who egregiously violates this principle, for
+ instance by doxxing another community member, whether in official
+ community channels or elsewhere, will be immediately and permanently
+ banned.
+
+- The goal in providing official community channels (e.g., the mailing
+ list), is to provide a public space for the development of nncli(1)
+ with high signal-to-noise ratio. Persuant to this, community members
+ should understand that disagreements naturally arise from time to
+ time. If they don't pertain to nncli(1), then they should be
+ discussed outside official community channels. This is not a
+ judgment about the importance of any given topic, merely a
+ recognition that this community cannot sustain discussion about
+ anything and everything.
+
+- Maintainers shall be selected from the community as-needed based on
+ their ability to productively contribute to nncli(1). Productivity
+ in this context is measured *both* in terms of code contributions
+ *and* ability to forge consensus in community discussions.
+
+- Decisions regarding the development of nncli(1) fall to the
+ maintainers collectively. When the maintainers are not able to form
+ a consensus on the best path forward, the lead maintainer shall be
+ the final authority on decisions.
+
+Getting Started
+---------------
+
+To get started with the code, you will need to clone it and install
+development dependencies. We recommend the isolating your development
+environment with ``venv`` Python module. We also recommend using
+``pip-tools`` to manage dependencies. Its use is expected when
+updating requirements files.
+
+::
+
+ $ git clone https://git.danielmoch.com/nncli.git
+ $ cd nncli
+ $ python3 -m venv .venv
+ $ source .venv/bin/activate
+ (.venv)$ pip install pip-tools
+ (.venv)$ pip-sync requirements-dev.txt
+
+Discussion and Requests
+-----------------------
+
+All discussion takes place on the public `mailing list`_. The list's
+archive can be found at https://lists.danielmoch.com/nncli-dev. Emails
+can be sent to the following addresses to manage your subscription to
+the mailing list.
+
+- nncli-dev+subscribe@
+- nncli-dev+unsubscribe@
+- nncli-dev+help@
+
+Patches and pull requests are welcome, preferably via emailed output
+of `git-request-pull(1)`_ sent to the mailing list. Bug reports should
+also be directed to the mailing list.
+
+If you aren't hosting a fork anywhere online, you can also send patches
+using `git-format-patch(1)`_.
+
+Releases
+--------
+
+Releases are published to PyPI_. Signed source tarballs are maintained
+at https://dl.danielmoch.com/nncli. Instructions for verifying
+tarballs are in the README file at the previous link.
+
+.. _PyPI: https://pypi.org/project/nncli/
+.. _mailing list: nncli-dev@danielmoch.com
+.. _git-format-patch(1): https://www.git-scm.com/docs/git-format-patch
+.. _git-request-pull(1): https://www.git-scm.com/docs/git-request-pull
diff --git a/LICENSE b/LICENSE
index 820f037..280e27d 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,7 @@
The MIT License (MIT)
-Copyright (c) 2018 Daniel Moch
+Copyright (c) 2018-2022 Daniel Moch
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/Makefile b/Makefile
index 2f01dd7..32944b9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,98 +1,52 @@
-.PHONY: clean clean-test clean-pyc clean-build help lint coverage coverage-html release dist install run debug docs
-.DEFAULT_GOAL := help
+.POSIX:
-define BROWSER_PYSCRIPT
-import os, webbrowser, sys
+.PHONY: clean clean-test clean-pycache clean-build help lint coverage coverage-html release dist install run debug docs
-try:
- from urllib import pathname2url
-except:
- from urllib.request import pathname2url
+dist:
+ flit build
-webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1])))
-endef
-export BROWSER_PYSCRIPT
-
-define PRINT_HELP_PYSCRIPT
-import re, sys
-
-for line in sys.stdin:
- match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line)
- if match:
- target, help = match.groups()
- print("%-20s %s" % (target, help))
-endef
-export PRINT_HELP_PYSCRIPT
-
-BROWSER := python -c "$$BROWSER_PYSCRIPT"
-PIPENV := pipenv
-PIPRUN := $(PIPENV) run
-PIPINST := $(PIPENV) --bare install --dev --skip-lock
-
-help:
- @python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST)
-
-clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts
+clean: clean-build clean-pycache clean-test
make -C docs clean
-clean-build: ## remove build artifacts
- rm -fr build/
+clean-build:
rm -fr dist/
- rm -fr .eggs/
- find . -name '*.egg-info' -exec rm -fr {} +
- find . -name '*.egg' -exec rm -f {} +
-
-clean-pyc: ## remove Python file artifacts
- find . -name '*.pyc' -exec rm -f {} +
- find . -name '*.pyo' -exec rm -f {} +
- find . -name '*~' -exec rm -f {} +
+
+clean-pycache:
find . -name '__pycache__' -exec rm -fr {} +
- $(PIPRUN) pip uninstall -y nncli
-clean-test: ## remove test and coverage artifacts
+clean-test:
rm -f .coverage
rm -fr htmlcov/
rm -fr .pytest_cache
rm -fr .tox
-lint: ## check style with pylint
- $(PIPRUN) pylint nncli tests --disable=parse-error
- $(PIPRUN) vulture nncli .vulture_whitelist.py
+lint:
+ pylint nncli tests --disable=parse-error
+ vulture nncli .vulture_whitelist.py
-test: ## run tests quickly with the default Python
- $(PIPRUN) python -m pytest
+test:
+ python -m pytest
-test-all: ## run tests on every Python version with tox
- $(PIPRUN) tox
+test-all:
+ tox
-test-install: ## install dependenices from Pipfile (for tox / CI builds)
- $(PIPINST)
+coverage:
+ python -m pytest --cov=nncli
-coverage: ## check code coverage quickly with the default Python
- $(PIPRUN) python -m pytest --cov=nncli
+coverage-html: coverage
+ coverage html
-coverage-html: coverage ## generate an HTML report and open in browser
- $(PIPRUN) coverage html
- $(BROWSER) htmlcov/index.html
-
-release: dist ## package and upload a release
+release: dist
twine upload -s dist/*
-dist: ## builds source and wheel package
- $(PIPRUN) flit build
- ls -l dist
-
-docs: ## builds the sphinx documentation and opens in the browser
- make -C docs html
- make -C docs latexpdf
- make -C docs man
- $(BROWSER) docs/build/html/index.html
+docs:
+ make -C docs html man
-install: ## install the package to the active Python's site-packages
- $(PIPRUN) flit install --deps=none
+install:
+ flit install --deps=none
-run: ## run the package from site-packages
- $(PIPRUN) python -m nncli $(cmd)
+run:
+ python -m nncli $(cmd)
-debug: install ## debug the package from site packages
- $(PIPRUN) pudb3 $$($(PIPRUN) which nncli) $(cmd)
+debug: install
+ pudb3 $$(which nncli) $(cmd)
diff --git a/Pipfile b/Pipfile
deleted file mode 100644
index d7ed55f..0000000
--- a/Pipfile
+++ /dev/null
@@ -1,27 +0,0 @@
-[[source]]
-url = "https://pypi.org/simple"
-verify_ssl = true
-name = "pypi"
-
-[packages]
-appdirs = "*"
-requests = "*"
-urwid = "*"
-click = "*"
-
-[dev-packages]
-pytest = ">=5.2,<5.3"
-pytest-cov = "*"
-pytest-mock = "*"
-pylint = "*"
-pudb = "*"
-sphinx = "*"
-flit = "*"
-setuptools = "*"
-mock = "*"
-tox = "*"
-pathlib2 = {version = "*",markers = "python_version < '3.5'"}
-scandir = {version = "*",markers = "python_version < '3.5'"}
-vulture = "*"
-sphinx-rtd-theme = "*"
-sphinx-sitemap = "*"
diff --git a/README.rst b/README.rst
index 1df5363..382cb8e 100644
--- a/README.rst
+++ b/README.rst
@@ -1,4 +1,4 @@
-nncli is a Python application that gives you access to your NextCloud
+``nncli`` is a Python application that gives you access to your NextCloud
Notes account via the command line. It's a "hard" fork of
sncli_. You can access your notes via
a customizable console GUI that implements vi-like keybinds or via a
@@ -10,40 +10,16 @@ automatically sync'ed when nncli is brought online.
More detailed documentation can be found at the homepage_.
-Requirements
-------------
-
-- `Python 3`_
-
-- Urwid_ Python 3 module
-
-- Requests_ Python 3 module
-
-- A love for the command line!
-
Installation
------------
-- Via pip (latest release):
-
- - ``pip3 install nncli``
-
-- Manually:
-
- - If you don't already have it, install Flit_: ``pip3 install flit``
-
- - Clone this repository to your hard disk: ``git clone
- https://git.danielmoch.com/nncli.git``
-
- - Install nncli: ``flit install --deps production``
+Assuming your system has both ``python3`` and ``pip3``, you can
+globally install ``nncli`` and its dependencies with ``pip3 install
+nncli``.
-- Development:
-
- - Clone the repo
-
- - Install Pipenv: ``pip3 install pipenv``
-
- - Stand up development virtualenv: ``pipenv install --dev``
+If you are interested in packaging ``nncli`` for various
+distributions, please consult the file CONTRIBUTING.rst_ in this
+repository and reach out to the mailing list with any questions.
Features
--------
@@ -52,80 +28,36 @@ Features
- full two-way sync with NextCloud Notes performed dynamically in the
background
-
- all actions logged and easily reviewed
-
- list note titles (configurable format w/ title, date, flags, category,
keys, etc)
-
- sort notes by date, alpha by title, category, favorite on top
-
- search for notes using a Google style search pattern or Regular
Expression
-
- view note contents and meta data
-
- pipe note contents to external command
-
- create and edit notes (using your editor)
-
- edit note category
-
- delete notes
-
- favorite/unfavorite notes
-
- vi-like keybinds (fully configurable)
-
- Colors! (fully configurable)
- Command Line (scripting)
- force a full two-way sync with NextCloud Notes
-
- all actions logged and easily reviewed
-
- list note titles and keys
-
- search for notes using a Google style search pattern or Regular
Expression
-
- dump note contents
-
- create a new note (via stdin or editor)
-
- import a note with raw json data (stdin or editor)
-
- edit a note (via editor)
-
- delete a note
-
- favorite/unfavorite a note
-
- view and edit note category
-Contributing
-------------
-
-Pull requests are welcome, preferably via emailed output of ``git
-request-pull`` sent to the maintainer (see here_ for more information).
-Bug reports should also be directed to the maintainer via email_.
-
-If you aren't hosting a fork anywhere online, you can also send patches
-using ``git format-patch`` (again, see `the official documentation`_ ).
-
-Releases
---------
-
-Release tags will always be signed with the maintainer's `PGP key`_
-(also available on any public keyserver_). PGP-signed versions of
-release tarballs and pre-built wheel_ packages are available on PyPI_,
-with the signature files living alongside the corresponding artifact
-(simply append an ``.asc`` extension). Because the maintainers of PyPI
-do not consider PGP signatures to be a user-facing feature, the
-extension must be added manually in your browser's URL bar in order to
-download the signature files.
-
Acknowledgements
----------------
@@ -135,16 +67,9 @@ Schauenberg and the notes_db.py module from nvpy_ by Charl P. Botha.
.. _homepage: https://nncli.org
.. _sncli: https://github.com/insanum/sncli
+.. _CONTRIBUTING.rst: https://git.danielmoch.com/nncli/tree/CONTRIBUTING.rst
.. _Python 3: http://python.org
.. _Urwid: http://urwid.org
.. _Requests: https://requests.readthedocs.org/en/master
.. _simplenote.py: https://github.com/mrtazz/simplenote.py
.. _nvpy: https://github.com/cpbotha/nvpy
-.. _Flit: https://flit.readthedocs.io
-.. _here: https://www.git-scm.com/docs/git-request-pull
-.. _PGP key: https://www.danielmoch.com/static/gpg.asc
-.. _wheel: https://pythonwheels.com/
-.. _PyPI: https://pypi.org/project/nncli/
-.. _keyserver: https://pgp.mit.edu/pks/lookup?op=get&search=0x323C9F1784BDDD43
-.. _email: daniel@danielmoch.com
-.. _the official documentation: https://www.git-scm.com/docs/git-format-patch
diff --git a/TODO.txt b/TODO.txt
index 57e456f..f1ccfa7 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -1,5 +1,6 @@
TODO
----
+- Support NextCloud Notes v1.0 API
- Create a proper groff manual
- Address duplicate code (pylint finding)
- Target 80% unit test coverage
diff --git a/docs/Makefile b/docs/Makefile
index 855249f..8c38174 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -3,7 +3,7 @@
# You can set these variables from the command line.
SPHINXOPTS =
-SPHINXBUILD = pipenv run sphinx-build
+SPHINXBUILD = sphinx-build
SPHINXPROJ = nncli
SOURCEDIR = source
BUILDDIR = build
diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst
new file mode 100644
index 0000000..6f90edd
--- /dev/null
+++ b/docs/source/changelog.rst
@@ -0,0 +1 @@
+.. include:: ../../CHANGELOG.rst \ No newline at end of file
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 8ca6b32..9bbdfdb 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -14,13 +14,13 @@
#
import os
import sys
-sys.path.insert(0, os.path.abspath(os.path.sep.join(['..', '..'])))
+sys.path.insert(0, os.path.abspath(os.path.sep.join(['..', '..', 'src'])))
import nncli
# -- Project information -----------------------------------------------------
project = 'nncli'
-copyright = '2018-2019, Daniel Moch'
+copyright = '2018-2022, Daniel Moch'
author = 'Daniel Moch'
# The short X.Y version
@@ -54,9 +54,6 @@ templates_path = ['.templates']
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
-# The master toctree document.
-master_doc = 'index'
-
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
@@ -67,10 +64,10 @@ language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path .
-exclude_patterns = []
+exclude_patterns = ['usage/*', 'configuration/*']
# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = 'bw'
# -- Options for HTML output -------------------------------------------------
@@ -78,7 +75,7 @@ pygments_style = 'sphinx'
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
-html_theme = 'sphinx_rtd_theme'
+html_theme = 'sphinx_material'
html_extra_path = ['robots.txt']
html_baseurl = 'https://nncli.org/'
@@ -88,13 +85,38 @@ html_baseurl = 'https://nncli.org/'
# documentation.
#
html_theme_options = {
- 'canonical_url': 'https://nncli.org/'
+ 'nav_title': 'NextCloud Notes Command Line Interface',
+ 'base_url': 'https://nncli.org/',
+
+ # Set the color and the accent color
+ 'color_primary': 'grey',
+ 'color_accent': 'blue',
+
+ # Set the repo location to get a badge with stats
+ 'repo_url': 'https://git.danielmoch.com/nncli/',
+ 'repo_name': 'Git Repository',
+ 'repo_type': None,
+
+ 'logo_icon': '&#xe261',
+ 'master_doc': False,
+
+ 'nav_links': [
+ {'title': 'Home', 'href': 'index', 'internal': True},
+ {'title': 'Index', 'href': 'genindex', 'internal': True},
+ ],
+
+ # Visible levels of the global TOC; -1 means unlimited
+ 'globaltoc_depth': -1,
+ # If False, expand all TOC entries
+ 'globaltoc_collapse': True,
+ # If True, show hidden TOC entries
+ 'globaltoc_includehidden': False,
}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['.static']
+html_static_path = []
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
@@ -104,7 +126,7 @@ html_static_path = ['.static']
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
-# html_sidebars = {}
+html_sidebars = {'**': ['globaltoc.html', 'localtoc.html', 'searchbox.html']}
# -- Options for HTMLHelp output ---------------------------------------------
@@ -137,7 +159,7 @@ latex_elements = {
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
- (master_doc, 'nncli.tex', 'nncli Documentation',
+ (None, 'nncli.tex', 'nncli Documentation',
'Daniel Moch', 'manual'),
]
@@ -147,8 +169,30 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
- (master_doc, 'nncli', 'nncli Documentation',
- [author], 1)
+ ('nncli.1', 'nncli', 'NextCloud Notes Command Line Interface',
+ [author], 1),
+ ('nncli-sync.1', 'nncli-sync', 'Sync a NextCloud Notes Database',
+ [author], 1),
+ ('nncli-list.1', 'nncli-list', 'List Notes In a NextCloud Notes Database',
+ [author], 1),
+ ('nncli-export.1', 'nncli-export', 'Export Notes From a NextCloud Notes Database',
+ [author], 1),
+ ('nncli-dump.1', 'nncli-dump', 'Print a NextCloud Note',
+ [author], 1),
+ ('nncli-create.1', 'nncli-create', 'Create a New NextCloud Note',
+ [author], 1),
+ ('nncli-import.1', 'nncli-import', 'Import Notes To a NextCloud Notes Database',
+ [author], 1),
+ ('nncli-edit.1', 'nncli-edit', 'Edit a NextCloud Note',
+ [author], 1),
+ ('nncli-delete.1', 'nncli-delete', 'Delete a NextCloud Note',
+ [author], 1),
+ ('nncli-favorite.1', 'nncli-favorite', 'Favorite a NextCloud Note',
+ [author], 1),
+ ('nncli-cat.1', 'nncli-cat', 'Operate on a NextCloud Note\'s Category',
+ [author], 1),
+ ('nncli.config.5', 'nncli.config', 'Configuration File For nncli(1)',
+ [author], 5),
]
@@ -158,7 +202,7 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
- (master_doc, 'nncli', 'nncli Documentation',
+ (None, 'nncli', 'nncli Documentation',
author, 'nncli', 'One line description of project.',
'Miscellaneous'),
]
diff --git a/docs/source/configuration.rst b/docs/source/configuration.rst
index 6836e32..a31a65c 100644
--- a/docs/source/configuration.rst
+++ b/docs/source/configuration.rst
@@ -1,11 +1,10 @@
.. _configuration:
+.. |here| replace:: :ref:`here<urwid:16-standard-foreground>`
Configuration
=============
-The current NextCloud Notes API does not support oauth authentication so
-your NextCloud Notes account password must be stored someplace
-accessible to nncli.
+.. include configuration/intro.rst
.. index:: single: configuration file
@@ -14,440 +13,30 @@ accessible to nncli.
Configuration File
------------------
-nncli pulls in configuration from the ``config`` file located in the
+nncli pulls in configuration from the *config* file located in the
standard location for your platform:
- Windows: ``%USERPROFILE%\AppData\Local\djmoch\nncli``
-- macOS: ``~/Library/Preferences/nncli``
+- macOS: ``$HOME/Library/Preferences/nncli``
- \*nix: ``$XDG_CONFIG_HOME/nncli/config`` or
``$HOME/.config/nncli/config``
-The following directives are accepted within the ``config`` file:
+The following directives are accepted within the *config* file:
.. index:: pair: configuration file; general options
General Options
~~~~~~~~~~~~~~~
-.. confval:: cfg_nn_host
-
- Sets the URL of the NextCloud instance to connect to.
-
- Required.
-
-.. confval:: cfg_nn_username
-
- The user name to log in as.
-
- Required.
-
-.. confval:: cfg_nn_password
-
- The password to use for log in.
-
- Optional. Overrides :confval:`cfg_nn_password_eval` if both are
- specified.
-
- .. note::
-
- For security reasons, use of the ``cfg_nn_password_eval`` option
- is recommended
-
-.. confval:: cfg_nn_password_eval
-
- A command to run to retrieve the password. The command should return
- the password on ``stdout``.
-
- Optional. Required if :confval:`cfg_nn_password` is not specified.
-
-.. confval:: cfg_db_path
-
- Specifies the path of the local notes cache.
-
- Optional. Default value:
-
- - Windows: ``%USERPROFILE%\AppData\Local\djmoch\nncli\Cache``
-
- - macOS: ``~/Library/Caches/nncli``
-
- - \*nix: ``$XDG_CACHE_HOME/nncli`` or ``$HOME/.cache/nncli``
-
-.. confval:: cfg_search_categories
-
- Set to ``yes`` to include categories in searches. Otherwise set to
- ``no``.
-
- Optional. Default value: ``yes``
-
-.. confval:: cfg_sort_mode
-
- Sets how notes are sorted in the console GUI. Set to ``date``
- to have them sorted by date (newest on top). Set to ``alpha`` to have
- them sorted alphabetically.
-
- Optional. Default value: ``date``
-
-.. confval:: cfg_favorite_ontop
-
- Determines whether notes marked as favorite are sorted on top.
-
- Optional. Default value: ``yes``
-
-.. confval:: cfg_tabstop
-
- Sets the width of a tabstop character.
-
- Optional. Default value: ``4``
-
-.. confval:: cfg_format_strftime
-
- Sets the format of the note timestamp (``%D``) in the note title. The
- format values are the specified in :py:func:`time.strftime`.
-
- Optional. Default value: ``%Y/%m/%d``
-
-.. confval:: cfg_format_note_title
-
- Sets the format of each line in the console GUI note list. Various
- formatting tags are supported for dynamically building the title
- string. Each of these formatting tags supports a width specifier
- (decimal) and a left justification (``-``) like that supported by
- printf:
-
- .. code-block:: none
-
- %F - flags (fixed 2 char width)
- X - needs sync
- * - favorited
- %T - category
- %D - date
- %N - title
-
- The default note title format pushes the note category to the far
- right of the terminal and left justifies the note title after the
- date and flags.
-
- Optional. Default value: ``[%D] %F %-N %T``
-
- Note that the ``%D`` date format is further defined by the strftime
- format specified in :confval:`cfg_format_strftime`.
-
-.. confval:: cfg_status_bar
-
- Sets whether or not the status bar is visible at the top of the
- console GUI.
-
- Optional. Default value: ``yes``
-
-.. confval:: cfg_editor
-
- Sets the command to run when opening a note for editing. The special
- values ``{fname}`` and ``{line}`` can be used to specify respectively
- the file name and line number to pass to the command.
-
- Optional. Default value: ``$VISUAL`` or ``$EDITOR`` if defined in the
- user's environment (preferring ``$VISUAL``), else ``vim {fname} +{line}``.
-
-.. confval:: cfg_pager
-
- Sets the command to run when opening a note for viewing in an
- external pager.
-
- Optional. Default value: ``$PAGER`` if defined in the user's
- environment, else ``less -c``.
-
-.. confval:: cfg_max_logs
-
- Sets the number of log events to display together in the consule GUI
- footer.
-
- Optional. Default value: ``5``
-
-.. confval:: cfg_log_timeout
-
- Sets the rate to poll for log events. Unit is seconds.
-
- Optional. Default value: ``5``
-
-.. confval:: cfg_log_reversed
-
- Sets whether or not the log is displayed in reverse-chronological
- order.
-
- Optional. Default value: ``yes``
-
-.. confval:: cfg_tempdir
-
- Sets a directory path to store temporary files in. ``nncli`` uses
- :func:`tempfile.mkstemp` under the hood, and the most nuanced
- description of how this value is used can be found in the discussion
- of the ``dir`` keyword argument there. Basically you should not
- specify this if you want to use the platform-standard temporary
- folder.
-
- Optional. Default value: *[blank]*
+.. include:: configuration/genopts.rst
.. index:: pair: configuration file; keybindings
Keybindings
~~~~~~~~~~~
-Keybindings specify the behavior of the console GUI, and are never
-required in the ``config`` file. However, they all have default values,
-as outlined below. More information on specifying keybindings can be
-found in the :ref:`Urwid documentation <urwid:keyboard-input>`.
-
-.. confval:: kb_help
-
- Press to enter the help screen.
-
- Default value: ``h``
-
-.. confval:: kb_quit
-
- Press to exit the console GUI.
-
- Default value: ``q``
-
-.. confval:: kb_sync
-
- Press to force a full, bi-directional sync with the server.
-
- Default value: ``S``
-
-.. confval:: kb_down
-
- Press to move down one row.
-
- Default value: ``j``
-
-.. confval:: kb_up
-
- Press to move one row up.
-
- Default value: ``k``
-
-.. confval:: kb_page_down
-
- Press to move one page down.
-
- Default value: ``space``
-
-.. confval:: kb_page_up
-
- Press to move one page up.
-
- Default value: ``b``
-
-.. confval:: kb_half_page_down
-
- Press to move one half-page down.
-
- Default value: ``ctrl d``
-
-.. confval:: kb_half_page_up
-
- Press to move one half-page up.
-
- Default value: ``ctrl u``
-
-.. confval:: kb_bottom
-
- Press to move to the last line.
-
- Default value: ``G``
-
-.. confval:: kb_top
-
- Press to move to the first line.
-
- Default value: ``g``
-
-.. confval:: kb_status
-
- Press to toggle the visibility of the status bar.
-
- Default value: ``s``
-
-.. confval:: kb_create_note
-
- Press to create a new note and open in the configured editor (see
- :confval:`cfg_editor`).
-
- Default value: ``C``
-
-.. confval:: kb_edit_note
-
- Press to edit the highlighted note in the configured editor (see
- :confval:`cfg_editor`).
-
- Default value: ``e``
-
-.. confval:: kb_view_note
-
- Press to view the highlighted note in read-only mode.
-
- Default value: ``enter``
-
-.. confval:: kb_view_note_ext
-
- Press to view the highlighted note in the configured pager (see
- :confval:`cfg_pager`).
-
- Default value: ``meta enter``
-
-.. confval:: kb_view_note_json
-
- Press to view the raw JSON contents of the highlighted note in
- read-only mode.
-
- Default value: ``O``
-
-.. confval:: kb_pipe_note
-
- Press to send the contents of the highlighted note to ``stdin`` of
- another program. A small command window opens at the bottom of the
- screen to enter the desired program.
-
- Default value: ``|``
-
-.. confval:: kb_view_next_note
-
- Press to view the contents of the next note in read-only mode.
-
- Default value: ``J``
-
-.. confval:: kb_view_prev_note
-
- Press to view the contents of the previous note in read-only mode.
-
- Default value: ``K``
-
-.. confval:: kb_view_log
-
- Press to view the log.
-
- Default value: ``l``
-
-.. confval:: kb_tabstop2
-
- Press to set the tabstop for the internal pager to a width of two
- characters.
-
- Default value: ``2``
-
-.. confval:: kb_tabstop4
-
- Press to set the tabstop for the internal pager to a width of four
- characters.
-
- Default value: ``4``
-
-.. confval:: kb_tabstop8
-
- Press to set the tabstop for the internal pager to a width of eight
- characters.
-
- Default value: ``8``
-
-.. confval:: kb_search_gstyle
-
- Press to initiate a search of your notes against a Google-style
- search term. A command window will open at the bottom of the screen
- to enter your search term.
-
- Default value: ``/``
-
-.. confval:: kb_search_regex
-
- Press to initiate a search of your notes against a regular
- expression. A command window will open at the bottom of the screen to
- enter your search term.
-
- Default value: ``meta /``
-
-.. confval:: kb_search_prev_gstyle
-
- Press to initiate a reverse search of your notes against a
- Google-style search term. A command window will open at the bottom of
- the screen to enter your search term.
-
- Default value: ``?``
-
-.. confval:: kb_search_prev_regex
-
- Press to initiate a reverse search of your notes against a regular
- expression. A command window will open at the bottom of the screen
- to enter your search term.
-
- Default value: ``meta ?``
-
-.. confval:: kb_search_next
-
- Press after a search has been initiated to move to the next match.
-
- Default value: ``n``
-
-.. confval:: kb_search_prev
-
- Press after a search has been initiated to move to the previous
- match.
-
- Default value: ``N``
-
-.. confval:: kb_clear_search
-
- Press to clear the current search.
-
- Default value: ``A``
-
-.. confval:: kb_sort_date
-
- Press to display notes sorted by date.
-
- Default value: ``d``
-
-.. confval:: kb_sort_alpha
-
- Press to display notes sorted alphabetically.
-
- Default value: ``a``
-
-.. confval:: kb_sort_categories
-
- Press to display notes sorted by category.
-
- Default value: ``ctrl t``
-
-.. confval:: kb_note_delete
-
- Press to delete a note. The note will be deleted locally and
- reflected on the server after the next full sync (see
- :confval:`kb_sync`).
-
- Default value: ``D``
-
-.. confval:: kb_note_favorite
-
- Press to toggle the ``favorite`` flag for a note.
-
- Default value: ``p``
-
-.. confval:: kb_note_category
-
- Press to set/edit the note category. A command window will appear at
- the bottom of the screen containing the current category (if it has
- one). Set to an empty string to clear the category.
-
- Default value: ``t``
-
-.. confval:: kb_copy_note_text
-
- Press to copy the note text to the system clipboard.
-
- Default value: ``y``
.. index:: pair: configuration file; colors
@@ -457,215 +46,10 @@ Colors
nncli utilizes the Python Urwid_ module to implement the console user
interface.
-.. note::
-
- At this time, nncli does not yet support 256-color terminals and is
- limited to just 16-colors. Color names that can be specified in the
- ``config`` file are listed :ref:`here
- <urwid:16-standard-foreground>`.
-
-The following pairs of configuration values represent the foreground and
-background colors for different elements of the console GUI. In each
-case the configuration value corresponding to the foreground color ends
-in ``_fg``, and the configuration value corresponding to the
-background color ends in ``_bg``. The default color values are listed in
-foreground/background format.
+.. include:: configuration/colors.rst
.. _Urwid: http://urwid.org
-.. confval:: clr_default_fg
-
-.. confval:: clr_default_bg
-
- The default foreground/background colors.
-
- Default values: ``default/default``
-
-.. confval:: clr_status_bar_fg
-
-.. confval:: clr_status_bar_bg
-
- The foreground/background colors for the status bar.
-
- Default values: ``dark gray/light gray``
-
-.. confval:: clr_log_fg
-
-.. confval:: clr_log_bg
-
- The foreground/background colors for the log.
-
- Default values: ``dark gray/light gray``
-
-.. confval:: clr_user_input_bar_fg
-
-.. confval:: clr_user_input_bar_bg
-
- The foreground/background colors for the input bar.
-
- Default values: ``white/light red``
-
-.. confval:: clr_note_focus_fg
-
-.. confval:: clr_note_focus_bg
-
- The foreground/background colors for the selected note.
-
- Default values: ``white/light red``
-
-.. confval:: clr_note_title_day_fg
-
-.. confval:: clr_note_title_day_bg
-
- The foreground/background colors for notes edited within the past 24
- hours.
-
- Default values: ``light red/default``
-
-.. confval:: clr_note_title_week_fg
-
-.. confval:: clr_note_title_week_bg
-
- The foreground/background colors for notes edited within the past
- week,
-
- Default values: ``light green/default``
-
-.. confval:: clr_note_title_month_fg
-
-.. confval:: clr_note_title_month_bg
-
- The foreground/background colors for notes edited within the past
- month.
-
- Default values: ``brown/default``
-
-.. confval:: clr_note_title_year_fg
-
-.. confval:: clr_note_title_year_bg
-
- The foreground/background colors for notes edited within the past
- year.
-
- Default values: ``light blue/default``
-
-.. confval:: clr_note_title_ancient_fg
-
-.. confval:: clr_note_title_ancient_bg
-
- The foreground/background colors for notes last edited more than one
- year ago.
-
- Default values: ``light blue/default``
-
-.. confval:: clr_note_date_fg
-
-.. confval:: clr_note_date_bg
-
- The foreground/background colors for the note date (i.e. the ``%D``
- portion of :confval:`cfg_format_note_title`).
-
- Default values: ``dark blue/default``
-
-.. confval:: clr_note_flags_fg
-
-.. confval:: clr_note_flags_bg
-
- The foreground/background colors for the note flags (i.e., the ``%F``
- portion of :confval:`cfg_format_note_title`).
-
- Default values: ``dark magenta/default``
-
-.. confval:: clr_note_category_fg
-
-.. confval:: clr_note_category_bg
-
- The foreground/background colors for the note category (i.e., the
- ``%T`` portion of :confval:`cfg_format_note_title`).
-
- Default values: ``dark red/default``
-
-.. confval:: clr_note_content_fg
-
-.. confval:: clr_note_content_bg
-
- The foreground/background colors for the note content as displayed
- in the internal pager.
-
- Default values: ``default/default``
-
-.. confval:: clr_note_content_focus_fg
-
-.. confval:: clr_note_content_focus_bg
-
- The foreground/background colors for focused content within the
- internal pager.
-
- Default values: ``white/light red``
-
-.. confval:: clr_note_content_old_fg
-
-.. confval:: clr_note_content_old_bg
-
- The foreground/background colors for old note content as displayed
- within the internal pager.
-
- Default values: ``yellow/dark gray``
-
-.. confval:: clr_note_content_old_focus_fg
-
-.. confval:: clr_note_content_old_focus_bg
-
- The foreground/background colors for old note focused content as
- displayed within the internal pager.
-
- Default values: ``white/light red``
-
-.. confval:: clr_help_focus_fg
-
-.. confval:: clr_help_focus_bg
-
- The foreground/background colors for focused content in the help
- screen.
-
- Default values: ``white/light red``
-
-.. confval:: clr_help_header_fg
-
-.. confval:: clr_help_header_bg
-
- The foreground/background colors for header content in the help
- screen.
-
- Default values: ``dark blue/default``
-
-.. confval:: clr_help_config_fg
-
-.. confval:: clr_help_config_bg
-
- The foreground/background colors for configuration option name (e.g.,
- ``clr_help_focus_bg``) in the help screen.
-
- Default values: ``dark green/default``
-
-.. confval:: clr_help_value_fg
-
-.. confval:: clr_help_value_bg
-
- The foreground/background colors for the value of a configuration
- option as set in ``config``.
-
- Default values: ``dark red/default``
-
-.. confval:: clr_help_descr_fg
-
-.. confval:: clr_help_descr_bg
-
- The foreground/background colors for the configuration options
- description in the help screen.
-
- Default values: ``default/default``
-
Examples
--------
@@ -690,7 +74,7 @@ used in your ``config`` to override the default setting.
See example configuration file below for more notes.
-.. code-block:: ini
+::
[nncli]
cfg_nn_username = lebowski@thedude.com
diff --git a/docs/source/configuration/colors.rst b/docs/source/configuration/colors.rst
new file mode 100644
index 0000000..cdf1e40
--- /dev/null
+++ b/docs/source/configuration/colors.rst
@@ -0,0 +1,205 @@
+.. note::
+
+ At this time, nncli does not yet support 256-color terminals and is
+ limited to just 16-colors. Color names that can be specified in the
+ ``config`` file are listed |here|.
+
+The following pairs of configuration values represent the foreground and
+background colors for different elements of the console GUI. In each
+case the configuration value corresponding to the foreground color ends
+in ``_fg``, and the configuration value corresponding to the
+background color ends in ``_bg``. The default color values are listed in
+foreground/background format.
+
+.. describe:: clr_default_fg
+
+.. describe:: clr_default_bg
+
+ The default foreground/background colors.
+
+ Default values: ``default/default``
+
+.. describe:: clr_status_bar_fg
+
+.. describe:: clr_status_bar_bg
+
+ The foreground/background colors for the status bar.
+
+ Default values: ``dark gray/light gray``
+
+.. describe:: clr_log_fg
+
+.. describe:: clr_log_bg
+
+ The foreground/background colors for the log.
+
+ Default values: ``dark gray/light gray``
+
+.. describe:: clr_user_input_bar_fg
+
+.. describe:: clr_user_input_bar_bg
+
+ The foreground/background colors for the input bar.
+
+ Default values: ``white/light red``
+
+.. describe:: clr_note_focus_fg
+
+.. describe:: clr_note_focus_bg
+
+ The foreground/background colors for the selected note.
+
+ Default values: ``white/light red``
+
+.. describe:: clr_note_title_day_fg
+
+.. describe:: clr_note_title_day_bg
+
+ The foreground/background colors for notes edited within the past 24
+ hours.
+
+ Default values: ``light red/default``
+
+.. describe:: clr_note_title_week_fg
+
+.. describe:: clr_note_title_week_bg
+
+ The foreground/background colors for notes edited within the past
+ week,
+
+ Default values: ``light green/default``
+
+.. describe:: clr_note_title_month_fg
+
+.. describe:: clr_note_title_month_bg
+
+ The foreground/background colors for notes edited within the past
+ month.
+
+ Default values: ``brown/default``
+
+.. describe:: clr_note_title_year_fg
+
+.. describe:: clr_note_title_year_bg
+
+ The foreground/background colors for notes edited within the past
+ year.
+
+ Default values: ``light blue/default``
+
+.. describe:: clr_note_title_ancient_fg
+
+.. describe:: clr_note_title_ancient_bg
+
+ The foreground/background colors for notes last edited more than one
+ year ago.
+
+ Default values: ``light blue/default``
+
+.. describe:: clr_note_date_fg
+
+.. describe:: clr_note_date_bg
+
+ The foreground/background colors for the note date (i.e. the ``%D``
+ portion of :confval:`cfg_format_note_title`).
+
+ Default values: ``dark blue/default``
+
+.. describe:: clr_note_flags_fg
+
+.. describe:: clr_note_flags_bg
+
+ The foreground/background colors for the note flags (i.e., the ``%F``
+ portion of :confval:`cfg_format_note_title`).
+
+ Default values: ``dark magenta/default``
+
+.. describe:: clr_note_category_fg
+
+.. describe:: clr_note_category_bg
+
+ The foreground/background colors for the note category (i.e., the
+ ``%T`` portion of :confval:`cfg_format_note_title`).
+
+ Default values: ``dark red/default``
+
+.. describe:: clr_note_content_fg
+
+.. describe:: clr_note_content_bg
+
+ The foreground/background colors for the note content as displayed
+ in the internal pager.
+
+ Default values: ``default/default``
+
+.. describe:: clr_note_content_focus_fg
+
+.. describe:: clr_note_content_focus_bg
+
+ The foreground/background colors for focused content within the
+ internal pager.
+
+ Default values: ``white/light red``
+
+.. describe:: clr_note_content_old_fg
+
+.. describe:: clr_note_content_old_bg
+
+ The foreground/background colors for old note content as displayed
+ within the internal pager.
+
+ Default values: ``yellow/dark gray``
+
+.. describe:: clr_note_content_old_focus_fg
+
+.. describe:: clr_note_content_old_focus_bg
+
+ The foreground/background colors for old note focused content as
+ displayed within the internal pager.
+
+ Default values: ``white/light red``
+
+.. describe:: clr_help_focus_fg
+
+.. describe:: clr_help_focus_bg
+
+ The foreground/background colors for focused content in the help
+ screen.
+
+ Default values: ``white/light red``
+
+.. describe:: clr_help_header_fg
+
+.. describe:: clr_help_header_bg
+
+ The foreground/background colors for header content in the help
+ screen.
+
+ Default values: ``dark blue/default``
+
+.. describe:: clr_help_config_fg
+
+.. describe:: clr_help_config_bg
+
+ The foreground/background colors for configuration option name (e.g.,
+ ``clr_help_focus_bg``) in the help screen.
+
+ Default values: ``dark green/default``
+
+.. describe:: clr_help_value_fg
+
+.. describe:: clr_help_value_bg
+
+ The foreground/background colors for the value of a configuration
+ option as set in ``config``.
+
+ Default values: ``dark red/default``
+
+.. describe:: clr_help_descr_fg
+
+.. describe:: clr_help_descr_bg
+
+ The foreground/background colors for the configuration options
+ description in the help screen.
+
+ Default values: ``default/default``
diff --git a/docs/source/configuration/genopts.rst b/docs/source/configuration/genopts.rst
new file mode 100644
index 0000000..2e5f9f0
--- /dev/null
+++ b/docs/source/configuration/genopts.rst
@@ -0,0 +1,157 @@
+.. describe:: cfg_nn_host
+
+ Sets the URL of the NextCloud instance to connect to.
+
+ Required.
+
+.. describe:: cfg_nn_username
+
+ The user name to log in as.
+
+ Required.
+
+.. describe:: cfg_nn_password
+
+ The password to use for log in.
+
+ Optional. Overrides :confval:`cfg_nn_password_eval` if both are
+ specified.
+
+ .. note::
+
+ For security reasons, use of the ``cfg_nn_password_eval`` option
+ is recommended
+
+.. describe:: cfg_nn_password_eval
+
+ A command to run to retrieve the password. The command should return
+ the password on ``stdout``.
+
+ Optional. Required if :confval:`cfg_nn_password` is not specified.
+
+.. describe:: cfg_db_path
+
+ Specifies the path of the local notes cache.
+
+ Optional. Default value:
+
+ - Windows: ``%USERPROFILE%\AppData\Local\djmoch\nncli\Cache``
+
+ - macOS: ``~/Library/Caches/nncli``
+
+ - \*nix: ``$XDG_CACHE_HOME/nncli`` or ``$HOME/.cache/nncli``
+
+.. describe:: cfg_search_categories
+
+ Set to ``yes`` to include categories in searches. Otherwise set to
+ ``no``.
+
+ Optional. Default value: ``yes``
+
+.. describe:: cfg_sort_mode
+
+ Sets how notes are sorted in the console GUI. Set to ``date``
+ to have them sorted by date (newest on top). Set to ``alpha`` to have
+ them sorted alphabetically.
+
+ Optional. Default value: ``date``
+
+.. describe:: cfg_favorite_ontop
+
+ Determines whether notes marked as favorite are sorted on top.
+
+ Optional. Default value: ``yes``
+
+.. describe:: cfg_tabstop
+
+ Sets the width of a tabstop character.
+
+ Optional. Default value: ``4``
+
+.. describe:: cfg_format_strftime
+
+ Sets the format of the note timestamp (``%D``) in the note title. The
+ format values are the specified in :py:func:`time.strftime`.
+
+ Optional. Default value: ``%Y/%m/%d``
+
+.. describe:: cfg_format_note_title
+
+ Sets the format of each line in the console GUI note list. Various
+ formatting tags are supported for dynamically building the title
+ string. Each of these formatting tags supports a width specifier
+ (decimal) and a left justification (``-``) like that supported by
+ printf:
+
+ .. code-block:: none
+
+ %F - flags (fixed 2 char width)
+ X - needs sync
+ * - favorited
+ %T - category
+ %D - date
+ %N - title
+
+ The default note title format pushes the note category to the far
+ right of the terminal and left justifies the note title after the
+ date and flags.
+
+ Optional. Default value: ``[%D] %F %-N %T``
+
+ Note that the ``%D`` date format is further defined by the strftime
+ format specified in :confval:`cfg_format_strftime`.
+
+.. describe:: cfg_status_bar
+
+ Sets whether or not the status bar is visible at the top of the
+ console GUI.
+
+ Optional. Default value: ``yes``
+
+.. describe:: cfg_editor
+
+ Sets the command to run when opening a note for editing. The special
+ values ``{fname}`` and ``{line}`` can be used to specify respectively
+ the file name and line number to pass to the command.
+
+ Optional. Default value: ``$VISUAL`` or ``$EDITOR`` if defined in the
+ user's environment (preferring ``$VISUAL``), else ``vim {fname} +{line}``.
+
+.. describe:: cfg_pager
+
+ Sets the command to run when opening a note for viewing in an
+ external pager.
+
+ Optional. Default value: ``$PAGER`` if defined in the user's
+ environment, else ``less -c``.
+
+.. describe:: cfg_max_logs
+
+ Sets the number of log events to display together in the consule GUI
+ footer.
+
+ Optional. Default value: ``5``
+
+.. describe:: cfg_log_timeout
+
+ Sets the rate to poll for log events. Unit is seconds.
+
+ Optional. Default value: ``5``
+
+.. describe:: cfg_log_reversed
+
+ Sets whether or not the log is displayed in reverse-chronological
+ order.
+
+ Optional. Default value: ``yes``
+
+.. describe:: cfg_tempdir
+
+ Sets a directory path to store temporary files in. ``nncli`` uses
+ :func:`tempfile.mkstemp` under the hood, and the most nuanced
+ description of how this value is used can be found in the discussion
+ of the ``dir`` keyword argument there. Basically you should not
+ specify this if you want to use the platform-standard temporary
+ folder.
+
+ Optional. Default value: *[blank]*
diff --git a/docs/source/configuration/intro.rst b/docs/source/configuration/intro.rst
new file mode 100644
index 0000000..f40c4b4
--- /dev/null
+++ b/docs/source/configuration/intro.rst
@@ -0,0 +1,3 @@
+The current NextCloud Notes API does not support OAuth authentication so
+your NextCloud Notes account password must be stored someplace
+accessible to :program:`nncli`.
diff --git a/docs/source/configuration/keybindings.rst b/docs/source/configuration/keybindings.rst
new file mode 100644
index 0000000..8749f2d
--- /dev/null
+++ b/docs/source/configuration/keybindings.rst
@@ -0,0 +1,254 @@
+Keybindings specify the behavior of the console GUI, and are never
+required in the ``config`` file. However, they all have default values,
+as outlined below. More information on specifying keybindings can be
+found in the :ref:`Urwid documentation <urwid:keyboard-input>`.
+
+.. describe:: kb_help
+
+ Press to enter the help screen.
+
+ Default value: ``h``
+
+.. describe:: kb_quit
+
+ Press to exit the console GUI.
+
+ Default value: ``q``
+
+.. describe:: kb_sync
+
+ Press to force a full, bi-directional sync with the server.
+
+ Default value: ``S``
+
+.. describe:: kb_down
+
+ Press to move down one row.
+
+ Default value: ``j``
+
+.. describe:: kb_up
+
+ Press to move one row up.
+
+ Default value: ``k``
+
+.. describe:: kb_page_down
+
+ Press to move one page down.
+
+ Default value: ``space``
+
+.. describe:: kb_page_up
+
+ Press to move one page up.
+
+ Default value: ``b``
+
+.. describe:: kb_half_page_down
+
+ Press to move one half-page down.
+
+ Default value: ``ctrl d``
+
+.. describe:: kb_half_page_up
+
+ Press to move one half-page up.
+
+ Default value: ``ctrl u``
+
+.. describe:: kb_bottom
+
+ Press to move to the last line.
+
+ Default value: ``G``
+
+.. describe:: kb_top
+
+ Press to move to the first line.
+
+ Default value: ``g``
+
+.. describe:: kb_status
+
+ Press to toggle the visibility of the status bar.
+
+ Default value: ``s``
+
+.. describe:: kb_create_note
+
+ Press to create a new note and open in the configured editor (see
+ :confval:`cfg_editor`).
+
+ Default value: ``C``
+
+.. describe:: kb_edit_note
+
+ Press to edit the highlighted note in the configured editor (see
+ :confval:`cfg_editor`).
+
+ Default value: ``e``
+
+.. describe:: kb_view_note
+
+ Press to view the highlighted note in read-only mode.
+
+ Default value: ``enter``
+
+.. describe:: kb_view_note_ext
+
+ Press to view the highlighted note in the configured pager (see
+ :confval:`cfg_pager`).
+
+ Default value: ``meta enter``
+
+.. describe:: kb_view_note_json
+
+ Press to view the raw JSON contents of the highlighted note in
+ read-only mode.
+
+ Default value: ``O``
+
+.. describe:: kb_pipe_note
+
+ Press to send the contents of the highlighted note to ``stdin`` of
+ another program. A small command window opens at the bottom of the
+ screen to enter the desired program.
+
+ Default value: ``|``
+
+.. describe:: kb_view_next_note
+
+ Press to view the contents of the next note in read-only mode.
+
+ Default value: ``J``
+
+.. describe:: kb_view_prev_note
+
+ Press to view the contents of the previous note in read-only mode.
+
+ Default value: ``K``
+
+.. describe:: kb_view_log
+
+ Press to view the log.
+
+ Default value: ``l``
+
+.. describe:: kb_tabstop2
+
+ Press to set the tabstop for the internal pager to a width of two
+ characters.
+
+ Default value: ``2``
+
+.. describe:: kb_tabstop4
+
+ Press to set the tabstop for the internal pager to a width of four
+ characters.
+
+ Default value: ``4``
+
+.. describe:: kb_tabstop8
+
+ Press to set the tabstop for the internal pager to a width of eight
+ characters.
+
+ Default value: ``8``
+
+.. describe:: kb_search_gstyle
+
+ Press to initiate a search of your notes against a Google-style
+ search term. A command window will open at the bottom of the screen
+ to enter your search term.
+
+ Default value: ``/``
+
+.. describe:: kb_search_regex
+
+ Press to initiate a search of your notes against a regular
+ expression. A command window will open at the bottom of the screen to
+ enter your search term.
+
+ Default value: ``meta /``
+
+.. describe:: kb_search_prev_gstyle
+
+ Press to initiate a reverse search of your notes against a
+ Google-style search term. A command window will open at the bottom of
+ the screen to enter your search term.
+
+ Default value: ``?``
+
+.. describe:: kb_search_prev_regex
+
+ Press to initiate a reverse search of your notes against a regular
+ expression. A command window will open at the bottom of the screen
+ to enter your search term.
+
+ Default value: ``meta ?``
+
+.. describe:: kb_search_next
+
+ Press after a search has been initiated to move to the next match.
+
+ Default value: ``n``
+
+.. describe:: kb_search_prev
+
+ Press after a search has been initiated to move to the previous
+ match.
+
+ Default value: ``N``
+
+.. describe:: kb_clear_search
+
+ Press to clear the current search.
+
+ Default value: ``A``
+
+.. describe:: kb_sort_date
+
+ Press to display notes sorted by date.
+
+ Default value: ``d``
+
+.. describe:: kb_sort_alpha
+
+ Press to display notes sorted alphabetically.
+
+ Default value: ``a``
+
+.. describe:: kb_sort_categories
+
+ Press to display notes sorted by category.
+
+ Default value: ``ctrl t``
+
+.. describe:: kb_note_delete
+
+ Press to delete a note. The note will be deleted locally and
+ reflected on the server after the next full sync (see
+ :confval:`kb_sync`).
+
+ Default value: ``D``
+
+.. describe:: kb_note_favorite
+
+ Press to toggle the ``favorite`` flag for a note.
+
+ Default value: ``p``
+
+.. describe:: kb_note_category
+
+ Press to set/edit the note category. A command window will appear at
+ the bottom of the screen containing the current category (if it has
+ one). Set to an empty string to clear the category.
+
+ Default value: ``t``
+
+.. describe:: kb_copy_note_text
+
+ Press to copy the note text to the system clipboard.
+
+ Default value: ``y``
diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst
new file mode 100644
index 0000000..02dd9fd
--- /dev/null
+++ b/docs/source/contributing.rst
@@ -0,0 +1,3 @@
+.. _contribution guide:
+
+.. include:: ../../CONTRIBUTING.rst
diff --git a/docs/source/index.rst b/docs/source/index.rst
index bcab7d0..5198797 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -11,27 +11,42 @@ NextCloud Notes Command Line Interface
.. image:: https://img.shields.io/pypi/l/nncli.svg
:alt: PyPI - License
:target: https://git.danielmoch.com/nncli/tree/LICENSE
- .. image:: https://builds.danielmoch.com/badges/nncli.svg
- :alt: Daniel Moch CI
- :target: https://builds.danielmoch.com/#/builders/nncli
.. image:: https://img.shields.io/pypi/v/nncli.svg
:alt: PyPI
:target: https://pypi.org/project/nncli
.. include:: ../../README.rst
-Contents
---------
+Documentation Contents
+----------------------
.. toctree::
:maxdepth: 2
configuration
usage
+ contributing
+ changelog
-
-Indices and tables
-------------------
-
-* :ref:`genindex`
-* :ref:`search`
+.. toctree::
+ :caption: Manuals
+ :titlesonly:
+
+ nncli.1
+ nncli-sync.1
+ nncli-list.1
+ nncli-export.1
+ nncli-dump.1
+ nncli-create.1
+ nncli-import.1
+ nncli-edit.1
+ nncli-delete.1
+ nncli-favorite.1
+ nncli-cat.1
+ nncli.config.5
+
+
+Index
+-----
+
+:ref:`genindex`
diff --git a/docs/source/nncli-cat.1.rst b/docs/source/nncli-cat.1.rst
new file mode 100644
index 0000000..0aa0e17
--- /dev/null
+++ b/docs/source/nncli-cat.1.rst
@@ -0,0 +1,27 @@
+nncli-cat(1)
+============
+
+Synopsis
+--------
+
+:program:`nncli` *--key|-k KEY cat get|set|rm* [*category_name*]
+
+Description
+-----------
+
+.. include:: usage/cat-desc.rst
+
+Options
+-------
+
+.. include:: usage/cat-args.rst
+
+Examples
+--------
+
+.. include:: usage/cat-example.rst
+
+See also
+--------
+
+:manpage:`nncli(1)`
diff --git a/docs/source/nncli-create.1.rst b/docs/source/nncli-create.1.rst
new file mode 100644
index 0000000..0b5e3dd
--- /dev/null
+++ b/docs/source/nncli-create.1.rst
@@ -0,0 +1,22 @@
+nncli-create(1)
+===============
+
+Synopsis
+--------
+
+**nncli create** [-]
+
+Description
+-----------
+
+.. include:: usage/create-desc.rst
+
+Examples
+--------
+
+.. include:: usage/create-example.rst
+
+See also
+--------
+
+:manpage:`nncli(1)`
diff --git a/docs/source/nncli-delete.1.rst b/docs/source/nncli-delete.1.rst
new file mode 100644
index 0000000..f2758f8
--- /dev/null
+++ b/docs/source/nncli-delete.1.rst
@@ -0,0 +1,22 @@
+nncli-delete(1)
+===============
+
+Synopsis
+--------
+
+:program:`nncli` *--key|-k KEY delete*
+
+Description
+-----------
+
+.. include:: usage/delete-desc.rst
+
+Options
+-------
+
+.. include:: usage/delete-args.rst
+
+See also
+--------
+
+:manpage:`nncli(1)`
diff --git a/docs/source/nncli-dump.1.rst b/docs/source/nncli-dump.1.rst
new file mode 100644
index 0000000..89a8a23
--- /dev/null
+++ b/docs/source/nncli-dump.1.rst
@@ -0,0 +1,22 @@
+nncli-dump(1)
+=============
+
+Synopsis
+--------
+
+**nncli dump** [*options*] [*search_string*]
+
+Description
+-----------
+
+.. include:: usage/dump-desc.rst
+
+Options
+-------
+
+.. include:: usage/dump-args.rst
+
+See also
+--------
+
+:manpage:`nncli(1)`
diff --git a/docs/source/nncli-edit.1.rst b/docs/source/nncli-edit.1.rst
new file mode 100644
index 0000000..5b6ead0
--- /dev/null
+++ b/docs/source/nncli-edit.1.rst
@@ -0,0 +1,22 @@
+nncli-edit(1)
+=============
+
+Synopsis
+--------
+
+:program:`nncli` *--key|-k KEY edit*
+
+Description
+-----------
+
+.. include:: usage/edit-desc.rst
+
+Options
+-------
+
+.. include:: usage/edit-args.rst
+
+See also
+--------
+
+:manpage:`nncli(1)`
diff --git a/docs/source/nncli-export.1.rst b/docs/source/nncli-export.1.rst
new file mode 100644
index 0000000..cfb3d96
--- /dev/null
+++ b/docs/source/nncli-export.1.rst
@@ -0,0 +1,27 @@
+nncli-export(1)
+===============
+
+Synopsis
+--------
+
+**nncli export** [*options*] [*search_string*]
+
+Description
+-----------
+
+.. include:: usage/export-desc.rst
+
+Options
+-------
+
+.. include:: usage/export-args.rst
+
+Examples
+--------
+
+.. include:: usage/export-example.rst
+
+See also
+--------
+
+:manpage:`nncli(1)`
diff --git a/docs/source/nncli-favorite.1.rst b/docs/source/nncli-favorite.1.rst
new file mode 100644
index 0000000..a3d237d
--- /dev/null
+++ b/docs/source/nncli-favorite.1.rst
@@ -0,0 +1,22 @@
+nncli-favorite(1)
+=================
+
+Synopsis
+--------
+
+:program:`nncli` *--key|-k KEY favorite|unfavorite*
+
+Description
+-----------
+
+.. include:: usage/favorite-desc.rst
+
+Options
+-------
+
+.. include:: usage/favorite-args.rst
+
+See also
+--------
+
+:manpage:`nncli(1)`
diff --git a/docs/source/nncli-import.1.rst b/docs/source/nncli-import.1.rst
new file mode 100644
index 0000000..25b2a5a
--- /dev/null
+++ b/docs/source/nncli-import.1.rst
@@ -0,0 +1,22 @@
+nncli-import(1)
+===============
+
+Synopsis
+--------
+
+**nncli import** [-]
+
+Description
+-----------
+
+.. include:: usage/import-desc.rst
+
+Examples
+--------
+
+.. include:: usage/import-example.rst
+
+See also
+--------
+
+:manpage:`nncli(1)`
diff --git a/docs/source/nncli-list.1.rst b/docs/source/nncli-list.1.rst
new file mode 100644
index 0000000..1f1e90e
--- /dev/null
+++ b/docs/source/nncli-list.1.rst
@@ -0,0 +1,22 @@
+nncli-list(1)
+=============
+
+Synopsis
+--------
+
+**nncli list** [*options*] [*search_string*]
+
+Description
+-----------
+
+.. include:: usage/list-desc.rst
+
+Options
+-------
+
+.. include:: usage/list-args.rst
+
+See also
+--------
+
+:manpage:`nncli(1)`
diff --git a/docs/source/nncli-sync.1.rst b/docs/source/nncli-sync.1.rst
new file mode 100644
index 0000000..2be9beb
--- /dev/null
+++ b/docs/source/nncli-sync.1.rst
@@ -0,0 +1,17 @@
+nncli-sync(1)
+=============
+
+Synopsis
+--------
+
+**nncli sync**
+
+Description
+-----------
+
+.. include:: usage/sync-desc.rst
+
+See also
+--------
+
+:manpage:`nncli(1)`
diff --git a/docs/source/nncli.1.rst b/docs/source/nncli.1.rst
index c38d649..6f1dcb7 100644
--- a/docs/source/nncli.1.rst
+++ b/docs/source/nncli.1.rst
@@ -1,10 +1,10 @@
-nncli - NextCloud Notes Command Line Interface
-==============================================
+nncli(1)
+========
Synopsis
--------
-**nncli** [*options*] *command* [*args*]...
+**nncli** [*options*] *subcommand* [*subcommand-options*] [*args*]...
Description
-----------
@@ -21,12 +21,57 @@ automatically sync'ed when nncli is brought online.
Options
-------
-.. include:: usage.rst
+.. include:: usage/genopts.rst
+.. include:: usage/subopts.rst
+
+Subcommands
+-----------
+
+:program:`nncli` provides the following subcommands:
+
+- :manpage:`nncli-sync(1)`
+- :manpage:`nncli-list(1)`
+- :manpage:`nncli-export(1)`
+- :manpage:`nncli-dump(1)`
+- :manpage:`nncli-create(1)`
+- :manpage:`nncli-import(1)`
+- :manpage:`nncli-edit(1)`
+- :manpage:`nncli-delete(1)`
+- :manpage:`nncli-favorite(1)`
+- :manpage:`nncli-cat(1)`
+
Environment Variables
---------------------
+.. describe:: VISUAL
+
+ Used to determine which program to open when editing a note.
+
+.. describe:: EDITOR
+
+ Used when VISUAL is not defined to determine which program to open
+ when editing a note. If neither is defined, :manpage:`vim(1)` is
+ used.
+
+.. describe:: PAGER
+
+ Used to specify the program used to open notes for reading. If not
+ defined, the default is **less -c**.
+
+.. describe:: XDG_CACHE_HOME
+
+ Used to determine the location of the local notes database. If not
+ specified, *$HOME/.cache* will be used.
+
+.. describe:: XDG_CONFIG_HOME
+
+ Used to determine the location of the configuration file. If not
+ specified, *$HOME/.config* will be used.
+
+
See also
--------
+:manpage:`less(1)`,
:manpage:`nncli.config(5)`
diff --git a/docs/source/nncli.config.5.rst b/docs/source/nncli.config.5.rst
new file mode 100644
index 0000000..e464687
--- /dev/null
+++ b/docs/source/nncli.config.5.rst
@@ -0,0 +1,56 @@
+nncli.config(5)
+===============
+
+.. include:: configuration/intro.rst
+.. |here| replace:: in the Urwid manual
+
+Configuration File
+------------------
+
+nncli pulls in configuration from the *config* file located in the
+standard location for your platform:
+
+.. describe:: macOS
+
+ $HOME/Library/Preferences/nncli
+
+.. describe:: Linux/BSD
+
+ $XDG_CONFIG_HOME/nncli/config or $HOME/.config/nncli/config
+
+The following directives are accepted within the *config* file:
+
+General Options
+~~~~~~~~~~~~~~~
+
+.. include:: configuration/genopts.rst
+
+Keybindings
+~~~~~~~~~~~
+
+.. include:: configuration/keybindings.rst
+
+Colors
+~~~~~~
+
+.. include:: configuration/colors.rst
+
+Examples
+--------
+
+At the very least, the following example *config* will get you going
+(using your account information):
+
+::
+
+ [nncli]
+ cfg_nn_username = lebowski@thedude.com
+ cfg_nn_password = nihilist
+ cfg_nn_host = nextcloud.thedude.com
+
+See Also
+--------
+
+:manpage:`nncli(1)`
+
+The Urwid Manual, Display Attributes, 16 Standard Foreground Colors
diff --git a/docs/source/usage.rst b/docs/source/usage.rst
index 7502ecd..f9f3c66 100644
--- a/docs/source/usage.rst
+++ b/docs/source/usage.rst
@@ -1,25 +1,7 @@
Usage
=====
-.. program:: nncli
-
-When ``nncli`` is run without any options or arguments an interactive
-console GUI will appear. The behavior of this interface is highly
-configurable (see: :ref:`configuration`).
-
-In addition to this default behavior, there are several options
-available when calling ``nncli`` without a subcommand.
-
-.. option:: --help, -h
-
-Displays a brief decription of the ``nncli`` options and subcommands.
-
-.. option:: --version, -V
-
-Displays the version information.
-
-Also available when calling ``nncli`` by itself is the ``--config``
-option, for which see: :ref:`general-options`.
+.. include:: usage/genopts.rst
Subcommands
-----------
@@ -51,34 +33,8 @@ scripting against your NextCloud Notes database. The subcommands are:
These subcommands and the options available to them are described below.
.. _general-options:
-
-General Subcommand Options
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Several ``nncli`` options apply to multiple subcommands. They are:
-
-.. option:: --verbose, -v
-
-Print verbose logging information to ``stdout``
-
-.. option:: --nosync, -n
-
-Operate only on the local notes cache. Do not reach out to the server.
-
-.. option:: --regex, -r
-
-For subcommands that accept a search string, treat the search string as
-a regular expression.
-
-.. option:: --key, -k
-
-The ID of the note to operate on. This option is required for many of
-the subcommands.
-
-.. option:: --config, -c
-
-Specify the config file to read from. This option is only required to
-override the default location (see: :ref:`config-file`).
+.. include:: usage/genopts.rst
+.. include:: usage/subopts.rst
nncli sync
~~~~~~~~~~
@@ -87,124 +43,63 @@ nncli sync
Command format: ``nncli sync``
-Performs a full, bi-directional sync between the local notes cache and
-the NextCloud Notes server. There are no available options for this
-subcommand.
-
-- Available options: None
-
-- Arguments: None
+.. include:: usage/sync-desc.rst
nncli list
~~~~~~~~~~
.. program:: nncli list
-Command format: ``nncli list [search_string]``
+Command format: :program:`nncli list` [*options*] [*search_string*]
-List notes by ID, flags, and title. Flags indicate whether the note has
-been modified locally (``X``), and/or if it is marked as a favorite
-(``*``).
+.. include:: usage/list-desc.rst
-- Available options:
+Options are as follows:
- - ``--regex, -r`` See :ref:`general-options`
-
-- Arguments:
-
- - ``search_string`` Optional. A search term used to refine the search.
+.. include:: usage/list-args.rst
nncli export
~~~~~~~~~~~~
.. program:: nncli export
-Command format: ``nncli export [search_string]``
-
-Exports notes in raw, JSON format. The JSON format is a superset of the
-format outlined in the NextCloud Notes API specification with
-information added for managing the local notes cache. Note that nncli
-still stores all the notes data in the directory specified by
-``cfg_db_path``, so for easy backups, it may be easier/quicker to simply
-backup this entire directory.
-
-- Available options:
-
- - :ref:`general-options`
-
- - ``--regex, -r`` Mutually exclusive with ``--key``
+Command format: :program:`nncli export` [*options*] [*search_string*]
- - ``--key, -k``
+.. include:: usage/export-desc.rst
-- Arguments:
+Options are as follows:
- - ``search_string`` Required if ``--regex`` is specified. A search
- term used to refine the search.
+.. include:: usage/export-args.rst
Example:
-.. code-block:: sh
-
- # export a single note by id
- nncli -k somekeyid export
-
- # export all notes
- nncli export
-
- # export notes matching search string
- nncli [-r] export some search keywords or regex
+.. include:: usage/export-example.rst
nncli dump
~~~~~~~~~~
.. program:: nncli dump
-Command format: ``nncli dump [search_string]``
-
-Prints notes to ``stdout``. The printed format is the text of the note
-preceeded by a header displaying information about the note title, key,
-modified date, category, and flags. Flags indicate whether the note has
-been modified locally (``X``), and/or if it is marked as a favorite
-(``*``).
-
-- Available options:
-
- - :ref:`general-options`
-
- - ``--regex, -r`` Mutually exclusive with ``--key``
+Command format: :program:`nncli dump` [search_string]``
- - ``--key, -k``
+.. include:: usage/dump-desc.rst
-- Arguments:
+Options are as follows:
- - ``search_string`` Required if ``--regex`` is specified. A search
- term used to refine the search.
+.. include:: usage/dump-args.rst
nncli create
~~~~~~~~~~~~
.. program:: nncli create
-Command format: ``nncli create [-]``
+Command format: program:`nncli create` [*-*]
-Create a note. Without arguments, this command will open your configured
-editor. The note syncs to the server after the editor is closed.
-
-- Available options: None
-
-- Arguments:
-
- - `-` Optional. If specified, the note content is read from ``stdin``.
+.. include: usage/create-desc.rst
Example:
-.. code-block:: sh
-
- # create a new note and open in editor
- nncli create
-
- # create a new note with contents of stdin
- echo 'hi' | nncli create -
+.. include:: usage/create-example.rst
nncli import
~~~~~~~~~~~~
@@ -213,104 +108,67 @@ nncli import
Command format: ``nncli import [-]``
-Import a JSON-formatted note. nncli can import notes from raw json data
-(via stdin or editor). Allowed fields are ``content``, ``category``,
-``favorite``, and ``modified``.
-
-- Available options: None
-
-- Arguments:
-
- - ``-`` Optional. If specified, the note content is read from ``stdin``.
+.. include:: usage/import-desc.rst
Example:
-.. code-block:: none
-
- echo '{"category":"testing","content":"New note!"}' | nncli import -
+.. include:: usage/import-example.rst
nncli edit
~~~~~~~~~~
.. program:: nncli edit
-Command format: ``nncli -k <key> edit``
-
-Open the note specified by ``<key>`` in the configured editor. The note
-syncs to the server after the editor is saved and closed.
+Command format: :program:`nncli` [*--key|-k*] *KEY edit*
-- Available options:
+.. include:: usage/edit-desc.rst
- - ``--key, -k`` Required. See :ref:`general-options`
+Options are as follows:
-- Arguments: None
+.. include:: usage/edit-args.rst
nncli delete
~~~~~~~~~~~~
.. program:: nncli delete
-Command format: ``nncli -k <key> delete``
+Command format: :program:`nncli` [*--key|-k*] *KEY delete*
-Delete the note specified by ``<key>``.
+.. include:: usage/delete-desc.rst
-- Available options:
+Options are as follows:
- - ``--key, -k`` Required. See :ref:`general-options`
-
-- Arguments: None
+.. include:: usage/delete-args.rst
nncli favorite
~~~~~~~~~~~~~~
.. program:: nncli favorite
-Command format: ``nncli -k <key> favorite|unfavorite``
-
-Favorite (or unfavorite) the note specified by ``<key>``.
+Command format: :program:`nncli` *--key|-k KEY favorite|unfavorite*
-- Available options:
+.. include:: usage/favorite-desc.rst
- - ``--key, -k`` Required. See :ref:`general-options`
+Options are as follows:
-- Arguments: None
+.. include:: usage/favorite-args.rst
nncli cat
~~~~~~~~~
.. program:: nncli cat
-Command format: ``nncli -k <key> cat get|set|rm``
-
-Read or modify a note category from the command line.
+Command format: :program:`nncli` *--key|-k KEY cat get|set|rm* [*category_name*]
-- Available options:
+.. include:: usage/cat-desc.rst
- - ``--key, -k`` Required. See :ref:`general-options`
+Options are as follows:
-- Arguments:
-
- - ``get`` Get the note category
-
- - ``set`` Set the note category
-
- - ``rm`` Remove the note category
+.. include:: usage/cat-args.rst
Example:
-.. code-block:: sh
-
- # Retrieve note category (e.g. "category1")
- nncli -k somekeyid cat get
- # Returns "category1"
-
- # Add a category to a note, overwriting any existing one
- nncli -k somekeyid cat set "category3"
- # Now tagged as "category3"
-
- # Remove a category from a note
- nncli -k somekeyid cat rm
- # Note now has no category
+.. include:: usage/cat-example.rst
Console GUI Usage
-----------------
diff --git a/docs/source/usage/cat-args.rst b/docs/source/usage/cat-args.rst
new file mode 100644
index 0000000..a3d0b52
--- /dev/null
+++ b/docs/source/usage/cat-args.rst
@@ -0,0 +1,3 @@
+.. option:: --key, -k
+
+ The ID of the note to operate on. \ No newline at end of file
diff --git a/docs/source/usage/cat-desc.rst b/docs/source/usage/cat-desc.rst
new file mode 100644
index 0000000..cc6975d
--- /dev/null
+++ b/docs/source/usage/cat-desc.rst
@@ -0,0 +1,4 @@
+Modify a note category from the command line. With the *get* argument,
+the command returns the note category. With the *set* argument, the
+note category is set to the required *category_name* argument. With
+the *rm* argument, the note's category is removed.
diff --git a/docs/source/usage/cat-example.rst b/docs/source/usage/cat-example.rst
new file mode 100644
index 0000000..b5bccac
--- /dev/null
+++ b/docs/source/usage/cat-example.rst
@@ -0,0 +1,11 @@
+::
+
+ # Retrieve note category (e.g. "category1")
+ $ nncli -k 42 cat get
+ category1
+
+ # Add a category to a note, overwriting any existing one
+ nncli -k 42 cat set "category3"
+
+ # Remove a category from a note
+ nncli -k 42 cat rm
diff --git a/docs/source/usage/create-desc.rst b/docs/source/usage/create-desc.rst
new file mode 100644
index 0000000..faf1f76
--- /dev/null
+++ b/docs/source/usage/create-desc.rst
@@ -0,0 +1,3 @@
+Create a note. Without arguments, this command will open your
+configured editor. If *-* is specified, the note content is read from
+*stdin*. The note syncs to the server after the command completes.
diff --git a/docs/source/usage/create-example.rst b/docs/source/usage/create-example.rst
new file mode 100644
index 0000000..c80ae6f
--- /dev/null
+++ b/docs/source/usage/create-example.rst
@@ -0,0 +1,7 @@
+::
+
+ # create a new note and open in editor
+ $ nncli create
+
+ # create a new note with contents of stdin
+ $ echo 'hi' | nncli create -
diff --git a/docs/source/usage/delete-args.rst b/docs/source/usage/delete-args.rst
new file mode 100644
index 0000000..a3d0b52
--- /dev/null
+++ b/docs/source/usage/delete-args.rst
@@ -0,0 +1,3 @@
+.. option:: --key, -k
+
+ The ID of the note to operate on. \ No newline at end of file
diff --git a/docs/source/usage/delete-desc.rst b/docs/source/usage/delete-desc.rst
new file mode 100644
index 0000000..c9aa019
--- /dev/null
+++ b/docs/source/usage/delete-desc.rst
@@ -0,0 +1 @@
+Delete the note specified by *KEY*.
diff --git a/docs/source/usage/dump-args.rst b/docs/source/usage/dump-args.rst
new file mode 100644
index 0000000..e28eb2f
--- /dev/null
+++ b/docs/source/usage/dump-args.rst
@@ -0,0 +1,8 @@
+.. option:: --regex, -r
+
+ Treat *search_string* as a regular expression. Mutually exclusive
+ with *--key*.
+
+.. option:: --key, -k
+
+ The ID of the note to operate on.
diff --git a/docs/source/usage/dump-desc.rst b/docs/source/usage/dump-desc.rst
new file mode 100644
index 0000000..707db43
--- /dev/null
+++ b/docs/source/usage/dump-desc.rst
@@ -0,0 +1,6 @@
+:program:`nncli dump` dumps notes to *stdout*. The printed format is
+the text of the note preceeded by a header displaying information
+about the note title, key, modified date, category, and flags. Flags
+indicate whether the note has been modified locally (*X*), and/or if
+it is marked as a favorite (*\**). If *search_string* is specified, it
+is used to filter the notes prior to export.
diff --git a/docs/source/usage/edit-args.rst b/docs/source/usage/edit-args.rst
new file mode 100644
index 0000000..a3d0b52
--- /dev/null
+++ b/docs/source/usage/edit-args.rst
@@ -0,0 +1,3 @@
+.. option:: --key, -k
+
+ The ID of the note to operate on. \ No newline at end of file
diff --git a/docs/source/usage/edit-desc.rst b/docs/source/usage/edit-desc.rst
new file mode 100644
index 0000000..8b9cfa9
--- /dev/null
+++ b/docs/source/usage/edit-desc.rst
@@ -0,0 +1,2 @@
+Open the note specified by *KEY* in the configured editor. The note
+syncs to the server after the editor is saved and closed.
diff --git a/docs/source/usage/export-args.rst b/docs/source/usage/export-args.rst
new file mode 100644
index 0000000..e28eb2f
--- /dev/null
+++ b/docs/source/usage/export-args.rst
@@ -0,0 +1,8 @@
+.. option:: --regex, -r
+
+ Treat *search_string* as a regular expression. Mutually exclusive
+ with *--key*.
+
+.. option:: --key, -k
+
+ The ID of the note to operate on.
diff --git a/docs/source/usage/export-desc.rst b/docs/source/usage/export-desc.rst
new file mode 100644
index 0000000..1f325ea
--- /dev/null
+++ b/docs/source/usage/export-desc.rst
@@ -0,0 +1,11 @@
+:program:`nncli export` exports notes in raw, JSON format. The JSON
+format is a superset of the format outlined in the NextCloud Notes API
+specification with information added for managing the local notes
+cache. If *search_string* is specified, it is used to filter the notes
+prior to export.
+
+.. note::
+
+ :program:`nncli` already stores all notes locally in the cache
+ directory, so for easy backups, it may be easier/quicker to simply
+ backup this entire directory.
diff --git a/docs/source/usage/export-example.rst b/docs/source/usage/export-example.rst
new file mode 100644
index 0000000..c8cce53
--- /dev/null
+++ b/docs/source/usage/export-example.rst
@@ -0,0 +1,10 @@
+::
+
+ # export a single note by id
+ $ nncli -k somekeyid export
+
+ # export all notes
+ $ nncli export
+
+ # export notes matching search string
+ $ nncli [-r] export "some search keywords or regex"
diff --git a/docs/source/usage/favorite-args.rst b/docs/source/usage/favorite-args.rst
new file mode 100644
index 0000000..a3d0b52
--- /dev/null
+++ b/docs/source/usage/favorite-args.rst
@@ -0,0 +1,3 @@
+.. option:: --key, -k
+
+ The ID of the note to operate on. \ No newline at end of file
diff --git a/docs/source/usage/favorite-desc.rst b/docs/source/usage/favorite-desc.rst
new file mode 100644
index 0000000..426efe6
--- /dev/null
+++ b/docs/source/usage/favorite-desc.rst
@@ -0,0 +1 @@
+Favorite (or unfavorite) the note specified by *KEY*.
diff --git a/docs/source/usage/genopts.rst b/docs/source/usage/genopts.rst
new file mode 100644
index 0000000..47c2bfa
--- /dev/null
+++ b/docs/source/usage/genopts.rst
@@ -0,0 +1,24 @@
+General Subcommand Options
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. program:: nncli
+
+When ``nncli`` is run without any options or arguments an interactive
+console GUI will appear. The appearance and behavior of the GUI may be
+customized through a configuration file, described elsewhere.
+
+In addition to this default behavior, there are several options
+available when calling ``nncli`` without a subcommand.
+
+.. option:: --help, -h
+
+Displays a brief decription of the ``nncli`` options and subcommands.
+
+.. option:: --version, -V
+
+Displays the version information.
+
+.. option:: --config, -c
+
+Specify the config file to read from. This option is only required to
+override the default location.
diff --git a/docs/source/usage/import-desc.rst b/docs/source/usage/import-desc.rst
new file mode 100644
index 0000000..c9a8c28
--- /dev/null
+++ b/docs/source/usage/import-desc.rst
@@ -0,0 +1,5 @@
+Import a JSON-formatted note. nncli can import notes from raw json
+data (via stdin or editor). Allowed fields are *content*, *category*,
+*favorite*, and *modified*. If *-* is specified, the note content is
+read from *stdin*. The note syncs to the server after the command
+completes.
diff --git a/docs/source/usage/import-example.rst b/docs/source/usage/import-example.rst
new file mode 100644
index 0000000..e73b265
--- /dev/null
+++ b/docs/source/usage/import-example.rst
@@ -0,0 +1,4 @@
+::
+
+ $ echo '{"category":"testing","content":"New note!"}' \
+ | nncli import -
diff --git a/docs/source/usage/list-args.rst b/docs/source/usage/list-args.rst
new file mode 100644
index 0000000..b3c8ac2
--- /dev/null
+++ b/docs/source/usage/list-args.rst
@@ -0,0 +1,4 @@
+.. option:: --regex, -r
+
+For subcommands that accept a search string, treat the search string as
+a regular expression.
diff --git a/docs/source/usage/list-desc.rst b/docs/source/usage/list-desc.rst
new file mode 100644
index 0000000..a699e69
--- /dev/null
+++ b/docs/source/usage/list-desc.rst
@@ -0,0 +1,4 @@
+:program:`nncli list` lists notes by ID, flags, and title. Flags
+indicate whether the note has been modified locally (``X``), and/or if
+it is marked as a favorite (``*``). If *search_string* is provided, it
+is used to filter the list of notes.
diff --git a/docs/source/usage/subopts.rst b/docs/source/usage/subopts.rst
new file mode 100644
index 0000000..4f7fd44
--- /dev/null
+++ b/docs/source/usage/subopts.rst
@@ -0,0 +1,23 @@
+Common Subcommand Options
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In addition to the global options, several ``nncli`` options apply to
+multiple subcommands. They are:
+
+.. option:: --verbose, -v
+
+Print verbose logging information to ``stdout``
+
+.. option:: --nosync, -n
+
+Operate only on the local notes cache. Do not reach out to the server.
+
+.. option:: --regex, -r
+
+For subcommands that accept a search string, treat the search string as
+a regular expression.
+
+.. option:: --key, -k
+
+The ID of the note to operate on. This option is required for many of
+the subcommands.
diff --git a/docs/source/usage/sync-desc.rst b/docs/source/usage/sync-desc.rst
new file mode 100644
index 0000000..54cc03e
--- /dev/null
+++ b/docs/source/usage/sync-desc.rst
@@ -0,0 +1,3 @@
+:program:`nncli sync` performs a full, bi-directional sync between the
+local notes cache and the NextCloud Notes server. The command accepts
+no options or arguments.
diff --git a/pyproject.toml b/pyproject.toml
index 5463289..6f11eb3 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,28 +1,92 @@
[build-system]
-requires = ["flit"]
-build-backend = "flit.buildapi"
-
-[tool.flit.metadata]
-module = "nncli"
-author = "Daniel Moch"
-author-email = "daniel@danielmoch.com"
-home-page = "https://nncli.org"
-description-file = "README.rst"
-requires = ["urwid", "requests", "appdirs", "click"]
-classifiers = ["License :: OSI Approved :: MIT License",
- "Development Status :: 4 - Beta",
- "Environment :: Console :: Curses",
- "Intended Audience :: End Users/Desktop",
- "License :: OSI Approved :: MIT License",
- "Programming Language :: Python :: 3 :: Only"]
+requires = ["flit_core>=3.2,<4"]
+build-backend = "flit_core.buildapi"
+
+[project]
+name = "nncli"
+authors = [
+ {name = "Daniel Moch", email = "daniel@danielmoch.com"},
+]
+readme = "README.rst"
requires-python = ">=3"
+classifiers = [
+ "License :: OSI Approved :: MIT License",
+ "Development Status :: 4 - Beta",
+ "Environment :: Console :: Curses",
+ "Intended Audience :: End Users/Desktop",
+ "License :: OSI Approved :: MIT License",
+ "Programming Language :: Python :: 3 :: Only",
+]
+dependencies = [
+ "appdirs",
+ "click",
+ "requests",
+ "urwid",
+]
+
+dynamic = [ "version", "description" ]
-[tool.flit.metadata.urls]
-"Source Code" = "https://git.danielmoch.com"
+[project.urls]
+Homepage = "https://nncli.org"
+"Source Code" = "https://git.danielmoch.com/nncli"
-[tool.flit.metadata.requires-extra]
-dev = ["pipenv"]
-doc = ["sphinx"]
+[project.optional-dependencies]
+dev = [
+ "flit",
+ "mock",
+ "pathlib2; python_version < '3.5'",
+ "pip-tools",
+ "pylint",
+ "pytest-cov",
+ "pytest-mock",
+ "pytest>=6.2.5",
+ "scandir; python_version < '3.5'",
+ "sphinx",
+ "sphinx-material",
+ "sphinx-sitemap",
+ "vulture",
+]
+doc = [
+ "sphinx",
+ "sphinx-material",
+ "sphinx-sitemap",
+]
-[tool.flit.scripts]
+[project.scripts]
nncli = "nncli.cli:main"
+
+[tool.coverage.run]
+branch = true
+omit = "nncli/__main__.py"
+
+[tool.coverage.report]
+show_missing = true
+
+[tool.pytest.ini_options]
+mock_use_standalone_module = true
+
+[tool.tox]
+legacy_tox_ini = """
+[tox]
+envlist = py37, py38, py39, py310, pylint, coverage
+skipsdist = True
+
+[testenv:pylint]
+deps = -rrequirements-dev.txt
+allowlist_externals = make
+commands =
+ make lint
+
+[testenv:coverage]
+deps = -rrequirements-dev.txt
+allowlist_externals = make
+commands =
+ make coverage
+
+[testenv]
+deps = -rrequirements-dev.txt
+allowlist_externals = make
+commands =
+ make install
+ python -m pytest
+"""
diff --git a/pytest.ini b/pytest.ini
deleted file mode 100644
index 86d57a4..0000000
--- a/pytest.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[pytest]
-mock_use_standalone_module = true
diff --git a/requirements-dev.txt b/requirements-dev.txt
new file mode 100644
index 0000000..6d60504
--- /dev/null
+++ b/requirements-dev.txt
@@ -0,0 +1,531 @@
+#
+# This file is autogenerated by pip-compile with Python 3.10
+# by the following command:
+#
+# pip-compile --extra=dev --generate-hashes --output-file=requirements-dev.txt pyproject.toml
+#
+alabaster==0.7.12 \
+ --hash=sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359 \
+ --hash=sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02
+ # via sphinx
+appdirs==1.4.4 \
+ --hash=sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41 \
+ --hash=sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128
+ # via nncli (pyproject.toml)
+astroid==2.9.0 \
+ --hash=sha256:5939cf55de24b92bda00345d4d0659d01b3c7dafb5055165c330bc7c568ba273 \
+ --hash=sha256:776ca0b748b4ad69c00bfe0fff38fa2d21c338e12c84aa9715ee0d473c422778
+ # via pylint
+attrs==21.2.0 \
+ --hash=sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1 \
+ --hash=sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb
+ # via pytest
+babel==2.9.1 \
+ --hash=sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9 \
+ --hash=sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0
+ # via sphinx
+beautifulsoup4==4.11.1 \
+ --hash=sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30 \
+ --hash=sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693
+ # via sphinx-material
+certifi==2021.10.8 \
+ --hash=sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872 \
+ --hash=sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569
+ # via requests
+charset-normalizer==2.0.9 \
+ --hash=sha256:1eecaa09422db5be9e29d7fc65664e6c33bd06f9ced7838578ba40d58bdf3721 \
+ --hash=sha256:b0b883e8e874edfdece9c28f314e3dd5badf067342e42fb162203335ae61aa2c
+ # via requests
+click==8.0.3 \
+ --hash=sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3 \
+ --hash=sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b
+ # via
+ # nncli (pyproject.toml)
+ # pip-tools
+coverage[toml]==6.2 \
+ --hash=sha256:01774a2c2c729619760320270e42cd9e797427ecfddd32c2a7b639cdc481f3c0 \
+ --hash=sha256:03b20e52b7d31be571c9c06b74746746d4eb82fc260e594dc662ed48145e9efd \
+ --hash=sha256:0a7726f74ff63f41e95ed3a89fef002916c828bb5fcae83b505b49d81a066884 \
+ --hash=sha256:1219d760ccfafc03c0822ae2e06e3b1248a8e6d1a70928966bafc6838d3c9e48 \
+ --hash=sha256:13362889b2d46e8d9f97c421539c97c963e34031ab0cb89e8ca83a10cc71ac76 \
+ --hash=sha256:174cf9b4bef0db2e8244f82059a5a72bd47e1d40e71c68ab055425172b16b7d0 \
+ --hash=sha256:17e6c11038d4ed6e8af1407d9e89a2904d573be29d51515f14262d7f10ef0a64 \
+ --hash=sha256:215f8afcc02a24c2d9a10d3790b21054b58d71f4b3c6f055d4bb1b15cecce685 \
+ --hash=sha256:22e60a3ca5acba37d1d4a2ee66e051f5b0e1b9ac950b5b0cf4aa5366eda41d47 \
+ --hash=sha256:2641f803ee9f95b1f387f3e8f3bf28d83d9b69a39e9911e5bfee832bea75240d \
+ --hash=sha256:276651978c94a8c5672ea60a2656e95a3cce2a3f31e9fb2d5ebd4c215d095840 \
+ --hash=sha256:3f7c17209eef285c86f819ff04a6d4cbee9b33ef05cbcaae4c0b4e8e06b3ec8f \
+ --hash=sha256:3feac4084291642165c3a0d9eaebedf19ffa505016c4d3db15bfe235718d4971 \
+ --hash=sha256:49dbff64961bc9bdd2289a2bda6a3a5a331964ba5497f694e2cbd540d656dc1c \
+ --hash=sha256:4e547122ca2d244f7c090fe3f4b5a5861255ff66b7ab6d98f44a0222aaf8671a \
+ --hash=sha256:5829192582c0ec8ca4a2532407bc14c2f338d9878a10442f5d03804a95fac9de \
+ --hash=sha256:5d6b09c972ce9200264c35a1d53d43ca55ef61836d9ec60f0d44273a31aa9f17 \
+ --hash=sha256:600617008aa82032ddeace2535626d1bc212dfff32b43989539deda63b3f36e4 \
+ --hash=sha256:619346d57c7126ae49ac95b11b0dc8e36c1dd49d148477461bb66c8cf13bb521 \
+ --hash=sha256:63c424e6f5b4ab1cf1e23a43b12f542b0ec2e54f99ec9f11b75382152981df57 \
+ --hash=sha256:6dbc1536e105adda7a6312c778f15aaabe583b0e9a0b0a324990334fd458c94b \
+ --hash=sha256:6e1394d24d5938e561fbeaa0cd3d356207579c28bd1792f25a068743f2d5b282 \
+ --hash=sha256:86f2e78b1eff847609b1ca8050c9e1fa3bd44ce755b2ec30e70f2d3ba3844644 \
+ --hash=sha256:8bdfe9ff3a4ea37d17f172ac0dff1e1c383aec17a636b9b35906babc9f0f5475 \
+ --hash=sha256:8e2c35a4c1f269704e90888e56f794e2d9c0262fb0c1b1c8c4ee44d9b9e77b5d \
+ --hash=sha256:92b8c845527eae547a2a6617d336adc56394050c3ed8a6918683646328fbb6da \
+ --hash=sha256:9365ed5cce5d0cf2c10afc6add145c5037d3148585b8ae0e77cc1efdd6aa2953 \
+ --hash=sha256:9a29311bd6429be317c1f3fe4bc06c4c5ee45e2fa61b2a19d4d1d6111cb94af2 \
+ --hash=sha256:9a2b5b52be0a8626fcbffd7e689781bf8c2ac01613e77feda93d96184949a98e \
+ --hash=sha256:a4bdeb0a52d1d04123b41d90a4390b096f3ef38eee35e11f0b22c2d031222c6c \
+ --hash=sha256:a9c8c4283e17690ff1a7427123ffb428ad6a52ed720d550e299e8291e33184dc \
+ --hash=sha256:b637c57fdb8be84e91fac60d9325a66a5981f8086c954ea2772efe28425eaf64 \
+ --hash=sha256:bf154ba7ee2fd613eb541c2bc03d3d9ac667080a737449d1a3fb342740eb1a74 \
+ --hash=sha256:c254b03032d5a06de049ce8bca8338a5185f07fb76600afff3c161e053d88617 \
+ --hash=sha256:c332d8f8d448ded473b97fefe4a0983265af21917d8b0cdcb8bb06b2afe632c3 \
+ --hash=sha256:c7912d1526299cb04c88288e148c6c87c0df600eca76efd99d84396cfe00ef1d \
+ --hash=sha256:cfd9386c1d6f13b37e05a91a8583e802f8059bebfccde61a418c5808dea6bbfa \
+ --hash=sha256:d5d2033d5db1d58ae2d62f095e1aefb6988af65b4b12cb8987af409587cc0739 \
+ --hash=sha256:dca38a21e4423f3edb821292e97cec7ad38086f84313462098568baedf4331f8 \
+ --hash=sha256:e2cad8093172b7d1595b4ad66f24270808658e11acf43a8f95b41276162eb5b8 \
+ --hash=sha256:e3db840a4dee542e37e09f30859f1612da90e1c5239a6a2498c473183a50e781 \
+ --hash=sha256:edcada2e24ed68f019175c2b2af2a8b481d3d084798b8c20d15d34f5c733fa58 \
+ --hash=sha256:f467bbb837691ab5a8ca359199d3429a11a01e6dfb3d9dcc676dc035ca93c0a9 \
+ --hash=sha256:f506af4f27def639ba45789fa6fde45f9a217da0be05f8910458e4557eed020c \
+ --hash=sha256:f614fc9956d76d8a88a88bb41ddc12709caa755666f580af3a688899721efecd \
+ --hash=sha256:f9afb5b746781fc2abce26193d1c817b7eb0e11459510fba65d2bd77fe161d9e \
+ --hash=sha256:fb8b8ee99b3fffe4fd86f4c81b35a6bf7e4462cba019997af2fe679365db0c49
+ # via pytest-cov
+css-html-js-minify==2.5.5 \
+ --hash=sha256:3da9d35ac0db8ca648c1b543e0e801d7ca0bab9e6bfd8418fee59d5ae001727a \
+ --hash=sha256:4a9f11f7e0496f5284d12111f3ba4ff5ff2023d12f15d195c9c48bd97013746c
+ # via sphinx-material
+docutils==0.17.1 \
+ --hash=sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125 \
+ --hash=sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61
+ # via
+ # flit
+ # sphinx
+flit==3.5.1 \
+ --hash=sha256:2e3b7377714483ecc54b236330d7bf3467b9f5b909b22333b50b6b4324162510 \
+ --hash=sha256:9b60008eb0df1c97057704a9f979d546d175c137b773e5c912e56035047fccee
+ # via nncli (pyproject.toml)
+flit-core==3.5.1 \
+ --hash=sha256:3083720351a6cb00e0634a1ec0e26eae7b273174c3c6c03d5b597a14203b282e \
+ --hash=sha256:42d144fa25df9493bfb655036279c4a4ed323e2e3db178b757e898af5aba0334
+ # via flit
+idna==3.3 \
+ --hash=sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff \
+ --hash=sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d
+ # via requests
+imagesize==1.3.0 \
+ --hash=sha256:1db2f82529e53c3e929e8926a1fa9235aa82d0bd0c580359c67ec31b2fddaa8c \
+ --hash=sha256:cd1750d452385ca327479d45b64d9c7729ecf0b3969a58148298c77092261f9d
+ # via sphinx
+iniconfig==1.1.1 \
+ --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \
+ --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32
+ # via pytest
+isort==5.10.1 \
+ --hash=sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7 \
+ --hash=sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951
+ # via pylint
+jinja2==3.0.3 \
+ --hash=sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8 \
+ --hash=sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7
+ # via sphinx
+lazy-object-proxy==1.6.0 \
+ --hash=sha256:17e0967ba374fc24141738c69736da90e94419338fd4c7c7bef01ee26b339653 \
+ --hash=sha256:1fee665d2638491f4d6e55bd483e15ef21f6c8c2095f235fef72601021e64f61 \
+ --hash=sha256:22ddd618cefe54305df49e4c069fa65715be4ad0e78e8d252a33debf00f6ede2 \
+ --hash=sha256:24a5045889cc2729033b3e604d496c2b6f588c754f7a62027ad4437a7ecc4837 \
+ --hash=sha256:410283732af311b51b837894fa2f24f2c0039aa7f220135192b38fcc42bd43d3 \
+ --hash=sha256:4732c765372bd78a2d6b2150a6e99d00a78ec963375f236979c0626b97ed8e43 \
+ --hash=sha256:489000d368377571c6f982fba6497f2aa13c6d1facc40660963da62f5c379726 \
+ --hash=sha256:4f60460e9f1eb632584c9685bccea152f4ac2130e299784dbaf9fae9f49891b3 \
+ --hash=sha256:5743a5ab42ae40caa8421b320ebf3a998f89c85cdc8376d6b2e00bd12bd1b587 \
+ --hash=sha256:85fb7608121fd5621cc4377a8961d0b32ccf84a7285b4f1d21988b2eae2868e8 \
+ --hash=sha256:9698110e36e2df951c7c36b6729e96429c9c32b3331989ef19976592c5f3c77a \
+ --hash=sha256:9d397bf41caad3f489e10774667310d73cb9c4258e9aed94b9ec734b34b495fd \
+ --hash=sha256:b579f8acbf2bdd9ea200b1d5dea36abd93cabf56cf626ab9c744a432e15c815f \
+ --hash=sha256:b865b01a2e7f96db0c5d12cfea590f98d8c5ba64ad222300d93ce6ff9138bcad \
+ --hash=sha256:bf34e368e8dd976423396555078def5cfc3039ebc6fc06d1ae2c5a65eebbcde4 \
+ --hash=sha256:c6938967f8528b3668622a9ed3b31d145fab161a32f5891ea7b84f6b790be05b \
+ --hash=sha256:d1c2676e3d840852a2de7c7d5d76407c772927addff8d742b9808fe0afccebdf \
+ --hash=sha256:d7124f52f3bd259f510651450e18e0fd081ed82f3c08541dffc7b94b883aa981 \
+ --hash=sha256:d900d949b707778696fdf01036f58c9876a0d8bfe116e8d220cfd4b15f14e741 \
+ --hash=sha256:ebfd274dcd5133e0afae738e6d9da4323c3eb021b3e13052d8cbd0e457b1256e \
+ --hash=sha256:ed361bb83436f117f9917d282a456f9e5009ea12fd6de8742d1a4752c3017e93 \
+ --hash=sha256:f5144c75445ae3ca2057faac03fda5a902eff196702b0a24daf1d6ce0650514b
+ # via astroid
+lxml==4.9.2 \
+ --hash=sha256:01d36c05f4afb8f7c20fd9ed5badca32a2029b93b1750f571ccc0b142531caf7 \
+ --hash=sha256:04876580c050a8c5341d706dd464ff04fd597095cc8c023252566a8826505726 \
+ --hash=sha256:05ca3f6abf5cf78fe053da9b1166e062ade3fa5d4f92b4ed688127ea7d7b1d03 \
+ --hash=sha256:090c6543d3696cbe15b4ac6e175e576bcc3f1ccfbba970061b7300b0c15a2140 \
+ --hash=sha256:0dc313ef231edf866912e9d8f5a042ddab56c752619e92dfd3a2c277e6a7299a \
+ --hash=sha256:0f2b1e0d79180f344ff9f321327b005ca043a50ece8713de61d1cb383fb8ac05 \
+ --hash=sha256:13598ecfbd2e86ea7ae45ec28a2a54fb87ee9b9fdb0f6d343297d8e548392c03 \
+ --hash=sha256:16efd54337136e8cd72fb9485c368d91d77a47ee2d42b057564aae201257d419 \
+ --hash=sha256:1ab8f1f932e8f82355e75dda5413a57612c6ea448069d4fb2e217e9a4bed13d4 \
+ --hash=sha256:223f4232855ade399bd409331e6ca70fb5578efef22cf4069a6090acc0f53c0e \
+ --hash=sha256:2455cfaeb7ac70338b3257f41e21f0724f4b5b0c0e7702da67ee6c3640835b67 \
+ --hash=sha256:2899456259589aa38bfb018c364d6ae7b53c5c22d8e27d0ec7609c2a1ff78b50 \
+ --hash=sha256:2a29ba94d065945944016b6b74e538bdb1751a1db6ffb80c9d3c2e40d6fa9894 \
+ --hash=sha256:2a87fa548561d2f4643c99cd13131acb607ddabb70682dcf1dff5f71f781a4bf \
+ --hash=sha256:2e430cd2824f05f2d4f687701144556646bae8f249fd60aa1e4c768ba7018947 \
+ --hash=sha256:36c3c175d34652a35475a73762b545f4527aec044910a651d2bf50de9c3352b1 \
+ --hash=sha256:3818b8e2c4b5148567e1b09ce739006acfaa44ce3156f8cbbc11062994b8e8dd \
+ --hash=sha256:3ab9fa9d6dc2a7f29d7affdf3edebf6ece6fb28a6d80b14c3b2fb9d39b9322c3 \
+ --hash=sha256:3efea981d956a6f7173b4659849f55081867cf897e719f57383698af6f618a92 \
+ --hash=sha256:4c8f293f14abc8fd3e8e01c5bd86e6ed0b6ef71936ded5bf10fe7a5efefbaca3 \
+ --hash=sha256:5344a43228767f53a9df6e5b253f8cdca7dfc7b7aeae52551958192f56d98457 \
+ --hash=sha256:58bfa3aa19ca4c0f28c5dde0ff56c520fbac6f0daf4fac66ed4c8d2fb7f22e74 \
+ --hash=sha256:5b4545b8a40478183ac06c073e81a5ce4cf01bf1734962577cf2bb569a5b3bbf \
+ --hash=sha256:5f50a1c177e2fa3ee0667a5ab79fdc6b23086bc8b589d90b93b4bd17eb0e64d1 \
+ --hash=sha256:63da2ccc0857c311d764e7d3d90f429c252e83b52d1f8f1d1fe55be26827d1f4 \
+ --hash=sha256:6749649eecd6a9871cae297bffa4ee76f90b4504a2a2ab528d9ebe912b101975 \
+ --hash=sha256:6804daeb7ef69e7b36f76caddb85cccd63d0c56dedb47555d2fc969e2af6a1a5 \
+ --hash=sha256:689bb688a1db722485e4610a503e3e9210dcc20c520b45ac8f7533c837be76fe \
+ --hash=sha256:699a9af7dffaf67deeae27b2112aa06b41c370d5e7633e0ee0aea2e0b6c211f7 \
+ --hash=sha256:6b418afe5df18233fc6b6093deb82a32895b6bb0b1155c2cdb05203f583053f1 \
+ --hash=sha256:76cf573e5a365e790396a5cc2b909812633409306c6531a6877c59061e42c4f2 \
+ --hash=sha256:7b515674acfdcadb0eb5d00d8a709868173acece5cb0be3dd165950cbfdf5409 \
+ --hash=sha256:7b770ed79542ed52c519119473898198761d78beb24b107acf3ad65deae61f1f \
+ --hash=sha256:7d2278d59425777cfcb19735018d897ca8303abe67cc735f9f97177ceff8027f \
+ --hash=sha256:7e91ee82f4199af8c43d8158024cbdff3d931df350252288f0d4ce656df7f3b5 \
+ --hash=sha256:821b7f59b99551c69c85a6039c65b75f5683bdc63270fec660f75da67469ca24 \
+ --hash=sha256:822068f85e12a6e292803e112ab876bc03ed1f03dddb80154c395f891ca6b31e \
+ --hash=sha256:8340225bd5e7a701c0fa98284c849c9b9fc9238abf53a0ebd90900f25d39a4e4 \
+ --hash=sha256:85cabf64adec449132e55616e7ca3e1000ab449d1d0f9d7f83146ed5bdcb6d8a \
+ --hash=sha256:880bbbcbe2fca64e2f4d8e04db47bcdf504936fa2b33933efd945e1b429bea8c \
+ --hash=sha256:8d0b4612b66ff5d62d03bcaa043bb018f74dfea51184e53f067e6fdcba4bd8de \
+ --hash=sha256:8e20cb5a47247e383cf4ff523205060991021233ebd6f924bca927fcf25cf86f \
+ --hash=sha256:925073b2fe14ab9b87e73f9a5fde6ce6392da430f3004d8b72cc86f746f5163b \
+ --hash=sha256:998c7c41910666d2976928c38ea96a70d1aa43be6fe502f21a651e17483a43c5 \
+ --hash=sha256:9b22c5c66f67ae00c0199f6055705bc3eb3fcb08d03d2ec4059a2b1b25ed48d7 \
+ --hash=sha256:9f102706d0ca011de571de32c3247c6476b55bb6bc65a20f682f000b07a4852a \
+ --hash=sha256:a08cff61517ee26cb56f1e949cca38caabe9ea9fbb4b1e10a805dc39844b7d5c \
+ --hash=sha256:a0a336d6d3e8b234a3aae3c674873d8f0e720b76bc1d9416866c41cd9500ffb9 \
+ --hash=sha256:a35f8b7fa99f90dd2f5dc5a9fa12332642f087a7641289ca6c40d6e1a2637d8e \
+ --hash=sha256:a38486985ca49cfa574a507e7a2215c0c780fd1778bb6290c21193b7211702ab \
+ --hash=sha256:a5da296eb617d18e497bcf0a5c528f5d3b18dadb3619fbdadf4ed2356ef8d941 \
+ --hash=sha256:a6e441a86553c310258aca15d1c05903aaf4965b23f3bc2d55f200804e005ee5 \
+ --hash=sha256:a82d05da00a58b8e4c0008edbc8a4b6ec5a4bc1e2ee0fb6ed157cf634ed7fa45 \
+ --hash=sha256:ab323679b8b3030000f2be63e22cdeea5b47ee0abd2d6a1dc0c8103ddaa56cd7 \
+ --hash=sha256:b1f42b6921d0e81b1bcb5e395bc091a70f41c4d4e55ba99c6da2b31626c44892 \
+ --hash=sha256:b23e19989c355ca854276178a0463951a653309fb8e57ce674497f2d9f208746 \
+ --hash=sha256:b264171e3143d842ded311b7dccd46ff9ef34247129ff5bf5066123c55c2431c \
+ --hash=sha256:b26a29f0b7fc6f0897f043ca366142d2b609dc60756ee6e4e90b5f762c6adc53 \
+ --hash=sha256:b64d891da92e232c36976c80ed7ebb383e3f148489796d8d31a5b6a677825efe \
+ --hash=sha256:b9cc34af337a97d470040f99ba4282f6e6bac88407d021688a5d585e44a23184 \
+ --hash=sha256:bc718cd47b765e790eecb74d044cc8d37d58562f6c314ee9484df26276d36a38 \
+ --hash=sha256:be7292c55101e22f2a3d4d8913944cbea71eea90792bf914add27454a13905df \
+ --hash=sha256:c83203addf554215463b59f6399835201999b5e48019dc17f182ed5ad87205c9 \
+ --hash=sha256:c9ec3eaf616d67db0764b3bb983962b4f385a1f08304fd30c7283954e6a7869b \
+ --hash=sha256:ca34efc80a29351897e18888c71c6aca4a359247c87e0b1c7ada14f0ab0c0fb2 \
+ --hash=sha256:ca989b91cf3a3ba28930a9fc1e9aeafc2a395448641df1f387a2d394638943b0 \
+ --hash=sha256:d02a5399126a53492415d4906ab0ad0375a5456cc05c3fc0fc4ca11771745cda \
+ --hash=sha256:d17bc7c2ccf49c478c5bdd447594e82692c74222698cfc9b5daae7ae7e90743b \
+ --hash=sha256:d5bf6545cd27aaa8a13033ce56354ed9e25ab0e4ac3b5392b763d8d04b08e0c5 \
+ --hash=sha256:d6b430a9938a5a5d85fc107d852262ddcd48602c120e3dbb02137c83d212b380 \
+ --hash=sha256:da248f93f0418a9e9d94b0080d7ebc407a9a5e6d0b57bb30db9b5cc28de1ad33 \
+ --hash=sha256:da4dd7c9c50c059aba52b3524f84d7de956f7fef88f0bafcf4ad7dde94a064e8 \
+ --hash=sha256:df0623dcf9668ad0445e0558a21211d4e9a149ea8f5666917c8eeec515f0a6d1 \
+ --hash=sha256:e5168986b90a8d1f2f9dc1b841467c74221bd752537b99761a93d2d981e04889 \
+ --hash=sha256:efa29c2fe6b4fdd32e8ef81c1528506895eca86e1d8c4657fda04c9b3786ddf9 \
+ --hash=sha256:f1496ea22ca2c830cbcbd473de8f114a320da308438ae65abad6bab7867fe38f \
+ --hash=sha256:f49e52d174375a7def9915c9f06ec4e569d235ad428f70751765f48d5926678c
+ # via sphinx-material
+markupsafe==2.0.1 \
+ --hash=sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298 \
+ --hash=sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64 \
+ --hash=sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b \
+ --hash=sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194 \
+ --hash=sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567 \
+ --hash=sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff \
+ --hash=sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724 \
+ --hash=sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74 \
+ --hash=sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646 \
+ --hash=sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35 \
+ --hash=sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6 \
+ --hash=sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a \
+ --hash=sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6 \
+ --hash=sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad \
+ --hash=sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26 \
+ --hash=sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38 \
+ --hash=sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac \
+ --hash=sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7 \
+ --hash=sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6 \
+ --hash=sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047 \
+ --hash=sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75 \
+ --hash=sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f \
+ --hash=sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b \
+ --hash=sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135 \
+ --hash=sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8 \
+ --hash=sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a \
+ --hash=sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a \
+ --hash=sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1 \
+ --hash=sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9 \
+ --hash=sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864 \
+ --hash=sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914 \
+ --hash=sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee \
+ --hash=sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f \
+ --hash=sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18 \
+ --hash=sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8 \
+ --hash=sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2 \
+ --hash=sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d \
+ --hash=sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b \
+ --hash=sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b \
+ --hash=sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86 \
+ --hash=sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6 \
+ --hash=sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f \
+ --hash=sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb \
+ --hash=sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833 \
+ --hash=sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28 \
+ --hash=sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e \
+ --hash=sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415 \
+ --hash=sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902 \
+ --hash=sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f \
+ --hash=sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d \
+ --hash=sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9 \
+ --hash=sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d \
+ --hash=sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145 \
+ --hash=sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066 \
+ --hash=sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c \
+ --hash=sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1 \
+ --hash=sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a \
+ --hash=sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207 \
+ --hash=sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f \
+ --hash=sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53 \
+ --hash=sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd \
+ --hash=sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134 \
+ --hash=sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85 \
+ --hash=sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9 \
+ --hash=sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5 \
+ --hash=sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94 \
+ --hash=sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509 \
+ --hash=sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51 \
+ --hash=sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872
+ # via jinja2
+mccabe==0.6.1 \
+ --hash=sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42 \
+ --hash=sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f
+ # via pylint
+mock==4.0.3 \
+ --hash=sha256:122fcb64ee37cfad5b3f48d7a7d51875d7031aaf3d8be7c42e2bee25044eee62 \
+ --hash=sha256:7d3fbbde18228f4ff2f1f119a45cdffa458b4c0dee32eb4d2bb2f82554bac7bc
+ # via nncli (pyproject.toml)
+packaging==21.3 \
+ --hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \
+ --hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522
+ # via
+ # pytest
+ # sphinx
+pep517==0.12.0 \
+ --hash=sha256:931378d93d11b298cf511dd634cf5ea4cb249a28ef84160b3247ee9afb4e8ab0 \
+ --hash=sha256:dd884c326898e2c6e11f9e0b64940606a93eb10ea022a2e067959f3a110cf161
+ # via pip-tools
+pip-tools==6.4.0 \
+ --hash=sha256:65553a15b1ba34be5e43889345062e38fb9b219ffa23b084ca0d4c4039b6f53b \
+ --hash=sha256:bb2c3272bc229b4a6d25230ebe255823aba1aa466a0d698c48ab7eb5ab7efdc9
+ # via nncli (pyproject.toml)
+platformdirs==2.4.0 \
+ --hash=sha256:367a5e80b3d04d2428ffa76d33f124cf11e8fff2acdaa9b43d545f5c7d661ef2 \
+ --hash=sha256:8868bbe3c3c80d42f20156f22e7131d2fb321f5bc86a2a345375c6481a67021d
+ # via pylint
+pluggy==0.13.1 \
+ --hash=sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0 \
+ --hash=sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d
+ # via pytest
+py==1.11.0 \
+ --hash=sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719 \
+ --hash=sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378
+ # via pytest
+pygments==2.10.0 \
+ --hash=sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380 \
+ --hash=sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6
+ # via sphinx
+pylint==2.12.2 \
+ --hash=sha256:9d945a73640e1fec07ee34b42f5669b770c759acd536ec7b16d7e4b87a9c9ff9 \
+ --hash=sha256:daabda3f7ed9d1c60f52d563b1b854632fd90035bcf01443e234d3dc794e3b74
+ # via nncli (pyproject.toml)
+pyparsing==3.0.6 \
+ --hash=sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4 \
+ --hash=sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81
+ # via packaging
+pytest==6.2.5 \
+ --hash=sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89 \
+ --hash=sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134
+ # via
+ # nncli (pyproject.toml)
+ # pytest-cov
+ # pytest-mock
+pytest-cov==3.0.0 \
+ --hash=sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6 \
+ --hash=sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470
+ # via nncli (pyproject.toml)
+pytest-mock==3.6.1 \
+ --hash=sha256:30c2f2cc9759e76eee674b81ea28c9f0b94f8f0445a1b87762cadf774f0df7e3 \
+ --hash=sha256:40217a058c52a63f1042f0784f62009e976ba824c418cced42e88d5f40ab0e62
+ # via nncli (pyproject.toml)
+python-slugify[unidecode]==7.0.0 \
+ --hash=sha256:003aee64f9fd955d111549f96c4b58a3f40b9319383c70fad6277a4974bbf570 \
+ --hash=sha256:7a0f21a39fa6c1c4bf2e5984c9b9ae944483fd10b54804cb0e23a3ccd4954f0b
+ # via sphinx-material
+pytz==2021.3 \
+ --hash=sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c \
+ --hash=sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326
+ # via babel
+requests==2.26.0 \
+ --hash=sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24 \
+ --hash=sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7
+ # via
+ # flit
+ # nncli (pyproject.toml)
+ # sphinx
+six==1.16.0 \
+ --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
+ --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
+ # via sphinx-sitemap
+snowballstemmer==2.2.0 \
+ --hash=sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1 \
+ --hash=sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a
+ # via sphinx
+soupsieve==2.3.2.post1 \
+ --hash=sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759 \
+ --hash=sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d
+ # via beautifulsoup4
+sphinx==4.3.1 \
+ --hash=sha256:048dac56039a5713f47a554589dc98a442b39226a2b9ed7f82797fcb2fe9253f \
+ --hash=sha256:32a5b3e9a1b176cc25ed048557d4d3d01af635e6b76c5bc7a43b0a34447fbd45
+ # via
+ # nncli (pyproject.toml)
+ # sphinx-material
+ # sphinx-sitemap
+sphinx-material==0.0.35 \
+ --hash=sha256:27f0f1084aa0201b43879aef24a0521b78dc8df4942b003a4e7d79ab11515852 \
+ --hash=sha256:a62a0a48d4c32edc260f9bdbca658e7d149beb10e1d338848b0076bb13be0775
+ # via nncli (pyproject.toml)
+sphinx-sitemap==2.2.0 \
+ --hash=sha256:65adda39233cb17c0da10ba1cebaa2df73e271cdb6f8efd5cec8eef3b3cf7737
+ # via nncli (pyproject.toml)
+sphinxcontrib-applehelp==1.0.2 \
+ --hash=sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a \
+ --hash=sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58
+ # via sphinx
+sphinxcontrib-devhelp==1.0.2 \
+ --hash=sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e \
+ --hash=sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4
+ # via sphinx
+sphinxcontrib-htmlhelp==2.0.0 \
+ --hash=sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07 \
+ --hash=sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2
+ # via sphinx
+sphinxcontrib-jsmath==1.0.1 \
+ --hash=sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 \
+ --hash=sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8
+ # via sphinx
+sphinxcontrib-qthelp==1.0.3 \
+ --hash=sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72 \
+ --hash=sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6
+ # via sphinx
+sphinxcontrib-serializinghtml==1.1.5 \
+ --hash=sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd \
+ --hash=sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952
+ # via sphinx
+text-unidecode==1.3 \
+ --hash=sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8 \
+ --hash=sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93
+ # via python-slugify
+toml==0.10.2 \
+ --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \
+ --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f
+ # via
+ # pylint
+ # pytest
+ # vulture
+tomli==1.2.2 \
+ --hash=sha256:c6ce0015eb38820eaf32b5db832dbc26deb3dd427bd5f6556cf0acac2c214fee \
+ --hash=sha256:f04066f68f5554911363063a30b108d2b5a5b1a010aa8b6132af78489fe3aade
+ # via
+ # coverage
+ # flit
+ # flit-core
+ # pep517
+tomli-w==1.0.0 \
+ --hash=sha256:9f2a07e8be30a0729e533ec968016807069991ae2fd921a78d42f429ae5f4463 \
+ --hash=sha256:f463434305e0336248cac9c2dc8076b707d8a12d019dd349f5c1e382dd1ae1b9
+ # via flit
+unidecode==1.3.6 \
+ --hash=sha256:547d7c479e4f377b430dd91ac1275d593308dce0fc464fb2ab7d41f82ec653be \
+ --hash=sha256:fed09cf0be8cf415b391642c2a5addfc72194407caee4f98719e40ec2a72b830
+ # via python-slugify
+urllib3==1.26.7 \
+ --hash=sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece \
+ --hash=sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844
+ # via requests
+urwid==2.1.2 \
+ --hash=sha256:588bee9c1cb208d0906a9f73c613d2bd32c3ed3702012f51efe318a3f2127eae
+ # via nncli (pyproject.toml)
+vulture==2.3 \
+ --hash=sha256:03d5a62bcbe9ceb9a9b0575f42d71a2d414070229f2e6f95fa6e7c71aaaed967 \
+ --hash=sha256:f39de5e6f1df1f70c3b50da54f1c8d494159e9ca3d01a9b89eac929600591703
+ # via nncli (pyproject.toml)
+wheel==0.37.0 \
+ --hash=sha256:21014b2bd93c6d0034b6ba5d35e4eb284340e09d63c59aef6fc14b0f346146fd \
+ --hash=sha256:e2ef7239991699e3355d54f8e968a21bb940a1dbf34a4d226741e64462516fad
+ # via pip-tools
+wrapt==1.13.3 \
+ --hash=sha256:086218a72ec7d986a3eddb7707c8c4526d677c7b35e355875a0fe2918b059179 \
+ --hash=sha256:0877fe981fd76b183711d767500e6b3111378ed2043c145e21816ee589d91096 \
+ --hash=sha256:0a017a667d1f7411816e4bf214646d0ad5b1da2c1ea13dec6c162736ff25a374 \
+ --hash=sha256:0cb23d36ed03bf46b894cfec777eec754146d68429c30431c99ef28482b5c1df \
+ --hash=sha256:1fea9cd438686e6682271d36f3481a9f3636195578bab9ca3382e2f5f01fc185 \
+ --hash=sha256:220a869982ea9023e163ba915077816ca439489de6d2c09089b219f4e11b6785 \
+ --hash=sha256:25b1b1d5df495d82be1c9d2fad408f7ce5ca8a38085e2da41bb63c914baadff7 \
+ --hash=sha256:2dded5496e8f1592ec27079b28b6ad2a1ef0b9296d270f77b8e4a3a796cf6909 \
+ --hash=sha256:2ebdde19cd3c8cdf8df3fc165bc7827334bc4e353465048b36f7deeae8ee0918 \
+ --hash=sha256:43e69ffe47e3609a6aec0fe723001c60c65305784d964f5007d5b4fb1bc6bf33 \
+ --hash=sha256:46f7f3af321a573fc0c3586612db4decb7eb37172af1bc6173d81f5b66c2e068 \
+ --hash=sha256:47f0a183743e7f71f29e4e21574ad3fa95676136f45b91afcf83f6a050914829 \
+ --hash=sha256:498e6217523111d07cd67e87a791f5e9ee769f9241fcf8a379696e25806965af \
+ --hash=sha256:4b9c458732450ec42578b5642ac53e312092acf8c0bfce140ada5ca1ac556f79 \
+ --hash=sha256:51799ca950cfee9396a87f4a1240622ac38973b6df5ef7a41e7f0b98797099ce \
+ --hash=sha256:5601f44a0f38fed36cc07db004f0eedeaadbdcec90e4e90509480e7e6060a5bc \
+ --hash=sha256:5f223101f21cfd41deec8ce3889dc59f88a59b409db028c469c9b20cfeefbe36 \
+ --hash=sha256:610f5f83dd1e0ad40254c306f4764fcdc846641f120c3cf424ff57a19d5f7ade \
+ --hash=sha256:6a03d9917aee887690aa3f1747ce634e610f6db6f6b332b35c2dd89412912bca \
+ --hash=sha256:705e2af1f7be4707e49ced9153f8d72131090e52be9278b5dbb1498c749a1e32 \
+ --hash=sha256:766b32c762e07e26f50d8a3468e3b4228b3736c805018e4b0ec8cc01ecd88125 \
+ --hash=sha256:77416e6b17926d953b5c666a3cb718d5945df63ecf922af0ee576206d7033b5e \
+ --hash=sha256:778fd096ee96890c10ce96187c76b3e99b2da44e08c9e24d5652f356873f6709 \
+ --hash=sha256:78dea98c81915bbf510eb6a3c9c24915e4660302937b9ae05a0947164248020f \
+ --hash=sha256:7dd215e4e8514004c8d810a73e342c536547038fb130205ec4bba9f5de35d45b \
+ --hash=sha256:7dde79d007cd6dfa65afe404766057c2409316135cb892be4b1c768e3f3a11cb \
+ --hash=sha256:81bd7c90d28a4b2e1df135bfbd7c23aee3050078ca6441bead44c42483f9ebfb \
+ --hash=sha256:85148f4225287b6a0665eef08a178c15097366d46b210574a658c1ff5b377489 \
+ --hash=sha256:865c0b50003616f05858b22174c40ffc27a38e67359fa1495605f96125f76640 \
+ --hash=sha256:87883690cae293541e08ba2da22cacaae0a092e0ed56bbba8d018cc486fbafbb \
+ --hash=sha256:8aab36778fa9bba1a8f06a4919556f9f8c7b33102bd71b3ab307bb3fecb21851 \
+ --hash=sha256:8c73c1a2ec7c98d7eaded149f6d225a692caa1bd7b2401a14125446e9e90410d \
+ --hash=sha256:936503cb0a6ed28dbfa87e8fcd0a56458822144e9d11a49ccee6d9a8adb2ac44 \
+ --hash=sha256:944b180f61f5e36c0634d3202ba8509b986b5fbaf57db3e94df11abee244ba13 \
+ --hash=sha256:96b81ae75591a795d8c90edc0bfaab44d3d41ffc1aae4d994c5aa21d9b8e19a2 \
+ --hash=sha256:981da26722bebb9247a0601e2922cedf8bb7a600e89c852d063313102de6f2cb \
+ --hash=sha256:ae9de71eb60940e58207f8e71fe113c639da42adb02fb2bcbcaccc1ccecd092b \
+ --hash=sha256:b73d4b78807bd299b38e4598b8e7bd34ed55d480160d2e7fdaabd9931afa65f9 \
+ --hash=sha256:d4a5f6146cfa5c7ba0134249665acd322a70d1ea61732723c7d3e8cc0fa80755 \
+ --hash=sha256:dd91006848eb55af2159375134d724032a2d1d13bcc6f81cd8d3ed9f2b8e846c \
+ --hash=sha256:e05e60ff3b2b0342153be4d1b597bbcfd8330890056b9619f4ad6b8d5c96a81a \
+ --hash=sha256:e6906d6f48437dfd80464f7d7af1740eadc572b9f7a4301e7dd3d65db285cacf \
+ --hash=sha256:e92d0d4fa68ea0c02d39f1e2f9cb5bc4b4a71e8c442207433d8db47ee79d7aa3 \
+ --hash=sha256:e94b7d9deaa4cc7bac9198a58a7240aaf87fe56c6277ee25fa5b3aa1edebd229 \
+ --hash=sha256:ea3e746e29d4000cd98d572f3ee2a6050a4f784bb536f4ac1f035987fc1ed83e \
+ --hash=sha256:ec7e20258ecc5174029a0f391e1b948bf2906cd64c198a9b8b281b811cbc04de \
+ --hash=sha256:ec9465dd69d5657b5d2fa6133b3e1e989ae27d29471a672416fd729b429eb554 \
+ --hash=sha256:f122ccd12fdc69628786d0c947bdd9cb2733be8f800d88b5a37c57f1f1d73c10 \
+ --hash=sha256:f99c0489258086308aad4ae57da9e8ecf9e1f3f30fa35d5e170b4d4896554d80 \
+ --hash=sha256:f9c51d9af9abb899bd34ace878fbec8bf357b3194a10c4e8e0a25512826ef056 \
+ --hash=sha256:fd76c47f20984b43d93de9a82011bb6e5f8325df6c9ed4d8310029a55fa361ea
+ # via astroid
+
+# WARNING: The following packages were not pinned, but pip requires them to be
+# pinned when the requirements file includes hashes. Consider using the --allow-unsafe flag.
+# pip
+# setuptools
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..9b0ce95
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,37 @@
+#
+# This file is autogenerated by pip-compile with python 3.9
+# To update, run:
+#
+# pip-compile --generate-hashes pyproject.toml
+#
+appdirs==1.4.4 \
+ --hash=sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41 \
+ --hash=sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128
+ # via nncli (pyproject.toml)
+certifi==2021.10.8 \
+ --hash=sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872 \
+ --hash=sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569
+ # via requests
+charset-normalizer==2.0.9 \
+ --hash=sha256:1eecaa09422db5be9e29d7fc65664e6c33bd06f9ced7838578ba40d58bdf3721 \
+ --hash=sha256:b0b883e8e874edfdece9c28f314e3dd5badf067342e42fb162203335ae61aa2c
+ # via requests
+click==8.0.3 \
+ --hash=sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3 \
+ --hash=sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b
+ # via nncli (pyproject.toml)
+idna==3.3 \
+ --hash=sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff \
+ --hash=sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d
+ # via requests
+requests==2.26.0 \
+ --hash=sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24 \
+ --hash=sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7
+ # via nncli (pyproject.toml)
+urllib3==1.26.7 \
+ --hash=sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece \
+ --hash=sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844
+ # via requests
+urwid==2.1.2 \
+ --hash=sha256:588bee9c1cb208d0906a9f73c613d2bd32c3ed3702012f51efe318a3f2127eae
+ # via nncli (pyproject.toml)
diff --git a/nncli/__init__.py b/src/nncli/__init__.py
index 80704cf..0787000 100644
--- a/nncli/__init__.py
+++ b/src/nncli/__init__.py
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
"""NextCloud Notes Command Line Interface"""
-__version__ = '0.3.5'
+__version__ = '0.3.6'
diff --git a/nncli/__main__.py b/src/nncli/__main__.py
index bd96fc2..bd96fc2 100644
--- a/nncli/__main__.py
+++ b/src/nncli/__main__.py
diff --git a/nncli/cli.py b/src/nncli/cli.py
index 91d0eb8..a5af603 100644
--- a/nncli/cli.py
+++ b/src/nncli/cli.py
@@ -75,7 +75,7 @@ cat.add_command(rm_category, 'rm')
@click.pass_obj
def favorite(nncli, key):
"""Mark as note as a favorite."""
- nncli.cli_note_favorite(key, 1)
+ nncli.cli_note_favorite(key, True)
@click.command()
@click.option(
@@ -88,7 +88,7 @@ def favorite(nncli, key):
@click.pass_obj
def unfavorite(nncli, key):
"""Remove favorite flag from a note."""
- nncli.cli_note_favorite(key, 0)
+ nncli.cli_note_favorite(key, False)
@click.command(short_help="Print JSON-formatted note to stdout.")
@click.option('-k', '--key', type=click.INT, help="Specify the note key.")
@@ -167,7 +167,7 @@ def delete(nncli, key):
"""Delete an existing note."""
nncli.cli_note_delete(key, True)
-@click.command()
+@click.command(short_help="Edit an existing note.")
@click.option(
'-k',
'--key',
@@ -175,10 +175,14 @@ def delete(nncli, key):
type=click.INT,
help="Specify the note key."
)
+@click.argument('from_stdin', metavar='[-]', type=STDIN_FLAG)
@click.pass_obj
-def edit(nncli, key):
- """Edit an existing note."""
- nncli.cli_note_edit(key)
+def edit(nncli, key, from_stdin):
+ """
+ Edit an existing note. If - is specified, the note contents are
+ read from stdin, otherwise the editor will open.
+ """
+ nncli.cli_note_edit(from_stdin, key)
@click.command(short_help="Import a JSON note.")
@click.argument('from_stdin', metavar='[-]', type=STDIN_FLAG)
diff --git a/nncli/clipboard.py b/src/nncli/clipboard.py
index 14dbcdb..14dbcdb 100644
--- a/nncli/clipboard.py
+++ b/src/nncli/clipboard.py
diff --git a/nncli/config.py b/src/nncli/config.py
index 62b84a2..62b84a2 100644
--- a/nncli/config.py
+++ b/src/nncli/config.py
diff --git a/nncli/gui.py b/src/nncli/gui.py
index 875af2b..875af2b 100644
--- a/nncli/gui.py
+++ b/src/nncli/gui.py
diff --git a/nncli/log.py b/src/nncli/log.py
index b0d9a68..b0d9a68 100644
--- a/nncli/log.py
+++ b/src/nncli/log.py
diff --git a/nncli/nextcloud_note.py b/src/nncli/nextcloud_note.py
index d4c5b6c..d4c5b6c 100644
--- a/nncli/nextcloud_note.py
+++ b/src/nncli/nextcloud_note.py
diff --git a/nncli/nncli.py b/src/nncli/nncli.py
index 03c5cfd..ffb9d2f 100644
--- a/nncli/nncli.py
+++ b/src/nncli/nncli.py
@@ -130,7 +130,10 @@ class Nncli:
if content:
self.logger.log('New note created')
self.ndb.create_note(content)
- self.ndb.sync_now()
+ if self.config.state.do_server_sync:
+ self.ndb.sync_now()
+ else:
+ self.ndb.save_note(note['localkey'], note)
def cli_note_import(self, from_stdin):
"""Import a note from the command line"""
@@ -145,7 +148,10 @@ class Nncli:
note = json.loads(raw)
self.logger.log('New note created')
self.ndb.import_note(note)
- self.ndb.sync_now()
+ if self.config.state.do_server_sync:
+ self.ndb.sync_now()
+ else:
+ self.ndb.save_note(note['localkey'], note)
except ValueError as ex:
self.logger.log('(IMPORT) ValueError: {}'.format(ex))
sys.exit(1)
@@ -170,14 +176,17 @@ class Nncli:
notes_data = [n.note for n in note_list]
print(json.dumps(notes_data, indent=2))
- def cli_note_edit(self, key):
+ def cli_note_edit(self, from_stdin, key):
"""Edit a note from the command line"""
note = self.ndb.get_note(key)
if not note:
self.logger.log('ERROR: Key does not exist')
return
- content = exec_cmd_on_note(note, self.config, self.nncli_gui,
+ if from_stdin:
+ content = ''.join(sys.stdin)
+ else:
+ content = exec_cmd_on_note(note, self.config, self.nncli_gui,
self.logger)
if not content:
return
@@ -188,7 +197,10 @@ class Nncli:
if md5_old != md5_new:
self.logger.log('Note updated')
self.ndb.set_note_content(note['localkey'], content)
- self.ndb.sync_now()
+ if self.config.state.do_server_sync:
+ self.ndb.sync_now()
+ else:
+ self.ndb.save_note(note['localkey'], note)
else:
self.logger.log('Note unchanged')
@@ -200,7 +212,10 @@ class Nncli:
return
self.ndb.set_note_deleted(key, delete)
- self.ndb.sync_now()
+ if self.config.state.do_server_sync:
+ self.ndb.sync_now()
+ else:
+ self.ndb.save_note(note['localkey'], note)
def cli_note_favorite(self, key, favorite):
"""Favorite a note from the command line"""
@@ -210,7 +225,10 @@ class Nncli:
return
self.ndb.set_note_favorite(key, favorite)
- self.ndb.sync_now()
+ if self.config.state.do_server_sync:
+ self.ndb.sync_now()
+ else:
+ self.ndb.save_note(note['localkey'], note)
def cli_note_category_get(self, key):
"""Get a note category from the command line"""
@@ -230,7 +248,10 @@ class Nncli:
return
self.ndb.set_note_category(key, category.lower())
- self.ndb.sync_now()
+ if self.config.state.do_server_sync:
+ self.ndb.sync_now()
+ else:
+ self.ndb.save_note(note['localkey'], note)
def cli_note_category_rm(self, key):
"""Remove a note category from the command line"""
diff --git a/nncli/notes_db.py b/src/nncli/notes_db.py
index c995a16..70774af 100644
--- a/nncli/notes_db.py
+++ b/src/nncli/notes_db.py
@@ -422,7 +422,7 @@ class NotesDB():
"""Convert a note key into a file name"""
return os.path.join(self.config.get_config('db_path'), str(k)) + '.json'
- def _helper_save_note(self, k, note):
+ def save_note(self, k, note):
"""Save a note to the file system"""
# Save a single note to disc.
func = self._helper_key_to_fname(k)
@@ -634,7 +634,7 @@ class NotesDB():
for key in list(local_updates.keys()):
try:
- self._helper_save_note(key, self.notes[key])
+ self.save_note(key, self.notes[key])
except WriteError as ex:
raise WriteError(str(ex))
self.log("Saved note to disk (key={0})".format(key))
diff --git a/nncli/temp.py b/src/nncli/temp.py
index a6f53bc..a6f53bc 100644
--- a/nncli/temp.py
+++ b/src/nncli/temp.py
diff --git a/nncli/user_input.py b/src/nncli/user_input.py
index 0e83ad9..0e83ad9 100644
--- a/nncli/user_input.py
+++ b/src/nncli/user_input.py
diff --git a/nncli/utils.py b/src/nncli/utils.py
index 50399ed..50399ed 100644
--- a/nncli/utils.py
+++ b/src/nncli/utils.py
diff --git a/nncli/view_help.py b/src/nncli/view_help.py
index dbe3a18..dbe3a18 100644
--- a/nncli/view_help.py
+++ b/src/nncli/view_help.py
diff --git a/nncli/view_log.py b/src/nncli/view_log.py
index 503ea73..503ea73 100644
--- a/nncli/view_log.py
+++ b/src/nncli/view_log.py
diff --git a/nncli/view_note.py b/src/nncli/view_note.py
index 48aa543..48aa543 100644
--- a/nncli/view_note.py
+++ b/src/nncli/view_note.py
diff --git a/nncli/view_titles.py b/src/nncli/view_titles.py
index edcf9fe..edcf9fe 100644
--- a/nncli/view_titles.py
+++ b/src/nncli/view_titles.py
diff --git a/tox.ini b/tox.ini
deleted file mode 100644
index d4f3873..0000000
--- a/tox.ini
+++ /dev/null
@@ -1,34 +0,0 @@
-[tox]
-envlist = py34, py35, py36, py37, py38, pylint, coverage
-skipsdist = True
-
-[testenv:pylint]
-deps = pylint
-setenv =
- PIPENV_NO_INHERIT = 1
- PIPENV_HIDE_EMOJIS = 1
-whitelist_externals = make
-commands =
- make test-install
- make lint
-
-[testenv:coverage]
-deps = pipenv
-setenv =
- PIPENV_NO_INHERIT = 1
- PIPENV_HIDE_EMOJIS = 1
-whitelist_externals = make
-commands =
- make test-install
- make coverage
-
-[testenv]
-deps = pipenv
-setenv =
- PIPENV_NO_INHERIT = 1
- PIPENV_HIDE_EMOJIS = 1
-whitelist_externals = make
-commands =
- make test-install
- make install
- python -m pytest