Skip to content

Commit f436932

Browse files
authored
Resolves (#67). Urls support added (#103)
Now `status` and `info` are displaying clickable URLs
1 parent de8ebfd commit f436932

3 files changed

Lines changed: 48 additions & 24 deletions

File tree

src/mud/runner.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,14 @@ def get_git_origin_host_icon(url: str) -> str:
5555
return YELLOW + glyphs('gitlab') + RESET
5656
elif 'bitbucket' in url:
5757
return CYAN + glyphs('bitbucket') + RESET
58+
elif len(url) == 0:
59+
return ''
5860
else:
5961
return YELLOW + glyphs('git') + RESET
6062

6163
table: PrettyTable = utils.get_table([
6264
f'{YELLOW}{glyphs('git-repo')}{glyphs('space')}{RESET}Directory',
65+
f'{BRIGHT_RED}{glyphs('git')}{glyphs('space')}{RESET}Url',
6366
f'{BLUE}{glyphs('commit')}{glyphs('space')}{RESET}Commits',
6467
f'{BLUE}{glyphs('commit')}{glyphs('space')}{RESET}User Commits',
6568
f'{MAGENTA}{glyphs('weight')}{glyphs('space')}{RESET}Size',
@@ -84,13 +87,14 @@ def get_git_origin_host_icon(url: str) -> str:
8487
walker = repo.walk(repo.head.target, pygit2.GIT_SORT_TOPOLOGICAL)
8588
user_commits_count = sum(1 for c in walker if c.author.name == user_name)
8689

87-
formatted_path = f'{get_git_origin_host_icon(origin_url)}{glyphs('space')}{self._get_formatted_path(path)}'
90+
formatted_path = link(self._get_formatted_path(path), os.path.abspath(path))
91+
url = f'{get_git_origin_host_icon(origin_url)}{glyphs('space')}{link(origin_url.split('://', 1)[-1].split("/", 1)[0], origin_url)}'
8892
size = format_size(get_directory_size(path))
8993
total_commits = '' if total_commits_count is None else f'{BOLD}{total_commits_count}{RESET} {DIM}commits{RESET}'
9094
user_commits = '' if user_commits_count is None else f'{GREEN}{BOLD}{user_commits_count}{RESET} {DIM}by you{RESET}'
9195
colored_labels = self._get_formatted_labels(labels)
9296

93-
table.add_row([formatted_path, total_commits, user_commits, size, colored_labels])
97+
table.add_row([formatted_path, url, total_commits, user_commits, size, colored_labels])
9498

9599
utils.print_table(table)
96100

@@ -104,10 +108,11 @@ def status(self, repos: Dict[str, List[str]]) -> None:
104108
f'{BRIGHT_GREEN}{glyphs('git-modified')}{glyphs('space')}{RESET}Modified Files'])
105109

106110
for path, labels in repos.items():
107-
repo = Repository(os.path.abspath(path))
111+
repo_path = os.path.abspath(path)
112+
repo = Repository(repo_path)
108113
status = repo.status()
109114
modified = status.items()
110-
formatted_path = self._get_formatted_path(path)
115+
formatted_path = link(self._get_formatted_path(path), os.path.abspath(path))
111116
origin_sync = self._get_origin_sync(repo)
112117
mini_status = self._get_status_string(modified)
113118
head_info = self._get_head_info(repo)
@@ -124,8 +129,7 @@ def status(self, repos: Dict[str, List[str]]) -> None:
124129
color = BLUE
125130
else:
126131
color = CYAN
127-
colored_output.append(self._get_formatted_path(file, False, color))
128-
132+
colored_output.append(link(self._get_formatted_path(file, False, color), os.path.join(repo_path, file)))
129133
table.add_row([formatted_path, head_info, origin_sync, mini_status, ', '.join(colored_output)])
130134

131135
utils.print_table(table)
@@ -137,7 +141,7 @@ def labels(self, repos: Dict[str, List[str]]) -> None:
137141
f'{MAGENTA}{glyphs('labels')}{glyphs('space')}{RESET}Labels'])
138142

139143
for path, labels in repos.items():
140-
formatted_path = self._get_formatted_path(path)
144+
formatted_path = link(self._get_formatted_path(path), os.path.abspath(path))
141145
colored_labels = self._get_formatted_labels(labels)
142146
table.add_row([formatted_path, colored_labels])
143147

@@ -165,7 +169,7 @@ def log(self, repos: Dict[str, List[str]]) -> None:
165169
time = datetime.fromtimestamp(commit.commit_time, timezone(timedelta(minutes=commit.commit_time_offset))).strftime('%Y-%m-%d %H:%M:%S')
166170
message = commit.message.splitlines()[0]
167171

168-
formatted_path = self._get_formatted_path(path)
172+
formatted_path = link(self._get_formatted_path(path), os.path.abspath(path))
169173
head_info = self._get_head_info(repo)
170174

171175
table.add_row([formatted_path, head_info, commit_hash, author, time, message])
@@ -190,7 +194,7 @@ def branches(self, paths: Dict[str, List[str]], remote: bool) -> None:
190194
branch_counter = Counter(all_branches)
191195

192196
for path, repo in repos:
193-
formatted_path = self._get_formatted_path(path)
197+
formatted_path = link(self._get_formatted_path(path), os.path.abspath(path))
194198
branches = [ref.replace(prefix + (repo.remotes[0].name + '/' if remote else ''), '') for ref in repo.references if ref.startswith(prefix + (repo.remotes[0].name + '/' if remote else ''))]
195199
current_branch = '' if repo.head_is_unborn or repo.head_is_detached else repo.head.shorthand
196200
sorted_branches = sorted(branches, key=lambda x: branch_counter.get(x, 0), reverse=True)
@@ -232,7 +236,7 @@ def assign_color(tag: str) -> str:
232236
]
233237
tags.sort()
234238

235-
formatted_path = self._get_formatted_path(path)
239+
formatted_path = link(self._get_formatted_path(path), os.path.abspath(path))
236240

237241
tags = [f'{assign_color(tag)}{glyphs('tag')} {RESET}{tag}' for tag in tags]
238242
table.add_row([formatted_path, ' '.join(tags)])
@@ -306,7 +310,7 @@ def _print_process(self, info: Dict[str, List[str]]) -> None:
306310
table = utils.get_table([f'{YELLOW}{glyphs('git-repo')}{glyphs('space')}{RESET}Directory', f'{BRIGHT_YELLOW}{glyphs('info')}{glyphs('space')}{RESET}Status', 'Output'])
307311
table.header = False
308312
for path, (line, status) in info.items():
309-
formatted_path = self._get_formatted_path(path)
313+
formatted_path = link(self._get_formatted_path(path), os.path.abspath(path))
310314
table.add_row([formatted_path, status, line])
311315

312316
table_str = utils.table_to_str(table)
@@ -411,7 +415,7 @@ def _get_formatted_path(path: str, file_system: bool = True, color: str = '') ->
411415
path = path.replace('\'', '')
412416

413417
def apply_styles(text: str) -> str:
414-
return color + quote + text + quote + RESET
418+
return color + quote + text + quote + END_FRG
415419

416420
if file_system and abs_path:
417421
return apply_styles(os.path.abspath(path))
@@ -444,7 +448,7 @@ def _get_formatted_labels(labels: List[str]) -> str:
444448
colored_labels = ''
445449
for label in labels:
446450
color_index = Runner._get_color_index(label) % len(TEXT)
447-
colored_labels += f'{TEXT[(color_index + 3) % len(TEXT)]}{glyphs('label')}{glyphs('space')}{label}{RESET} '
451+
colored_labels += f'{TEXT[(color_index + 3) % len(TEXT)]}{glyphs('label')}{glyphs('space')}{label}{END_FRG} '
448452

