| sidebar_position | 5 |
|---|
Klunok can be configured with the Lua programming language.
Settings are global Lua variables assigned in a file.
(If you want to use an auxiliary variable with a name that is guaranteed not to clash
with any future settings, begin the name with aux or custom).
If the file is within directories that are monitored by Klunok,
the settings are automatically reloaded when the file is written to.
Here is an example of the content of the configuration file:
debounce_seconds = 5
editors['emacs-28.2'] = trueThe file is passed to Klunok via the -c command-line option,
like this:
klunok -c ~/.config/klunok.luaThis page documents the available settings, their types, and default values.
Configuration parsing code is extracted from this page
to ensure that the documentation is always up to date.
This imposes a certain structure on this page.
Lua code blocks titled pre-config are executed before the passed configuration file.
These blocks assign static default values to some settings.
You can use these values in your configuration file, like this:
debounce_seconds = debounce_seconds * 2
prefix_var = prefix .. '/volatile'Lua code blocks titled post-config are executed after the passed configuration file.
These blocks invoke the declare function.
The invocations specify the name of a setting,
its dynamically computed default value and its type.
Here is a sample invocation:
declare('prefix_var', prefix .. '/var', is_string)This invocation means that a setting called prefix_var must be a string,
and if it's not set in the configuration file,
its value is dynamically computed as the string /var concatenated to
the value of the prefix setting.
The declare function is defined below:
function declare(name, default, assertion)
if _G[name] == nil and default ~= nil then
_G[name] = default
else
assertion(name)
end
endThe functions below check that a setting is of the right type.
They are used as the third argument to the declare function.
is_string accepts only strings.
Strings in Lua are enclosed in double or single quotes, like "this" or 'this'.
function is_string(name)
assert(type(_G[name]) == 'string', name .. ' must be a string')
endis_nil_or_string accepts nil and strings.
nil in Lua is a representation of the absence of a value.
nil is not the same as an empty string ''.
The description of a setting of this type will specify what exactly nil represents in the
context of the setting.
function is_nil_or_string(name)
assert(_G[name] == nil or type(_G[name]) == 'string', name .. ' must be nil or a string')
endis_positive accepts integers greater than or equal to zero.
function is_positive(name)
local value = _G[name]
assert(
type(value) == 'number' and math.floor(value) == value and value >= 0,
name .. ' must be a positive integer'
)
endis_set_of_strings accepts Lua tables with string keys.
Working with settings of this type usually means setting individual keys to true or nil.
For example, to add the string 'abc' to the set xyz, you can write xyz.abc = true.
To remove 'abc' from xyz, you can write xyz.abc = nil.
If the key contains characters that are not letters, for example string '/@',
you can add the key as xyz['/@'] = true and remove it as xyz['/@'] = nil.
function is_set_of_strings(name)
local value = _G[name]
assert(type(value) == 'table', name .. ' must be a table')
for key, _ in pairs(value) do
assert(type(key) == 'string', name .. ' must contain only string keys')
end
endPrefix used by default for all of the paths that Klunok writes to.
prefix = '/var/klunok'prefix = 'klunok'declare('prefix', nil, is_string)Prefix used by default for non-store paths that Klunok writes to.
declare('prefix_var', prefix .. '/var', is_string)Root of the store. This is where the backed up versions of files that you edit are placed.
declare('store_root', prefix .. '/store', is_string)Path to the queue. The queue is a directory that contains symbolic links to files that you edit. Klunok uses the queue for debouncing.
declare('queue_path', prefix_var .. '/queue', is_string)Path to the journal.
The journal is a file where Klunok records various events,
for example a file being backed up.
See the other events here.
If nil, Klunok does not write journal events anywhere.
Specifying nil is more efficient than '/dev/null'.
journal_path = '/dev/stderr' -- write the events to the terminaldeclare('journal_path', prefix_var .. '/journal', is_nil_or_string)Root of an auxiliary store used for keeping track of offsets of
history_paths.
declare('offset_store_root', prefix_var .. '/offsets', is_string)If not empty, a symbolic link with this name plus the original file extension will be kept in the store alongside the backed-up versions and will point to the original file.
declare('working_copy_link_name', '', is_string)Debouncing means delaying copying until some time passes without any further modifications.
The delay, in seconds, before a file is copied to the store after the last modification.
debounce_seconds = 60declare('debounce_seconds', nil, is_positive)These settings use
the strftime special characters.
Pattern of timestamps in the journal.
journal_timestamp_pattern = '%Y-%m-%d-%H-%M'declare('journal_timestamp_pattern', nil, is_string)Pattern of file versions in the store.
declare('version_pattern', 'v' .. journal_timestamp_pattern, is_string)By default, a file is copied to the store only if it's written to by
an editor application and it's not hidden.
A file is hidden if its name or the name of one of its ancestor directories begins with a dot,
for example .config,
unless that whole path segment is listed in ignored_leading_dots.
Relative paths are interpreted relative to the common parent of directories
monitored via
the -w command line option.
For example, if Klunok is invoked as
klunok -w /home/nazar/src -w /home/nazar/.config/nvim -w /home/nazar/.config/klunok,
relative paths are interpreted relative to /home/nazar.
history_paths, excluded_paths, included_paths and cluded_paths
can be paths not only to files, but also to directories.
If a path is a directory,
the setting applies to each file in the directory and its descendants.
More specific paths override less specific ones.
For example, let's consider this configuration:
excluded_paths['/home/nazar'] = true
included_paths['/home/nazar/src'] = true
excluded_paths['/home/nazar/src/secret.txt'] = true
included_paths['/home/nazar/.config/klunok'] = trueWith this configuration:
/home/nazar/file.txtis excluded;/home/nazar/src/file.txtis included;/home/nazar/src/project/file.txtis included;/home/nazar/src/secret.txtis excluded;/home/nazar/.config/file.txtis excluded because the.configdirectory is hidden;/home/nazar/.config/klunok/file.txtis included;/home/nazar/.config/klunok/.file.txtis excluded.
Path segments whose leading dot does not make a path hidden.
This applies only to exact segment names, not prefixes.
For example, if .github is listed here, then .github/workflows/ci.yml is not hidden,
but .github/.env is still hidden because .env is not listed.
ignored_leading_dots['.custom-hidden'] = trueignored_leading_dots = {
['.clang-format'] = true,
['.clang-format-ignore'] = true,
['.clang-tidy'] = true,
['.clangd'] = true,
['.dockerignore'] = true,
['.editorconfig'] = true,
['.gitattributes'] = true,
['.github'] = true,
['.gitignore'] = true,
['.gitlab'] = true,
['.gitlab-ci.yml'] = true,
['.mailmap'] = true,
['.pre-commit-config.yaml'] = true,
['.pre-commit-config.yml'] = true,
['.prettierignore'] = true,
['.prettierrc'] = true,
['.prettierrc.cjs'] = true,
['.prettierrc.js'] = true,
['.prettierrc.json'] = true,
['.prettierrc.json5'] = true,
['.prettierrc.mjs'] = true,
['.prettierrc.toml'] = true,
['.prettierrc.yaml'] = true,
['.prettierrc.yml'] = true,
}declare('ignored_leading_dots', nil, is_set_of_strings)Filenames of executables that are considered editors. By default, only files edited by these applications are copied to the store. If you have problems registering an application as an editor, please read the editors section.
editors.ed = true
editors['emacs-28.3'] = true
editors.code = nil -- do not treat "code" as an editoreditors = {
atom = true,
code = true,
codium = true,
gedit = true,
howl = true,
hx = true,
inkscape = true,
kak = true,
kate = true,
kwrite = true,
micro = true,
nano = true,
nvim = true,
pluma = true,
rsession = true,
sublime_text = true,
vi = true,
vim = true,
xed = true,
['gnome-text-editor'] = true,
['notepadqq-bin'] = true,
['soffice.bin'] = true,
['vim.basic'] = true,
['vim.tiny'] = true,
['.gedit-wrapped'] = true,
['.gnome-text-editor-wrapped'] = true,
['.howl-wrapped'] = true,
['.hx-wrapped'] = true,
['.inkscape-wrapped'] = true,
['.kate-wrapped'] = true,
['.kwrite-wrapped'] = true,
['.pluma-wrapped'] = true,
['.xed-wrapped'] = true,
}declare('editors', nil, is_set_of_strings)Paths that are assumed to be always appended to.
Only changes will be stored as new versions.
These paths are copied to the store regardless of the application that writes to them
and hence regardless of the editors setting.
history_paths['/home/nazar/.bash_history'] = truehistory_paths = {}declare('history_paths', nil, is_set_of_strings)Paths that are never copied to the store.
excluded_paths = {}declare('excluded_paths', nil, is_set_of_strings)Paths that are copied to the store regardless of the application that writes to them,
and hence regardless of the editors setting.
included_paths = {}declare('included_paths', nil, is_set_of_strings)Paths that are copied to the store only if they are written to by an editor application.
Editor applications are defined in the editors setting.
This is the default, so this setting is mainly useful to:
- override
history_paths,excluded_pathsandincluded_paths; - include files in hidden directories if the files themselves are not hidden, for example
specifying
cluded_paths['/home/nazar/.config'] = truewill allow/home/nazar/.config/klunok.luato be copied when written to by an editor application, but/home/nazar/.config/.klunok.luaand/home/nazar/.config/.klunok/config.luawill not be copied.
cluded_paths = {}declare('cluded_paths', nil, is_set_of_strings)See the projects section.
Roots of projects.
project_roots['/home/nazar/src/klunok'] = trueproject_roots = {}declare('project_roots', nil, is_set_of_strings)Directories that contain roots of projects.
project_parents['/home/nazar/src'] = trueproject_parents = {}declare('project_parents', nil, is_set_of_strings)Root of the project store.
declare('project_store_root', prefix .. '/projects', is_string)Root of the unstable project store.
declare('unstable_project_store_root', prefix_var .. '/projects', is_string)These settings control the trade-off between RAM usage and performance. Tinkering with these settings cannot impact Klunok in any other way.
Guess of the maximum queue size.
declare('queue_size_guess', debounce_seconds * 2, is_positive)Guess of the maximum length of the majority of the paths in the system.
path_length_guess = 1024declare('path_length_guess', nil, is_positive)Guess of the maximum PID (process ID) in the system while Klunok is running.
max_pid_guess = 2^15declare('max_pid_guess', nil, is_positive)Guess of how many ELF interpreters there are in the system.
elf_interpreter_count_guess = 1declare('elf_interpreter_count_guess', nil, is_positive)If a setting from this section is nil, the corresponding event is not logged to
the journal.
Otherwise, the corresponding event is logged to the journal with
the provided prefix.
If the prefix is not an empty string, it is separated from the
rest of the logged line by a tab.
event_queue_head_stored = ''declare('event_open_exec_not_editor', nil, is_nil_or_string)
declare('event_open_exec_editor', nil, is_nil_or_string)
declare('event_close_write_ignored', event_close_write_not_by_editor, is_nil_or_string)
declare('event_close_write_not_ignored', event_close_write_by_editor, is_nil_or_string)
declare('event_queue_head_deleted', nil, is_nil_or_string)
declare('event_queue_head_forbidden', nil, is_nil_or_string)
declare('event_queue_head_stored', nil, is_nil_or_string)