summary refs log tree commit diff stats
path: root/lib/wrappers/linenoise/linenoise.nim
diff options
context:
space:
mode:
Diffstat (limited to 'lib/wrappers/linenoise/linenoise.nim')
-rw-r--r--lib/wrappers/linenoise/linenoise.nim42
1 files changed, 40 insertions, 2 deletions
diff --git a/lib/wrappers/linenoise/linenoise.nim b/lib/wrappers/linenoise/linenoise.nim
index a6260eb12..186b3b252 100644
--- a/lib/wrappers/linenoise/linenoise.nim
+++ b/lib/wrappers/linenoise/linenoise.nim
@@ -9,14 +9,14 @@
 
 type
   Completions* = object
-    len*: csize
+    len*: csize_t
     cvec*: cstringArray
 
   CompletionCallback* = proc (a2: cstring; a3: ptr Completions) {.cdecl.}
 
 {.compile: "linenoise.c".}
 
-proc setCompletionCallback*(a2: ptr CompletionCallback) {.
+proc setCompletionCallback*(a2: CompletionCallback) {.
     importc: "linenoiseSetCompletionCallback".}
 proc addCompletion*(a2: ptr Completions; a3: cstring) {.
     importc: "linenoiseAddCompletion".}
@@ -32,3 +32,41 @@ proc printKeyCodes*() {.importc: "linenoisePrintKeyCodes".}
 
 proc free*(s: cstring) {.importc: "free", header: "<stdlib.h>".}
 
+when defined(nimExperimentalLinenoiseExtra) and not defined(windows):
+  # C interface
+  type LinenoiseStatus = enum
+    linenoiseStatus_ctrl_unknown
+    linenoiseStatus_ctrl_C
+    linenoiseStatus_ctrl_D
+
+  type LinenoiseData* = object
+    status: LinenoiseStatus
+
+  proc linenoiseExtra(prompt: cstring, data: ptr LinenoiseData): cstring {.importc.}
+
+  # stable nim interface
+  type Status* = enum
+    lnCtrlUnkown
+    lnCtrlC
+    lnCtrlD
+
+  type ReadLineResult* = object
+    line*: string
+    status*: Status
+
+  proc readLineStatus*(prompt: string, result: var ReadLineResult) =
+    ## line editing API that allows returning the line entered and an indicator
+    ## of which control key was entered, allowing user to distinguish between
+    ## for example ctrl-C vs ctrl-D.
+    runnableExamples("-d:nimExperimentalLinenoiseExtra -r:off"):
+      var ret: ReadLineResult
+      while true:
+        readLineStatus("name: ", ret) # ctrl-D will exit, ctrl-C will go to next prompt
+        if ret.line.len > 0: echo ret.line
+        if ret.status == lnCtrlD: break
+      echo "exiting"
+    var data: LinenoiseData
+    let buf = linenoiseExtra(prompt, data.addr)
+    result.line = $buf
+    free(buf)
+    result.status = data.status.ord.Status