*denote.txt* Handling denote entries – the vim way Last change: 2026 Mar 3 This is the documentation for the denote package. This package also introduces the |libdenote| plugin in the file autoload/libdenote.vim, which may be of independent interest. If this package is loaded automatically, but you prefer to opt-out, then add this line to your vimrc: > let g:loaded_denote = 1 < ============================================================================== CONTENTS *vim-denote* *denote* 1. Introduction |denote-intro| 2. Commands |denote-commands| 2.1 Universal commands |denote-universal-commands| 2.2 Note command |denote-note-command| 2.3 Denote-list commands |denote-list-commands| 3. Settings |denote-settings| 4. Keys |denote-keys| Appendices A. The libdenote plugin |libdenote| A.1 File-naming functions |libdentoe-filenaming| A.2 Front-matter functions |libdenote-frontmatter| B. Package API |denote-api| ============================================================================== INTRODUCTION *denote-intro* Denote is a file-naming scheme developed by Protesilaos Stavrou and an Emacs tool for handling such files. Notes and other files that follow this scheme can be linked, and the links are preserved even when the files are renamed due do adjusting the tags or changing the title of a note. The official manual is available online: https://protesilaos.com/emacs/denote The denote plugin adds denote functionality to vim — the vim way. We are aware of two other plugins, but we fear that these plugins are not flexible enough, and more importantly, do not follow the vim philosophy for handling denote notes. These mentioned plugins are available here: https://github.com/shuckster/denote-md https://git.sr.ht/~ashton314/vim-denote In contrast to these plugins, the present package relies on the |location-list| features for displaying denote entries, and on the options 'quickfixtextfunc', 'includeexpr', and 'omnifunc'. With these, denote links can be followed using |gf|, and completed using omni completion (see, |compl-omni|). For link completion, press |i_CTRL-X_CTRL-O| after typing any prefix of a denote link. This completion also works with titles: by invoking omni completion after typing "denote:foo", denote links are completed for entries containing "foo" in the title. ============================================================================== COMMANDS *denote-commands* After loading this package, only the first of the following commands is available. This first command, as descried below, sets the directory to be used for the denote entries. After that command has been issued, several other commands become possible, such as |:DenoteTag|. Some command are available within any window, others only in denote notes, and yet other again only in the location-list that lists denote entries. *denote-universal-commands* Universal commands~ *:DenoteDirectory* *:DenoteDirectory!* :DenoteDirectory[!] {path} Set the provided {path} as the denote directory that will be used by all following commands. The {path} argument is autocompleted. With the bang, the autocompletion works for all directories available on your system. Without the bang, only directories listed in the |g:denote_directories| variable are autocompleted. After the denote directory has been specified, the following commands become available. They all operate on that specified directory. *:Denote* :Denote [{keyword ..}] Populate the location list of the current window with the denote entries present in the specified directory. This command may be supplemented with any number of arguments that filter the entries according to the appearance of the keywords in the file name. *:DenoteByTag* :DenoteByTag {tag} This command takes as argument a tag, and populates the location list with all denote entries of that are tagged accordingly. The tags are autocompleted (see, |c_|). Also fuzzy matching is possible when "fuzzy" is contained in 'wildoptions'. *:DenoteGrep* :DenoteGrep /{pattern}/[g][j][f] This command is a wrapper around |:lvimgrep| to search for a pattern in the denote entries. The required argument is a pattern as required by |:vimgrep|, i.e., /{pattern}/[g][j][f]. *:DenoteNew* :DenoteNew {title} This command takes as argument a note title, and generates a new denote entry with the specified title. The entry file type is controlled by the setting |g:denote_new_ft|. *:DenoteCopy* :DenoteCopy {file} With this, the specified file is copied into the denote directory. The file name is taken as the title, and the identifier is freshly generated. Any file, i.e., not only those specified using |g:denote_note_file_extension| may be chosen. *denote-note-command* Note command~ This is the only command exclusive to the windows that hold denote note entries, i.e., files with an extension in |g:denote_note_file_extension|. *:DenoteBackReferences* :DenoteBackReferences This command populates the location list with all references to the current note. This command can only be called from an opened denote note. *denote-list-commands* Denote-list commands~ The denote list may be opened using one of the commands |:Denote| or |:DenoteByTag|. Also the commands |:DenoteGrep| and |:DenoteBackReferences| open the location list, but not as a list of entries, but as a list of matching patterns. The following commands are available in the denote list (first case). *:DenoteSetTitle* :DenoteSetTitle {string} The title of the selected entry is changed as specified. *:DenoteTagAdd* :DenoteTagAdd {tag} With this, the provided tag is added to the list of tags of the selected entry. The tag may be autocompleted. This command also accepts a range, resulting in adding the tag to every entry within that range. *:DenoteTagRm* :DenoteTagRm {tag} Just as above, but for removing the specified tag. *:DenoteDelete* :DenoteDelete[!] With this, the selected entry is deleted from the denote directory (and from the disk). This command also accepts a range, to delete a bunch of entries. After the deletion command has been invoked, the user is asked to confirm the deletion. With the optional bang, no confirmation will be asked. ============================================================================== SETTINGS *denote-settings* All settings described below are set to default values. For this package to function, it is not necessary to specify a setting manually. *g:denote_directories* g:denote_directories list With this option, may may specify a list of your denote directories. This list is used for the autocompletion of the |:DenoteDirectory| command. The default value is > let g:denote_directories = [] < *g:denote_note_file_extension* g:denote_note_file_extension list With this setting, you may specify the file extensions of all denote entries within which |:DenoteGrep| will search, and for which files denote link completion and the |:DenoteBackReferences| command will be available. If left unspecified, it is set to the following default value: > let g:denote_note_file_extension = ['md', 'org', 'txt'] < *g:denote_loc_title_columns* g:denote_loc_title_columns number This integer specifies the number of columns used to display the titles of denote entries. Per default, it is set to: > let g:denote_loc_title_columns = 60 < *g:denote_new_ft* g:denote_new_ft string Newly created notes are of this file type. Possible values are 'md', 'org', or 'txt', with the following default: > let g:denote_new_ft = 'md' < *g:denote_fm_md_type* g:denote_fm_md_type string The front matter of 'md' notes is given as 'yaml' or as 'toml'. By default, this package uses 'yaml': > let g:denote_fm_md_type = 'yaml' < *g:Denote_identifier_fun* g:Denote_identifier_fun Funcref Denote allows the use of custom identifiers. This variable, if set, points to a function that generates identifiers for newly created notes. The function is supposed to return a unique string. By default, the variable set as > let g:Denote_identifier_fun = function('denote#meta#identifier_generate') < which calls |strftime('%Y%m%dT%H%M%S')| if |strftime()| is available, and |rand()| otherwise. Another reasonable setting would be to use some uuid generator and to specify, e.g., > let g:Denote_identifier_fun = { -> system('uuidgen') \ ->substitute('[^[:xdigit:]]', '', 'g') } < ============================================================================== KEYS *denote-keys* The location lists generated by the present package, e.g., through the command |:DenoteGrep| or |:DenoteByTag|, have the following key key-bindings. *denote-r* r Reload the location list. *denote-q* q Close the location list. In addition, denote lists (see |denote-list-commands|) come with the following keys: *denote-list-C* C Change the title of the selected entry. *denote-list-+* + Add a tag to the selected entries (also in visual mode). *denote-list--* - As |denote-list-+| but for removing tags. *denote-list-dd* dd Delete the selected entry. {Visual}d Delete the visually selected entries. ============================================================================== APPENDIX A - THE LIBDENOTE PLUGIN *libdenote* The present package has as constituent the libdenote plugin for basic denote-centered operations. That plugin is given by the file autoload/libdenote.vim. Each function in this plugin is pure, i.e., produces no side effects. There are two classes of functions: functions concerning the file-naming scheme (prefixed with scheme_, see |libdenote-filenaming|) and functions concerning the front matter (prefixed with fm_, see |libdenote-frontmatter|). *libdenote-filenaming* File-naming functions~ *libdenote#scheme_idgen()* libdenote#scheme_idgen() This function generates a new identifier. If the function |strftime()| is available, than strftime(%Y%m%dT%H%M%S) is used, otherwise a random identifier is generated using |rand()|. *libdenote#scheme_filename()* libdenote#scheme_filename({ext}, {id}, {title}, {tags}, {sig}) With this, the file name of the denote entry with the given metadata is returned. The parameter {ext} describes the extension of the file is is one of 'md', 'txt', or 'org'. The parameter {id} is the denote identifier, possibly generated via |libdenote#scheme_idgen()|. The {title} parameter is optional and describes the title of the note. By default, it is set to the empty string ''. The {tags} parameter is optional as well, is a list of tags associated to the note. The default value is the empty list []. Also, the {sig} parameter is optional, and used to describe the signature of the entry. *libdenote#scheme_metadata()* libdenote#scheme_metadata({filename}) This function returns the metadata of the file given by {filename}. This parameter may describe the path to the file, or the tail only. The returned |dict| has the keys 'id' for the identifier, 'title' for the title, 'tags' for the list of tags, and 'sig' for the signature. *libdenote-frontmatter* Front-matter functions~ *libdenote#fm_gen()* libdenote#fm_gen({ext}, {id}, {title}, {tags}, {md_type}) This function returns the list of lines for the front matter that stores the given metadata. The paramter {ext} is the extension of the file, the parameter {id} the identifier, the parameter {title}, the title of the note, and {tags} the optional parameter as a list of tags associated to the note. Per default {tags} is set to the empty list []. Finally, {md_type} descries the format to be used in markdown. For markdown files (extension 'md'), two formats are possible: 'yaml' and 'toml'. The former format is used per default. *libdenote#fm_alter()* libdenote#fm_alter({fm}, {mod}) Similar to |libdenote#fm_gen()|, this function returns a list containing the lines of a front matter. In contrast to the above function, this functions takes a front matter {fm} as base (again, given as list of lines), and updates the fields specified by the |dict| {mod}. If {mod} contains the key "date", then the date string will be updated. If {mod} contains the key "id", then the identifier will be updated with the value a:mod.id. Similarly, the keys "title" and "tags" are used to update the title and tag list of the front matter. *libdenote#fm_len()* libdenote#fm_len({ext}) This returns the number of lines of the front matter for files with the extension {ext}. ============================================================================== APPENDIX B - PACKAGE API *denote-api* Here, we list and briefly describe all functions that come with this package. The aim of providing this information is to keep vim-denote hackable. *denote#commands#load()* denote#commands#load() This function initializes the user commands (see, |denote-commands|) that are globally available. *denote#completion#tags()* denote#completion#tags({ArgLead}, {CmdLine}, {CursorPos}) This is the autocompletion function for tag arguments in the user commands |:DenoteByTag|, |:DenoteTagAdd|, and |:DenoteTagRm|. *denote#loclist#clear()* denote#loclist#clear() With this, the location list is cleared. *denote#loclist*fill()* denote#loclist*fill({title}, {files}, {Gfun}) This function populates the location list with denote entries. The {title} argument specifies the title of the location list. The {files} argument is a list of filenames of denote entries. Finally, the {Gfun} argument is a Funcref to the function that reloads the location list — this is the function (with all arguments set) that invoked this call to |denote#loclist#fill()|. *denote#loclist#setgrep()* denote#loclist#setgrep({title}, {Gfun}) This function makes the location list fit for showing the result of |:DenoteGrep|. The {title} and {Gfun} arguments are as in |denote#loclist#fill()|. *denote#loclist#reload()* denote#loclist#reload() This function reruns the location-list generating function (see {Gfun} in |denote#loclist#fill()|. *denote#loclist#jumptowindow()* denote#loclist#jumptowindow() With this, the cursor is moved from the location list to the window the location list belongs to. *denote#notes#list()* denote#notes#list({search}) This function searches for denote entries that contain {search} in the path, and displays the results in the location list. The command |:Denote| is bound to this function. *denote#notes#bytag()* denote#notes#bytag({tag}) This is similar to |denote#notes#list()|, but only entries with the tag {tag} are put to the location list. This is used by the command |:DenoteByTag|. *denote#notes#grep()* denote#notes#grep({re}) This is the function used by |:DenoteGrep| and |:DenoteBackReferences| to search for patterns within the denote files. *denote#notes#new()* denote#notes#new({title}, {ext}) This function is used by |:DenoteNew|. Here, {title} is the title of the new note, and {ext} the file extension. This second argument is optional and has the default value |g:denote_new_ext|. *denote#notes#settitle()* denote#notes#settitle({linenr}, {title}) With this, the title of the entry on line {linenr} of the location list is set to {title}. This is used by |:DenoteSetTitle|. *denote#notes#tagmod()* denote#notes#tagmod({line1}, {line2}, {tag}, {add}) This function modifies the tags of the denote entries from line {line1} to line {line2} of the location list. In each of these entries, the tag {tag} is added if {add} is 1, and removed if {add} is 0. *denote#notes#copy()* denote#notes#copy({origfile}) This copies the file {origfile} to the denote directory, and renames the copy to make it denote compatible. This function is used by |:DenoteCopy|. *denote#notes#rm()* denote#notes#rm({line1}, {line2}, {bang}) With this, the files that correspond to the entries from line {line1} to line {line2} of the location list are deleted. If the {bang} is set to 1, then no confirmation will be asked. Otherwise, the user is asked to confirm every deletion. This function is used by |:DenoteDelete|. vim:tw=78:sw=4:ts=8:noet:ft=help:norl: