Skip to content

Instantly share code, notes, and snippets.

@davebrny
Last active February 21, 2024 08:35
Show Gist options
  • Save davebrny/7dbeda0baea3ec467c804772833fe2a5 to your computer and use it in GitHub Desktop.
Save davebrny/7dbeda0baea3ec467c804772833fe2a5 to your computer and use it in GitHub Desktop.
🏷️ (autohotkey) - add a tagspaces style [tag] to a filename
/*
[tag list]
bank
car
insurance
receipt
tax
[settings]
recent_total = 11
recent_tags =
[script info]
version = 0.4
description = add a tagspaces style [tag] to a filename
author = davebrny
source = https://gist.github.com/davebrny/7dbeda0baea3ec467c804772833fe2a5
*/
#noEnv
#singleInstance, force
onExit, exit_label
iniRead, tag_list, % a_lineFile, tag list
recent := []
iniRead, recent_total, % a_lineFile, settings, recent_total
iniRead, recent_tags, % a_lineFile, settings, recent_tags
loop, parse, % recent_tags, `, , % a_space
recent.push(a_loopField)
groupAdd, file_browsers, ahk_exe explorer.exe
groupAdd, file_browsers, ahk_exe XYplorerFree.exe
hotkey, ifWinActive, ahk_group file_browsers
hotkey, !t, square_menu
return ; end of auto-execute---------------------------------------------------
square_menu:
file_path := get_file()
if (file_path = "")
return ; dont continue
menu, square_menu, add, square tag, add_tag
menu, square_menu, default, square tag
menu, square_menu, disable, square tag
menu, square_menu, add
splitPath, file_path, , dir, ext, filename
tags := get_tags(filename)
if (tags)
{
menu, current_tags, add, select to remove:, remove_tag
menu, current_tags, disable, select to remove:
menu, current_tags, add
loop, parse, tags, `, , % a_space
menu, current_tags, add, % a_loopfield, remove_tag
menu, square_menu, add, current tags, :current_tags
menu, square_menu, add
}
if (tag_list)
{
loop, parse, tag_list, `n, `r
{
menu, tag_list, add, % a_loopfield, add_tag
if already_in(tags, a_loopfield)
menu, tag_list, disable, % a_loopfield
}
menu, square_menu, add, tag list, :tag_list
}
if (tags_in_folder())
{
loop, % in_folder.maxIndex()
{
menu, in_folder, add, % in_folder[a_index], add_tag
if already_in(tags, in_folder[a_index])
menu, in_folder, disable, % in_folder[a_index]
}
menu, square_menu, add, in folder, :in_folder
}
if (recent.maxIndex())
{
menu, square_menu, add
menu, square_menu, add, recent tags:, add_tag
menu, square_menu, disable, recent tags:
menu, square_menu, add
loop, % recent.maxIndex()
{
menu, square_menu, add, % recent[a_index], add_tag
if already_in(tags, recent[a_index])
menu, square_menu, disable, % recent[a_index]
}
menu, square_menu, add
menu, square_menu, add, clear recent, clear_recent
}
menu, square_menu, useErrorLevel
menu, square_menu, show
menu, square_menu, delete
menu, current_tags, delete
menu, tag_list, delete
menu, in_folder, delete
file_path := ""
tags := ""
new_tags := ""
return
get_file() {
if winActive("ahk_class CabinetWClass") ; file explorer
file_path := selected_file_ex()
else if winActive("ahk_exe XYplorerFree.exe") ; xyplorer
file_path := selected_file_xy()
return file_path
}
selected_file_ex() { ; file explorer
for window in comObjCreate("shell.application").windows
{
if (window.hwnd != winExist("a"))
continue
for file in window.document.selectedItems
selected .= (selected ? "`n" : "") . file.path
}
file_path := first_file(selected)
return file_path
}
selected_file_xy() { ; xyplorer
restore_clipboard := clipboardAll
clipboard := ""
send ^{p}
clipWait, 0.3
selected := clipboard
clipboard := restore_clipboard
file_path := first_file(selected)
return file_path
}
first_file(list) {
loop, parse, list, `n, `r
{
if fileExist(a_loopField)
return a_loopField
}
}
get_tags(byRef filename) {
if inStr(filename, "[") and inStr(filename, "]")
{
stringGetPos, pos, filename, [, R1
stringMid, str_right, filename, pos + 2
stringMid, name_without_tags, filename, pos, , L
filename := rTrim(name_without_tags)
stringGetPos, pos, str_right, ], R1
stringMid, tags, str_right, pos, , L
return tags
}
}
already_in(tags, item) {
if inStr(", " tags ", " , ", " item ", ")
return true
}
tags_in_folder() {
global in_folder, dir
in_folder := []
loop, files, % dir "\*", FD
{
splitPath, a_loopFileFullPath, , , , filename
tags := get_tags(filename)
loop, parse, % tags, `, , % a_space
in_folder.push(a_loopField)
}
if (in_folder.maxIndex())
return in_folder
}
remove_tag:
loop, parse, tags, `, , % a_space
{
if (a_loopField != a_thisMenuItem)
new_tags .= (new_tags? ", " : "") . a_loopfield
}
new_path := dir "\" filename . (new_tags ? " [" new_tags "]" : "")
if (fileExist(file_path) = "D")
fileMoveDir, % file_path, % new_path
else fileMove, % file_path, % new_path "." ext
return
add_tag:
new_path := dir "\" filename " [" tags . (tags? ", " : "") . a_thisMenuItem "]"
if (fileExist(file_path) = "D")
fileMoveDir, % file_path, % new_path
else fileMove, % file_path, % new_path "." ext
add_to_recent(a_thisMenuItem)
return
add_to_recent(item) {
global recent, recent_total
for index, value in recent
if (value = item) ; if already in recent
recent.removeAt(index)
recent.insertAt(1, item)
if (recent.maxIndex() > recent_total)
recent.pop()
}
clear_recent:
recent := []
iniWrite, % "", % a_lineFile, settings, recent_tags
return
exit_label:
recent_tags := ""
loop, % recent.maxIndex()
recent_tags .= (recent_tags ? ", " : "") . recent[a_index]
iniRead, ini_value, % a_lineFile, settings, recent_tags
if (recent_tags != ini_value)
iniWrite, % " " recent_tags, % a_lineFile, settings, recent_tags
exitApp
@haukebasse
Copy link

Incredible! I only added "FreeCommander.exe" in two places, and then one single more line for getting the file path, and now it already works! So great; thank you!

@science2002
Copy link

science2002 commented Feb 20, 2024

Very helpful script. Many thanks. Two additional features, if it is possible, could improve even more its functionality.

  1. Select the tags with a tick box, instead as now using the click. The advantage would be that more tags could be selected at the same time - by flagging each tick box - and not as now just one tag at the time (also - as alternative - a Ctrl click to select multiple tags could be helpful, in place of the tick boxes).
  2. Using still ^t to make the tag list appear also while saving a file. Once one has written the name of a file in the Window, "Save as...", it would be helpful to add in the name the tags on the fly, so to have the file with tags since its creation, instead of adding them afterwards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment