mirror of
https://github.com/daylinmorgan/tsm.git
synced 2024-12-22 13:10:43 -06:00
refactor: abstract tmux/project
This commit is contained in:
parent
8a267c514a
commit
e4fc240441
5 changed files with 61 additions and 38 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,3 +1,5 @@
|
||||||
/src/tui
|
/src/tui
|
||||||
/dist
|
/dist
|
||||||
/bin
|
/bin
|
||||||
|
# atlas
|
||||||
|
src/nim.cfg
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
import std/[algorithm, os, osproc, strutils, tables, times]
|
import std/[algorithm, os, strutils, tables, times]
|
||||||
|
|
||||||
|
|
||||||
proc listTmuxSessions*(): seq[string] =
|
|
||||||
let (output, _) = execCmdEx("tmux list-sessions -F '#S'")
|
|
||||||
return output.splitLines()
|
|
||||||
|
|
||||||
|
import utils
|
||||||
|
|
||||||
type
|
type
|
||||||
Project* = object
|
Project* = object
|
||||||
|
@ -20,14 +16,12 @@ proc newProject(path: string, sessions: seq[string]): Project =
|
||||||
|
|
||||||
proc name*(p: Project): string = splitPath(p.location)[1].replace(".", "_")
|
proc name*(p: Project): string = splitPath(p.location)[1].replace(".", "_")
|
||||||
|
|
||||||
|
|
||||||
proc findProjects*(open: bool = false): tuple[header: string,
|
proc findProjects*(open: bool = false): tuple[header: string,
|
||||||
projects: OrderedTable[string, Project]] =
|
projects: OrderedTable[string, Project]] =
|
||||||
## get a table of possible project paths
|
## get a table of possible project paths
|
||||||
|
|
||||||
let
|
let
|
||||||
tsmDirs = getEnv("TSM_DIRS")
|
tsmDirs = getEnv("TSM_DIRS")
|
||||||
sessions = listTmuxSessions()
|
|
||||||
|
|
||||||
if tsmDirs == "":
|
if tsmDirs == "":
|
||||||
echo "Please set $TSM_DIRS to a colon-delimited list of paths"
|
echo "Please set $TSM_DIRS to a colon-delimited list of paths"
|
||||||
|
@ -36,7 +30,7 @@ proc findProjects*(open: bool = false): tuple[header: string,
|
||||||
var projects: seq[Project]
|
var projects: seq[Project]
|
||||||
for devDir in tsmDirs.split(":"):
|
for devDir in tsmDirs.split(":"):
|
||||||
for d in walkDir(devDir):
|
for d in walkDir(devDir):
|
||||||
let p = newProject(d.path, sessions)
|
let p = newProject(d.path, tmux.sessions)
|
||||||
if open and p.open: projects.add p
|
if open and p.open: projects.add p
|
||||||
else:
|
else:
|
||||||
projects.add p
|
projects.add p
|
||||||
|
@ -59,4 +53,3 @@ proc findProjects*(open: bool = false): tuple[header: string,
|
||||||
if len(result.projects) != len(projects):
|
if len(result.projects) != len(projects):
|
||||||
echo "there may be nonunique entries in the project names"
|
echo "there may be nonunique entries in the project names"
|
||||||
|
|
||||||
|
|
||||||
|
|
28
src/tsm.nim
28
src/tsm.nim
|
@ -1,36 +1,20 @@
|
||||||
import std/[os, osproc, strformat, tables]
|
import std/[tables]
|
||||||
|
|
||||||
import tui, project
|
import tui, project, utils
|
||||||
|
|
||||||
proc checkExe(names: varargs[string]) =
|
|
||||||
for name in names:
|
|
||||||
if findExe(name) == "":
|
|
||||||
echo "tsm requires " & name
|
|
||||||
|
|
||||||
template tmux(cmd: string) =
|
|
||||||
discard execCmd("tmux " & cmd)
|
|
||||||
|
|
||||||
proc tsm() =
|
proc tsm() =
|
||||||
checkExe "tmux"
|
|
||||||
|
|
||||||
let
|
let
|
||||||
project = selectProject()
|
project = selectProject()
|
||||||
selected = project.name
|
selected = project.name
|
||||||
|
|
||||||
if existsEnv("TMUX"):
|
if selected notin tmux.sessions:
|
||||||
if selected notin listTmuxSessions():
|
tmux.new project.name, project.location
|
||||||
tmux &"new-session -d -s {selected} -c {project.location}"
|
|
||||||
else:
|
|
||||||
tmux &"switch-client -t {selected}"
|
|
||||||
else:
|
else:
|
||||||
if selected notin listTmuxSessions():
|
tmux.attach project.name
|
||||||
tmux &"new-session -s {selected} -c {project.location}"
|
|
||||||
else:
|
|
||||||
tmux &"attach -t {selected}"
|
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
import cligen
|
import cligen
|
||||||
const vsn = staticExec "git describe --tags --always HEAD"
|
const vsn = staticExec "git describe --tags --always HEAD --match 'v*'"
|
||||||
clCfg.version = vsn
|
clCfg.version = vsn
|
||||||
|
|
||||||
if clCfg.helpAttr.len == 0:
|
if clCfg.helpAttr.len == 0:
|
||||||
|
|
12
src/tui.nim
12
src/tui.nim
|
@ -12,9 +12,9 @@ proc exitProc() {.noconv.} =
|
||||||
illwillDeinit()
|
illwillDeinit()
|
||||||
showCursor()
|
showCursor()
|
||||||
|
|
||||||
template withfgColor(ForegroundColor, body: untyped) =
|
template withfgColor(fgColor, body: untyped) =
|
||||||
var tb = state.buffer
|
var tb = state.buffer
|
||||||
tb.setForegroundColor(ForegroundColor, bright = true)
|
tb.setForegroundColor(fgColor, bright = true)
|
||||||
body
|
body
|
||||||
tb.setForegroundColor(fgWhite, bright = true)
|
tb.setForegroundColor(fgWhite, bright = true)
|
||||||
|
|
||||||
|
@ -100,8 +100,9 @@ proc getProject(): Project =
|
||||||
|
|
||||||
proc clip(s: string): string =
|
proc clip(s: string): string =
|
||||||
let maxWidth = state.window.width - 2
|
let maxWidth = state.window.width - 2
|
||||||
result = if s.len > maxWidth:
|
result =
|
||||||
s[0..^state.window.width]
|
if s.len > maxWidth:
|
||||||
|
s[0..^state.window.width]
|
||||||
else: s
|
else: s
|
||||||
|
|
||||||
proc displayProject(tb: var TerminalBuffer, x, y: int, project: Project) =
|
proc displayProject(tb: var TerminalBuffer, x, y: int, project: Project) =
|
||||||
|
@ -155,7 +156,6 @@ when defined(debug):
|
||||||
for i, line in lines:
|
for i, line in lines:
|
||||||
tb.write(x, y+i, line)
|
tb.write(x, y+i, line)
|
||||||
|
|
||||||
|
|
||||||
proc draw() =
|
proc draw() =
|
||||||
var
|
var
|
||||||
tb = state.buffer
|
tb = state.buffer
|
||||||
|
@ -164,7 +164,7 @@ proc draw() =
|
||||||
tb.setForegroundColor(fgWhite, bright = true)
|
tb.setForegroundColor(fgWhite, bright = true)
|
||||||
|
|
||||||
let
|
let
|
||||||
(x1, x2, y1, _) = state.window.coord.values()
|
(x1, x2, y1, y2) = state.window.coord.values()
|
||||||
maxWidth = x2 - x1 - 4
|
maxWidth = x2 - x1 - 4
|
||||||
|
|
||||||
when defined(debug):
|
when defined(debug):
|
||||||
|
|
44
src/utils.nim
Normal file
44
src/utils.nim
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import std/[os, osproc, strformat, strutils]
|
||||||
|
|
||||||
|
type
|
||||||
|
Tmux = object
|
||||||
|
active: bool
|
||||||
|
sessions*: seq[string]
|
||||||
|
|
||||||
|
proc checkExe(names: varargs[string]) =
|
||||||
|
for name in names:
|
||||||
|
if findExe(name) == "":
|
||||||
|
echo "tsm requires " & name
|
||||||
|
|
||||||
|
checkExe "tmux"
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
template cmd(tmux: Tmux, args: string) =
|
||||||
|
discard execCmd("tmux " & args)
|
||||||
|
|
||||||
|
proc newTmux(): Tmux =
|
||||||
|
result.active = existsEnv("TMUX")
|
||||||
|
result.sessions = (
|
||||||
|
result.cmdGet "list-sessions -F '#S'"
|
||||||
|
).strip().split("\n")
|
||||||
|
|
||||||
|
proc attach*(t: Tmux, session: string) =
|
||||||
|
let args =
|
||||||
|
if t.active:"switch-client -t"
|
||||||
|
else: "attach -t"
|
||||||
|
t.cmd fmt"{args} {session}"
|
||||||
|
|
||||||
|
proc new*(t: Tmux, session: string, loc: string) =
|
||||||
|
let args =
|
||||||
|
if t.active: "new-session -d"
|
||||||
|
else: "new-session"
|
||||||
|
t.cmd fmt"{args} -s {session} -c {loc}"
|
||||||
|
|
||||||
|
let tmux* = newTmux()
|
Loading…
Reference in a new issue