Skip to content

Commit

Permalink
Fixed some issues with plugin bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
Nimaoth committed Jan 14, 2024
1 parent 3cf24e7 commit 4e89efa
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 47 deletions.
12 changes: 6 additions & 6 deletions config/absytree_config.nim
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import absytree_runtime
import std/[strutils, sugar, sequtils, macros]

import keybindings_vim
import keybindings_vim_like
import keybindings_helix
import keybindings_normal

proc handleAction*(action: string, args: JsonNode): bool {.wasmexport.} =
when not defined(wasm):
return false
Expand Down Expand Up @@ -78,9 +73,14 @@ proc postInitialize*(): bool {.wasmexport.} =
import default_config

when defined(wasm):
import keybindings_vim
import keybindings_vim_like
import keybindings_helix
import keybindings_normal

loadDefaultOptions()
loadDefaultKeybindings()
loadVimLikeKeybindings()
loadVimKeybindings()

# Triple click to selects a line
setOption "editor.text.triple-click-command", "extend-select-move"
Expand Down
Binary file modified config/absytree_config_wasm.wasm
Binary file not shown.
1 change: 1 addition & 0 deletions config/keybindings_normal.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ proc setModeChangedHandler*(handler: proc(editor: TextDocumentEditor, oldMode: s
if modeChangedHandler != "":
onEditorModeChanged.unsubscribe(parseId(modeChangedHandler))
let id = onEditorModeChanged.subscribe proc(arg: auto) =
# infof"onEditorModeChanged: {arg.editor}, {arg.oldMode}, {arg.newMode}"
if arg.editor.isTextEditor(editor) and not editor.isRunningSavedCommands:
handler(editor, arg.oldMode, arg.newMode)
setOption("editor.text.mode-changed-handler", $id)
Expand Down
37 changes: 23 additions & 14 deletions scripting/absytree_runtime.nim
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ template isModelEditor*(editorId: EditorId, injected: untyped): bool =
(scriptIsModelEditor(editorId) and ((let injected {.inject.} = ModelDocumentEditor(id: editorId); true)))

proc handleCallbackImpl*(id: int, args: JsonNode): bool =
# infof"handleCallbackImpl {id}, {args}"
if voidCallbacks.contains(id):
voidCallbacks[id](args)
return true
Expand All @@ -102,17 +103,18 @@ proc handleCallbackImpl*(id: int, args: JsonNode): bool =
return false

proc handleAnyCallbackImpl*(id: int, args: JsonNode): JsonNode =
# infof"handleAnyCallbackImpl {id}, {args}"
if voidCallbacks.contains(id):
voidCallbacks[id](args)
return nil
return newJNull()
elif boolCallbacks.contains(id):
return newJBool(boolCallbacks[id](args))
elif anyCallbacks.contains(id):
return anyCallbacks[id](args)
return nil

proc handleScriptActionImpl*(name: string, args: JsonNode): JsonNode =
# echo "handleScriptActionImpl ", name, ", ", args
# infof"handleScriptActionImpl {name}, {args}"
if scriptActions.contains(name):
return scriptActions[name](args)
return nil
Expand Down Expand Up @@ -202,9 +204,14 @@ macro addCommand*(context: string, keys: string, action: string, args: varargs[u
addCommandScript(context, keysPrefix & keys, action, str)

proc addCommand*(context: string, keys: string, action: proc(): void) =
let key = context & keys
lambdaActions[key] = action
addCommandScript(context, keysPrefix & keys, "lambda-action", key.toJsonString)
let key = "$" & context & keys
# lambdaActions[key] = action
scriptActions[key] = proc(args: JsonNode): JsonNode =
action()
return newJNull()

# addCommandScript(context, keysPrefix & keys, "lambda-action", key.toJsonString)
addCommandScript(context, keysPrefix & keys, key, "")

template addCommandBlock*(context: static[string], keys: string, body: untyped): untyped =
addCommand context, keys, proc() =
Expand Down Expand Up @@ -246,7 +253,7 @@ template addTextCommandBlock*(mode: static[string], keys: string, body: untyped)
except:
let m {.inject.} = mode
let k {.inject.} = keys
infof "TextCommandBlock {m} {k}: {getCurrentExceptionMsg()}"
infof"TextCommandBlock {m} {k}: {getCurrentExceptionMsg()}"

proc addTextCommand*(mode: string, keys: string, action: proc(editor: TextDocumentEditor): void) =
let context = if mode.len == 0: "editor.text" else: "editor.text." & mode
Expand All @@ -256,7 +263,7 @@ proc addTextCommand*(mode: string, keys: string, action: proc(editor: TextDocume
except:
let m {.inject.} = mode
let k {.inject.} = keys
infof "TextCommand {m} {k}: {getCurrentExceptionMsg()}"
infof"TextCommand {m} {k}: {getCurrentExceptionMsg()}"

macro addTextCommand*(mode: static[string], keys: string, action: string, args: varargs[untyped]): untyped =
let context = if mode.len == 0: "editor.text" else: "editor.text." & mode
Expand All @@ -271,18 +278,18 @@ proc setTextInputHandler*(context: string, action: proc(editor: TextDocumentEdit
let input = args.str
return action(TextDocumentEditor(id: getActiveEditor()), input)
except:
infof "TextInputHandler {context}: {getCurrentExceptionMsg()}"
infof"TextInputHandler {context}: {getCurrentExceptionMsg()}"

scriptSetCallback("editor.text.input-handler." & context, id)
setHandleInputs("editor.text." & context, true)

var customMoves = initTable[string, proc(editor: TextDocumentEditor, cursor: Cursor, count: int): Selection]()
proc handleCustomTextMove*(editor: TextDocumentEditor, move: string, cursor: Cursor, count: int): Selection =
proc handleCustomTextMove*(editor: TextDocumentEditor, move: string, cursor: Cursor, count: int): Option[Selection] =
if customMoves.contains(move):
return customMoves[move](editor, cursor, count)
return cursor.toSelection
return customMoves[move](editor, cursor, count).some
return Selection.none

when defined(wasm):
block: # Custom moves
let id = addCallback proc(args: JsonNode): JsonNode =
type Payload = object
editor: EditorId
Expand All @@ -293,7 +300,9 @@ when defined(wasm):
let input = args.jsonTo(Payload)
if input.editor.isTextEditor editor:
let selection = handleCustomTextMove(editor, input.move, input.cursor, input.count)
return selection.toJson
if selection.isSome:
return selection.toJson
return nil
else:
infof"Custom move: editor {input.editor} is not a text editor"
return nil
Expand All @@ -313,7 +322,7 @@ template addModelCommandBlock*(mode: static[string], keys: string, body: untyped
except:
let m {.inject.} = mode
let k {.inject.} = keys
infof "modelCommandBlock {m} {k}: {getCurrentExceptionMsg()}"
infof"ModelCommandBlock {m} {k}: {getCurrentExceptionMsg()}"

proc addModelCommand*(mode: string, keys: string, action: proc(editor: ModelDocumentEditor): void) =
let context = if mode.len == 0: "editor.model" else: "editor.model." & mode
Expand Down
2 changes: 2 additions & 0 deletions scripting/absytree_runtime_impl.nim
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ proc handleUnknownPopupAction*(id: EditorId, action: string, args: JsonNode): bo
return handlePopupAction(id, action, args)

proc handleEditorModeChanged*(editor: EditorId, oldMode: string, newMode: string) =
# infof"handleEditorModeChanged {editor} {oldMode} {newMode}"
onEditorModeChanged.invoke (editor, oldMode, newMode)

when defined(wasm):
Expand All @@ -53,6 +54,7 @@ when defined(wasm):
return false

proc handleEditorModeChangedWasm(id: int32, oldMode: cstring, newMode: cstring) {.wasmexport.} =
# infof"handleEditorModeChangedWasm {id} {oldMode} {newMode}"
try:
handleEditorModeChanged(id.EditorId, $oldMode, $newMode)
except:
Expand Down
2 changes: 2 additions & 0 deletions src/absytree.nim
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,9 @@ proc runApp(): Future[void] {.async.} =

logger.flush()

log lvlInfo, "Shutting down editor"
ed.shutdown()
log lvlInfo, "Shutting down platform"
rend.deinit()

waitFor runApp()
Expand Down
5 changes: 0 additions & 5 deletions src/misc/wrap.nim
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,7 @@ proc createJsonWrapper*(def: NimNode, newName: NimNode): NimNode =

result = genAst(functionName = newName, call, argName = jsonArg):
proc functionName*(argName: JsonNode): JsonNode {.nimcall, used.} =
# try:
call
# except CatchableError:
# let name = `pureFunctionNameStr`
# echo "[editor] Failed to run function " & name & fmt": Invalid arguments: {getCurrentExceptionMsg()}"
# echo getCurrentException().getStackTrace

proc serializeArgumentsToJson*(def: NimNode, targetUiae: NimNode): (NimNode, NimNode) =
let argsName = genSym(nskVar)
Expand Down
32 changes: 21 additions & 11 deletions src/scripting/expose.nim
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@


import std/[json, strutils, sequtils, tables, options, macros, genasts, macrocache, typetraits, sugar]
from std/logging import nil
import fusion/matching
import misc/[util, custom_logger, macro_utils, wrap]
import compilation_config, dispatch_tables
Expand Down Expand Up @@ -293,7 +294,7 @@ macro expose*(moduleName: static string, def: untyped): untyped =
let lineNumber = def.lineInfoObj.line

if returnType.isSome:
let uiae = genAst(res=callJsonStringWrapperFunctionWasmRes, resStr="resStr".ident):
let uiae = genAst(res=callJsonStringWrapperFunctionWasmRes):
result = parseJson($res).jsonTo(typeof(result))
callJsonStringWrapperFunctionWasm.add uiae

Expand Down Expand Up @@ -330,14 +331,17 @@ macro expose*(moduleName: static string, def: untyped): untyped =
result.add quote do:
var `jsonStringWrapperFunctionReturnValue`: string = ""
proc `jsonStringWrapperFunctionName`*(arg: cstring): cstring {.exportc, used.} =
# try:
let argJson = parseJson($arg)
`jsonStringWrapperFunctionReturnValue` = $`jsonWrapperFunctionName`(argJson)
return `jsonStringWrapperFunctionReturnValue`.cstring
# except CatchableError:
# let name = `pureFunctionNameStr`
# echo "[editor] Failed to run function " & name & fmt": Invalid arguments: {getCurrentExceptionMsg()}"
# echo getCurrentException().getStackTrace
try:
let argJson = parseJson($arg)
let res = `jsonWrapperFunctionName`(argJson)
if res.isNil:
`jsonStringWrapperFunctionReturnValue` = ""
else:
`jsonStringWrapperFunctionReturnValue` = $res
return `jsonStringWrapperFunctionReturnValue`.cstring
except:
let name = `pureFunctionNameStr`
logging.log lvlError, "Failed to run function " & name & &": Invalid arguments: {getCurrentExceptionMsg()}\n{getStackTrace()}"

static:
addWasmImportedFunction(`moduleName`, `jsonStringWrapperFunctionName`, `jsonStringWrapperFunctionWasm`):
Expand Down Expand Up @@ -417,10 +421,16 @@ macro genDispatcher*(moduleName: static string): untyped =
else:
alternative.add c

let call = genAst(target, arg):
let res = target(arg)
if res.isNil:
return JsonNode.none
return res.some

if name == alternative:
switch.add nnkOfBranch.newTree(newLit(name), quote do: `target`(`arg`).some)
switch.add nnkOfBranch.newTree(newLit(name), call)
else:
switch.add nnkOfBranch.newTree(newLit(name), newLit(alternative), quote do: `target`(`arg`).some)
switch.add nnkOfBranch.newTree(newLit(name), newLit(alternative), call)

switch.add nnkElse.newTree(quote do: JsonNode.none)

Expand Down
17 changes: 6 additions & 11 deletions src/scripting/scripting_nim.nim
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,11 @@ proc createInterpreterAsync(args: (ptr Interpreter, string, seq[string], seq[(st
var intr = createInterpreter(args[1], args[2], flags = {allowInfiniteLoops}, defines = args[3])

for uProc in args[4].procs:
intr.implementRoutine("Absytree", args[6], uProc.name, uProc.vmProc)
intr.implementRoutine("absytree", args[6], uProc.name, uProc.vmProc)

for (module, addins) in args[5]:
for uProc in addins.procs:
intr.implementRoutine("Absytree", module, uProc.name, uProc.vmProc)
intr.implementRoutine("absytree", module, uProc.name, uProc.vmProc)

setUseIc(true)

Expand All @@ -98,12 +98,6 @@ import std/[strformat, sequtils, macros, tables, options, sugar, strutils, genas
import scripting_api
import misc/[util, myjsonutils]
import absytree_runtime
import keybindings_vim
import keybindings_helix
import keybindings_normal
import languages
"""
intr.evalString(initCode)

Expand Down Expand Up @@ -315,13 +309,14 @@ macro invoke*(self: ScriptContext; pName: untyped;
call.add x
call.add nnkExprEqExpr.newTree(ident"returnType", returnType)

return genAst(self, call):
return genAst(self, call, name = pName.repr.newLit):
if self.state != Initialized:
log lvlError, fmt"ScriptContext not initialized yet. State is {self.state}"
log lvlWarn, fmt"ScriptContext not initialized yet. State is {self.state} (trying to invoke" & name & ")"
return
if self.inter.isNone:
log(lvlError, fmt"Interpreter is none. State is {self.state}")
log lvlError, fmt"Interpreter is none. State is {self.state}"
return

call

method handleUnknownPopupAction*(self: ScriptContextNim, popup: Popup, action: string, arg: JsonNode): bool =
Expand Down
2 changes: 2 additions & 0 deletions src/scripting/scripting_wasm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ method init*(self: ScriptContextWasm, path: string): Future[void] {.async.} =
self.handleScriptActionCallbacks.add (module, f)

if findFunction(module, "absytree_main", void, proc(): void).getSome(f):
log lvlInfo, "Run absytree_main"
f()
log lvlInfo, "Finished absytree_main"

self.modules.add module

Expand Down

0 comments on commit 4e89efa

Please sign in to comment.