feat: sort configured sessions

This commit is contained in:
Daylin Morgan 2024-09-13 14:46:00 -05:00
parent 2dcb4f9640
commit f9b3470c35
Signed by: daylin
GPG key ID: 950D13E9719334AD
2 changed files with 44 additions and 30 deletions

View file

@ -1,4 +1,4 @@
import std/[os, streams, strformat, strutils] import std/[os, sequtils, streams, strformat, strutils, ]
import yaml import yaml
import term import term
@ -10,6 +10,9 @@ type
Session = object Session = object
name*, dir*: string name*, dir*: string
proc sessionNames*(tc: TsmConfig): seq[string] =
tc.sessions.mapIt(it.name)
proc loadConfigFile(): TsmConfig = proc loadConfigFile(): TsmConfig =
let configPath = getEnv("TSM_CONFIG", getConfigDir() / "tsm" / "config.yml") let configPath = getEnv("TSM_CONFIG", getConfigDir() / "tsm" / "config.yml")
try: try:

View file

@ -10,18 +10,16 @@ type
open*: bool open*: bool
matched*: bool matched*: bool
proc pathToName(path: string): string = splitPath(path)[1].replace(".", "_") proc pathToName(path: string): string =
splitPath(path)[1].replace(".", "_")
proc newProject( proc newProject(path: string, open: bool, name = "", named: bool = false): Project =
path: string,
open: bool,
name = "",
named: bool = false
): Project =
result.location = path result.location = path
result.name = result.name =
if name != "": name if name != "":
else: path.pathToName() name
else:
path.pathToName()
result.updated = getLastModificationTime(path) result.updated = getLastModificationTime(path)
result.open = open result.open = open
result.named = named result.named = named
@ -37,7 +35,7 @@ proc getTsmDirs(): seq[string] =
result = tsmDirs.split(":") result = tsmDirs.split(":")
proc findDuplicateProjects( proc findDuplicateProjects(
paths: seq[string], sessions: var HashSet[string] paths: seq[string], sessions: var HashSet[string]
): seq[Project] = ): seq[Project] =
var candidates: Table[string, seq[string]] var candidates: Table[string, seq[string]]
for p in paths: for p in paths:
@ -45,30 +43,37 @@ proc findDuplicateProjects(
let maxExtra = min(candidates.values.toSeq.mapIt(it.len)) let maxExtra = min(candidates.values.toSeq.mapIt(it.len))
for i in 2..maxExtra: for i in 2..maxExtra:
let deduplicated = collect: let
for path, pathSplit in candidates.pairs: deduplicated =
(name: pathSplit[^i..^1].joinPath, path: path) collect:
for path, pathSplit in candidates.pairs:
(name: pathSplit[^i..^1].joinPath, path: path)
if deduplicated.mapIt(it[0]).toHashSet.len == candidates.len: if deduplicated.mapIt(it[0]).toHashSet.len == candidates.len:
for (name, path) in deduplicated: for (name, path) in deduplicated:
let open = name in sessions let open = name in sessions
result.add newProject(path, open, name) result.add newProject(path, open, name)
if open: sessions.excl name if open:
sessions.excl name
break break
if result.len == 0: if result.len == 0:
termQuit "failed to deduplicate these paths:" & paths.join(", ") termQuit "failed to deduplicate these paths:" & paths.join(", ")
proc `<-`(candidates: var Table[string, seq[string]], path: string) =
let name = path.splitPath.tail
if candidates.hasKeyOrPut(name, @[path]):
candidates[name].add path
proc findProjects*(open: bool = false): seq[Project] = proc findProjects*(open: bool = false): seq[Project] =
let tsmConfig = loadTsmConfig() let tsmConfig = loadTsmConfig()
var candidates: Table[string, seq[string]] var candidates: Table[string, seq[string]]
var sessions = tmux.sessions.toHashSet() var sessions = tmux.sessions.toHashSet()
for devDir in tsmConfig.dirs: for devDir in tsmConfig.dirs:
for path in walkDir(devDir): for (kind, path) in walkDir(devDir):
if ({path.kind} * {pcFile, pcLinkToFile}).len > 0: continue if ({kind} * {pcFile, pcLinkToFile}).len > 0:
let name = path.path.splitPath.tail continue
if candidates.hasKeyOrPut(name, @[path.path]): candidates <- path
candidates[name].add path.path
for name, paths in candidates.pairs: for name, paths in candidates.pairs:
if len(paths) == 1: if len(paths) == 1:
@ -76,28 +81,35 @@ proc findProjects*(open: bool = false): seq[Project] =
path = paths[0] path = paths[0]
open = path.pathToName in sessions open = path.pathToName in sessions
result.add newProject(path, open) result.add newProject(path, open)
if open: sessions.excl path.pathToName if open:
sessions.excl path.pathToName
else: else:
result &= findDuplicateProjects(paths, sessions) result &= findDuplicateProjects(paths, sessions)
for session in tsmConfig.sessions: for session in tsmConfig.sessions:
if session.name notin sessions: if session.name notin sessions:
result.add newProject( result.add newProject(
path = session.dir, path = session.dir, open = false, name = session.name, named = true
open = false,
name = session.name,
named = true
) )
if open: if open:
result = result.filterIt(it.open) result = result.filterIt(it.open)
let sessionNames = tsmConfig.sessionNames
# default order # order open -> configured -> mod time
# open -> configured -> mod time result.sort do(x, y: Project) -> int:
result.sort do (x, y: Project) -> int:
result = cmp(y.open, x.open) result = cmp(y.open, x.open)
if result == 0: if result == 0:
result = cmp(y.updated, x.updated) result =
if y.name in sessionNames:
if x.name in sessionNames:
cmp(y.name, x.name)
else:
1
elif x.name in sessionNames:
-1
else:
cmp(y.updated, x.updated)
if sessions.len > 0: if sessions.len > 0:
result = sessions.toSeq().mapIt(newUnknownProject(it)) & result result = sessions.toSeq().mapIt(newUnknownProject(it)) & result
@ -107,4 +119,3 @@ proc findProjects*(open: bool = false): seq[Project] =
termEcho "searched these directories: " termEcho "searched these directories: "
echo getTsmDirs().mapIt(" " & it).join("\n") echo getTsmDirs().mapIt(" " & it).join("\n")
quit QuitFailure quit QuitFailure