# QuickSearch configuration reference. # # The live config is created at ~/.config/quicksearch/config.toml # (Windows: %APPDATA%\quicksearch\config.toml). A config.toml next to the # quicksearch binary overrides it entirely (portable mode). Relative paths # resolve against the config file's directory, so a portable folder can be # moved wholesale. # # Every key is optional; missing keys take the defaults shown here. [paths] # One or more folders to index; `~` expands to home. No two may be the same # folder or nested one inside the other: indexing pauses until the overlap is # removed. Adding a folder reindexes to pick it up; removing one deletes only # its entries. Order and spelling do not matter: "~/docs", "/home/you/docs" # and "/home/you/docs/" are one folder. indexing_paths = ["~"] # The index file. Default: ~/.local/share/quicksearch/index.sqlite (Windows: # %LOCALAPPDATA%\quicksearch\index.sqlite). Write Windows paths as TOML # literal strings (single quotes), and keep the index out of a roaming # profile: it is far too large to sync. Created if missing and replaced if it # is an index from an older QuickSearch; a SQLite database belonging to # another program is refused with an error, and nothing is deleted. database_path = "~/.local/share/quicksearch/index.sqlite" [indexing] # true = automatic: filesystem watchers apply changes a couple of seconds # after they happen, and a full reindex every reindex_interval_minutes # catches whatever they missed. false = manual: nothing is indexed until you # ask. The Manage Index tab's Stop and Return to Automatic buttons write this, # so the app starts in the mode you left it in. auto_index = true reindex_interval_minutes = 60 # Follow symbolic links, to files and to directories. Off, a link is not # resolved at all, so a target outside every root is never indexed. A # resolved target is stored under its own real path, not the link's. follow_symlinks = false # Index hidden files and directories: dot-files everywhere, plus anything with # the Hidden attribute on Windows (AppData, $RECYCLE.BIN, System Volume # Information ...). The System attribute alone does not count: cloud sync # roots carry it only for a branded folder icon, and are indexed normally. include_hidden = false # Extensions whose text is extracted; empty means every supported format. # Other files are still indexed by name. Case-insensitive, leading dot # optional; "(none)" includes files with no extension (Makefile, README, # .bashrc), which a non-empty list otherwise skips. "#" starts a comment # inside an entry: # content_extensions = ["txt", "md # docs", "# pdf, too slow", "(none)"] # Narrowing drops stored text for newly excluded files; widening extracts the # newly allowed ones. content_extensions = [] # Excluded from the index entirely. A pattern without a separator matches any # single path component (so ".git" prunes whole subtrees); one with a # separator matches full paths. Glob syntax (*, ?, [..]); a name pattern must # match the whole name, so ignoring an extension needs the wildcard ("*.jpg"). # Matching is case-insensitive on Windows and macOS. The Windows defaults add # "$RECYCLE.BIN", "System Volume Information", "pagefile.sys", "hiberfil.sys", # "swapfile.sys", "Thumbs.db" and "desktop.ini"; when indexing a whole Windows # drive, add 'C:\Windows' and 'C:\Windows\WinSxS' by hand. The index's own # files are always skipped. ignore_patterns = [".git", "node_modules", "*.tmp", ".venv", "venv"] # Walker threads per root, keyed by the exact root string from # indexing_paths. Absent or 0 = auto (4 on local storage, 16 on network # mounts, detected per root). Applies from the next run. # root_workers = { "/media/share" = 24 } [processing] # Bytes read from the start of each file to hash it (with its size) for # duplicate detection and to detect its type. Files of equal size with # identical heads are reported as duplicates even if they differ later; # verify on the Duplicates tab before deleting. 8192 is tuned; 16384 is # reasonable, lower is not. Changing it rebuilds the index. Clamped to # 262..1048576. hash_length = 8192 # Most extracted text stored per file (bytes). Clamped to 1..16777216. maximum_text_size = 262144 # Files larger than this skip text extraction entirely (bytes). Clamped to # 1..4294967296. maximum_text_file_size = 52428800 # Rows per database write batch when indexing, reconciling and applying live # changes. batch_size = 500 # Longest one root may hold the index writer per turn (ms), so a root # extracting large documents cannot stall another root's walk. 0 = one batch # per turn. Clamped to 0..10000. writer_turn_slice_ms = 100 # How large the write-ahead log (index.sqlite-wal) may grow during an indexing # run before a checkpoint is forced (bytes). 0 disables the limit; any other # value below 16777216 is raised to it. On a nearly full volume the indexer # checkpoints sooner and stops with an error before the disk fills. # # A checkpoint pauses indexing, so a low value stalls runs; a high one slows # searches that run alongside indexing and lengthens crash recovery. The # default favours faster runs. maximum_wal_size = 2147483648 # FTS5 tokenizer: 'trigram' (substring matching, the default; gets # remove_diacritics 1 appended), 'unicode61', 'porter', or a full FTS5 option # string. See https://www.sqlite.org/fts5.html#tokenizers. Changing it # rebuilds the index. tokenize = "trigram" # Store extracted text (zstd-compressed) alongside the FTS index. Off, the # index shrinks considerably, but search loses snippet previews, occurrence # ranking, case verification and fuzzy full-text. Turning it off discards # the stored text at once; turning it on re-extracts, because the text of # files already indexed was never kept. store_text_for_snippets = true [security] # Encrypt the index with a password (SQLCipher). The password is asked for at # every start; turning this on or off deletes and rebuilds the index. Change # it from the GUI (Settings → Security), not by hand: enabling protection also # generates the KDF salt below. password_protected = false # Store the derived key in the OS keychain (Secret Service / KWallet on Linux, # Credential Manager on Windows) and skip the startup prompt. use_keychain = false # With a password set, the app writes a `salt` value here (32 hex digits). It # is not a secret, but it is unique to your index: do not create or edit it by # hand, and keep it if you copy this file, because the password unlocks the # index only together with its salt. [ui] # Zoom for the whole window (0.5 to 2.5): text, spacing and controls scale # together. Ctrl +/- and Ctrl 0 adjust it until the app closes; this is the # size it starts at. scale = 1.25 # Written by QuickSearch: the folders that have already shown the "more # subfolders than the watcher can follow" warning, so a restart does not # repeat it. Deleting it just brings each warning back once. watch_cap_warned_roots = [] # The shortcut QuickSearch claims while it is running: brings it to the front, # switches to the Search tab and selects the search text. Modifiers are Ctrl, # Alt and Shift, joined to one key with "+"; "" for none. To also start # QuickSearch when it is closed, use "Set up system shortcut" on the Settings # tab, or bind "quicksearch --toggle" in your desktop's keyboard settings. search_hotkey = "Ctrl+Shift+F" # 'dark' or 'light' (anything else means dark); applies as soon as it is # changed on the Settings tab. color_scheme = "dark" # Written by QuickSearch: whether the Settings tab shows the technical # settings (byte budgets, the tokenizer, the database path and the like) # alongside the everyday ones. The checkbox at the top of that tab writes it # at once, without an Apply. show_advanced_settings = false # Written by QuickSearch: whether the introduction shown on a new installation # has been dismissed. Absent means the config predates it, so an upgraded # installation is not offered it. The Help tab can show it again at any time. tutorial_seen = false [search] # Whether the Fuzzy box on the Search tab starts ticked. Off by default: the # fuzzy passes cost noticeable time on every keystroke, and most searches do # not need them. fuzzy_default = false # Most typos the fuzzy stages allow: one edit per three characters of the # search term, up to this value, so 2 means 1 edit for 3-5 character terms # and 2 for longer ones. 0 turns the fuzzy stages off. Above 3 is allowed but # not recommended: matches become coincidence and every fuzzy pass slows. fuzzy_max_edits = 2 # Most results per search (the length of the GUI's list). Clamped to # 1..1000000: at zero every search would return nothing. display_limit = 1000 # Results per streamed batch (a latency knob, not a page size). results_per_page = 100 # How long the GUI waits after the last keystroke before searching (ms). debounce_ms = 150 # Watch the visible results and show renames, deletions and content changes as # they happen. A row's details are read from the file itself, so this works # whether or not indexing is running, and the index is updated for those # files. Editing the query drops the watches. live_results = true # Memory, in MiB, the search connection keeps index pages in, held while # searching and released after a long idle. 0 (recommended) sizes it from the # index: about 168 bytes per indexed file, capped at 128 MiB. # # It matters for an encrypted index, which must decrypt every page the cache # misses (at 600k files: 127 ms per keystroke with too small a cache, 34 ms # with enough). An unencrypted index gets a flat 16 MiB; more measured no # faster. # # Set it by hand only for deeply nested folders (wider rows) or indexes over # ~800k files, where the automatic cap is too low. Clamped to 16..1024. cache_size_mib = 0 # Which columns the Search tab shows; the right-click menu of any column # header and Settings → Search both write here at once, without an Apply. # There is no 'path' key: the path is always shown, because it is the only # column that identifies a result on its own. [search.columns] name = true # The excerpt of a file's contents around the match. Rows that matched on # their name or path show a dash there instead. content_match = true # Off by default: their width is usually better spent on the path and the # matched text. Turning one on also makes it sortable; sorting by a hidden # column falls back to rank. size = false modified = false rank = true # What the Duplicates tab lists. The tab writes both keys itself, from its # exclusion box and its right-click menu. Neither changes what is indexed or # found: a file left out of the listing is still in the index. [duplicates] # Paths left out of the listing. Same syntax and matcher as # indexing.ignore_patterns: a pattern without a separator matches any single # name ("*.iso"), one with a separator matches a whole path and everything # under it ("/home/you/Backups/*"). # # A matching member is not counted, and the group is sized from the copies # left; a group down to one copy is not listed. For a folder meant to hold # copies, this is the key to use. exclude_patterns = [] # Groups dismissed with "Hide this group", for groups that only look like # duplicates, since grouping reads just each file's size and first # processing.hash_length bytes. Stored by content hash (lowercase hex), so a # hidden group stays hidden when its files move and returns if their contents # change. Changing processing.hash_length rebuilds the index and strands these # entries; the tab's Clear button empties the list. hidden_groups = []