gcd now has string similarity metrics
This commit is contained in:
@@ -1,11 +1,15 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import sys,os,re
|
import sys,os,re
|
||||||
|
import difflib as dl
|
||||||
|
|
||||||
|
# Define color codes
|
||||||
Green="\033[32;1m"
|
Green="\033[32;1m"
|
||||||
Red="\033[31;1m"
|
Red="\033[31;1m"
|
||||||
Reset="\033[0m"
|
Reset="\033[0m"
|
||||||
|
# Available shortcut keys
|
||||||
key_list="1234567890qwertyuiop"
|
key_list="1234567890qwertyuiop"
|
||||||
|
|
||||||
class getch:
|
class getch:
|
||||||
def get(self):
|
def get(self):
|
||||||
fd = sys.stdin.fileno()
|
fd = sys.stdin.fileno()
|
||||||
@@ -16,13 +20,30 @@ class getch:
|
|||||||
finally:
|
finally:
|
||||||
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
|
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
|
||||||
return ch
|
return ch
|
||||||
|
|
||||||
def printerr(s):
|
def printerr(s):
|
||||||
sys.stderr.write(s+"\n")
|
sys.stderr.write(s+"\n")
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
def colorize_matches(directories,repl):
|
||||||
|
return [repl.sub("%s\g<1>%s"%(Green,Reset),d) for d in directories]
|
||||||
|
|
||||||
|
def search_close_match(directories, key):
|
||||||
|
""" Return a list of Components whose name closely matches key """
|
||||||
|
match=[]
|
||||||
|
key=key.lower()
|
||||||
|
for name in directories:
|
||||||
|
s=dl.SequenceMatcher(None, name.lower(), key)
|
||||||
|
s_ratio=s.ratio()
|
||||||
|
if s_ratio > 0:
|
||||||
|
match.append(( s_ratio, name ))
|
||||||
|
match.sort(key=lambda x:x[0], reverse=True)
|
||||||
|
best_matches=[x[1] for x in match[0:10]]
|
||||||
|
return best_matches
|
||||||
|
|
||||||
# Print help
|
# Print help
|
||||||
if len(sys.argv)==1 or sys.argv[-1]=="-h":
|
if len(sys.argv)==1 or sys.argv[-1]=="-h":
|
||||||
printerr("Guess cd: Find first match in folder, interactive if multiple matches\n Arguments: [dir/]pattern_to_match_folders")
|
printerr("Guess cd: Find first match in folder, interactive if multiple matches\n Arguments: [dir/]pattern_to_match_folders")
|
||||||
if sys.argv[-1]=="-h":
|
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
pattern=".".join(sys.argv[1:])
|
pattern=".".join(sys.argv[1:])
|
||||||
@@ -35,34 +56,46 @@ if pat_dir=="":
|
|||||||
if not os.path.exists(pat_dir):
|
if not os.path.exists(pat_dir):
|
||||||
printerr("%s: %sNo such folder%s"%(pat_dir,Red,Reset))
|
printerr("%s: %sNo such folder%s"%(pat_dir,Red,Reset))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# list sub-folders in the folder
|
# list sub-folders in the folder
|
||||||
current_folders=[d for d in os.listdir(pat_dir) if os.path.isdir(d)]
|
current_folders=[d for d in os.listdir(pat_dir) if os.path.isdir(os.path.join(pat_dir,d))]
|
||||||
current_folders=[d for d in current_folders if not d.startswith(".")]
|
current_folders=[d for d in current_folders if not d.startswith(".")]
|
||||||
current_folders.sort()
|
current_folders.sort()
|
||||||
|
|
||||||
|
# no sub-folders
|
||||||
|
if len(current_folders)==0:
|
||||||
|
printerr("There are no subfolders in %s"%(pat_dir,))
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
# find matches
|
# find matches
|
||||||
match_case=re.compile(".*"+pat_base+".*")
|
match_case=re.compile(".*"+pat_base+".*")
|
||||||
repl_case=re.compile("("+pat_base+")")
|
repl_case=re.compile("("+pat_base+")")
|
||||||
|
|
||||||
matching_folders=[d for d in current_folders if match_case.match(d)]
|
matching_folders=[d for d in current_folders if match_case.match(d)]
|
||||||
matches=[repl_case.sub("%s\g<1>%s"%(Green,Reset),d) for d in matching_folders]
|
matches=colorize_matches(matching_folders, repl_case)
|
||||||
|
#[repl_case.sub("%s\g<1>%s"%(Green,Reset),d) for d in matching_folders]
|
||||||
|
|
||||||
# no matches, try case insensitive
|
# no matches, try case insensitive
|
||||||
if len(matching_folders)==0:
|
if len(matching_folders)==0:
|
||||||
match_nocase=re.compile(".*"+pat_base+".*",re.I)
|
match_nocase=re.compile(".*"+pat_base+".*",re.I)
|
||||||
repl_nocase=re.compile("("+pat_base+")",re.I)
|
repl_nocase=re.compile("("+pat_base+")",re.I)
|
||||||
matching_folders=[d for d in current_folders if match_nocase.match(d)]
|
matching_folders=[d for d in current_folders if match_nocase.match(d)]
|
||||||
matches=[repl_nocase.sub("%s\g<1>%s"%(Green,Reset),d) for d in matching_folders]
|
matches=colorize_matches(matching_folders, repl_nocase)
|
||||||
|
#matches=[repl_nocase.sub("%s\g<1>%s"%(Green,Reset),d) for d in matching_folders]
|
||||||
|
|
||||||
|
# No matches, try close match
|
||||||
|
if len(matching_folders)==0:
|
||||||
|
matching_folders=search_close_match(current_folders, pat_base)
|
||||||
|
matches=[d for d in matching_folders]
|
||||||
|
print("close")
|
||||||
|
print(matches)
|
||||||
|
|
||||||
# One match, print and return
|
# One match, print and return
|
||||||
if len(matching_folders)==1:
|
if len(matching_folders)==1:
|
||||||
printerr(matches[0])
|
printerr(matches[0])
|
||||||
print(os.path.join(pat_dir,matching_folders[0]))
|
print(os.path.join(pat_dir,matching_folders[0]))
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
# No matches
|
|
||||||
if len(matching_folders)==0:
|
|
||||||
printerr("%sno matches%s"%(Red,Reset))
|
|
||||||
sys.exit(1)
|
|
||||||
# Many matches, ask the user for folder index
|
# Many matches, ask the user for folder index
|
||||||
for i,m in enumerate(matches[0:len(key_list)]):
|
for i,m in enumerate(matches[0:len(key_list)]):
|
||||||
printerr(key_list[i]+": "+m)
|
printerr(key_list[i]+": "+m)
|
||||||
|
|||||||
Reference in New Issue
Block a user