mirror of
https://github.com/daylinmorgan/tsm.git
synced 2024-12-21 20:50:45 -06:00
feat: handle duplicates/and term improvements
This commit is contained in:
parent
1d08c01e6e
commit
8673532e2a
4 changed files with 77 additions and 31 deletions
|
@ -1,7 +1,5 @@
|
|||
import std/[algorithm, os, sequtils, sets, strutils, tables, times]
|
||||
|
||||
import bbansi
|
||||
import utils
|
||||
import std/[algorithm, os, sequtils, sets, strutils, sugar, tables, times]
|
||||
import tmuxutils, term
|
||||
|
||||
type
|
||||
Project* = object
|
||||
|
@ -13,22 +11,45 @@ type
|
|||
|
||||
proc pathToName(path: string): string = splitPath(path)[1].replace(".", "_")
|
||||
|
||||
proc newProject(path: string, open: bool): Project =
|
||||
proc newProject(path: string, open: bool, name = ""): Project =
|
||||
result.location = path
|
||||
result.name = path.pathToName()
|
||||
result.name =
|
||||
if name != "": name
|
||||
else: path.pathToName()
|
||||
result.updated = getLastModificationTime(path)
|
||||
result.open = open
|
||||
|
||||
proc newUnknownProject(name: string): Project =
|
||||
result.name = name
|
||||
result.open = true
|
||||
|
||||
proc getTsmDirs(): seq[string] =
|
||||
let tsmDirs = getEnv("TSM_DIRS")
|
||||
if tsmDirs == "":
|
||||
bbEcho "[red]Please set [cyan]$TSM_DIRS[/] to a colon-delimited list of paths"
|
||||
quit QuitFailure
|
||||
termQuit "Please set [yellow]$TSM_DIRS[/] to a colon-delimited list of paths"
|
||||
result = tsmDirs.split(":")
|
||||
|
||||
proc findDuplicateProjects(paths: seq[string],
|
||||
sessions: var HashSet[string]): seq[Project] =
|
||||
var candidates: Table[string, seq[string]]
|
||||
for p in paths:
|
||||
candidates[p] = p.split(DirSep)
|
||||
|
||||
let maxExtra = min(candidates.values.toSeq.mapIt(it.len))
|
||||
for i in 2..maxExtra:
|
||||
let deduplicated = collect:
|
||||
for path, pathSplit in candidates.pairs:
|
||||
(name: pathSplit[^i..^1].joinPath, path: path)
|
||||
if deduplicated.mapIt(it[0]).toHashSet.len == candidates.len:
|
||||
for (name, path) in deduplicated:
|
||||
let open = name in sessions
|
||||
result.add newProject(path, open, name)
|
||||
if open: sessions.excl name
|
||||
break
|
||||
|
||||
if result.len == 0:
|
||||
termQuit "failed to deduplicate these paths:" & paths.join(", ")
|
||||
|
||||
proc findProjects*(open: bool = false): seq[Project] =
|
||||
var candidates: Table[string, seq[string]]
|
||||
var sessions = tmux.sessions.toHashSet()
|
||||
|
@ -36,20 +57,19 @@ proc findProjects*(open: bool = false): seq[Project] =
|
|||
for devDir in getTsmDirs():
|
||||
for path in walkDir(devDir):
|
||||
if ({path.kind} * {pcFile, pcLinkToFile}).len > 0: continue
|
||||
let name = path.path.tailDir()
|
||||
if name in candidates:
|
||||
let name = path.path.splitPath.tail
|
||||
if candidates.hasKeyOrPut(name, @[path.path]):
|
||||
candidates[name].add path.path
|
||||
else:
|
||||
candidates[name] = @[path.path]
|
||||
|
||||
# TODO: improve this to handle duplicate entries by appending parent?
|
||||
for name, paths in candidates:
|
||||
for name, paths in candidates.pairs:
|
||||
if len(paths) == 1:
|
||||
let path = paths[0]
|
||||
let open = path.pathToName in sessions
|
||||
let
|
||||
path = paths[0]
|
||||
open = path.pathToName in sessions
|
||||
result.add newProject(path, open)
|
||||
if open:
|
||||
sessions.excl toHashSet([path.pathToName])
|
||||
if open: sessions.excl path.pathToName
|
||||
else:
|
||||
result &= findDuplicateProjects(paths, sessions)
|
||||
|
||||
if open:
|
||||
result = result.filterIt(it.open)
|
||||
|
@ -64,7 +84,8 @@ proc findProjects*(open: bool = false): seq[Project] =
|
|||
result = sessions.toSeq().mapIt(newUnknownProject(it)) & result
|
||||
|
||||
if len(result) == 0:
|
||||
echo "nothing to select"
|
||||
quit 1
|
||||
|
||||
termError "nothing to select, check your [yellow]$TSM_DIRS"
|
||||
termEcho "searched these directories: "
|
||||
echo getTsmDirs().mapIt(" " & it).join("\n")
|
||||
quit QuitFailure
|
||||
|
||||
|
|
17
src/term.nim
Normal file
17
src/term.nim
Normal file
|
@ -0,0 +1,17 @@
|
|||
import std/strutils
|
||||
import bbansi
|
||||
|
||||
const
|
||||
sep = " [magenta]|[/] "
|
||||
prefix = "[cyan]tsm[/]" & sep
|
||||
errPrefix = prefix & "[red]error[/]" & sep
|
||||
|
||||
proc termEcho*(x: varargs[string, `$`]) =
|
||||
bbEcho prefix, x.join(" ")
|
||||
|
||||
proc termError*(x: varargs[string, `$`]) =
|
||||
bbEcho errPrefix, x.join(" ")
|
||||
|
||||
proc termQuit*(x: varargs[string, `$`]) =
|
||||
termError x
|
||||
quit QuitFailure
|
|
@ -1,5 +1,7 @@
|
|||
import std/[os, osproc, strformat, strutils]
|
||||
|
||||
import term
|
||||
|
||||
type
|
||||
Tmux = object
|
||||
active: bool
|
||||
|
@ -8,24 +10,31 @@ type
|
|||
proc checkExe(names: varargs[string]) =
|
||||
for name in names:
|
||||
if findExe(name) == "":
|
||||
echo "tsm requires " & name
|
||||
termError "tsm requires " & name
|
||||
|
||||
checkExe "tmux"
|
||||
|
||||
proc tmuxError(args: string, output: string = "") =
|
||||
termError "failed to run: [bold]tmux", args
|
||||
if output != "":
|
||||
termError "see below for error"
|
||||
echo output
|
||||
quit QuitFailure
|
||||
|
||||
|
||||
proc cmdGet(tmux: Tmux, args: string): string =
|
||||
let (output, code) = execCmdEx("tmux " & args)
|
||||
if code != 0:
|
||||
echo "ERROR: failed to run: tmux ", args, "see below for error"
|
||||
echo output
|
||||
quit QuitFailure
|
||||
return output
|
||||
if code == 0: return output
|
||||
tmuxError args, output
|
||||
|
||||
template cmd(tmux: Tmux, args: string) =
|
||||
discard execCmd("tmux " & args)
|
||||
let code = execCmd "tmux " & args
|
||||
if code != 0: tmuxError(args)
|
||||
# discard tmux.cmdGet args
|
||||
|
||||
proc newTmux(): Tmux =
|
||||
result.active = existsEnv("TMUX")
|
||||
# check if server is active?
|
||||
# check if server is active
|
||||
if execCmdEx("tmux run").exitCode == 0:
|
||||
result.sessions = (
|
||||
result.cmdGet "list-sessions -F '#S'"
|
||||
|
@ -44,5 +53,4 @@ proc new*(t: Tmux, session: string, loc: string) =
|
|||
else:
|
||||
t.cmd fmt"new-session -s {session} -c {loc}"
|
||||
|
||||
|
||||
let tmux* = newTmux()
|
|
@ -1,6 +1,6 @@
|
|||
import std/[tables]
|
||||
|
||||
import selector, project, utils
|
||||
import selector, project, tmuxutils
|
||||
|
||||
proc tsm(open: bool = false) =
|
||||
let
|
||||
|
|
Loading…
Reference in a new issue