Tscout utilizes tree-sitter language grammar dynamic libraries to scout for useful (configurable) identifiers from source files and emits them on standard output.
The dynamic libraries are loaded at runtime so that adding support for new parsers is as trivial as editing a JSON configuration file.
It works on both Windows and Linux. May work on other systems too, but I haven't tested.
2025-12-30.14-35-04-00.00.02.801-00.00.09.399.mp4
2025-12-30.18-56-36-00.00.05.803-00.00.29.194.mp4
This was largely LLM-generated because I don't know Elisp and neither want to.
(defun my/tscout--jump (cand)
(when (string-match
"^\\([^:]+\\):\\([0-9]+\\):\\([0-9]+\\):"
cand)
(let ((file (match-string 1 cand))
(line (string-to-number (match-string 2 cand)))
(col (string-to-number (match-string 3 cand))))
(find-file file)
(goto-char (point-min))
(forward-line (1- line))
(move-to-column (- col 1)))))
(defun my/tscout (&optional dir)
(interactive)
(let* ((default-directory
(or dir
;; Projectile (preferred)
(when (fboundp 'projectile-project-root)
(ignore-errors (projectile-project-root)))
;; project.el fallback
(and (fboundp 'project-current)
(when-let ((proj (project-current)))
(project-root proj)))
default-directory))
(candidates
(process-lines "tscout" "." "-d:-1")))
(unless candidates
(user-error "No tscout results found"))
(my/tscout--jump
(if (fboundp 'consult--read)
(consult--read
candidates
:prompt "tscout: ")
(completing-read
"tscout: "
candidates
nil
t))))){
".odin": {
grammar_dll: "../libtree-sitter-odin.so",
grammar_init: "tree_sitter_odin",
filters: ["procedure_declaration", "struct_declaration", "var_declaration", "const_declaration", "enum_declaration"]
},
".c": {
grammar_dll: "../libtree-sitter-c.so",
grammar_init: "tree_sitter_c",
filters: ["function_declarator", "struct_specifier", "declaration", "type_definition", "enum_specifier", "preproc_def", "preproc_function_def"]
},
".h": {
grammar_dll: "../libtree-sitter-c.so",
grammar_init: "tree_sitter_c",
filters: ["function_declarator", "struct_specifier", "declaration", "type_definition", "enum_specifier", "preproc_def", "preproc_function_def"]
}
}grammar_dll: The path to the parser compiled as a dynamic library. Can be relative or absolute.grammar_init: The function symbol that gets called to initialize the parser.filters: List of strings where each is the node type of the immediate parent of an identifier. This list will be used to filter for useful identifiers.
Important
The current working directory is not used. This may be implemented as an optional flag in the future.
By default it looks for the configuration file config.json5 at the directory
where the tscout executable resides. Use -c flag to override it.
Tip
Learn about JSON5: https://json5.org
Relative paths are joined with the directory where the tscout executable
resides. Use absolute paths to avoid that if necessary.
Tscout has officially only been tested on Linux and Windows AMD64 system.
You can download prebuilt binaries from Github Releases. Platforms included:
- Linux AMD64
- Windows AMD64
Tscout was developed using the Odin programming language.
git clone --recurse-submodules https://github.com/eeriemyxi/tscout
cd tscout
make
bin/tscout -helpHelp: tscout -help
Usage:
tscout [i] [-c] [-d] [-f] [-l] [-v]
Flags:
-i:<string> | Input file or directory
|
-c:<string> | Override config path
-d:<int> | Directory traversal depth. 1 by default. -1 for infinite
-f | Include full text for each match
-l:<Logger_Level> | Set log level. Info by default. Options: Debug, Info, Warning, Error, Fatal
-v | Show version info