pull/534/merge
Mitchell Ludwig 8 months ago committed by GitHub
commit 2bee71df0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

1
.gitignore vendored

@ -8,3 +8,4 @@ __pycache__
.pytest_cache
.tox
tags
.idea/

@ -1,17 +1,15 @@
language: python
python: 2.7
env:
- TOX_ENV=py26
- TOX_ENV=py27
- TOX_ENV=py32
- TOX_ENV=py33
- TOX_ENV=py34
- TOX_ENV=flake8
python:
- 2.7
- 3.3
- 3.4
- 3.5
- 3.6
install:
- pip install tox
- pip install mock coverage ipdb ipython pytest pre-commit autopep8 flake8
script:
- tox -e $TOX_ENV
- coverage run --source=bin/ --omit=bin/autojump_argparse.py -m py.test -vv -rxs --tb native -s --strict
- coverage report -m

@ -26,6 +26,8 @@ from itertools import chain
from math import sqrt
from operator import attrgetter
from operator import itemgetter
from sys import stderr
import re
if sys.version_info[0] == 3:
ifilter = filter
@ -65,73 +67,39 @@ from autojump_utils import sanitize
from autojump_utils import take
from autojump_utils import unico
VERSION = '22.5.3'
VERSION = "22.5.3"
FUZZY_MATCH_THRESHOLD = 0.6
TAB_ENTRIES_COUNT = 9
TAB_SEPARATOR = '__'
TAB_SEPARATOR = "__"
def set_defaults():
config = {}
if is_osx():
data_home = os.path.join(os.path.expanduser('~'), 'Library')
data_home = os.path.join(os.path.expanduser("~"), "Library")
elif is_windows():
data_home = os.getenv('APPDATA')
data_home = os.getenv("APPDATA")
else:
data_home = os.getenv(
'XDG_DATA_HOME',
os.path.join(
os.path.expanduser('~'),
'.local',
'share',
),
)
config['data_path'] = os.path.join(data_home, 'autojump', 'autojump.txt')
config['backup_path'] = os.path.join(data_home, 'autojump', 'autojump.txt.bak')
data_home = os.getenv("XDG_DATA_HOME", os.path.join(os.path.expanduser("~"), ".local", "share"))
config["data_path"] = os.path.join(data_home, "autojump", "autojump.txt")
config["backup_path"] = os.path.join(data_home, "autojump", "autojump.txt.bak")
return config
def parse_arguments():
parser = ArgumentParser(
description='Automatically jump to directory passed as an argument.',
epilog='Please see autojump(1) man pages for full documentation.',
)
parser.add_argument(
'directory', metavar='DIRECTORY', nargs='*', default='',
help='directory to jump to',
)
parser.add_argument(
'-a', '--add', metavar='DIRECTORY',
help='add path',
)
parser.add_argument(
'-i', '--increase', metavar='WEIGHT', nargs='?', type=int,
const=10, default=False,
help='increase current directory weight',
)
parser.add_argument(
'-d', '--decrease', metavar='WEIGHT', nargs='?', type=int,
const=15, default=False,
help='decrease current directory weight',
)
parser.add_argument(
'--complete', action='store_true', default=False,
help='used for tab completion',
)
parser.add_argument(
'--purge', action='store_true', default=False,
help='remove non-existent paths from database',
)
parser.add_argument(
'-s', '--stat', action='store_true', default=False,
help='show database entries and their key weights',
)
parser.add_argument(
'-v', '--version', action='version', version='%(prog)s v' +
VERSION, help='show version information',
description="Automatically jump to directory passed as an argument.", epilog="Please see autojump(1) man pages for full documentation."
)
parser.add_argument("directory", metavar="DIRECTORY", nargs="*", default="", help="directory to jump to")
parser.add_argument("-a", "--add", metavar="DIRECTORY", help="add path")
parser.add_argument("-i", "--increase", metavar="WEIGHT", nargs="?", type=int, const=10, default=False, help="increase current directory weight")
parser.add_argument("-d", "--decrease", metavar="WEIGHT", nargs="?", type=int, const=15, default=False, help="decrease current directory weight")
parser.add_argument("--complete", action="store_true", default=False, help="used for tab completion")
parser.add_argument("--purge", action="store_true", default=False, help="remove non-existent paths from database")
parser.add_argument("-s", "--stat", action="store_true", default=False, help="show database entries and their key weights")
parser.add_argument("-v", "--version", action="version", version="%(prog)s v" + VERSION, help="show version information")
return parser.parse_args()
@ -145,12 +113,13 @@ def add_path(data, path, weight=10):
path.
"""
path = unico(path).rstrip(os.sep)
if path == os.path.expanduser('~'):
if path == os.path.expanduser("~"):
return data, Entry(path, 0)
slash_only_path = re.sub(re.escape(os.sep), "/", path)
orig_weight = data.get(slash_only_path, 0)
data[slash_only_path] = sqrt((orig_weight ** 2) + (weight ** 2))
data[path] = sqrt((data.get(path, 0) ** 2) + (weight ** 2))
return data, Entry(path, data[path])
return data, Entry(path, data[slash_only_path])
def decrease_path(data, path, weight=15):
@ -171,7 +140,7 @@ def detect_smartcase(needles):
def find_matches(entries, needles, check_entries=True):
"""Return an iterator to matching entries."""
# TODO(wting|2014-02-24): replace assertion with unit test
assert isinstance(needles, list), 'Needles must be a list.'
assert isinstance(needles, list), "Needles must be a list."
ignore_case = detect_smartcase(needles)
try:
@ -188,19 +157,11 @@ def find_matches(entries, needles, check_entries=True):
else:
path_exists = lambda _: True
data = sorted(
entries,
key=attrgetter('weight', 'path'),
reverse=True,
)
data = sorted(entries, key=attrgetter("weight", "path"), reverse=True)
return ifilter(
lambda entry: not is_cwd(entry) and path_exists(entry),
chain(
match_consecutive(needles, data, ignore_case),
match_fuzzy(needles, data, ignore_case),
match_anywhere(needles, data, ignore_case),
),
chain(match_consecutive(needles, data, ignore_case), match_fuzzy(needles, data, ignore_case), match_anywhere(needles, data, ignore_case)),
)
@ -211,35 +172,12 @@ def handle_tab_completion(needle, entries):
print_local(tab_path)
elif tab_index:
get_ith_path = lambda i, iterable: last(take(i, iterable)).path
print_local(get_ith_path(
tab_index,
find_matches(entries, [tab_needle], check_entries=False),
))
print_local(get_ith_path(tab_index, find_matches(entries, [tab_needle], check_entries=False)))
elif tab_needle:
# found partial tab completion entry
print_tab_menu(
tab_needle,
take(
TAB_ENTRIES_COUNT, find_matches(
entries,
[tab_needle],
check_entries=False,
),
),
TAB_SEPARATOR,
)
print_tab_menu(tab_needle, take(TAB_ENTRIES_COUNT, find_matches(entries, [tab_needle], check_entries=False)), TAB_SEPARATOR)
else:
print_tab_menu(
needle,
take(
TAB_ENTRIES_COUNT, find_matches(
entries,
[needle],
check_entries=False,
),
),
TAB_SEPARATOR,
)
print_tab_menu(needle, take(TAB_ENTRIES_COUNT, find_matches(entries, [needle], check_entries=False)), TAB_SEPARATOR)
def purge_missing_paths(entries):
@ -252,26 +190,24 @@ def print_stats(data, data_path):
for path, weight in sorted(data.items(), key=itemgetter(1)):
print_entry(Entry(path, weight))
print('________________________________________\n')
print('%d:\t total weight' % sum(data.values()))
print('%d:\t number of entries' % len(data))
print("________________________________________\n")
print("%d:\t total weight" % sum(data.values()))
print("%d:\t number of entries" % len(data))
try:
print_local(
'%.2f:\t current directory weight' % data.get(os.getcwdu(), 0),
)
print_local("%.2f:\t current directory weight" % data.get(os.getcwdu(), 0))
except OSError:
# current directory no longer exists
pass
print('\ndata:\t %s' % data_path)
print("\ndata:\t %s" % data_path)
def main(args): # noqa
if not is_autojump_sourced() and not is_windows():
print("Please source the correct autojump file in your shell's")
print('startup file. For more information, please reinstall autojump')
print('and read the post installation instructions.')
print("startup file. For more information, please reinstall autojump")
print("and read the post installation instructions.")
return 1
config = set_defaults()
@ -280,10 +216,7 @@ def main(args): # noqa
if args.add:
save(config, first(add_path(load(config), args.add)))
elif args.complete:
handle_tab_completion(
needle=first(chain(sanitize(args.directory), [''])),
entries=entriefy(load(config)),
)
handle_tab_completion(needle=first(chain(sanitize(args.directory), [""])), entries=entriefy(load(config)))
elif args.decrease:
data, entry = decrease_path(load(config), get_pwd(), args.decrease)
save(config, data)
@ -296,47 +229,48 @@ def main(args): # noqa
old_data = load(config)
new_data = dictify(purge_missing_paths(entriefy(old_data)))
save(config, new_data)
print('Purged %d entries.' % (len(old_data) - len(new_data)))
print("Purged %d entries." % (len(old_data) - len(new_data)))
elif args.stat:
print_stats(load(config), config['data_path'])
print_stats(load(config), config["data_path"])
elif not args.directory:
# Return best match.
entries = entriefy(load(config))
print_local(first(chain(
imap(attrgetter('path'), find_matches(entries, [''])),
# always return a path to calling shell functions
['.'],
)))
print_local(
first(
chain(
imap(attrgetter("path"), find_matches(entries, [""])),
# always return a path to calling shell functions
["."],
)
)
)
else:
entries = entriefy(load(config))
needles = sanitize(args.directory)
tab_needle, tab_index, tab_path = \
get_tab_entry_info(first(needles), TAB_SEPARATOR)
tab_needle, tab_index, tab_path = get_tab_entry_info(first(needles), TAB_SEPARATOR)
# Handle `j foo__`, assuming first index.
if not tab_path and not tab_index \
and tab_needle and needles[0] == tab_needle + TAB_SEPARATOR:
if not tab_path and not tab_index and tab_needle and needles[0] == tab_needle + TAB_SEPARATOR:
tab_index = 1
if tab_path:
print_local(tab_path)
elif tab_index:
get_ith_path = lambda i, iterable: last(take(i, iterable)).path
print_local(get_ith_path(tab_index, find_matches(entries, [tab_needle])))
else:
print_local(
get_ith_path(
tab_index,
find_matches(entries, [tab_needle]),
),
first(
chain(
imap(attrgetter("path"), find_matches(entries, needles)),
# always return a path to calling shell functions
["."],
)
)
)
else:
print_local(first(chain(
imap(attrgetter('path'), find_matches(entries, needles)),
# always return a path to calling shell functions
['.'],
)))
return 0
if __name__ == '__main__':
if __name__ == "__main__":
sys.exit(main(parse_arguments()))

@ -1,130 +1,140 @@
export AUTOJUMP_SOURCED=1
if [[ -z $AUTOJUMP_SOURCED ]]; then
export AUTOJUMP_SOURCED=1
# set user installation paths
if [[ -d ~/.autojump/ ]]; then
export PATH=~/.autojump/bin:"${PATH}"
fi
# Script include
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# set user installation paths
export PATH="${SCRIPT_DIR}:${PATH}"
# set error file location
if [[ "$(uname)" == "Darwin" ]]; then
# set error file location
if [[ "$(uname)" == "Darwin" ]]; then
export AUTOJUMP_ERROR_PATH=~/Library/autojump/errors.log
elif [[ -n "${XDG_DATA_HOME}" ]]; then
elif [[ -n "${XDG_DATA_HOME}" ]]; then
export AUTOJUMP_ERROR_PATH="${XDG_DATA_HOME}/autojump/errors.log"
else
else
export AUTOJUMP_ERROR_PATH=~/.local/share/autojump/errors.log
fi
fi
if [[ ! -d "$(dirname ${AUTOJUMP_ERROR_PATH})" ]]; then
if [[ ! -d "$(dirname ${AUTOJUMP_ERROR_PATH})" ]]; then
mkdir -p "$(dirname ${AUTOJUMP_ERROR_PATH})"
fi
fi
# enable tab completion
_autojump() {
local cur
cur=${COMP_WORDS[*]:1}
comps=$(autojump --complete $cur)
while read i; do
COMPREPLY=("${COMPREPLY[@]}" "${i}")
done <<EOF
$comps
EOF
}
complete -F _autojump j
# enable tab completion
_autojump() {
local cur
cur=${COMP_WORDS[*]:1}
comps=$(autojump --complete $cur)
echo "$comps" | while read i; do
COMPREPLY=("${COMPREPLY[@]}" "${i}")
done
}
complete -F _autojump j
# change pwd hook
autojump_add_to_database() {
# change pwd hook
autojump_add_to_database() {
if [[ -f "${AUTOJUMP_ERROR_PATH}" ]]; then
(autojump --add "$(pwd)" >/dev/null 2>>${AUTOJUMP_ERROR_PATH} &) &>/dev/null
(autojump --add "$(pwd)" >/dev/null 2>>${AUTOJUMP_ERROR_PATH} &) &>/dev/null
else
(autojump --add "$(pwd)" >/dev/null &) &>/dev/null
(autojump --add "$(pwd)" >/dev/null &) &>/dev/null
fi
}
}
case $PROMPT_COMMAND in
case $PROMPT_COMMAND in
*autojump*)
;;
;;
*)
PROMPT_COMMAND="${PROMPT_COMMAND:+$(echo "${PROMPT_COMMAND}" | awk '{gsub(/; *$/,"")}1') ; }autojump_add_to_database"
;;
esac
PROMPT_COMMAND="${PROMPT_COMMAND:+$(echo "${PROMPT_COMMAND}" | awk '{gsub(/; *$/,"")}1') ; }autojump_add_to_database"
;;
esac
# default autojump command
j() {
# default autojump command
j() {
if [[ ${1} == -* ]] && [[ ${1} != "--" ]]; then
autojump ${@}
return
autojump ${@}
return
fi
output="$(autojump ${@})"
if [[ -d "${output}" ]]; then
if [ -t 1 ]; then # if stdout is a terminal, use colors
echo -e "\\033[31m${output}\\033[0m"
else
echo -e "${output}"
fi
cd "${output}"
if [ -t 1 ]; then # if stdout is a terminal, use colors
echo -e "\\033[31m${output}\\033[0m"
else
echo -e "${output}"
fi
cd "${output}"
else
echo "autojump: directory '${@}' not found"
echo "\n${output}\n"
echo "Try \`autojump --help\` for more information."
false
echo "autojump: directory '${@}' not found"
echo "\n${output}\n"
echo "Try \`autojump --help\` for more information."
false
fi
}
}
# jump to child directory (subdirectory of current path)
jc() {
# jump to child directory (subdirectory of current path)
jc() {
if [[ ${1} == -* ]] && [[ ${1} != "--" ]]; then
autojump ${@}
return
autojump ${@}
return
else
j $(pwd) ${@}
j $(pwd) ${@}
fi
}
}
# open autojump results in file browser
jo() {
# open autojump results in file browser
jo() {
if [[ ${1} == -* ]] && [[ ${1} != "--" ]]; then
autojump ${@}
return
autojump ${@}
return
fi
output="$(autojump ${@})"
if [[ -d "${output}" ]]; then
case ${OSTYPE} in
linux*)
xdg-open "${output}"
;;
darwin*)
open "${output}"
;;
cygwin)
cygstart "" $(cygpath -w -a ${output})
;;
*)
echo "Unknown operating system: ${OSTYPE}." 1>&2
;;
esac
case ${OSTYPE} in
linux*)
xdg-open "${output}"
;;
darwin*)
open "${output}"
;;
cygwin)
cygstart "" $(cygpath -w -a ${output})
;;
*)
echo "Unknown operating system: ${OSTYPE}." 1>&2
;;
esac
else
echo "autojump: directory '${@}' not found"
echo "\n${output}\n"
echo "Try \`autojump --help\` for more information."
false
echo "autojump: directory '${@}' not found"
echo "\n${output}\n"
echo "Try \`autojump --help\` for more information."
false
fi
}
}
# open autojump results (child directory) in file browser
jco() {
# open autojump results (child directory) in file browser
jco() {
if [[ ${1} == -* ]] && [[ ${1} != "--" ]]; then
autojump ${@}
return
autojump ${@}
return
else
jo $(pwd) ${@}
jo $(pwd) ${@}
fi
}
}
# Jump around a git repo
g() {
REPO_ROOT=`git rev-parse --show-toplevel`
j "$REPO_ROOT" "$@"
}
else
echo "ERROR: autojump was sourced twice"
fi

@ -1,8 +1,10 @@
# the login $SHELL isn't always the one used
# NOTE: problems might occur if /bin/sh is symlinked to /bin/bash
if [ -n "${BASH}" ]; then
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
shell="bash"
elif [ -n "${ZSH_NAME}" ]; then
SCRIPT_DIR="${0:a:h}"
shell="zsh"
elif [ -n "${__fish_datadir}" ]; then
shell="fish"
@ -23,4 +25,10 @@ elif [ -s ~/.autojump/share/autojump/autojump.${shell} ]; then
# check global install
elif [ -s /usr/local/share/autojump/autojump.${shell} ]; then
source /usr/local/share/autojump/autojump.${shell}
else
if [ -s "$SCRIPT_DIR/autojump.${shell}" ]; then
source "$SCRIPT_DIR/autojump.${shell}"
else
echo "ERROR: autojump not found"
fi
fi

@ -1,11 +1,13 @@
export AUTOJUMP_SOURCED=1
SCRIPT_DIR="${0:a:h}"
# set user installation paths
path=(${SCRIPT_DIR} "${path[@]}")
if [[ -d ~/.autojump/bin ]]; then
path=(~/.autojump/bin ${path})
path=(~/.autojump/bin "${path[@]}")
fi
if [[ -d ~/.autojump/functions ]]; then
fpath=(~/.autojump/functions ${fpath})
fpath=(~/.autojump/functions "${fpath[@]}")
fi
@ -13,11 +15,11 @@ fi
if command -v brew &>/dev/null; then
local brew_prefix=${BREW_PREFIX:-$(brew --prefix)}
if [[ -d "${brew_prefix}/share/zsh/site-functions" ]]; then
fpath=("${brew_prefix}/share/zsh/site-functions" ${fpath})
fpath=("${brew_prefix}/share/zsh/site-functions" "${fpath[@]}")
fi
fi
# set this installation path
# set error file location
if [[ "$(uname)" == "Darwin" ]]; then
export AUTOJUMP_ERROR_PATH=~/Library/autojump/errors.log
@ -123,3 +125,14 @@ jco() {
jo $(pwd) ${@}
fi
}
# Jump around a git repo
g() {
if [[ ${1} == -* ]] && [[ ${1} != "--" ]]; then
autojump ${@}
return
else
REPO_ROOT=`git rev-parse --show-toplevel`
j "$REPO_ROOT" ${@}
fi
}

@ -3,6 +3,7 @@
from __future__ import print_function
import os
import re
import shutil
import sys
from codecs import open
@ -26,7 +27,7 @@ else:
BACKUP_THRESHOLD = 24 * 60 * 60
Entry = namedtuple('Entry', ['path', 'weight'])
Entry = namedtuple("Entry", ["path", "weight"])
def dictify(entries):
@ -51,21 +52,16 @@ def entriefy(data):
def load(config):
"""Returns a dictonary (key=path, value=weight) loaded from data file."""
xdg_aj_home = os.path.join(
os.path.expanduser('~'),
'.local',
'share',
'autojump',
)
xdg_aj_home = os.path.join(os.path.expanduser("~"), ".local", "share", "autojump")
if is_osx() and os.path.exists(xdg_aj_home):
migrate_osx_xdg_data(config)
if not os.path.exists(config['data_path']):
if not os.path.exists(config["data_path"]):
return {}
# example: u'10.0\t/home/user\n' -> ['10.0', u'/home/user']
parse = lambda line: line.strip().split('\t')
parse = lambda line: line.strip().split("\t")
correct_length = lambda x: len(x) == 2
@ -73,24 +69,15 @@ def load(config):
tupleize = lambda x: (x[1], float(x[0]))
try:
with open(
config['data_path'],
'r', encoding='utf-8',
errors='replace',
) as f:
return dict(
imap(
tupleize,
ifilter(correct_length, imap(parse, f)),
),
)
with open(config["data_path"], "r", encoding="utf-8", errors="replace") as f:
return dict(imap(tupleize, ifilter(correct_length, imap(parse, f))))
except (IOError, EOFError):
return load_backup(config)
def load_backup(config):
if os.path.exists(config['backup_path']):
move_file(config['backup_path'], config['data_path'])
if os.path.exists(config["backup_path"]):
move_file(config["backup_path"], config["data_path"])
return load(config)
return {}
@ -100,17 +87,17 @@ def migrate_osx_xdg_data(config):
Older versions incorrectly used Linux XDG_DATA_HOME paths on OS X. This
migrates autojump files from ~/.local/share/autojump to ~/Library/autojump
"""
assert is_osx(), 'This function should only be run on OS X.'
assert is_osx(), "This function should only be run on OS X."
xdg_data_home = os.path.join(os.path.expanduser('~'), '.local', 'share')
xdg_aj_home = os.path.join(xdg_data_home, 'autojump')
data_path = os.path.join(xdg_aj_home, 'autojump.txt')
backup_path = os.path.join(xdg_aj_home, 'autojump.txt.bak')
xdg_data_home = os.path.join(os.path.expanduser("~"), ".local", "share")
xdg_aj_home = os.path.join(xdg_data_home, "autojump")
data_path = os.path.join(xdg_aj_home, "autojump.txt")
backup_path = os.path.join(xdg_aj_home, "autojump.txt.bak")
if os.path.exists(data_path):
move_file(data_path, config['data_path'])
move_file(data_path, config["data_path"])
if os.path.exists(backup_path):
move_file(backup_path, config['backup_path'])
move_file(backup_path, config["backup_path"])
# cleanup
shutil.rmtree(xdg_aj_home)
@ -120,7 +107,7 @@ def migrate_osx_xdg_data(config):
def save(config, data):
"""Save data and create backup, creating a new data file if necessary."""
data_dir = os.path.dirname(config['data_path'])
data_dir = os.path.dirname(config["data_path"])
create_dir(data_dir)
# atomically save by writing to temporary file and moving to destination
@ -129,20 +116,21 @@ def save(config, data):
# Windows cannot reuse the same open file name
temp.close()
with open(temp.name, 'w', encoding='utf-8', errors='replace') as f:
with open(temp.name, "w", encoding="utf-8", errors="replace") as f:
for path, weight in data.items():
f.write(unico('%s\t%s\n' % (weight, path)))
weight_with_age = weight * 0.999
slash_only_path = re.sub(re.escape(os.sep), "/", path)
f.write(unico("%s\t%s\n" % (weight_with_age, slash_only_path)))
f.flush()
os.fsync(f)
except IOError as ex:
print('Error saving autojump data (disk full?)' % ex, file=sys.stderr)
print("Error saving autojump data (disk full?)" % ex, file=sys.stderr)
sys.exit(1)
# move temp_file -> autojump.txt
move_file(temp.name, config['data_path'])
move_file(temp.name, config["data_path"])
# create backup file if it doesn't exist or is older than BACKUP_THRESHOLD
if not os.path.exists(config['backup_path']) or \
(time() - os.path.getmtime(config['backup_path']) > BACKUP_THRESHOLD): # noqa
shutil.copy(config['data_path'], config['backup_path'])
if not os.path.exists(config["backup_path"]) or (time() - os.path.getmtime(config["backup_path"]) > BACKUP_THRESHOLD): # noqa
shutil.copy(config["data_path"], config["backup_path"])

