├── README.md └── incresearch.py /README.md: -------------------------------------------------------------------------------- 1 | #incresearch 2 | Search as you type. A frontend over egrep. 3 | 4 | python incresearch.py 5 | -------------------------------------------------------------------------------- /incresearch.py: -------------------------------------------------------------------------------- 1 | import os 2 | import tty 3 | import select 4 | import sys 5 | import termios 6 | import signal 7 | 8 | from sh import egrep 9 | 10 | # TODO Proper encapsulation 11 | 12 | 13 | class Interact(object): 14 | def __init__(self): 15 | self.count = 0 16 | self.muted = False 17 | self.limit = 0 18 | 19 | def __call__(self, line, stdin, process): 20 | if self.limit > 0 and self.count >= self.limit: 21 | process.kill() 22 | self.count = 0 23 | print 24 | else: 25 | self.count += 1 26 | if not self.muted: 27 | print line, 28 | else: 29 | process.kill() 30 | self.count = 0 31 | print 32 | 33 | def mute(self): 34 | self.muted = True 35 | 36 | 37 | class TermSearch(object): 38 | def __init__(self, path): 39 | self.s = '' 40 | self.old_settings = termios.tcgetattr(sys.stdin) 41 | self.old = None 42 | self.path = path 43 | 44 | def escape(self, s): 45 | escape_chars = ['(', ')', '.'] 46 | 47 | for c in escape_chars: 48 | return s.replace(c, '\\' + c) 49 | 50 | return s 51 | 52 | def start(self): 53 | try: 54 | tty.setcbreak(sys.stdin.fileno()) 55 | while True: 56 | if self.isData(): 57 | c = sys.stdin.read(1) 58 | self.s += c 59 | if c == '\x0A': # Return 60 | continue; 61 | if c == '\x7f': # Backspace 62 | self.s = self.s[:-2] 63 | 64 | if self.s != '': 65 | n = Interact() 66 | egrep( 67 | # Recursive 68 | "-R", 69 | # Case insensitive 70 | "-i", 71 | # Prefix line number 72 | "-n", 73 | # Ignore binary 74 | "-I", 75 | # Max 3 results per file 76 | "-m", 3, 77 | # 2 lines of context 78 | "-C", 2, 79 | # Only list files 80 | "-l", 81 | self.escape(self.s), self.path, _bg=True, _out=n) 82 | if self.old is not None: 83 | self.old.mute() 84 | print 85 | print '-----------------------------------------' 86 | print self.s 87 | self.old = n 88 | 89 | finally: 90 | termios.tcsetattr(sys.stdin, termios.TCSADRAIN, self.old_settings) 91 | 92 | def isData(self): 93 | return select.select([sys.stdin], [], [], 250) == ([sys.stdin], [], []) 94 | 95 | if __name__ == '__main__': 96 | def signal_handler(signal, frame): 97 | sys.exit(0) 98 | 99 | signal.signal(signal.SIGINT, signal_handler) 100 | if len(sys.argv) == 2: 101 | TermSearch(sys.argv[1]).start() 102 | else: 103 | TermSearch().start() 104 | 105 | --------------------------------------------------------------------------------