mirror of
https://github.com/daylinmorgan/tsm.git
synced 2024-12-22 05:00:44 -06:00
chore: use nph
This commit is contained in:
parent
f9b3470c35
commit
fcdd419c31
4 changed files with 74 additions and 65 deletions
|
@ -1,4 +1,4 @@
|
||||||
import std/[os, sequtils, streams, strformat, strutils, ]
|
import std/[os, sequtils, streams, strformat, strutils]
|
||||||
import yaml
|
import yaml
|
||||||
import term
|
import term
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ type
|
||||||
Session = object
|
Session = object
|
||||||
name*, dir*: string
|
name*, dir*: string
|
||||||
|
|
||||||
proc sessionNames*(tc: TsmConfig): seq[string] =
|
proc sessionNames*(tc: TsmConfig): seq[string] =
|
||||||
tc.sessions.mapIt(it.name)
|
tc.sessions.mapIt(it.name)
|
||||||
|
|
||||||
proc loadConfigFile(): TsmConfig =
|
proc loadConfigFile(): TsmConfig =
|
||||||
|
|
|
@ -2,7 +2,8 @@ import std/[enumerate, os, strformat, strutils, terminal]
|
||||||
from illwill import illwillDeinit, illwillInit, getKey, Key
|
from illwill import illwillDeinit, illwillInit, getKey, Key
|
||||||
import term, project
|
import term, project
|
||||||
|
|
||||||
func toStr(k: Key): string = $chr(ord(k))
|
func toStr(k: Key): string =
|
||||||
|
$chr(ord(k))
|
||||||
|
|
||||||
proc getMaxHeight(): int =
|
proc getMaxHeight(): int =
|
||||||
result = 10
|
result = 10
|
||||||
|
@ -13,7 +14,6 @@ proc getMaxHeight(): int =
|
||||||
except ValueError:
|
except ValueError:
|
||||||
termQuit fmt"failed to parse TSM_HEIGHT of `{setting}`, expected integer"
|
termQuit fmt"failed to parse TSM_HEIGHT of `{setting}`, expected integer"
|
||||||
|
|
||||||
|
|
||||||
let maxHeight = getMaxHeight()
|
let maxHeight = getMaxHeight()
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -41,7 +41,7 @@ proc addLine(b: var Buffer, text: string) =
|
||||||
b.buffer.add (" " & text).alignLeft(b.width) & "\n"
|
b.buffer.add (" " & text).alignLeft(b.width) & "\n"
|
||||||
|
|
||||||
proc addDivider(b: var Buffer) =
|
proc addDivider(b: var Buffer) =
|
||||||
b.addLine "─".repeat(b.width-2)
|
b.addLine "─".repeat(b.width - 2)
|
||||||
|
|
||||||
proc addInput(b: var Buffer) =
|
proc addInput(b: var Buffer) =
|
||||||
b.addLine "$ " & state.input
|
b.addLine "$ " & state.input
|
||||||
|
@ -59,9 +59,7 @@ proc draw(b: var Buffer) =
|
||||||
stdout.writeLine ""
|
stdout.writeLine ""
|
||||||
stdout.writeLine "DEBUG INFO -------------"
|
stdout.writeLine "DEBUG INFO -------------"
|
||||||
stdout.writeLine $state.cursor
|
stdout.writeLine $state.cursor
|
||||||
stdout.writeLine(
|
stdout.writeLine(alignLeft("Key: " & $(state.lastKey), b.Buffer.width))
|
||||||
alignLeft("Key: " & $(state.lastKey), b.Buffer.width)
|
|
||||||
)
|
|
||||||
stdout.cursorUp(b.numLines + 4)
|
stdout.cursorUp(b.numLines + 4)
|
||||||
else:
|
else:
|
||||||
stdout.cursorUp(b.numLines)
|
stdout.cursorUp(b.numLines)
|
||||||
|
@ -72,8 +70,9 @@ proc scrollUp() =
|
||||||
dec state.projectIdx
|
dec state.projectIdx
|
||||||
|
|
||||||
proc scrollDown() =
|
proc scrollDown() =
|
||||||
if (state.projects.len - state.projectIdx) >
|
if (state.projects.len - state.projectIdx) > (
|
||||||
(state.buffer.height - state.buffer.inputPad):
|
state.buffer.height - state.buffer.inputPad
|
||||||
|
):
|
||||||
inc state.projectIdx
|
inc state.projectIdx
|
||||||
|
|
||||||
proc up() =
|
proc up() =
|
||||||
|
@ -89,7 +88,8 @@ proc down() =
|
||||||
scrollDown()
|
scrollDown()
|
||||||
|
|
||||||
proc backspace(s: string): string =
|
proc backspace(s: string): string =
|
||||||
if s != "": result = s[0..^2]
|
if s != "":
|
||||||
|
result = s[0..^2]
|
||||||
|
|
||||||
proc match(project: Project): Project =
|
proc match(project: Project): Project =
|
||||||
result = project
|
result = project
|
||||||
|
@ -97,7 +97,6 @@ proc match(project: Project): Project =
|
||||||
|
|
||||||
# TODO: convert this into a proper sorter
|
# TODO: convert this into a proper sorter
|
||||||
proc sortProjects(): seq[Project] =
|
proc sortProjects(): seq[Project] =
|
||||||
|
|
||||||
var
|
var
|
||||||
priority: seq[Project]
|
priority: seq[Project]
|
||||||
rest: seq[Project]
|
rest: seq[Project]
|
||||||
|
@ -116,19 +115,23 @@ proc getProject(): Project =
|
||||||
var idx = state.cursor.y - state.cursor.min + state.projectIdx
|
var idx = state.cursor.y - state.cursor.min + state.projectIdx
|
||||||
return projects[idx]
|
return projects[idx]
|
||||||
|
|
||||||
|
|
||||||
proc clip(s: string): string =
|
proc clip(s: string): string =
|
||||||
let maxWidth = state.buffer.width - 2
|
let maxWidth = state.buffer.width - 2
|
||||||
result =
|
result =
|
||||||
if s.len > maxWidth:
|
if s.len > maxWidth:
|
||||||
s[0..^maxWidth]
|
s[0..^maxWidth]
|
||||||
else: s
|
else:
|
||||||
|
s
|
||||||
|
|
||||||
proc highlight(p: Project): string =
|
proc highlight(p: Project): string =
|
||||||
if p.location == "": "green"
|
if p.location == "":
|
||||||
elif p.open: "yellow"
|
"green"
|
||||||
elif p.named: "bold cyan"
|
elif p.open:
|
||||||
else: "default"
|
"yellow"
|
||||||
|
elif p.named:
|
||||||
|
"bold cyan"
|
||||||
|
else:
|
||||||
|
"default"
|
||||||
|
|
||||||
proc addProject(b: var Buffer, project: Project, selected: bool) =
|
proc addProject(b: var Buffer, project: Project, selected: bool) =
|
||||||
let
|
let
|
||||||
|
@ -140,7 +143,8 @@ proc addProject(b: var Buffer, project: Project, selected: bool) =
|
||||||
var displayName = fmt"[red]{input}[/]"
|
var displayName = fmt"[red]{input}[/]"
|
||||||
if input.len < name.len:
|
if input.len < name.len:
|
||||||
# bbansi missing add(string, bbstring) interface
|
# bbansi missing add(string, bbstring) interface
|
||||||
displayName &= fmt"[{project.highlight}]{name[input.len..^1]}[/{project.highlight}]"
|
displayName &=
|
||||||
|
fmt"[{project.highlight}]{name[input.len..^1]}[/{project.highlight}]"
|
||||||
b.addLine(cur & $displayName.bb)
|
b.addLine(cur & $displayName.bb)
|
||||||
else:
|
else:
|
||||||
b.addLine(cur & $name.bb(project.highlight))
|
b.addLine(cur & $name.bb(project.highlight))
|
||||||
|
@ -150,8 +154,8 @@ proc addProjectCount(b: var Buffer) =
|
||||||
maxNumProjects = state.buffer.height - state.buffer.inputPad
|
maxNumProjects = state.buffer.height - state.buffer.inputPad
|
||||||
numProjects = state.projects.len
|
numProjects = state.projects.len
|
||||||
# TODO: use variables here for readability
|
# TODO: use variables here for readability
|
||||||
let
|
let
|
||||||
low= state.projectIdx+1
|
low = state.projectIdx + 1
|
||||||
high = state.projectIdx + min(maxNumProjects, numProjects)
|
high = state.projectIdx + min(maxNumProjects, numProjects)
|
||||||
b.addLine $(fmt"[[{low}-{high}/{numProjects}]".bb("faint"))
|
b.addLine $(fmt"[[{low}-{high}/{numProjects}]".bb("faint"))
|
||||||
|
|
||||||
|
@ -164,7 +168,8 @@ proc addProjects(b: var Buffer) =
|
||||||
for (i, project) in enumerate(projects[state.projectIdx..^1]):
|
for (i, project) in enumerate(projects[state.projectIdx..^1]):
|
||||||
b.addProject(project, state.cursor.y == numProjects)
|
b.addProject(project, state.cursor.y == numProjects)
|
||||||
inc numProjects
|
inc numProjects
|
||||||
if numProjects > maxNumProjects: break
|
if numProjects > maxNumProjects:
|
||||||
|
break
|
||||||
|
|
||||||
proc reset() =
|
proc reset() =
|
||||||
state.cursor.y = state.cursor.min
|
state.cursor.y = state.cursor.min
|
||||||
|
@ -180,11 +185,14 @@ proc draw() =
|
||||||
|
|
||||||
proc update(s: var State) =
|
proc update(s: var State) =
|
||||||
s.buffer.width = terminalWidth()
|
s.buffer.width = terminalWidth()
|
||||||
s.buffer.height = min([
|
s.buffer.height =
|
||||||
terminalHeight(),
|
min(
|
||||||
maxHeight + state.buffer.inputPad,
|
[
|
||||||
state.buffer.inputPad + state.projects.len
|
terminalHeight(),
|
||||||
])
|
maxHeight + state.buffer.inputPad,
|
||||||
|
state.buffer.inputPad + state.projects.len
|
||||||
|
]
|
||||||
|
)
|
||||||
s.cursor.max = s.buffer.height - state.buffer.inputPad
|
s.cursor.max = s.buffer.height - state.buffer.inputPad
|
||||||
|
|
||||||
proc clear(b: var Buffer) =
|
proc clear(b: var Buffer) =
|
||||||
|
@ -203,7 +211,6 @@ proc exitProc() {.noconv.} =
|
||||||
showCursor()
|
showCursor()
|
||||||
|
|
||||||
proc selectProject*(projects: seq[Project]): Project =
|
proc selectProject*(projects: seq[Project]): Project =
|
||||||
|
|
||||||
state.projects = projects
|
state.projects = projects
|
||||||
illwillInit(fullscreen = false)
|
illwillInit(fullscreen = false)
|
||||||
setControlCHook(quitProc)
|
setControlCHook(quitProc)
|
||||||
|
@ -213,15 +220,23 @@ proc selectProject*(projects: seq[Project]): Project =
|
||||||
state.update()
|
state.update()
|
||||||
var key = getKey()
|
var key = getKey()
|
||||||
case key
|
case key
|
||||||
of Key.None: discard
|
of Key.None:
|
||||||
of Key.Escape: quitProc()
|
discard
|
||||||
|
of Key.Escape:
|
||||||
|
quitProc()
|
||||||
of Key.Enter:
|
of Key.Enter:
|
||||||
exitProc()
|
exitProc()
|
||||||
return getProject()
|
return getProject()
|
||||||
of Key.Up: up()
|
of Key.Up:
|
||||||
of Key.Down: down()
|
up()
|
||||||
of Key.CtrlA..Key.CtrlL, Key.CtrlN..Key.CtrlZ, Key.CtrlRightBracket,
|
of Key.Down:
|
||||||
Key.CtrlBackslash, Key.Right..Key.F12:
|
down()
|
||||||
|
of
|
||||||
|
Key.CtrlA..Key.CtrlL,
|
||||||
|
Key.CtrlN..Key.CtrlZ,
|
||||||
|
Key.CtrlRightBracket,
|
||||||
|
Key.CtrlBackslash,
|
||||||
|
Key.Right..Key.F12:
|
||||||
state.lastKey = key
|
state.lastKey = key
|
||||||
else:
|
else:
|
||||||
reset()
|
reset()
|
||||||
|
@ -237,9 +252,7 @@ proc selectProject*(projects: seq[Project]): Project =
|
||||||
draw()
|
draw()
|
||||||
sleep(10)
|
sleep(10)
|
||||||
|
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
projects = findProjects(open)
|
projects = findProjects(open)
|
||||||
let selected = selectProject(projects)
|
let selected = selectProject(projects)
|
||||||
echo "selected project -> " & $selected.name
|
echo "selected project -> " & $selected.name
|
||||||
|
|
||||||
|
|
|
@ -21,29 +21,26 @@ proc tmuxError(args: string, output: string = "") =
|
||||||
echo output
|
echo output
|
||||||
quit QuitFailure
|
quit QuitFailure
|
||||||
|
|
||||||
|
|
||||||
proc cmdGet(tmux: Tmux, args: string): string =
|
proc cmdGet(tmux: Tmux, args: string): string =
|
||||||
let (output, code) = execCmdEx("tmux " & args)
|
let (output, code) = execCmdEx("tmux " & args)
|
||||||
if code == 0: return output
|
if code == 0:
|
||||||
|
return output
|
||||||
tmuxError args, output
|
tmuxError args, output
|
||||||
|
|
||||||
template cmd(tmux: Tmux, args: string) =
|
template cmd(tmux: Tmux, args: string) =
|
||||||
let code = execCmd "tmux " & args
|
let code = execCmd "tmux " & args
|
||||||
if code != 0: tmuxError(args)
|
if code != 0:
|
||||||
|
tmuxError(args)
|
||||||
# discard tmux.cmdGet args
|
# discard tmux.cmdGet args
|
||||||
|
|
||||||
proc newTmux(): Tmux =
|
proc newTmux(): Tmux =
|
||||||
result.active = existsEnv("TMUX")
|
result.active = existsEnv("TMUX")
|
||||||
# check if server is active
|
# check if server is active
|
||||||
if execCmdEx("tmux run").exitCode == 0:
|
if execCmdEx("tmux run").exitCode == 0:
|
||||||
result.sessions = (
|
result.sessions = (result.cmdGet "list-sessions -F '#S'").strip().split("\n")
|
||||||
result.cmdGet "list-sessions -F '#S'"
|
|
||||||
).strip().split("\n")
|
|
||||||
|
|
||||||
proc attach*(t: Tmux, session: string) =
|
proc attach*(t: Tmux, session: string) =
|
||||||
let args =
|
let args = if t.active: "switch-client -t" else: "attach -t"
|
||||||
if t.active: "switch-client -t"
|
|
||||||
else: "attach -t"
|
|
||||||
t.cmd fmt"{args} {session}"
|
t.cmd fmt"{args} {session}"
|
||||||
|
|
||||||
proc new*(t: Tmux, session: string, loc: string) =
|
proc new*(t: Tmux, session: string, loc: string) =
|
||||||
|
|
39
src/tsm.nim
39
src/tsm.nim
|
@ -20,24 +20,23 @@ when isMainModule:
|
||||||
clCfg.version = vsn
|
clCfg.version = vsn
|
||||||
|
|
||||||
if clCfg.helpAttr.len == 0:
|
if clCfg.helpAttr.len == 0:
|
||||||
clCfg.helpAttr = {
|
clCfg.helpAttr =
|
||||||
"cmd" : "\e[1;36m",
|
{
|
||||||
"clDescrip": "",
|
"cmd": "\e[1;36m",
|
||||||
"clDflVal" : "\e[33m",
|
"clDescrip": "",
|
||||||
"clOptKeys": "\e[32m",
|
"clDflVal": "\e[33m",
|
||||||
"clValType": "\e[31m",
|
"clOptKeys": "\e[32m",
|
||||||
"args" : "\e[3m"
|
"clValType": "\e[31m",
|
||||||
}.toTable
|
"args": "\e[3m"
|
||||||
clCfg.helpAttrOff = {
|
}.toTable
|
||||||
"cmd" : "\e[m",
|
clCfg.helpAttrOff =
|
||||||
"clDescrip": "\e[m",
|
{
|
||||||
"clDflVal" : "\e[m",
|
"cmd": "\e[m",
|
||||||
"clOptKeys": "\e[m",
|
"clDescrip": "\e[m",
|
||||||
"clValType": "\e[m",
|
"clDflVal": "\e[m",
|
||||||
"args" : "\e[m"
|
"clOptKeys": "\e[m",
|
||||||
}.toTable
|
"clValType": "\e[m",
|
||||||
|
"args": "\e[m"
|
||||||
|
}.toTable
|
||||||
|
|
||||||
dispatch(
|
dispatch(tsm, short = {"version": 'v'})
|
||||||
tsm,
|
|
||||||
short = {"version": 'v'},
|
|
||||||
)
|
|
||||||
|
|
Loading…
Reference in a new issue