{"id":13707120,"url":"https://github.com/dkaslovsky/textnote","last_synced_at":"2025-12-24T12:09:35.169Z","repository":{"id":52527777,"uuid":"319649088","full_name":"dkaslovsky/textnote","owner":"dkaslovsky","description":"Simple tool for creating and organizing daily notes on the command line","archived":false,"fork":false,"pushed_at":"2023-11-28T00:32:14.000Z","size":257,"stargazers_count":179,"open_issues_count":2,"forks_count":6,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-02-15T14:47:33.430Z","etag":null,"topics":["cli","command-line","consolidating-notes","daily-notes","plaintext","productivity","vim"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dkaslovsky.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-12-08T13:36:35.000Z","updated_at":"2024-07-15T13:14:34.000Z","dependencies_parsed_at":"2024-01-14T20:34:20.289Z","dependency_job_id":null,"html_url":"https://github.com/dkaslovsky/textnote","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkaslovsky%2Ftextnote","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkaslovsky%2Ftextnote/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkaslovsky%2Ftextnote/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkaslovsky%2Ftextnote/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dkaslovsky","download_url":"https://codeload.github.com/dkaslovsky/textnote/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252593337,"owners_count":21773444,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","command-line","consolidating-notes","daily-notes","plaintext","productivity","vim"],"created_at":"2024-08-02T22:01:20.287Z","updated_at":"2025-12-24T12:09:35.161Z","avatar_url":"https://github.com/dkaslovsky.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# textnote\nSimple tool for creating and organizing daily notes on the command line\n\n[![Build Status](https://travis-ci.com/dkaslovsky/textnote.svg?branch=main)](https://travis-ci.com/github/dkaslovsky/textnote)\n[![Coverage Status](https://coveralls.io/repos/github/dkaslovsky/textnote/badge.svg?branch=main)](https://coveralls.io/github/dkaslovsky/textnote?branch=main)\n[![Go Report Card](https://goreportcard.com/badge/github.com/dkaslovsky/textnote)](https://goreportcard.com/report/github.com/dkaslovsky/textnote)\n[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/dkaslovsky/textnote/blob/main/LICENSE)\n\n\u003cbr/\u003e\n\n## Overview\ntextnote is a command line tool for quickly creating and managing daily plain text notes.\nIt is designed for ease of use to encourage the practice of daily, organized note taking.\ntextnote intentionally facilitates only the management (creation, opening, organizing, and consolidated archiving) of notes, following the philosophy that notes are best written in a text editor and not via a CLI.\n\nKey features:\n- Configurable, sectioned note template\n- Easily bring content forward to the next day's note (for those to-dos that didn't quite get done today...)\n- Simple command to consolidate daily notes into monthly archive files\n- Create and open today's note with the default `textnote` command\n\nAll note files are stored locally on the file system in a single directory.\nNotes can easily be synced to a remote server or cloud service if so desired by ensuring the application directory is remotely synced.\n\ntextnote opens notes using the text editor specified by the environment variable `$EDITOR` and defaults to Vim if the environment variable is not set.\nSee the [Editor-Specific Configuration](#editor-specific-configuration) subsection for more details. \n\n\u003cbr/\u003e\n\n## Table of Contents\n- [Overview](#overview)\n- [Quick Start](#quick-start)\n- [Installation](#installation)\n  - [Releases](#releases)\n  - [Installing from source](#installing-from-source)\n- [Usage](#usage)\n  - [`open`](#open)\n  - [`archive`](#archive)\n  - [Additional Functionality](#additional-functionality)\n- [Configuration](#configuration)\n  - [Defaults](#defaults)\n  - [Environment Variable Overrides](#environment-variable-overrides)\n  - [Editor-Specific Configuration](#editor-specific-configuration)\n- [License](#license)\n\n\u003cbr/\u003e\n\n## Quick Start\n1. Install textnote (see [Installation](#installation))\n2. Set a single environment variable `TEXTNOTE_DIR` to specify the directory for textnote's files\n\nThat's it, textnote is ready to go!\n\nThe directory specified by `TEXTNOTE_DIR` and the default configuration file will be automatically created the first time textnote is run.\n\nStart writing notes for today with a single command\n```\n$ textnote\n```\n\nTo first configure textnote before creating notes, run\n```\n$ textnote init\n```\nand then edit the configuration file found at the displayed path.\n\n\u003cbr/\u003e\n\n## Installation\ntextnote can be installed by downloading a prebuilt binary or by the `go get` command.\n\n\u003cbr/\u003e\n\n### Releases\nThe recommended installation method is downloading the latest released binary.\nDownload the appropriate binary for your operating system from this repository's [releases](https://github.com/dkaslovsky/textnote/releases/latest) page or via `curl`:\n\nmacOS\n```\n$ curl -o textnote -L https://github.com/dkaslovsky/textnote/releases/latest/download/textnote_darwin_amd64\n```\n\nLinux\n```\n$ curl -o textnote -L https://github.com/dkaslovsky/textnote/releases/latest/download/textnote_linux_amd64\n```\n\nWindows\n```\n\u003e curl.exe -o textnote.exe -L https://github.com/dkaslovsky/textnote/releases/latest/download/textnote_windows_amd64.exe\n```\n\n\u003cbr/\u003e\n\n### Installing from source\n\ntextnote can also be installed using Go's built-in tooling:\n```\n$ go get -u github.com/dkaslovsky/textnote\n```\nBuild from source by cloning this repository and running `go build`.\n\nIt is recommended to build using Go 1.15.7 or greater to avoid a potential security issue when looking for the desired editor in the `$PATH` ([details](https://blog.golang.org/path-security)).\n\n\u003cbr/\u003e\n\n## Usage\ntextnote is intentionally simple to use and supports two main commands: `open` for creating/opening notes and `archive` for consolidating notes into monthly archive files.\n\n\u003cbr/\u003e\n\n### **`open`**\nThe `open` command will open a dated note in an editor, creating it first if it does not exist.\n\nOpening or creating a note for the current day is the default action.\nSimply run the root command to open or create a note for the current day:\n```\n$ textnote\n```\nwhich, using the default configuration and assuming today is 2021-01-24, will create and open an empty note template:\n```\n[Sun] 24 Jan 2021\n\n___TODO___\n\n\n\n___DONE___\n\n\n\n___NOTES___\n\n\n\n```\nTo open a note for a specific date other than the current day, specify the date with the `--date` flag:\n```\n$ textnote open --date 2020-12-22\n```\nwhere the date format is specified in the configuration.\n\nAlternatively, a note can be opened by passing the number of days prior to the current day using the `-d` flag. For example,\n```\n$ textnote open -d 1\n```\nopens yesterday's note.\n\nSections from previous notes can be copied or moved into a current note.\nEach section to be copied is specified in a separate `-s` flag.\nThe most recent dated note is used as the source by default and a specific date for a source note can be provided through the `--copy` flag.\nFor example,\n```\n$ textnote open -s TODO -s NOTES\n```\nwill create today's note with the \"TODO\" and \"NOTES\" sections copied from the most recently dated (often yesterday's) note, while\n```\n$ textnote open --copy 2021-01-17 -s TODO\n```\ncreates today's note with the \"TODO\" section copied from the 2021-01-17 note.\nUse the `-c` flag to instead specify the source by the number of days back from the current day.\nFor example,\n```\n$ textnote open -c 3 -s TODO\n```\ncreates today's note with the \"TODO\" section copied from 3 days ago.\n\nTo move instead of copy, add the `-x` flag to any copy command.\nFor example,\n```\n$ textnote open --copy 2021-01-17 -s NOTES -x\n```\nmoves the \"NOTES\" section contents from the 2021-01-17 note into the note for today.\n\nPass two delete flags (`-xx`) to also delete the source note if moving section(s) leaves the source empty:\n```\n$ textnote open --copy 2021-01-17 -s NOTES -xx\n```\n\nThe `--date` and `--copy` (or `-d` and `-c`) flags can be used in combination if such a workflow is desired.\n\nFor convenience, the `-t` flag can be used to open tomorrow's note:\n```\n$ textnote open -t\n```\nFor example,\n```\n$ textnote open -t -s TODO\n```\ncreates a note for tomorrow with a copy of today's \"TODO\" section contents, assuming a note for today exits.\n\nAlso for convenience, the latest (most recent) dated note can be opened using the `-l` flag:\n```\n$ textnote open -l\n```\nThe most recently dated note is typically from the previous day or a few days ago, but this command will return the note for the current date if it already exists.\nIt will ignore notes dated in the future.\n\nWhen opening/copying requires searching for the latest (most recently dated) note, textnote checks the number of template files that were required to be searched.\nIf this number is above a threshold (as set in the [configuration](#configuration)), a message is displayed suggesting to run the [archive](#archive) command to reduce the number of template files.\nThis message can be effectively disabled by configuring the `templateFileCountThresh` configuration parameter to be very large, but doing so is not recommended.\n\nThe flag options are summarized by the command's help:\n```\n$ textnote open -h\n\nopen or create a note template\n\nUsage:\n  textnote open [flags]\n\nFlags:\n      --copy string       date of note for copying sections (defaults to date of most recent note, cannot be used with copy-back flag)\n  -c, --copy-back uint    number of days back from today for copying from a note (cannot be used with copy flag)\n      --date string       date for note to be opened (defaults to today)\n  -d, --days-back uint    number of days back from today for opening a note (cannot be used with date, tomorrow, or latest flags)\n  -x, --delete count      delete sections after copy (pass flag twice to also delete empty source note)\n  -h, --help              help for open\n  -l, --latest            specify the most recent dated note to be opened (cannot be used with date, days-back, or tomorrow flags)\n  -s, --section strings   section to copy (defaults to none)\n  -t, --tomorrow          specify tomorrow as the date for note to be opened (cannot be used with date, days-back, or latest flags)\n```\n\n\n\u003cbr/\u003e\n\n### **`archive`**\nThe `archive` command consolidates all daily notes into month archives, gathering together the contents for each section of a month in chronological order, labeled by the original date.\nOnly notes older than a number of days specified in the configuration are archived.\n\nRunning the archive command\n```\n$ textnote archive\n```\ngenerates an archive file for every month for which a note exists.\nFor example, an archive of the January 2021 notes, assuming the default configuration, will have the form\n```\nARCHIVE Jan2021\n\n___TODO___\n[2021-01-03]\n...\n[2021-01-04]\n...\n\n\n\n___DONE___\n[2021-01-03]\n...\n[2021-01-04]\n...\n[2021-01-06]\n...\n\n\n___NOTES___\n[2021-01-06]\n...\n\n\n\n```\nwith ellipses representing the daily notes' contents.\n\nBy default, the `archive` command is non-destructive: it will create archive files and leave all notes in place.\nTo delete the individual note files and retain only the generated archives, run the command with the `-x` flag:\n```\n$ textnote archive -x\n```\nThis is the intended mode of operation, as it is desirable to \"clean up\" notes into archives, but must be intentionally enabled with `-x` for safety.\nRunning with the `--dry-run` flag prints the file names to be deleted without performing any actions:\n```\n$ textnote archive --dry-run\n```\n\nIf the `archive` command is run without the delete flag, archive files are written and the original notes are left in place.\nTo \"clean up\" the original notes *after* archives have been generated, rerun the `archive` command with the `-x` flag as well as the `-n` flag to prevent duplicating the archive content:\n```\n$ textnote archive -x -n\n```\n\nThe flag options are summarized by the command's help:\n```\n$ textnote archive -h\n\nconsolidate notes into monthly archive files\n\nUsage:\n  textnote archive [flags]\n\nFlags:\n  -x, --delete     delete individual files after archiving\n      --dry-run    print file names to be deleted instead of performing deletes (other flags are ignored)\n  -h, --help       help for archive\n  -n, --no-write   disable writing archive files (helpful for deleting previously archived files)\n```\n\n\u003cbr/\u003e\n\n### **Additional Functionality**\ntextnote is designed for simplicity. \nBecause textnote writes files to a single directory on the local filesystem, most functionality outside of the scope described above can be easily accomplished using stanard command line tools (e.g., `grep` for search).\n\nA few simple command line functions for searching, listing, and printing notes are available in a [gist](https://gist.github.com/dkaslovsky/010fd26c4d0975639a5c286fa631d6c9).\n\n\u003cbr/\u003e\n\n## Configuration\nWhile textnote is intended to be extremely lightweight, it is also designed to be highly configurable.\nIn particular, the template (sections, headers, date formats, and whitespace) for generating notes can be customized as desired.\nOne might wish to configure headers and section titles for markdown compatibility or change date formats to match regional convention.\n\nConfiguration is read from the `$TEXTNOTE_DIR/.config.yml` file.\nChanges to configuration parameters can be made by updating this file.\nIndividual configuration parameters also can be overridden with [environment variables](#environment-variable-overrides).\n\nImportantly, if textnote's configuration is changed, notes created using a previous configuration might be incompatible with textnote's functionality.\n\nThe configuration file can be displayed by running the `config` command with the `-f` flag:\n```\n$ textnote config -f\n```\nThe configuration file path is displayed by using the `-p` flag:\n```\n$ textnote config -p\n```\n[Defaults](#defaults) are used for configuration parameters omitted from the configuration file or configuration [environment variables](#environment-variable-overrides).\nThe `config` command with the `-a` flag displays the full \"active\" configuration used when the application runs, including default and environment parameters:\n```\n$ textnote config -a\n```\nTo update the configuration file to match the active configuration, run\n```\n$ textnote config update\n```\nThis command overwrites the existing configuration file.\nIt can be used instead of manual updates to the configuration file by passing environment variables.\nFor example,\n```\n$ TEXTNOTE_ARCHIVE_FILE_PREFIX=\"my_archive-\" textnote config update\n```\nThe `update` command is also helpful for writing configuration parameters that have been added with new versions of textnote.\n\nThe `config` command options are summarized by the command's help:\n```\n$ textnote config -h\n\nmanages the application's configuration\n\nUsage:\n  textnote config [flags]\n  textnote config [command]\n\nAvailable Commands:\n  update      update the configuration file with active configuration\n\nFlags:\n  -a, --active   display configuration the application actively uses (includes environment variable configuration)\n  -f, --file     display contents of configuration file (default)\n  -h, --help     help for config\n  -p, --path     display path to configuration file\n\nUse \"textnote config [command] --help\" for more information about a command.\n```\n\n\u003cbr/\u003e\n\n### Defaults\nThe default configuration file is automatically written the first time textnote is run:\n```\nheader:\n  prefix: \"\"                              # prefix to attach to header\n  suffix: \"\"                              # suffix to attach to header\n  trailingNewlines: 1                     # number of newlines after header\n  timeFormat: '[Mon] 02 Jan 2006'         # Golang format for header dates\nsection:\n  prefix: ___                             # prefix to attach to section name\n  suffix: ___                             # suffix to attach to section name\n  trailingNewlines: 3                     # number of newlines for empty section\n  names:                                  # section names\n  - TODO\n  - DONE\n  - NOTES\nfile:\n  ext: txt                                # extension to use for note files\n  timeFormat: \"2006-01-02\"                # Golang format for note file names\n  cursorLine: 4                           # line to place cursor when opening a note\narchive:\n  afterDays: 14                           # number of days after which a note can be archived\n  filePrefix: archive-                    # prefix to attach to archive file names\n  headerPrefix: 'ARCHIVE '                # prefix to attach to header of archive notes\n  headerSuffix: \"\"                        # suffix to attach to header of archive notes\n  sectionContentPrefix: '['               # prefix to attach to section content date\n  sectionContentSuffix: ']'               # suffix to attach to section content date\n  sectionContentTimeFormat: \"2006-01-02\"  # Golang format for section content dates\n  monthTimeFormat: Jan2006                # Golang format for month archive file and header dates\ncli:\n  timeFormat: \"2006-01-02\"                # Golang format for CLI date input\ntemplateFileCountThresh: 90               # threshold for displaying a warning for too many template files\n```\n\n### Environment Variable Overrides\nAny configuration parameter can be overridden by setting a corresponding environment variable.\nNote that setting an environment variable does not change the value specified in the configuration file.\nThe full list of environment variables is listed below and is always available by running `textnote --help`:\n```\n  TEXTNOTE_TEMPLATE_FILE_COUNT_THRESH int\n    \tthreshold for warning too many template files\n  TEXTNOTE_HEADER_PREFIX string\n    \tprefix to attach to header\n  TEXTNOTE_HEADER_SUFFIX string\n    \tsuffix to attach to header\n  TEXTNOTE_HEADER_TRAILING_NEWLINES int\n    \tnumber of newlines to attach to end of header\n  TEXTNOTE_HEADER_TIME_FORMAT string\n    \tformatting string to form headers from timestamps\n  TEXTNOTE_SECTION_PREFIX string\n    \tprefix to attach to section names\n  TEXTNOTE_SECTION_SUFFIX string\n    \tsuffix to attach to section names\n  TEXTNOTE_SECTION_TRAILING_NEWLINES int\n    \tnumber of newlines to attach to end of each section\n  TEXTNOTE_SECTION_NAMES slice\n    \tsection names\n  TEXTNOTE_FILE_EXT string\n    \textension for all files written\n  TEXTNOTE_FILE_TIME_FORMAT string\n    \tformatting string to form file names from timestamps\n  TEXTNOTE_FILE_CURSOR_LINE int\n    \tline to place cursor when opening\n  TEXTNOTE_ARCHIVE_AFTER_DAYS int\n    \tnumber of days after which to archive a file\n  TEXTNOTE_ARCHIVE_FILE_PREFIX string\n    \tprefix attached to the file name of all archive files\n  TEXTNOTE_ARCHIVE_HEADER_PREFIX string\n    \toverride header prefix for archive files\n  TEXTNOTE_ARCHIVE_HEADER_SUFFIX string\n    \toverride header suffix for archive files\n  TEXTNOTE_ARCHIVE_SECTION_CONTENT_PREFIX string\n    \tprefix to attach to section content date\n  TEXTNOTE_ARCHIVE_SECTION_CONTENT_SUFFIX string\n    \tsuffix to attach to section content date\n  TEXTNOTE_ARCHIVE_SECTION_CONTENT_TIME_FORMAT string\n    \tformatting string dated section content\n  TEXTNOTE_ARCHIVE_MONTH_TIME_FORMAT string\n    \tformatting string for month archive timestamps\n  TEXTNOTE_CLI_TIME_FORMAT string\n    \tformatting string for timestamp CLI flags\n```\n\n\u003cbr/\u003e\n\n### Editor-Specific Configuration\nCurrently, textnote supports the `file.cusorLine` and `TEXTNOTE_FILE_CURSOR_LINE` configuration for the following editors:\n* Vi/Vim\n* Emacs\n* Neovim\n* Nano\n\ntextnote will work with all other editors but will not respect this configuration parameter.\n\n\u003cbr/\u003e\n\n## License\ntextnote is released under the [MIT License](https://github.com/dkaslovsky/textnote/blob/main/LICENSE).\nDependency licenses are available in this repository's [CREDITS](./CREDITS) file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdkaslovsky%2Ftextnote","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdkaslovsky%2Ftextnote","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdkaslovsky%2Ftextnote/lists"}