Skip to content

exlee/ssort

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ssort is a utility designed to buffer, filter, and prioritize text streams. It allows specific matches to bypass the queue immediately while buffering other lines to be sorted and flushed periodically or upon reaching a limit.

It is particularly useful when piping output from tools like ripgrep, fd, GNU Global, or similar tools, where you want specific results (like definitions or exact matches) to appear at the top of the output, regardless of when the search tool found them.

Installation

go install github.com/exlee/ssort@latest

Usage

Direct CLI Usage

You can use ssort as a direct pipe filter. Use the -f flag to define comma-separated priority strings.

Example: Search for "foo" but ensure lines containing "Important" or "Error" appear first.

rg "foo" | ssort -f "Important,Error" --limit 20

or...

ssort -e 'rg "foo"' -f "Important,Error" --limit 20

Semi-scripted / Config Usage

For repeated tasks, such as finding specific language constructs (e.g., Rust structs or Elixir modules), you can define a filter file.

The filter file format supports:

  1. Comments: Lines starting with #.
  2. Arguments: The first non-comment line (if it starts with - or whitespace) is parsed as CLI arguments. This supports multi-line definitions using \ at the end of the line.
  3. Filters: Subsequent lines are treated as priority buckets (top = highest priority).

Example: Elixir Module Finder (elixir_def.txt)

# Configuration line: keep going without sorting remainder, match word boundaries, enable color
-k -w --color \
--limit 50

# Priority Filters
defmodule
defp
def

Execution:

# Pipe into ssort
rg "User" | ssort elixir_def.txt

# Or use the built-in executor (-e) which supports env expansion
ssort -e "rg --color=always User" elixir_def.txt

Example: Rust Implementation Finder

# config
-w --color

# priorities
struct
impl
pub fn
fn

Flags

  • -f: Comma-separated list of prioritized strings (overridden by file filters if provided).
  • -o: Output only matching results.
  • -k, --keep-going: Output unsorted (unmatched) lines immediately instead of buffering them.
  • --limit: Flush buffer after N prioritized matches are found.
  • --timeout: Flush timeout (default 500ms).
  • --color: Enable color-aware mode (strips ANSI codes for sorting/filtering logic while preserving them in output).
  • -w: Match on word boundaries only.
  • -e: Execute a command and sort its output (supports ~/ and $VAR expansion).

Production Notes

This utility is something I wanted for a while but never got around to writing until I came down with the flu. I decided to try "easy mode" using Google Gemini (Pro version).

  • Development Time: ~5 hours (3h initial implementation, 2h grooming for release).
  • Design: Design was fully fed to Gemini including channel handling, edge cases (color handling, huge lines) and configuration file syntax
  • Code Split: Approximately 80% generated by Gemini, 20% manual implementation. Ratio shrunk to 60:40, test cases had to be written by hand and some annoying bugs surfaced.
  • Manual Logic: While the AI handled the boilerplate well, I had to implement the channel synchronization and result counting/limiting logic by hand, as the model struggled to get the concurrency correct.
  • Quirks: During generation, Gemini bugged out a few times and attempted to rewrite the entire tool into Python or a single React component, or tried to teach me Markdown for some reason.
  • Documentation: This readme was generated because I dislike writing them. It captures the "vibe" of the development process.

Future Ideas

Not sure, feels complete, but maybe:

  • with config files it'd be nice to have a "template" of some sort, so that -e flag could include printf-like string and ssort -t my_tool.txt QUERY would put QUERY inside - allowing for aliasing of rapid targeted searchers
  • per-value word boundary
  • regex support (unlikely though, as it would require ranking match value against regex, which might be plainly impossible to do)
  • magic values (e.g. \sH for either tab or space)

About me: xlii.space

About

Stream Sorter Utility

Resources

License

Stars

Watchers

Forks

Packages

No packages published