1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# Trail default configuration.
[]
= "nvim"
# Shell that runs `!<command>` and `:git`: a program, then the flags that make
# it read a command string as one argument. Empty keeps the platform default
# -- `cmd.exe /C` on Windows, `sh -c` elsewhere -- which is what Trail has
# always used, so leaving this alone changes nothing.
#
# Set it to pick a different interpreter, e.g. `pwsh -NoProfile -Command` on
# Windows so that `./program` and other POSIX-ish spellings resolve (cmd.exe
# reads a leading `/` as a switch and fails on `./program`), or `bash -c` to
# get bash syntax instead of whatever `sh` is on this system. The trade-off is
# startup cost per command -- pwsh is markedly slower to launch than cmd.exe,
# and `-NoProfile` is what keeps that from getting worse -- and that shell
# builtins stop matching the ones your muscle memory expects.
#
# Whitespace separates tokens; double-quote a program path containing spaces.
# Windows paths need a TOML literal string, e.g.
# shell = '"C:\Program Files\PowerShell\7\pwsh.exe" -NoProfile -Command'
= ""
# Whether to wait for Enter after a `!<command>` or `:git` finishes, before
# Trail takes the screen back: always | on_error | never.
#
# A command's output is printed on the normal screen, which Trail covers again
# the moment the command exits -- so without a pause, `!ls` paints its output and
# erases it in the same breath. The trade-off is a keystroke per command: set
# `on_error` to be held up only when something failed, or `never` if you run
# commands for their effect rather than their output and would rather read them
# in the log. Opening a file in the editor never pauses whatever this says --
# an editor owns the screen while it runs and leaves nothing behind to read.
= "always"
# How much of a file the preview reads, in KiB. Together with
# `[preview] max_lines` this bounds one preview: max_lines stops an ordinary
# file, this stops one whose lines are enormous -- minified JavaScript, a
# one-line JSON blob -- which would otherwise be loaded whole however few lines
# it has. Either ceiling marks the pane's footer with a `+`. Raising it lets
# you scroll further into such a file, at proportionally more worker time and
# memory per preview. The name is historical: it once chose which files were
# highlighted on the UI thread, which none are now.
= 256
# Where `dd` sends an entry: trash | permanent.
#
# `trash` hands it to the platform's recycle bin, so a mistake is recoverable by
# the user without Trail's help -- and `dd` on a directory takes everything under
# it, which is exactly the mistake worth being able to undo. The trade-offs are
# that deleting no longer frees the space until the bin is emptied, and that a
# path the recycle bin refuses (a network share, a removable volume without one)
# is reported as an error rather than silently deleted anyway. Use `permanent`
# for the old behaviour, and read the confirmation prompt: it says which one is
# about to happen.
= "trash"
# Show Trail's version on the preview pane's top border.
#
# A diagnostic, not decoration: `trail --version` cannot be asked of a session
# that is already running, and on Windows an upgrade leaves older sessions alive
# on the previous binary -- they cannot be overwritten, only renamed aside -- so
# several windows can be running different builds and look identical. Turn this
# on when that matters; it costs the right-hand end of a border that is drawn
# either way, and it is hidden when a long file name needs the room.
# A dev build reads `v1.10.1-dev.3+f7863b6` (3 commits past v1.10.1, at that
# commit, `.dirty` if built with uncommitted changes) in the git_dirty colour,
# so a build under test is never mistaken for a release.
= false
= true
= 200
[]
# How the listing is ordered: name | size | modified | extension.
#
# `size` puts the largest first and `modified` the most recent first, the way
# `ls -S` and `ls -t` do -- the end of the range you went looking for. `name`
# and `extension` run A-Z. `sort_reverse` flips whichever of those is active.
#
# This seeds the first tab only. Each tab then owns its order, so `ss` in a
# downloads tab does not re-sort the source tree in the next one, and a new tab
# inherits the order of the tab it was opened from.
= "name"
= false
# Group directories ahead of files whatever `sort_by` says. This is an axis of
# its own: `sort_reverse` does not flip it, because reversing a listing is
# asking for the files in the other order, not for the directories to move to
# the bottom. Set false to rank directories among the files -- though note that
# a directory has no meaningful size, so a size sort keeps them in name order
# either way.
= true
# What each row shows beside the name: none | size | modified | both.
#
# The navigation panel is 40% of the screen -- 28 columns on an 80-column
# terminal -- and `both` wants 26 of them, so the column stands down rather than
# crushing names when there is not room for a readable name beside it. On a
# narrow panel `both` first drops the clock time and keeps the date. Default is
# `none`: the name is what you navigate by, and the preview pane already shows
# size and modification time for whatever is selected.
= "none"
# Rows kept between the selection and the top or bottom of the panel while
# scrolling -- vim's `scrolloff`. The margin gives up at the true ends of the
# listing, so the first entry still reaches the top row and the last entry the
# bottom one. 0 lets the selection ride the edge, which shows the least context
# and scrolls the most. A value larger than half the panel keeps the selection
# centred.
= 3
[]
# Inline-image protocol: auto | kitty | iterm2 | sixel | halfblocks | none
= "auto"
# Terminal character cell size in pixels. 0 detects it where the platform will
# say (never on Windows) and otherwise assumes a deliberately small default, so
# that an image errs towards leaving a margin rather than overflowing the pane
# and being dropped by the terminal. Set a real measurement to fill the pane
# exactly: lower these if images overflow, raise them if images look too small.
= 0
= 0
# How many lines of a text file the preview loads. The preview scrolls within
# this window (J/K, Shift-arrows, Ctrl-f/Ctrl-b) and its footer marks a file
# that continues past it with a "+". Raising this lets you scroll further into
# long files, at proportionally more worker time and memory per preview; the
# accepted range is 1 to 100000.
= 2000
[]
# The terminal panel: real, interactive shells under the file list. Ctrl-.
# shows and hides it, F12 moves the keyboard between the file list and the
# shell; `:term new [profile]`, `:term close`, `:term <n>` and `:term max` do
# the rest. Nothing starts until the panel is first opened.
#
# Which profile a new shell runs. Blank means the first [[terminal.profile]],
# or -- with none configured -- PowerShell 7 if installed, else Windows
# PowerShell (on Linux/macOS: $SHELL).
= ""
# The panel's height as a percentage of the screen above the status bar, 10-90.
# A screen too short for both the file list and the panel gives the panel all
# of it. `:term max` fills the screen and restores it.
= 35
# Whether quitting Trail, and `:term close`, ask before ending shells:
# when_busy -- only if a shell is running a command (default). Trail tells by
# whether the shell has child processes; when it cannot tell, it
# asks, rather than risk ending a build.
# always -- every time there is a shell to end.
# never -- end them at once, whatever they are doing.
= "when_busy"
= "when_busy"
# Named shells. `command` is the program and its arguments, run directly (no
# shell parses it, so nothing in it is expanded). For example:
#
# [[terminal.profile]]
# name = "pwsh"
# command = ["pwsh.exe", "-NoLogo"]
#
# [[terminal.profile]]
# name = "gitbash"
# command = ['C:\Program Files\Git\bin\bash.exe', "--login", "-i"]
#
# Listing profiles in your own config replaces this empty list.
= []
[]
= "white"
= "black"
= "dark_gray"
= "black"
= "dark_gray"
= "blue"
= "cyan"
= "dark_gray"
= "dark_gray"
= "red"
= "yellow"
= "cyan"
= "green"
= "yellow"
[]
= "j"
= "k"
= "G"
= "gg"
= "l"
= "h"
= "u"
= "ctrl-r"
# Return from a jump: back to where the last :jump was made from, however far
# you wandered after it landed. u steps back one directory at a time; U skips
# everything since the jump.
= "U"
= "R"
= "."
# Listing order, per tab. `s` is a prefix rather than a binding of its own, so
# the second key picks the field: name, size, time, extension. `sr` flips the
# order and `sd` toggles directory grouping.
= "sn"
= "ss"
= "st"
= "se"
= "sr"
= "sd"
# Step the details column through none -> size -> modified -> both -> none.
= "m"
= "ya"
= "yr"
= "yn"
= "yc"
= "dd"
# Marks survive navigation: mark here, paste somewhere else. Space marks the
# selection and moves down; Esc clears every mark (it does nothing else in
# Navigation Mode, so nothing is lost by giving it this job).
= "space"
= "esc"
# Paste the marked entries into the directory you are looking at. `p` is a
# prefix: pp copies (the marks stay, so the same set can be pasted again), pm
# moves (the moved entries leave the mark set). A name already taken here is
# skipped and reported, never overwritten.
= "pp"
= "pm"
# Visual mode: v anchors a range at the selection, and moving extends it.
# Space or v adds the range to the marks, h/l add it and then navigate, dd
# deletes it, Esc abandons it.
= "v"
# Repeat the last file operation: a : or ! command, or dd, pp or pm, whichever
# came last (a repeated dd still asks). Moving and marking never replace it. @ works
# however your layout types it: Shift+2 on US English, AltGr+Q on Spanish and
# Latin American, AltGr+Q on German.
= "@"
= "/"
= ":"
= "q"
= "o"
= "ctrl-t"
= "ctrl-w"
= "tab"
= "shift-tab"
# Preview pane scrolling. Shift-down and Shift-up are built-in aliases for the
# first two, the same way the plain arrows alias move_down/move_up.
= "J"
= "K"
= "ctrl-f"
= "ctrl-b"
= "shift-home"
= "shift-end"
[]
# Search Mode is a typing mode: unmodified characters go into the query, so
# these must be named or modified keys. Binding a bare letter here is a
# config error -- it would make that letter impossible to search for.
# Ctrl-n / Ctrl-p / Ctrl-h also work as built-in aliases.
= "esc"
= "enter"
= "down"
= "up"
= "backspace"
[]
# The terminal panel's keys. Each is one chord -- ctrl-, alt-, shift- plus a
# character or a key name (f1-f12, pageup, pagedown, home, end, insert, delete,
# enter, esc, tab, space, arrows).
#
# toggle and focus work from anywhere. The other four are taken only while the
# shell has the keyboard, and every key here is one no program in the shell can
# receive -- which is why they avoid everything shells, vim and Windows Terminal
# already use. F12 in particular is used by none of them. The four PageUp /
# PageDown keys carry Alt because terminals keep Ctrl- and Shift-PageUp for
# themselves (WezTerm switches tabs and scrolls its own window with them), so
# Trail would never see them.
= "ctrl-."
= "f12"
= "alt-shift-pagedown"
= "alt-shift-pageup"
= "alt-pageup"
= "alt-pagedown"
[]
= []