Skip to content

Instantly share code, notes, and snippets.

@highfestiva
Last active April 7, 2021 17:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save highfestiva/2ed973e63f6331d2e60f259c27bd5973 to your computer and use it in GitHub Desktop.
Save highfestiva/2ed973e63f6331d2e60f259c27bd5973 to your computer and use it in GitHub Desktop.
A fast grep-like cli tool, which skips the usual suspects. (My first vlang experiment.)
import os
import os.cmdline
const (
exclude_dirs = map{
'.git': 1
'.svn': 1
'__pycache__': 1
}
exclude_exts = map{
'exe': 1
'bin': 1
'png': 1
'jpg': 1
'bmp': 1
'gif': 1
'tga': 1
'ppm': 1
'ico': 1
'icns': 1
'psd': 1
'wav': 1
'ogg': 1
'vorbis': 1
'webm': 1
'mp3': 1
'm4a': 1
'ttf': 1
'afm': 1
'eot': 1
'zip': 1
'7z': 1
'gz': 1
'jar': 1
'pyc': 1
'pyo': 1
'pyd': 1
'whl': 1
'class': 1
'war': 1
'dll': 1
'so': 1
'obj': 1
'a': 1
'pch': 1
'pdb': 1
'ilk': 1
'suo': 1
}
maxfilesize = 1024 * 1024
)
struct File {
fullname string
filename string
}
fn search_file(ch chan File, what string, ignore_case bool) {
for {
file := <-ch
filename := file.filename
fullname := file.fullname
if fullname.len == 0 {
break
}
ext := os.file_ext(filename).to_lower()
if ext.len == 0 || ext[1..] in exclude_exts {
continue
}
if os.file_size(fullname) > maxfilesize {
continue
}
s := os.read_file(fullname) or { '' }
w := match ignore_case {
true { s.to_lower() }
else { s }
}
mut idx := 0
for {
idx = w.index_after(what, idx)
if idx < 0 {
break
}
i0 := match idx - 20 < 0 {
true { 0 }
else { idx - 20 }
}
i1 := match idx + what.len + 20 > s.len {
true { s.len }
else { idx + what.len + 20 }
}
hit := s[i0..i1].split_into_lines().join(' ')
println('$fullname \t $hit')
idx++
}
}
}
fn handle_ls(path string, filenames []string, ch chan File) {
for filename in filenames {
fullname := path + '/' + filename
if os.is_dir(fullname) {
if filename !in exclude_dirs {
handle_ls(fullname, os.ls(fullname) or { panic('NO!!!') }, ch)
}
} else {
ch <- File{fullname, filename}
}
}
}
fn main() {
opts := cmdline.option(os.args, '-i', '')
ignore_case := opts.len > 0
search := cmdline.only_non_options(os.args[1..]).join(' ')
what := match ignore_case {
true { search.to_lower() }
else { search }
}
ch := chan File{}
mut threads := []thread{}
for _ in 0..2 {
threads << go search_file(ch, what, ignore_case)
}
handle_ls('.', os.ls('.') or { panic('NO!!!') }, ch)
for _ in 0..2 {
ch <- File{'', ''}
}
threads.wait()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment