Deft is an Emacs mode for quickly browsing, filtering, and editing directories of plain text notes, inspired by Notational Velocity. It was designed for increased productivity when writing and taking notes by making it fast and simple to find the right file at the right time and by automating many of the usual tasks such as creating new files and saving files.
Deft is open source software and may be freely distributed and modified under the BSD license. The latest stable release is version 0.8, released on January 12, 2018.
Installation via MELPA Stable
The recommended way to install Deft is to obtain the stable version
from MELPA Stable using
package.el
. First, configure package.el
and the MELPA Stable
repository by adding the following to your .emacs
, init.el
, or
equivalent startup file:
(require 'package)
(add-to-list 'package-archives
'("melpa-stable" . "https://stable.melpa.org/packages/"))
(package-initialize)
Then, after restarting Emacs or evaluating the above statements, issue the following command: M-x package-install RET deft RET.
Direct Download
Alternatively you can manually download and install Deft.
First, download the latest stable version of and save the file
where Emacs can find it---a directory in your load-path
:
Then, add the following line to your startup file:
(require 'deft)
Development Version
To follow or contribute to Deft development, you can browse or clone the Git repository on GitHub:
git clone https://github.com/jrblevin/deft.git
If you prefer to install and use the development version, which may become unstable at some times, you can either clone the Git repository as above or install Deft from MELPA.
If you clone the repository directly, then make sure that Emacs can find it by adding the following line to your startup file:
(add-to-list 'load-path "/path/to/deft/repository")
The Deft buffer is simply a file browser which lists the titles of all text files in the Deft directory followed by short summaries and last modified times. The title is taken to be the first line of the file and the summary is extracted from the text that follows. Files are, by default, sorted in terms of the last modified date, from newest to oldest.
All Deft files or notes are simple plain text files where the first line contains a title. As an example, the following directory structure generated the screenshot above.
% ls ~/.deft
about.txt browser.txt directory.txt operations.txt
ack.txt completion.txt extensions.org
binding.txt creation.txt filtering.txt
% cat ~/.deft/about.txt
# About
An Emacs mode for slicing and dicing plain text files.
Deft's primary operation is searching and filtering. The list of files can be limited or filtered using a search string, which will match both the title and the body text. To initiate a filter, simply start typing. Filtering happens on the fly. As you type, the file browser is updated to include only files that match the current string.
To open the first matching file, simply press RET. If no files match your search string, pressing RET will create a new file using the string as the title. This is a very fast way to start writing new notes. The filename will be generated automatically. If you prefer to provide a specific filename, use C-RET instead.
To open files other than the first match, navigate up and down using C-p and C-n and press RET on the file you want to open. When opening a file, Deft searches forward and leaves the point at the end of the first match of the filter string.
You can also press C-o to open a file in another window, without switching to the other window. Issue the same command with a prefix argument, C-u C-o, to open the file in another window and switch to that window.
To edit the filter string, press DEL
(backspace) to remove the
last character or M-DEL to remove the last "word". To yank
(paste) the most recently killed (cut or copied) text into the
filter string, press C-y. Press C-c C-c to clear the filter
string and display all files and C-c C-g to refresh the file
browser using the current filter string.
For more advanced editing operations, you can also edit the filter string in the minibuffer by pressing C-c C-l. While in the minibuffer, the history of previous edits can be cycled through by pressing M-p and M-n. This form of static, one-time filtering (as opposed to incremental, on-the-fly filtering) may be preferable in some situations, such as over slow connections or on systems where interactive filtering performance is poor.
By default, Deft filters files in incremental string search mode,
where "search string" will match all files containing both "search"
and "string" in any order. Alternatively, Deft supports direct
regexp filtering, where the filter string is interpreted as a
formal regular expression. For example, ^\(foo\|bar\)
matches
foo or bar at the beginning of a line. Pressing C-c C-t will
toggle between incremental and regexp search modes. Regexp
search mode is indicated by an "R" in the mode line.
Common file operations can also be carried out from within Deft. Files can be renamed using C-c C-r or deleted using C-c C-d. New files can also be created using C-c C-n for quick creation or C-c C-m for a filename prompt; with a prefix argument, these operations ask for a file extension. You can leave Deft at any time with C-c C-q.
Unused files can be archived by pressing C-c C-a. Files will be
moved to deft-archive-directory
, which is a directory named
archive
within your deft-directory
by default.
Files opened with deft are automatically saved after Emacs has been
idle for a customizable number of seconds. This value is a floating
point number given by deft-auto-save-interval
(default: 1.0).
Once you have installed Deft following one of the above methods,
you can simply run M-x deft to start Deft. It is useful
to create a global keybinding for the deft
function (e.g., a
function key) to start it quickly (see below for details).
When you first run Deft, it will complain that it cannot find the
~/.deft
directory. You can either create a symbolic link to
another directory where you keep your notes or run M-x deft-setup
to create the ~/.deft
directory automatically.
One useful way to use Deft is to keep a directory of notes in a Dropbox folder. This can be used with other applications and mobile devices, for example, nvALT, Notational Velocity, or Simplenote on OS X or Editorial, Byword, or 1Writer on iOS.
You can customize items in the deft
group to change the default
functionality.
By default, Deft looks for notes by searching for files with the
extensions .txt
, .text
, .md
, .markdown
, or .org
in the
~/.deft
directory. You can customize both the file extension and
the Deft directory by running M-x customize-group and typing
deft
. Alternatively, you can configure them in your .emacs
file:
(setq deft-extensions '("txt" "tex" "org"))
(setq deft-directory "~/Dropbox/notes")
The first element of deft-extensions
(or in Lisp parlance, the
car) is the default extension used to create new files.
By default, Deft only searches for files in deft-directory
but
not in any subdirectories. All files in deft-directory
with one
of the specified extensions will be included except for those
matching deft-ignore-file-regexp
. Set deft-recursive
to a
non-nil value to enable searching for files in subdirectories
(those not matching deft-recursive-ignore-dir-regexp
):
(setq deft-recursive t)
You can easily set up a global keyboard binding for Deft. For
example, to bind it to F8, add the following code to your .emacs
file:
(global-set-key [f8] 'deft)
If you manage loading packages with use-package, then you can configure by adding a declaration such as this one to your init file:
(use-package deft
:bind ("<f8>" . deft)
:commands (deft)
:config (setq deft-directory "~/Dropbox/notes"
deft-extensions '("md" "org")))
The displayed title of each file is taken to be the first line of
the file, with certain characters removed from the beginning. Hash
characters, as used in Markdown headers, and asterisks, as in Org
Mode headers, are removed. Additionally, Org mode #+TITLE:
tags,
MultiMarkdown Title:
tags, LaTeX comment markers, and
Emacs mode-line declarations (e.g., -*-mode-*-
) are stripped from
displayed titles. This can be customized by changing
deft-strip-title-regexp
.
More generally, the title post-processing function itself can be
customized by setting deft-parse-title-function
, which accepts
the first line of the file as an argument and returns the parsed
title to display in the file browser. The default function is
deft-strip-title
, which removes all occurrences of
deft-strip-title-regexp
as described above.
For compatibility with other applications which use the filename as
the title of a note (rather than the first line of the file), set the
deft-use-filename-as-title
flag to a non-nil
value. Deft will then
use note filenames to generate the displayed titles in the Deft
file browser. To enable this, add the following to your .emacs
file:
(setq deft-use-filename-as-title t)
Finally, the short summary that is displayed following the file
title can be customized by changing deft-strip-summary-regexp
. By
default, this is set to remove certain org-mode metadata statements
such as #+OPTIONS:
and #+AUTHOR:
.
Filenames for newly created files are generated by Deft automatically.
The process for doing so is determined by the variables
deft-use-filename-as-title
and deft-use-filter-string-for-filename
as well as the rules in the deft-file-naming-rules
alist.
The possible cases are as follows:
Default (deft-use-filename-as-title
and
deft-use-filter-string-for-filename
are both nil
):
The filename will be automatically generated using an short,
ISO-like timestamp as in 2016-05-12T09:00.txt
. The format
can be customized by setting the variable
deft-new-file-format
. The filter string will be inserted as
the first line of the file (which is also used as the display
title). In case of file name conflicts, an underscore and a
numerical suffix (e.g., _2
) will be appended before the
extension.
Filenames as titles (deft-use-filename-as-title
is non-nil
):
When deft-use-filename-as-title
is non-nil
, the filter string
will be used as the filename for new files (with the appropriate
file extension appended to the end). An example of new file creation
in this case:
Readable filenames (deft-use-filename-as-title
is
nil
but deft-use-filter-string-for-filename
is non-nil
):
In this case you can choose to display the title as parsed from
the first line of the file while also generating readable
filenames for new files based on the filter string. The
variable deft-use-filter-string-for-filename
controls this
behavior and decouples the title display
(deft-use-filename-as-title
) from the actual filename. New
filenames will be generated from the filter string and
processed according to the rules defined in the
deft-file-naming-rules
alist. By default, slashes are removed
and replaced by hyphens, but many other options are possible
(camel case, replacing spaces by hyphens, and so on). See the
documentation for deft-file-naming-rules
for additional
details.
As an example, with the following value for
deft-file-naming-rules
, Deft will replace all slashes and
spaces with hyphens and will convert the file name to
lowercase:
(setq deft-file-naming-rules
'((noslash . "-")
(nospace . "-")
(case-fn . downcase)))
Below is an example in this case, with the above file naming rules. Notice that the filter string is inserted as the first line of the file but it is also used to generate a "readable" file name.
Titles inserted into files from the filter string can also be
customized for two common modes, markdown-mode
and org-mode
, by
setting the following variables:
deft-markdown-mode-title-level
- When set to a positive
integer, determines how many hash marks will be added to titles
in new Markdown files. In other words, setting
deft-markdown-mode-title-level
to 2 will result in new files
being created with level-2 headings of the form ## Title
.
deft-org-mode-title-prefix
- When non-nil, automatically
generated titles in new org-mode
files will be prefixed with
#+TITLE:
.
Deft, by default, lists files from newest to oldest. You can set
deft-current-sort-method
to 'title to sort by file titles, case
ignored. Or, you can toggle sorting method using
deft-toggle-sort-method
.
Incremental string search is the default method of filtering on
startup, but you can set deft-incremental-search
to nil to make
regexp search the default.
Deft also provides a function for opening files without using the
Deft buffer directly. Calling deft-find-file
will prompt for a
file to open, much like find-file
, but limits consideration to
files in deft-directory
that are known to Deft (i.e., those files
matching deft-extensions
). Unlike find-file
, a list of all
such files is provided and the desired file name can be completed
using completing-read
(and, as a result, deft-find-file
will
read/complete filenames using ido, helm, etc. when enabled). If
the selected file is in deft-directory
, it is opened with the
usual Deft features (automatic saving, automatic updating of the
Deft buffer, etc.). Otherwise, the file will be opened by
find-file
as usual. Therefore, you can set up a global
keybinding for this function to open Deft files anywhere. For
example, to use C-x C-g, a neighbor of C-x C-f, use the
following:
(global-set-key (kbd "C-x C-g") 'deft-find-file)
The faces used for highlighting various parts of the screen can also be customized. By default, these faces inherit their properties from the standard font-lock faces defined by your current color theme.
Deft also provides several hooks: deft-mode-hook
,
deft-filter-hook
, and deft-open-file-hook
. See the
documentation for these variables for further details.
Thanks to Konstantinos Efstathiou for writing simplenote.el, from which I borrowed liberally, and to Zachary Schneirov for writing Notational Velocity, whose functionality and spirit I wanted to bring to Emacs.
Version 0.8 (2018-01-12):
deft-find-file
to files known to Deft and support
completing-read.deft-width-offset
for custom summary line width
offset.deft-filter-hook
for filter string changes and
deft-open-file-hook
which runs after opening a file.sublimity-mode
.deft-new-file-format
for new file names.deft-filter-only-filenames
to filter only on file names.Version 0.7 (2015-12-21):
deft-strip-summary-regexp
for
stripping extraneous text for generating the summary line. Strip
all org-mode
metadata by default.deft-recursive-ignore-dir-regexp
and
deft-ignore-file-regexp
.deft-extensions
and deft-default-extension
at
load time.#+TITLE:
might also appear in the body.with-current-buffer
instead of save-excursion
while auto-saving files since we do not want to save the point.deft-file-naming-rules
.Version 0.6 (2015-06-26):
deft-recursive
to a non-nil value to enable.deft-extensions
list.
As such, deft-extension
is now deprecated.deft-create-file-from-filter-string
can enable
generation of new filenames based on the filter string. This decouples
the title display (deft-use-filename-as-title
) from the actual filename
generation.deft-file-naming-rules
allows customizing generation
of filenames with regard to letter case and handling of spaces.deft-markdown-mode-title-level
and
deft-org-mode-title-prefix
for automatic insertion of title markup.deft-archive-directory
.deft-current-sort-method
.deft-strip-title-regexp
to remove the following:
#+TITLE:
tagsTitle:
tags-*-mode-*-
)hack-local-variables
to read file-local variables when
opening files.string-width
error with empty file.Version 0.5.1 (2013-01-28):
deft-use-filename-as-title
are non-nil resulted in an invalid path.deft-auto-save-buffers
.Version 0.5 (2013-01-25):
deft-incremental-search
.deft-parse-title-function
for post-processing titles.deft-parse-title-function
simply strips occurrences of
deft-strip-title-regexp
, which removes Markdown and Org headings.DEL
), delete word (M-DEL),
and yank (C-y).Version 0.4 (2011-12-11):
deft-use-filename-as-title
).deft-time-format
).deft-directory
properly with or without a trailing slash.Version 0.3 (2011-09-11):
Version 0.2 (2011-08-22):
Deft was originally written by Jason Blevins. The initial version, 0.1, was released on August 6, 2011.