@ -3,11 +3,11 @@
import os
import re
from difflib import SequenceMatcher
from sys import stderr
from autojump_utils import is_python3
from autojump_utils import last
if is_python3(): # pragma: no cover
ifilter = filter
imap = map
@ -36,13 +36,9 @@ def match_anywhere(needles, haystack, ignore_case=False):
(path='/foo/baz', weight=10),
]
"""
regex_needle = '.*' + '.*'.join(imap(re.escape, needles)) + '.*'
regex_needle = ".*" + ".*".join(imap(re.escape, needles)) + ".*"
regex_flags = re.IGNORECASE | re.UNICODE if ignore_case else re.UNICODE
found = lambda haystack: re.search(
regex_needle,
haystack.path,
flags=regex_flags,
)
found = lambda haystack: re.search(regex_needle, haystack.path, flags=regex_flags)
return ifilter(found, haystack)
@ -75,16 +71,21 @@ def match_consecutive(needles, haystack, ignore_case=False):
(path='/foo/baz', weight=10),
]
"""
regex_no_sep = '[^' + os.sep + ']*'
regex_no_sep_end = regex_no_sep + '$'
regex_one_sep = regex_no_sep + os.sep + regex_no_sep
regex_needle = regex_one_sep.join(imap(re.escape, needles)) + regex_no_sep_end
regex_needle = ""
for needle in needles:
slash_only_needle = re.sub(re.escape(os.sep), "/", needle)
if regex_needle == "":
regex_needle = slash_only_needle
else:
regex_needle += "[^/]*/.*" + slash_only_needle
regex_needle += "[^/]*$"
regex_flags = re.IGNORECASE | re.UNICODE if ignore_case else re.UNICODE
found = lambda entry: re.search(
regex_needle,
entry.path,
flags=regex_flags,
)
stderr.write("Regex: " + regex_needle + "\n")
def found(entry):
slash_only_path = re.sub(re.escape(os.sep), "/", entry.path)
return re.search(regex_needle, slash_only_path, flags=regex_flags)
return ifilter(found, haystack)
@ -115,15 +116,9 @@ def match_fuzzy(needles, haystack, ignore_case=False, threshold=0.6):
end_dir = lambda path: last(os.path.split(path))
if ignore_case:
needle = last(needles).lower()
match_percent = lambda entry: SequenceMatcher(
a=needle,
b=end_dir(entry.path.lower()),
).ratio()
match_percent = lambda entry: SequenceMatcher(a=needle, b=end_dir(entry.path.lower())).ratio()
else:
needle = last(needles)
match_percent = lambda entry: SequenceMatcher(
a=needle,
b=end_dir(entry.path),
).ratio()
match_percent = lambda entry: SequenceMatcher(a=needle, b=end_dir(entry.path)).ratio()
meets_threshold = lambda entry: match_percent(entry) >= threshold
return ifilter(meets_threshold, haystack)

@ -0,0 +1,29 @@
Set-Alias -Name ll -Value ls
Function .. {cd ..}
Function ... {cd ../..}
Function .... {cd ../../..}
Function ..... {cd ../../../..}
Function ...... {cd ../../../../..}
Function ....... {cd ../../../../../..}
Function ........ {cd ../../../../../../..}
Function ......... {cd ../../../../../../../..}
Function .......... {cd ../../../../../../../../..}
Function j {
$jumpdir = autojump $args
echo "$jumpdir"
cd $jumpdir
}
Function jc {
j "$pwd" @args
}
Function g {
$repo_root = git rev-parse --show-toplevel
j $repo_root @args
}
Set-PSBreakpoint -Variable pwd -Mode Write -Action {
autojump --add "$pwd"
} | out-null

@ -13,6 +13,7 @@ from itertools import islice
if sys.version_info[0] == 3:
imap = map
unicode = str
os.getcwdu = os.getcwd
else:
from itertools import imap

@ -19,8 +19,8 @@ class TestMatchAnywhere(object):
entry4 = Entry('/中/zhong/国/guo', 10)
entry5 = Entry('/is\'t/this/a/b*tchin/edge/case?', 10)
win_entry1 = Entry('C:\\foo\\bar\\baz', 10)
win_entry2 = Entry('D:\Program Files (x86)\GIMP', 10)
win_entry3 = Entry('C:\Windows\System32', 10)
win_entry2 = Entry('D:\\Program Files (x86)\\GIMP', 10)
win_entry3 = Entry('C:\\Windows\\System32', 10)
@pytest.fixture
def haystack(self):
@ -75,9 +75,9 @@ class TestMatchConsecutive(object):
entry4 = Entry('/中/zhong/国/guo', 10)
entry5 = Entry('/日/本', 10)
entry6 = Entry('/is\'t/this/a/b*tchin/edge/case?', 10)
win_entry1 = Entry('C:\Foo\Bar\Baz', 10)
win_entry2 = Entry('D:\Program Files (x86)\GIMP', 10)
win_entry3 = Entry('C:\Windows\System32', 10)
win_entry1 = Entry('C:\\Foo\\Bar\\Baz', 10)
win_entry2 = Entry('D:\\Program Files (x86)\\GIMP', 10)
win_entry3 = Entry('C:\\Windows\\System32', 10)
@pytest.fixture
def haystack(self):

@ -25,6 +25,7 @@ from autojump_utils import unico
if is_python3():
os.getcwdu = os.getcwd
xrange = range
unicode = str
def u(string):

@ -4,7 +4,8 @@ envlist =
py27,
py33,
py34,
py35
py35,
py36
# ignore missing setup.py
skipsdist = True
@ -31,3 +32,7 @@ commands =
[pytest]
norecursedirs = .git .tox docs
[pycodestyle]
ignore = E731,W504
max-line-length = 131

Loading…
Cancel
Save