o
odinpkg.dev
packages / library / tscout

tscout

v0.2.0library

Use tree-sitter parsers to emit locations of useful identifiers in source code

MIT · updated 6 months ago

Tscout

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.

Demo

2025-12-30.14-35-04-00.00.02.801-00.00.09.399.mp4

Emacs

2025-12-30.18-56-36-00.00.05.803-00.00.29.194.mp4

Configuration

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)))))

Example Configuration

{
  ".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.

Installation

Tscout has officially only been tested on Linux and Windows AMD64 system.

Prebuilt Binaries

You can download prebuilt binaries from Github Releases. Platforms included:

  • Linux AMD64
  • Windows AMD64

Compile from Source

Tscout was developed using the Odin programming language.

git clone --recurse-submodules https://github.com/eeriemyxi/tscout
cd tscout
make
bin/tscout -help

Command-line Arguments

Help: 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