449453
return colored_labels.rstrip()
450454

src/mud/styles.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
BRIGHT_MAGENTA = '\033[95m'
3333
BRIGHT_CYAN = '\033[96m'
3434

35+
END_FRG = '\033[39m'
36+
3537
TEXT = [WHITE, GRAY, BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, BRIGHT_WHITE, BRIGHT_RED, BRIGHT_GREEN, BRIGHT_YELLOW, BRIGHT_BLUE, BRIGHT_MAGENTA, BRIGHT_CYAN]
3638

3739
# Background colors
@@ -56,9 +58,9 @@
5658

5759
RESET = '\033[0m'
5860

59-
URL_START = '\033]8;;'
60-
URL_TEXT = '\a'
61-
URL_END = '\033]8;;\a'
61+
URL_START = '\u001b]8;;'
62+
URL_TEXT = '\u001b\\'
63+
URL_END = '\u001b]8;;\u001b\\'
6264

6365
ALL = BKG + TEXT + STYLES + END + [RESET, URL_START, URL_TEXT, URL_END]
6466

src/mud/utils.py

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import shutil
44
import random
55

6-
from typing import List, Any
6+
from typing import List
77
from prettytable import PrettyTable, PLAIN_COLUMNS
88

99
from mud.settings import *
@@ -31,7 +31,8 @@ def info() -> None:
3131
print(f' {m}__ _ {u}__ __{d}___/ /{RESET}')
3232
print(f' {m}/ \' \\{u}/ // / {d}_ /{RESET}')
3333
print(f'{m}/_/_/_/{u}\\_,_/{d}\\_,_/ {RESET}')
34-
print(f'Jasur Sadikov <jasur@sadikoff.com>\nhttps://github.com/jasursadikov/mud')
34+
print(f'Jasur Sadikov <{link('jasur@sadikoff.com', 'mailto:jasur@sadikoff.com')}>')
35+
print(link('https://github.com/jasursadikov/mud', 'https://github.com/jasursadikov/mud'))
3536

3637

3738
def configure() -> None:
@@ -68,17 +69,30 @@ def print_table(table: PrettyTable) -> None:
6869
width, _ = shutil.get_terminal_size()
6970

7071
def get_real_length(string):
71-
ansi_escape = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
72+
ansi_csi = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
7273
i = 0
7374
displayed_count = 0
7475

7576
while displayed_count < width and i < len(string):
76-
match = ansi_escape.match(string, i)
77+
if string.startswith(URL_START, i):
78+
end_of_wrapper = string.find(URL_TEXT, i + len(URL_START))
79+
if end_of_wrapper == -1:
80+
break
81+
i = end_of_wrapper + len(URL_TEXT)
82+
continue
83+
84+
if string.startswith(URL_END, i):
85+
i += len(URL_END)
86+
continue
87+
88+
match = ansi_csi.match(string, i)
7789
if match:
7890
i = match.end()
79-
else:
80-
displayed_count += 1
81-
i += 1
91+
continue
92+
93+
displayed_count += 1
94+
i += 1
95+
8296
return i
8397

8498
for col in table.field_names[:]:
@@ -91,7 +105,7 @@ def get_real_length(string):
91105
stripped = row.strip()
92106
if len(stripped) != 0:
93107
if len(stripped) > width:
94-
print(stripped[:get_real_length(stripped)] + RESET)
108+
print(stripped[:get_real_length(stripped)] + URL_END + RESET)
95109
else:
96110
print(stripped)
97111

@@ -102,6 +116,10 @@ def table_to_str(table: PrettyTable) -> str:
102116
return table
103117

104118

119+
def link(text: str, url: str):
120+
return f'{URL_START}{url}{URL_TEXT}{text}{URL_END}'
121+
122+
105123
def get_table(field_names: List[str]) -> PrettyTable:
106124
def set_style(item: str) -> str:
107125
return f'{GRAY}{item}{RESET}'

0 commit comments

Comments
 (0)