#!/usr/bin/python3 import os import subprocess import sys home = os.environ['HOME'] git_dirs = [ home + "/projects", home + "/git", home + "/git/worktrees", home + "/WebStormProjects", home + "/RiderProjects" ] icons = {} def get_application_desktop_file_info(application: str, prefix: str) -> str: existing_key = prefix + application existing = icons.get(existing_key) if existing is not None: return existing path = f"{home}/.local/share/applications/jetbrains-{application}.desktop" with open(path, 'r') as file: for line in file.readlines(): if line.startswith(prefix): icons[existing_key] = line return line def get_project_type(project) -> (str, str): ret = ("idea", None) for file in os.listdir(project): if file.endswith("pom.xml"): return ("idea", None) if file.endswith("package.json"): return ("webstorm", None) if file.endswith("cargo.toml") or file.endswith(".c"): return ("clion", None) if file.endswith(".csproj"): return ("rider", file) if file.endswith("DotSettings"): # Allow .csproj to override this value ret = ("rider", None) if file.endswith(".py"): return ("pycharm", None) if file.endswith(".go"): return ("goland", None) return ret def get_icon(project: str) -> str | None: (project_type, _) = get_project_type(project) if project_type is None: return None icon_line = get_application_desktop_file_info(project_type, 'Icon') return icon_line[5:].rstrip() def open_project(project: str) -> (): project = project.replace("~", home) (project_type, file) = get_project_type(project) if project_type is None: return if file is not None: project = f'{project}/{file}' command = get_application_desktop_file_info(project_type, 'Exec')[6:-5] subprocess.Popen([command + " " + project], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) def print_project_message(project: str) -> (): icon = get_icon(project) if icon is None: return project = project.replace(home, "~") print(f'git {project}') # print(f'{project}\0icon\x1f{icon}') if __name__ == '__main__': include_icon = sys.argv[1] != "--no-icon" if len(sys.argv) > 1 else True if len(sys.argv) == 1 or not include_icon: for git_dir in git_dirs: if not os.path.isdir(git_dir): continue for project in os.listdir(git_dir): project = f'{git_dir}/{project}' if os.path.isdir(project): if include_icon: print_project_message(project) else: print(f'git {project}') else: open_project(sys.argv[1][4:])