Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
294 changes: 22 additions & 272 deletions tags/file_manager/file_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from itertools import islice
from pathlib import Path

from talon import Context, Module, actions, app, imgui, registry, settings, ui
from talon import Context, Module, actions, app, imgui, scope, settings, ui

mod = Module()
ctx = Context()
Expand Down Expand Up @@ -31,12 +31,6 @@
"exe",
]

mod.setting(
"file_manager_auto_show_pickers",
type=bool,
default=False,
desc="Enable to show the file/directories pickers automatically",
)
mod.setting(
"file_manager_folder_limit",
type=int,
Expand All @@ -49,24 +43,6 @@
default=1000,
desc="Maximum number of files to iterate",
)
mod.setting(
"file_manager_imgui_limit",
type=int,
default=20,
desc="Maximum number of files/folders to display in the imgui",
)
mod.setting(
"file_manager_string_limit",
type=int,
default=20,
desc="Maximum like of string to display in the imgui",
)
cached_path = None
file_selections = folder_selections = []
current_file_page = current_folder_page = 1

ctx.lists["self.file_manager_directories"] = []
ctx.lists["self.file_manager_files"] = []


@mod.action_class
Expand Down Expand Up @@ -107,84 +83,6 @@ def file_manager_refresh_title():
"""Refreshes the title to match current directory. this is for e.g. windows command prompt that will need to do some magic."""
return

def file_manager_update_lists():
"""Forces an update of the lists (e.g., when file or folder created)"""
update_lists()

def file_manager_toggle_pickers():
"""Shows the pickers"""
if gui_files.showing:
gui_files.hide()
gui_folders.hide()
else:
gui_files.show()
gui_folders.show()

def file_manager_hide_pickers():
"""Hides the pickers"""
if gui_files.showing:
gui_files.hide()
gui_folders.hide()

def file_manager_get_directory_by_index(index: int) -> str:
"""Returns the requested directory for the imgui display by index"""
index = (current_folder_page - 1) * settings.get(
"user.file_manager_imgui_limit"
) + index
assert index < len(folder_selections)
return folder_selections[index]

def file_manager_get_file_by_index(index: int) -> str:
"""Returns the requested directory for the imgui display by index"""
index = (current_file_page - 1) * settings.get(
"user.file_manager_imgui_limit"
) + index
assert index < len(file_selections)
return file_selections[index]

def file_manager_next_file_page():
"""next_file_page"""
global current_file_page
if gui_files.showing:
if current_file_page != total_file_pages:
current_file_page += 1
else:
current_file_page = 1
gui_files.show()

def file_manager_previous_file_page():
"""previous_file_page"""
global current_file_page
if gui_files.showing:
if current_file_page != 1:
current_file_page -= 1
else:
current_file_page = total_file_pages

gui_files.show()

def file_manager_next_folder_page():
"""next_folder_page"""
global current_folder_page
if gui_folders.showing:
if current_folder_page != total_folder_pages:
current_folder_page += 1
else:
current_folder_page = 1

gui_folders.show()

def file_manager_previous_folder_page():
"""previous_folder_page"""
global current_folder_page
if gui_folders.showing:
if current_folder_page != 1:
current_folder_page -= 1
else:
current_folder_page = total_folder_pages

gui_folders.show()


def is_dir(f):
try:
Expand Down Expand Up @@ -228,193 +126,45 @@ def get_file_map(current_path):
)


@imgui.open(y=10, x=900)
def gui_folders(gui: imgui.GUI):
global current_folder_page, total_folder_pages
total_folder_pages = math.ceil(
len(ctx.lists["self.file_manager_directories"])
/ settings.get("user.file_manager_imgui_limit")
)
gui.text(f"Select a directory ({current_folder_page}/{total_folder_pages})")
gui.line()

index = 1
current_index = (current_folder_page - 1) * settings.get(
"user.file_manager_imgui_limit"
)

while index <= settings.get(
"user.file_manager_imgui_limit"
) and current_index < len(folder_selections):
name = (
(
folder_selections[current_index][
: settings.get("user.file_manager_string_limit")
]
+ ".."
)
if len(folder_selections[current_index])
> settings.get("user.file_manager_string_limit")
else folder_selections[current_index]
)
gui.text(f"{index}: {name} ")
current_index += 1
index = index + 1

# if total_folder_pages > 1:
# gui.spacer()

# if gui.button('Next...'):
# actions.user.file_manager_next_folder_page()

# if gui.button("Previous..."):
# actions.user.file_manager_previous_folder_page()

gui.spacer()
if gui.button("Manager close"):
actions.user.file_manager_hide_pickers()


@imgui.open(y=10, x=1300)
def gui_files(gui: imgui.GUI):
global file_selections, current_file_page, total_file_pages
total_file_pages = math.ceil(
len(file_selections) / settings.get("user.file_manager_imgui_limit")
)

gui.text(f"Select a file ({current_file_page}/{total_file_pages})")
gui.line()
index = 1
current_index = (current_file_page - 1) * settings.get(
"user.file_manager_imgui_limit"
)

while index <= settings.get(
"user.file_manager_imgui_limit"
) and current_index < len(file_selections):
name = (
(
file_selections[current_index][
: settings.get("user.file_manager_string_limit")
]
+ ".."
)
if len(file_selections[current_index])
> settings.get("user.file_manager_string_limit")
else file_selections[current_index]
)

gui.text(f"{index}: {name} ")
current_index = current_index + 1
index = index + 1

# if total_file_pages > 1:
# gui.spacer()

# if gui.button('Next...'):
# actions.user.file_manager_next_file_page()

# if gui.button("Previous..."):
# actions.user.file_manager_previous_file_page()


def clear_lists():
global folder_selections, file_selections, current_folder_page, current_file_page
if (
len(ctx.lists["self.file_manager_directories"]) > 0
or len(ctx.lists["self.file_manager_files"]) > 0
):
current_folder_page = current_file_page = 1
ctx.lists.update(
{
"self.file_manager_directories": [],
"self.file_manager_files": [],
}
)
folder_selections = []
file_selections = []


def update_gui():
if gui_folders.showing or settings.get("user.file_manager_auto_show_pickers"):
gui_folders.show()
gui_files.show()
@ctx.dynamic_list("user.file_manager_directories")
def file_manager_directories(phrase) -> dict[str, str]:
is_valid_path = False

path = actions.user.file_manager_current_path()

def update_lists(path=None):
global folder_selections, file_selections, current_folder_page, current_file_page
is_valid_path = False
if not path:
path = actions.user.file_manager_current_path()
directories = {}
files = {}
folder_selections = []
file_selections = []
# print(path)
try:
current_path = Path(path)
is_valid_path = current_path.is_dir()
except:
is_valid_path = False

if is_valid_path:
# print("valid..." + str(current_path))
try:
directories = get_directory_map(current_path)
files = get_file_map(current_path)
except:
# print("invalid path...")

directories = {}
files = {}

current_folder_page = current_file_page = 1
ctx.lists.update(
{
"self.file_manager_directories": directories,
"self.file_manager_files": files,
}
)

folder_selections = list(set(directories.values()))
folder_selections.sort(key=str.casefold)
file_selections = list(set(files.values()))
file_selections.sort(key=str.casefold)

update_gui()


def win_event_handler(window):
global cached_path

# on windows, we get events from the clock
# and such, so this check is important
if not window.app.exe or window != ui.active_window():
return
return directories

if "user.file_manager" not in registry.tags:
actions.user.file_manager_hide_pickers()
clear_lists()
cached_path = None
return

@ctx.dynamic_list("user.file_manager_files")
def file_manager_files(phrase) -> dict[str, str]:
global files
is_valid_path = False
path = actions.user.file_manager_current_path()

if path:
if cached_path != path:
update_lists(path)
elif cached_path:
clear_lists()
actions.user.file_manager_hide_pickers()

cached_path = path


def register_events():
ui.register("win_title", win_event_handler)
ui.register("win_focus", win_event_handler)
files = {}
try:
current_path = Path(path)
is_valid_path = current_path.is_dir()
except:
is_valid_path = False

if is_valid_path:
try:
files = get_file_map(current_path)
except:
files = {}

# prevent scary errors in the log by waiting for talon to be fully loaded
# before registering the events
app.register("ready", register_events)
return files
3 changes: 0 additions & 3 deletions tags/file_manager/file_manager.talon
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ tag: user.file_manager
tag(): user.navigation

title force: user.file_manager_refresh_title()
manager show: user.file_manager_toggle_pickers()
manager close: user.file_manager_hide_pickers()
manager refresh: user.file_manager_update_lists()
go <user.system_path>: user.file_manager_open_directory(system_path)
(go parent | daddy): user.file_manager_open_parent()
^follow {user.file_manager_directories}$:
Expand Down