Efficient directory scan + search utilities

View the Project on GitHub atom/scandal

scandal - Scandalous directory scanning and searching

Build Status

scandal provides two utilities:

Unsurprisingly, these two things can be combined to scan and search a directory.


It is written to be simple, flexible and efficient. Scandal does the minimum.

We want to provide modules to combine in any way you'd like. Want to scan in one process and search in another? You can do that.

To be clear, scandal is not a CLI. It can be used from the terminal, but in practice it's only used for benchmarking.


scandal provides two main modules: PathScanner and PathSearcher.


Usage is simple:

{PathScanner} = require 'scandal'
scanner = new PathScanner('/Users/me/myDopeProject', options)

scanner.on 'path-found', (path) ->

scanner.on 'finished-scanning', ->
  console.log('All done!')


PathScanner keeps no state. You must consume paths via the 'path-found' event.



{PathSearcher} = require 'scandal'
searcher = new PathSearcher()

# You can subscribe to a `results-found` event
searcher.on 'results-found', (result) ->
  # result will contain all the matches for a single path
  console.log("Single Path's Results", result)

# Search a list of paths
searcher.searchPaths /text/gi, ['/Some/path', ...], (results) ->
  console.log('Done Searching', results)

# Search a single path
searcher.searchPath /text/gi, '/Some/path', (result) ->
  console.log('Done Searching', result)

Results from line 10 (1 based) are in the following format.

  "path": "/Some/path",
  "matches": {
    "matchText": "Text",
    "lineText": "Text in this file!",
    "lineTextOffset": 0,
    "range": [[9, 0], [9, 4]]

Like the PathScanner the searcher keeps no state. You need to consume results via the done callbacks or event.

File reading is fast and memory efficient. It reads in 10k chunks and writes over each previous chunk. Small object creation is kept to a minimum during the read to make light use of the GC.


A third object, PathFilter is available, but intended for use by the PathScanner.

Using the scanner and searcher together

If you dont want to think about combining the PathScanner and PathSearcher in your own way, a search is function provided.

{search, PathScanner, PathSearcher} = require 'scandal'

path = '/path/to/search'
scanner = new PathScanner(path, excludeVcsIgnores: true)
searcher = new PathSearcher()

searcher.on 'results-found' (result) ->
  # do something rad with the result!

name = "Search #{path}"
console.time name
console.log name
search /text/ig, scanner, searcher, ->
  console.timeEnd name