mirror of
https://github.com/wting/autojump
synced 2024-10-27 20:34:07 +00:00
finish tab completion
This commit is contained in:
parent
71861c4402
commit
0422d23a86
49
bin/autojump
49
bin/autojump
@ -45,12 +45,16 @@ from data import save
|
|||||||
from utils import decode
|
from utils import decode
|
||||||
from utils import encode_local
|
from utils import encode_local
|
||||||
from utils import first
|
from utils import first
|
||||||
|
from utils import get_needle_and_index
|
||||||
from utils import get_pwd
|
from utils import get_pwd
|
||||||
from utils import has_uppercase
|
from utils import has_uppercase
|
||||||
from utils import is_osx
|
from utils import is_osx
|
||||||
|
from utils import is_tab_entry
|
||||||
|
from utils import is_tab_partial_match
|
||||||
from utils import last
|
from utils import last
|
||||||
from utils import print_entry
|
from utils import print_entry
|
||||||
from utils import print_tab_completion_menu
|
from utils import print_tab_menu
|
||||||
|
from utils import sanitize
|
||||||
from utils import second
|
from utils import second
|
||||||
from utils import surround_quotes
|
from utils import surround_quotes
|
||||||
from utils import take
|
from utils import take
|
||||||
@ -58,11 +62,11 @@ from utils import take
|
|||||||
VERSION = 'release-v21.8.0'
|
VERSION = 'release-v21.8.0'
|
||||||
FUZZY_MATCH_THRESHOLD = 0.6
|
FUZZY_MATCH_THRESHOLD = 0.6
|
||||||
TAB_COMPLETION_COUNT = 9
|
TAB_COMPLETION_COUNT = 9
|
||||||
|
TAB_SEPARATOR = '__'
|
||||||
|
|
||||||
|
|
||||||
def set_defaults():
|
def set_defaults():
|
||||||
config = {}
|
config = {}
|
||||||
config['tab_menu_separator'] = '__'
|
|
||||||
|
|
||||||
if is_osx():
|
if is_osx():
|
||||||
data_home = os.path.join(
|
data_home = os.path.join(
|
||||||
@ -170,8 +174,6 @@ def find_matches(entries, needles):
|
|||||||
if not needles:
|
if not needles:
|
||||||
return first(data).path
|
return first(data).path
|
||||||
|
|
||||||
sanitize = lambda x: decode(x).rstrip(os.sep)
|
|
||||||
needles = map(sanitize, needles)
|
|
||||||
ignore_case = detect_smartcase(needles)
|
ignore_case = detect_smartcase(needles)
|
||||||
|
|
||||||
exists = lambda entry: os.path.exists(entry.path)
|
exists = lambda entry: os.path.exists(entry.path)
|
||||||
@ -318,11 +320,11 @@ def main():
|
|||||||
if args.add:
|
if args.add:
|
||||||
save(config, first(add_path(load(config), args.add)))
|
save(config, first(add_path(load(config), args.add)))
|
||||||
elif args.complete:
|
elif args.complete:
|
||||||
print_tab_completion_menu(
|
needle = first(sanitize(args.directory))
|
||||||
separator=config['tab_menu_separator'],
|
tab_entries = take(
|
||||||
entries=take(
|
TAB_COMPLETION_COUNT,
|
||||||
TAB_COMPLETION_COUNT,
|
find_matches(entriefy(load(config)), needle))
|
||||||
find_matches(entriefy(load(config)), args.directory)))
|
print_tab_menu(needle, tab_entries, TAB_SEPARATOR)
|
||||||
elif args.decrease:
|
elif args.decrease:
|
||||||
data, entry = decrease_path(load(config), get_pwd(), args.decrease)
|
data, entry = decrease_path(load(config), get_pwd(), args.decrease)
|
||||||
save(config, data)
|
save(config, data)
|
||||||
@ -340,14 +342,31 @@ def main():
|
|||||||
print_stats(load(config), config['data_path'])
|
print_stats(load(config), config['data_path'])
|
||||||
else:
|
else:
|
||||||
# default behavior, no optional arguments
|
# default behavior, no optional arguments
|
||||||
result = first(find_matches(entriefy(load(config)), args.directory))
|
entries = entriefy(load(config))
|
||||||
|
needles = sanitize(args.directory)
|
||||||
|
needle = first(needles)
|
||||||
|
|
||||||
if result:
|
if is_tab_entry(needle, TAB_SEPARATOR):
|
||||||
print(encode_local(surround_quotes(result.path)))
|
# the needle is actually a tab entry here
|
||||||
|
needle, tab_index = get_needle_and_index(needle, TAB_SEPARATOR)
|
||||||
|
tab_entries = take(
|
||||||
|
TAB_COMPLETION_COUNT,
|
||||||
|
find_matches(entries, needle))
|
||||||
|
|
||||||
|
get_ith_path = lambda i, iterable: last(take(i, iterable)).path
|
||||||
|
print(encode_local(surround_quotes(
|
||||||
|
get_ith_path(tab_index, tab_entries))))
|
||||||
|
elif is_tab_partial_match(needle, TAB_SEPARATOR):
|
||||||
|
print("tab_partial_match")
|
||||||
else:
|
else:
|
||||||
# always return something so the calling shell function has an
|
result = first(find_matches(entries, needles))
|
||||||
# argument to `cd` to
|
|
||||||
print(encode_local('.'))
|
if result:
|
||||||
|
print(encode_local(surround_quotes(result.path)))
|
||||||
|
else:
|
||||||
|
# always return something so the calling shell function has an
|
||||||
|
# argument to `cd` to
|
||||||
|
print(encode_local('.'))
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
56
bin/utils.py
56
bin/utils.py
@ -8,6 +8,7 @@ import errno
|
|||||||
from itertools import islice
|
from itertools import islice
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import unicodedata
|
import unicodedata
|
||||||
@ -51,6 +52,21 @@ def first(xs):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_needle_and_index(tab_entry, separator):
|
||||||
|
"""
|
||||||
|
Given a tab entry in the following format return the needle and index:
|
||||||
|
|
||||||
|
[needle]__[index]__[possible_match]
|
||||||
|
"""
|
||||||
|
matches = re.search(
|
||||||
|
r'(.*)' + \
|
||||||
|
separator + \
|
||||||
|
r'([0-9]{1})' + \
|
||||||
|
separator, tab_entry)
|
||||||
|
return matches.group(1), int(matches.group(2))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_pwd():
|
def get_pwd():
|
||||||
try:
|
try:
|
||||||
return os.getcwdu()
|
return os.getcwdu()
|
||||||
@ -79,6 +95,24 @@ def is_osx():
|
|||||||
return platform.system() == 'Darwin'
|
return platform.system() == 'Darwin'
|
||||||
|
|
||||||
|
|
||||||
|
def is_tab_entry(needle, separator):
|
||||||
|
"""
|
||||||
|
Valid tab entry:
|
||||||
|
|
||||||
|
[needle]__[index]__[possible_match]
|
||||||
|
"""
|
||||||
|
pattern = re.compile(
|
||||||
|
'.*' + \
|
||||||
|
separator + \
|
||||||
|
'[0-9]{1}' + \
|
||||||
|
separator)
|
||||||
|
return re.search(pattern, needle)
|
||||||
|
|
||||||
|
|
||||||
|
def is_tab_partial_match(needle, separator):
|
||||||
|
return re.match(r'(.*)'+separator, needle)
|
||||||
|
|
||||||
|
|
||||||
def is_windows():
|
def is_windows():
|
||||||
return platform.system() == 'Windows'
|
return platform.system() == 'Windows'
|
||||||
|
|
||||||
@ -110,16 +144,30 @@ def print_entry(entry):
|
|||||||
print(encode_local("%.1f:\t%s" % (entry.weight, entry.path)))
|
print(encode_local("%.1f:\t%s" % (entry.weight, entry.path)))
|
||||||
|
|
||||||
|
|
||||||
def print_tab_completion_menu(separator, entries):
|
def print_tab_menu(needle, tab_entries, separator):
|
||||||
for i, entry in enumerate(entries):
|
"""
|
||||||
|
Prints the tab completion menu according to the following format:
|
||||||
|
|
||||||
|
[needle]__[index]__[possible_match]
|
||||||
|
|
||||||
|
The needle (search pattern) and index are necessary to recreate the results
|
||||||
|
on subsequent calls.
|
||||||
|
"""
|
||||||
|
for i, entry in enumerate(tab_entries):
|
||||||
print(encode_local(surround_quotes(
|
print(encode_local(surround_quotes(
|
||||||
'%s%d%s%s' % (
|
'%s%s%d%s%s' % (
|
||||||
|
needle,
|
||||||
separator,
|
separator,
|
||||||
i,
|
i+1,
|
||||||
separator,
|
separator,
|
||||||
entry.path))))
|
entry.path))))
|
||||||
|
|
||||||
|
|
||||||
|
def sanitize(directories):
|
||||||
|
clean = lambda x: decode(x).rstrip(os.sep)
|
||||||
|
return map(clean, directories)
|
||||||
|
|
||||||
|
|
||||||
def second(xs):
|
def second(xs):
|
||||||
it = iter(xs)
|
it = iter(xs)
|
||||||
try:
|
try:
|
||||||
|
Loading…
Reference in New Issue
Block a user