rpgsheet

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 752390bfe76c283afaf73fe27ba2f2b313a853a4
parent 515da219f2915c965b0639819bfdb584787ac22f
Author: Skylar Hill <stellarskylark@posteo.net>
Date:   Sun,  5 Jun 2022 18:38:23 -0500

Add edit function

Diffstat:
Mrpgsheet.nimble | 2+-
Msrc/rpgsheet.nim | 3+++
Msrc/tui.nim | 32++++++++++++++++++--------------
Msrc/utils.nim | 15+++++++++++++++
Msrc/verb.nim | 51++++++++++++++++++++++++++++++++++++++++++++-------
5 files changed, 81 insertions(+), 22 deletions(-)

diff --git a/rpgsheet.nimble b/rpgsheet.nimble @@ -1,6 +1,6 @@ # Package -version = "0.2.5" +version = "0.2.6" author = "Skylar Hill" description = "CLI/TUI application for TTRPG character sheets" license = "GPL-3.0-only" diff --git a/src/rpgsheet.nim b/src/rpgsheet.nim @@ -43,6 +43,7 @@ proc main(): void = case key of "v", "view": verb = View of "i", "interactive": verb = Tui + of "e", "edit": verb = Edit else: quit(usage) @@ -56,5 +57,7 @@ proc main(): void = runTui(sheet, sheetLocation) return echo doVerb(action, verb, sheet) + if verb == Edit: + write(sheet, sheetLocation) main() diff --git a/src/tui.nim b/src/tui.nim @@ -165,20 +165,21 @@ proc drawHelp(): void = tb.write(2, 4, "l Select window to the right") tb.write(2, 5, "j Select next item in window") tb.write(2, 6, "k Select previous item in window") - tb.write(2, 7, "Enter Roll selected item") - tb.write(2, 8, "] Scroll description forward") - tb.write(2, 9, "[ Scroll description backward") - tb.write(2, 10, "= Increase item value by 1 (if hardcoded integer)") - tb.write(2, 11, "- Decrease item value by 1 (if hardcoded integer)") - tb.write(2, 12, "+ Increase item value by 10 (if hardcoded integer)") - tb.write(2, 13, "_ Decrease item value by 10 (if hardcoded integer)") - tb.write(2, 14, "J/Tab Switch to next tab") - tb.write(2, 15, "K Switch to previous tab") - tb.write(2, 16, ": Run a command") - tb.write(2, 17, " :r[oll] <expression>") - tb.write(2, 18, " Roll a dice expression or item in your character sheet.") - tb.write(2, 19, " :w[rite] [optional-path]") - tb.write(2, 20, " Overwrite the current character sheet, or write to the given path.") + tb.write(2, 7, "e Edit selected item") + tb.write(2, 8, "Enter Roll selected item") + tb.write(2, 9, "] Scroll description forward") + tb.write(2, 10, "[ Scroll description backward") + tb.write(2, 11, "= Increase item value by 1 (if hardcoded integer)") + tb.write(2, 12, "- Decrease item value by 1 (if hardcoded integer)") + tb.write(2, 13, "+ Increase item value by 10 (if hardcoded integer)") + tb.write(2, 14, "_ Decrease item value by 10 (if hardcoded integer)") + tb.write(2, 15, "J/Tab Switch to next tab") + tb.write(2, 16, "K Switch to previous tab") + tb.write(2, 17, ": Run a command") + tb.write(2, 18, " :r[oll] <expression>") + tb.write(2, 19, " Roll a dice expression or item in your character sheet.") + tb.write(2, 20, " :w[rite] [optional-path]") + tb.write(2, 21, " Overwrite the current character sheet, or write to the given path.") tb.display() sleep(20) @@ -363,6 +364,9 @@ proc handleInput(state: State, file: string): int = state.sleepTime = 0 # smoother typing of Key.QuestionMark: state.mode = Help + of Key.E: + state.statusText = doVerb(state.selectedItem, Edit, state.sheet) + hideCursor() else: discard diff --git a/src/utils.nim b/src/utils.nim @@ -2,26 +2,38 @@ import tables, strutils, yaml let noCap = ["and", "of", "the", "as", "at", "but", "by", "for", "from", "if", "in", "on", "once", "onto", "or", "over", "so", "than", "that", "to", "up", "with", "when"] + proc loopInc*(index: int, list: seq): int = result = if index < list.high: index + 1 else: list.low + proc loopDec*(index: int, list: seq): int = result = if index > list.low: index - 1 else: list.high + proc expression*(sheet: YamlDocument, exp: string): YamlNode = sheet.root["expressions"][exp] + proc find*[T](list: seq[T], item: T): int = for i in 0..list.high: if list[i] == item: return i result = -1 + +proc key*(node: YamlNode, search: string): YamlNode = + for key, _ in node.pairs: + if key.content == search: + return key + raise newException(ValueError, search & " is not defined") + + proc fancyDisplay*(exp: string, maxLen: int): string = var working = exp working = @@ -37,10 +49,12 @@ proc fancyDisplay*(exp: string, maxLen: int): string = words[i] = words[i].capitalizeAscii result = words.join(" ") + proc deFancy*(display: string): string = result = display.replace(" ", "_") result = result.replace("-", "~") result = result.toLowerAscii() + proc contains*(node: YamlNode, search: string): bool = for key, _ in node.pairs: @@ -48,6 +62,7 @@ proc contains*(node: YamlNode, search: string): bool = return true return false + proc field*(node: YamlNode, search: string): string = for key, value in node.pairs: if key.content == search: diff --git a/src/verb.nim b/src/verb.nim @@ -1,9 +1,10 @@ import - osproc, - re, - streams, - strformat, - strutils, + std/os, + std/osproc, + std/re, + std/streams, + std/strformat, + std/strutils, yaml import utils @@ -17,6 +18,7 @@ type Roll View Tui + Edit proc expressionAsString(node: YamlNode): string = @@ -26,7 +28,7 @@ proc expressionAsString(node: YamlNode): string = result = result & fmt"""Window: {node.field("window")}""" -proc calculateModifier(exp: string, sheet: YamlDocument): string = +proc calculateModifier*(exp: string, sheet: YamlDocument): string = if exp == "": return "0" @@ -52,7 +54,7 @@ proc calculateModifier(exp: string, sheet: YamlDocument): string = return calculateModifier(working, sheet) -proc roll(action: string, sheet: YamlDocument): string = +proc roll*(action: string, sheet: YamlDocument): string = if action.contains(reDice): let (output, code) = execCmdEx("rolldice -s", input = action) if code == 0: @@ -96,6 +98,39 @@ proc view(action: string, sheet: YamlDocument): string = echo expressionAsString(node) +proc edit*(action: string, sheet: YamlDocument): string = + let outStream = newFileStream("/tmp/rpgsheet-tmp", fmWrite) + initYamlDoc(sheet.expression(action)).dumpDom(outStream) + outStream.close() + + if existsEnv("EDITOR"): + let cmd = getEnv("EDITOR") + let editor = startProcess(cmd, args = ["/tmp/rpgsheet-tmp"], + options = {poEchoCmd, poUsePath, poInteractive, poParentStreams}) + discard editor.waitForExit + elif findExe("editor") != "": + let editor = startProcess("editor", args = ["/tmp/rpgsheet-tmp"], + options = {poUsePath, poInteractive, poParentStreams}) + discard editor.waitForExit + elif findExe("vi") != "": + let editor = startProcess("vi", args = ["/tmp/rpgsheet-tmp"], + options = {poUsePath, poInteractive, poParentStreams}) + discard editor.waitForExit + else: + return "Could not find an editor to use" + + let inStream = newFileStream("/tmp/rpgsheet-tmp", fmRead) + let key = sheet.root["expressions"].key(action) + try: + let newNode = inStream.loadDom.root + sheet.root["expressions"][key] = newNode + result = "Successfully edited " & action + except YamlParserError as e: + result = "ERROR " & getCurrentExceptionMsg() & ": " & e.lineContent + finally: + inStream.close() + + proc write*(doc: YamlDocument, file: string) = let s = newfileStream(file, fmWrite) dumpDom(doc, s, options = defineOptions(style = psBlockOnly)) @@ -110,3 +145,5 @@ proc doVerb*(action: string, verb: Verb, sheet: YamlDocument): string = return view(action, sheet) of Tui: raise newException(Exception, "Please report this error, this code should never get run.") + of Edit: + return edit(action, sheet)