feat: selector improvements

This commit is contained in:
Daylin Morgan 2024-09-19 18:02:59 -05:00
parent 44ef292e5b
commit 0d7459bca1
Signed by: daylin
GPG key ID: 950D13E9719334AD
5 changed files with 56 additions and 49 deletions

5
.gitignore vendored
View file

@ -2,13 +2,10 @@
/dist /dist
/bin /bin
# atlas
src/nim.cfg
*.workspace
# nimble # nimble
nimbledeps nimbledeps
nimble.develop nimble.develop
nimble.paths nimble.paths
result result
src/selector

View file

@ -2,19 +2,19 @@ import std/[strformat, strutils]
task debugSelect, "debug select": task debugSelect, "debug select":
exec "nim -d:debug c -r src/selector.nim" exec "nim -d:debugSelect c -r src/selector.nim"
task build, "build app": task build, "build app":
selfExec "c -o:bin/tsm src/tsm.nim" selfExec "c -o:bin/tsm src/tsm.nim"
task buildRelease, "build app": task buildRelease, "build release app":
selfExec "c -d:release -o:bin/tsm src/tsm.nim" selfExec "c -d:release -o:bin/tsm src/tsm.nim"
task release, "build release assets": task release, "build release assets w/forge":
version = (gorgeEx "git describe --tags --always --match 'v*'").output version = (gorgeEx "git describe --tags --always --match 'v*'").output
exec &"forge release -v {version} -V" exec &"forge release -v {version} -V"
task bundle, "package build assets": task bundle, "package forge build assets":
withDir "dist": withDir "dist":
for dir in listDirs("."): for dir in listDirs("."):
echo dir echo dir

View file

@ -13,7 +13,7 @@ type
proc pathToName(path: string): string = proc pathToName(path: string): string =
splitPath(path)[1].replace(".", "_") splitPath(path)[1].replace(".", "_")
proc newProject(path: string, open: bool, name = "", named: bool = false): Project = proc newProject*(path: string, open: bool, name = "", named: bool = false): Project =
result.location = path result.location = path
result.name = result.name =
if name != "": if name != "":
@ -24,7 +24,7 @@ proc newProject(path: string, open: bool, name = "", named: bool = false): Proje
result.open = open result.open = open
result.named = named result.named = named
proc newUnknownProject(name: string): Project = proc newUnknownProject*(name: string): Project =
result.name = name result.name = name
result.open = true result.open = true

View file

@ -1,4 +1,4 @@
import std/[enumerate, os, strformat, strutils, terminal] import std/[enumerate, os, strformat, strutils, terminal, sequtils]
from illwill import illwillDeinit, illwillInit, getKey, Key from illwill import illwillDeinit, illwillInit, getKey, Key
import term, project import term, project
@ -22,10 +22,10 @@ type
max: Natural max: Natural
Buffer = object Buffer = object
height: int height: Natural
width: int width: Natural
buffer: string buffer: string
inputPad: int = 3 inputPad: Natural = 3
State = object State = object
buffer: Buffer buffer: Buffer
@ -37,30 +37,39 @@ type
var state = State() var state = State()
proc addLine(b: var Buffer, text: string) = func 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) = func 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
proc numLines(b: Buffer): int = func numLines(b: Buffer): int =
b.buffer.count '\n' b.buffer.count '\n'
func clip(
s: string,
width: int = state.buffer.width - 3
): string =
result =
if s.len > width: s[0..width]
else: s
proc draw(b: var Buffer) = proc draw(b: var Buffer) =
while b.numLines < b.height: while b.numLines < b.height:
b.addLine "" b.addLine ""
stdout.write(b.buffer) stdout.write(b.buffer)
when defined(debug): when defined(debugSelect):
stdout.writeLine "" stdout.writeLine ""
stdout.writeLine "DEBUG INFO -------------" stdout.writeLine "DEBUG INFO:"
stdout.writeLine $state.cursor stdout.writeLine $state.cursor
stdout.writeLine(alignLeft("Key: " & $(state.lastKey), b.Buffer.width)) stdout.writeLine alignLeft("Key: " & $(state.lastKey), b.Buffer.width)
stdout.cursorUp(b.numLines + 4) stdout.writeLine "(w: $1, h: $2)" % [$b.width, $b.height]
stdout.writeLine "-".repeat(b.width)
stdout.cursorUp b.numLines + 6
else: else:
stdout.cursorUp(b.numLines) stdout.cursorUp(b.numLines)
stdout.flushFile() stdout.flushFile()
@ -87,11 +96,11 @@ proc down() =
elif state.cursor.y == state.cursor.max: elif state.cursor.y == state.cursor.max:
scrollDown() scrollDown()
proc backspace(s: string): string = func backspace(s: string): string =
if s != "": if s != "":
result = s[0..^2] result = s[0..^2]
proc match(project: Project): Project = func match(project: Project): Project =
result = project result = project
result.matched = true result.matched = true
@ -111,27 +120,16 @@ proc sortProjects(): seq[Project] =
return priority & rest return priority & rest
proc getProject(): Project = proc getProject(): Project =
# NOTE: do i need to call sortProjects again here?
let projects = sortProjects() let projects = sortProjects()
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 = func highlight(p: Project): string =
let maxWidth = state.buffer.width - 2 if p.location == "": "green"
result = elif p.open: "yellow"
if s.len > maxWidth: elif p.named: "bold cyan"
s[0..^maxWidth] else: "default"
else:
s
proc highlight(p: Project): string =
if p.location == "":
"green"
elif p.open:
"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
@ -148,15 +146,14 @@ proc addProject(b: var Buffer, project: Project, selected: bool) =
else: else:
b.addLine(cur & $name.bb(project.highlight)) b.addLine(cur & $name.bb(project.highlight))
proc addProjectCount(b: var Buffer) = proc addInfoLine(b: var Buffer) =
let let
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
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")) infoLine = fmt"[[{low}-{high}/{numProjects}] Ctrl+E to new session"
b.addLine $(infoLine.clip(state.buffer.width - 2).bb("faint"))
proc addProjects(b: var Buffer) = proc addProjects(b: var Buffer) =
let let
@ -178,7 +175,7 @@ proc draw() =
var buffer = state.buffer var buffer = state.buffer
buffer.addInput buffer.addInput
buffer.addDivider buffer.addDivider
buffer.addProjectCount buffer.addInfoLine
buffer.addProjects buffer.addProjects
buffer.draw buffer.draw
@ -230,8 +227,16 @@ proc selectProject*(projects: seq[Project]): Project =
up() up()
of Key.Down: of Key.Down:
down() down()
of Key.CtrlE:
exitProc()
return newProject(
path = getCurrentDir(),
name = state.input,
open = false,
)
of of
Key.CtrlA..Key.CtrlL, Key.CtrlA..Key.CtrlD,
Key.CtrlF..Key.CtrlL,
Key.CtrlN..Key.CtrlZ, Key.CtrlN..Key.CtrlZ,
Key.CtrlRightBracket, Key.CtrlRightBracket,
Key.CtrlBackslash, Key.CtrlBackslash,
@ -252,6 +257,6 @@ proc selectProject*(projects: seq[Project]): Project =
sleep(10) sleep(10)
when isMainModule: when isMainModule:
projects = findProjects(open) let projects = findProjects(false)
let selected = selectProject(projects) let selected = selectProject(projects)
echo "selected project -> " & $selected.name echo "selected project -> " & $selected

5
todo.md Normal file
View file

@ -0,0 +1,5 @@
# tsm todo's
- [ ] add message about new keybind Ctrl+E
<!-- generated with <3 by daylinmorgan/todo -->