mirror of
https://github.com/daylinmorgan/tsm.git
synced 2024-12-22 05:00:44 -06:00
feat: sort configured sessions
This commit is contained in:
parent
2dcb4f9640
commit
f9b3470c35
2 changed files with 44 additions and 30 deletions
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue