diff --git a/foldermenu.py b/foldermenu.py new file mode 100755 index 0000000..5af296d --- /dev/null +++ b/foldermenu.py @@ -0,0 +1,201 @@ +#!/usr/bin/python + +import os +import sys +import subprocess +import termios +import tty +import readline +import math + +readline.parse_and_bind('tab: complete') +readline.parse_and_bind('set editing-mode vi') + +MENUFILE='.foldermenu' + +def termsize(): + rows, columns = os.popen('stty size', 'r').read().split() + return (int(rows),int(columns)) + +class bc: + MAG = '\033[95m' + BLU = '\033[94m' + GRE = '\033[92m' + YEL = '\033[93m' + RED = '\033[91m' + CYA = '\033[96m' + WHI = '\033[1m' + END = '\033[0m' + CLR = '\033[2J' + + def disable(self): + self.MAG = '' + self.BLU = '' + self.GRE = '' + self.YEL = '' + self.RED = '' + self.END = '' + self.CLR = '' + self.CYA = '' + self.WHI = '' + + def pos(self,y,x): + return "\033["+str(y)+";"+str(x)+"H" + +class getch: + def __init__(self): + import sys, tty, termios + + def get(self): + + fd = sys.stdin.fileno() + old_settings = termios.tcgetattr(fd) + try: + tty.setraw(sys.stdin.fileno()) + ch = sys.stdin.read(1) + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + return ch + +def read_menu(): + ''' Read ''' + entries=[] + if os.path.exists(MENUFILE): + f=file(MENUFILE,'r') + for row in f: + if row.strip()=='': + continue + if row[0]=='#': + continue + row=row.strip().split(':',1) + if len(row)==1: + row=[row[0], row[0]] + else: + row=[row[0].strip()+' ('+row[1]+')', row[1]] + entries.append(row) + return entries + +def read_folder(): + ''' Read ''' + + executables=[] + for f in os.listdir('.'): + if os.path.isfile(f): + if os.access(f,os.X_OK): + executables.append([f,f]) + executables.sort(key=lambda x: x[0]) + + return executables + +def print_help(): + if not os.path.exists(MENUFILE): + print('Consider having a '+MENUFILE+' file containing shell commands / line.') + print('Command may be of format "My Description: my_command" or simply "my_command -switch"') + + +def ichr(i): + ''' convert integer to 1-9, a-z, A-Z, omitting x ''' + + if i < 10: + return str(i) + i=i + 87 + if i>119: + i=i+1 + if i>122: + i=i-122+64 + return chr(i) + +def drawmenu(entries,args=""): + maxrows,maxcolumns = termsize() + maxrows-=5 + maxcolumns-=10 + twocol=False + co=bc() + print(co.CLR+co.pos(1,3)+co.YEL+'FolderMenu x:exit -:args ('+co.END+args+co.YEL+')'+co.END) + if len(entries)>10: + twocol=True + maxrows=int(math.ceil(min(maxrows/2.0, len(entries)/2.0))) + maxcolumns=int(math.ceil(maxcolumns/2.0)) + + r=1 + for e in range(len(entries)): + if r>maxrows: + break + printline=entries[e][1] + if len(printline)>maxcolumns: + printline=printline[:maxcolumns]+"..." + print(co.WHI+entries[e][0]+co.END+' '+entries[e][3]+printline+co.END) + r=1+r + if twocol: + r=1 + for e in range(e,len(entries)): + if r>maxrows: + break + printline=entries[e][1] + if len(printline)>maxcolumns: + printline=printline[:maxcolumns]+"..." + print(co.pos(r+1,maxcolumns)+'| '+co.WHI+entries[e][0]+co.END+' '+entries[e][3]+printline+co.END) + r=1+r + print(co.pos(maxrows+2,0)) + + +def append_index(entries,offset=0,color=None,x=False): + e=1+offset + for el in range(len(entries)): + entries[el]=[ichr(e), entries[el][0], entries[el][1], color,x] + e=e+1 + return entries + +def launch(key,entries,args=""): + ''' launch the given program ''' + bg=False + idx=[i for i in range(len(entries)) if entries[i][0]==key][0] + command_str=entries[idx][2] + if command_str[-1]=='&': + command_str=command_str[:-1] + bg=True + if len(args)>0: + command_str=command_str+" "+args + if entries[idx][4]: + command_str='./'+command_str + try: + print('#$ '+command_str) + if bg: + subprocess.Popen(command_str, stderr=subprocess.PIPE, shell=True) + else: + subprocess.call(command_str, stderr=subprocess.STDOUT, shell=True) + except: + print('Unable to run: "'+command_str+'"') + + print('Press any key...') + ch=getch() + inkey=ord(ch.get()) + + +def main(): + entries=read_menu() + entries=append_index(entries, color=bc.CYA) + execs=read_folder() + execs=append_index(execs, offset=len(entries), color=bc.GRE,x=True) + entries.extend(execs) + ch=getch() + args="" + drawmenu(entries,args) + while True: + inkey=ord(ch.get()) + #print('-'+str((inkey))+'-') + if inkey in [120,27,3,24,4]: + print_help() + sys.exit(0) + if inkey==45: + readline.set_startup_hook(lambda: readline.insert_text(args)) + args=raw_input('args: ') + readline.set_startup_hook(None) + if chr(inkey) in [x[0] for x in entries]: + launch(chr(inkey),entries,args) + + drawmenu(entries,args) + +main() + +