Skip to content
This repository has been archived by the owner on Jul 13, 2023. It is now read-only.

Commit

Permalink
Merge pull request #4 from Macuyler/development
Browse files Browse the repository at this point in the history
First Stable Update
  • Loading branch information
macuyler authored Jul 24, 2020
2 parents b8d3a23 + 7c288e5 commit 12ad31b
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 73 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ This is a utility that allows you to quickly jump to your favorite directories w
alias qd="source qd.sh"
```
- Open up a new terminal and give it a try using `qd`

## Notes:
- Windows is not (yet) supported.
- It seems that python caches the directories. So, the first time you run the command after boot it takes longer then normal operation.
6 changes: 4 additions & 2 deletions qd.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ def show_usage():

def main():
help_args = ['--help', '-h']
if len(sys.argv) == 2 and sys.argv[1] not in help_args: # Check for argument
if len(sys.argv) >= 2 and sys.argv[1] not in help_args: # Check for help argument or if path args is greater then 2
conf = get_config()
dirs = get_dirs(sys.argv[1], conf)
#Join path argument from bash script with a space
path_arg = ' '.join(sys.argv[1:])
dirs = get_dirs(path_arg, conf)
start_display(dirs, conf)
else:
show_usage()
Expand Down
6 changes: 2 additions & 4 deletions qd.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
#!/bin/bash

touch ~/.qd_path
qd.py $1 && \
cd $(cat ~/.qd_path)

qd.py $@ && \
cd "$(cat ~/.qd_path)"
167 changes: 117 additions & 50 deletions src/cli.py
Original file line number Diff line number Diff line change
@@ -1,64 +1,131 @@
import curses
from pathlib import Path

import sys
def start_display(paths, conf):
root = conf.root
clean_paths = []
for p in paths:
clean_paths.append(f"\t{p.replace(root, '')}")
if len(paths) > 0:
# INIT curses sesion
stdscr = curses.initscr()
curses.cbreak()
stdscr.keypad(1)

#get terminal x and y
term_y, term_x = stdscr.getmaxyx()

stdscr = curses.initscr()
curses.cbreak()
stdscr.keypad(1)
current_location = 0
current_location = 0

def clear_string(index):
if index < len(paths):
stdscr.addstr(index, 0,clean_paths[index])
root = conf.root
clean_paths = []
for p in paths:
clean_string = ''
#check if path length is greater then the width of terminal
if len(p.replace(root, '')) > term_x - 10:
#Make sure p doesn't start with / messes up splits later
split_p = p.replace(root, '')
if split_p[:1] == '/':
split_p = split_p[1:]

def select_string(index):
if index < len(path):
line = f">{clean_paths[index]}"
stdscr.addstr(index, 0, line, curses.A_STANDOUT)
split_p = split_p.split('/')

for index, path in enumerate(clean_paths):
stdscr.addstr(index, 0, path)
max_part_len = term_x - 13
max_part_len = max_part_len / 2

key = ''

quit = False
#Max length each path string seperated by ... can be
first_path_len = 0
last_path_len = 0
#count of split parts

select_string(0)
while not quit:

key = stdscr.getch()
stdscr.refresh()
if len(split_p[0]) + len(split_p[1]) < max_part_len:
first_path_len = 2
elif len(split_p[0]) < max_part_len:
first_path_len = 1

if len(split_p[-1]) + len(split_p[-2]) < max_part_len:
last_path_len = 2
elif len(split_p[-1]) < max_part_len:
last_path_len = 1

first_half_of_str = ''
last_half_of_str = ''

if first_path_len == 2:
first_half_of_str = f'{split_p[0]}/{split_p[2]}'
elif first_path_len ==1:
first_half_of_str = split_p[0]

if last_path_len == 1:
last_half_of_str = split_p[-1]
elif last_path_len == 2:
last_half_of_str = f'{split_p[-2]}/{split_p[-1]}'

if first_path_len == 0 and last_path_len == 0:
last_half_of_str = split_p[-1]

clean_string = f'{first_half_of_str}/.../{last_half_of_str}'


if key == curses.KEY_DOWN:
if current_location +1 < len(paths):
clear_string(current_location)
current_location = current_location +1
select_string(current_location)
else:
clear_string(current_location)
current_location = 0
select_string(current_location)
elif key == curses.KEY_UP:
if current_location - 1 >= 0 :
clear_string(current_location)
current_location = current_location - 1
select_string(current_location)
else:
clear_string(current_location)
current_location = len(paths) - 1
select_string(current_location)
elif key == 10:
curses.endwin()
quit = True
home = str(Path.home())
open(f'{home}/.qd_path', 'w').write(paths[current_location])
elif key == ord('q'):
quit = True

curses.endwin()
clean_string = p.replace(root, '')


clean_paths.append(clean_string)

def clear_string(index):
if index < len(paths):
stdscr.addch(index, 2, ' ')
stdscr.addstr(index, 4, clean_paths[index])

def select_string(index):
if index < len(path):
line = f">{clean_paths[index]}"
stdscr.addch(index, 2, ">")
stdscr.addstr(index, 4, clean_paths[index], curses.A_STANDOUT)
#stdscr.addstr(index, 0, line, curses.A_STANDOUT)

for index, path in enumerate(clean_paths):
stdscr.addstr(index, 4, path)

key = ''

quit = False

select_string(0)
while not quit:

key = stdscr.getch()
stdscr.refresh()

if key == curses.KEY_DOWN:
if current_location +1 < len(paths):
clear_string(current_location)
current_location = current_location +1
select_string(current_location)
else:
clear_string(current_location)
current_location = 0
select_string(current_location)
elif key == curses.KEY_UP:
if current_location - 1 >= 0 :
clear_string(current_location)
current_location = current_location - 1
select_string(current_location)
else:
clear_string(current_location)
current_location = len(paths) - 1
select_string(current_location)
elif key == 10:
curses.endwin()
quit = True
home = str(Path.home())
open(f'{home}/.qd_path', 'w').write(paths[current_location])
elif key == ord('q'):
quit = True
curses.endwin()
sys.exit(1)


else:
print("NO PATHS FOUND")
sys.exit(1)
#exit code is needed so that cd command does not issue into last qd path
45 changes: 28 additions & 17 deletions src/dirs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import os

def apply_rules(name, root, conf):
filtered_paths = []

def apply_rules(name, root, conf, inp):
path = os.path.join(root, name)
r = True
for e in conf.exclude:
Expand All @@ -15,12 +17,15 @@ def apply_rules(name, root, conf):
r = True
if name in conf.include:
r = True
if inp.lower() in name.lower():
filtered_paths.append(path)
return r

def match_points(match, exact_points, non_exact_points):
points = 0
# Char to the left of the inputed NAME string
left_char = match[len(match) - 2][len(match[len(match) - 2]) - 1]
left_string = match[len(match) - 2]
left_char = left_string[len(match[len(match) - 2]) - 1] if len(left_string) > 0 else ''
# Char to the right of the inputed NAME string
right_char = match[len(match) - 1][0] if len(match[len(match) - 1]) > 0 else ''
if left_char == '/' and right_char == '':
Expand Down Expand Up @@ -56,7 +61,15 @@ def dist_points(p):
points *= 300000
return points - repeat

def get_dirs(name, conf, results=8):
def walk(dir, conf, inp):
with os.scandir(dir) as it:
for sub in it:
path = os.path.join(dir, sub.name)
if sub.is_dir() and apply_rules(sub.name, dir, conf, inp):
walk(path, conf, inp)
return

def get_dirs(inp, conf, results=8):
scores = {}

def add_score(path, points):
Expand All @@ -65,19 +78,17 @@ def add_score(path, points):
else:
scores[path] = points

for root, dirs, files in os.walk(conf.root, topdown=True):
dirs[:] = list(filter(lambda d: apply_rules(d, root, conf), dirs))
for subdir in dirs:
path = os.path.join(root, subdir)
if name in path:
points = match_points(path.split(name), 500000, 480000)
if points > 0:
points += dist_points(path)
add_score(path, points)
elif name.lower() in path.lower():
points = match_points(path.lower().split(name.lower()), 300000, 300000)
if points > 0:
points += dist_points(path)
add_score(path, points)
walk(conf.root, conf, inp)
for path in filtered_paths:
if inp in path:
points = match_points(path.split(inp), 500000, 480000)
if points > 0:
points += dist_points(path)
add_score(path, points)
elif inp.lower() in path.lower():
points = match_points(path.lower().split(inp.lower()), 300000, 300000)
if points > 0:
points += dist_points(path)
add_score(path, points)
dirs = sorted(scores.items(), key=lambda item: -item[1])[:results]
return list(map(lambda x: x[0], dirs))

0 comments on commit 12ad31b

Please sign in to comment.