rdstdin.nim 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2015 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## This module contains code for reading from `stdin`:idx:. On UNIX the
  10. ## linenoise library is wrapped and set up to provide default key bindings
  11. ## (e.g. you can navigate with the arrow keys). On Windows `system.readLine`
  12. ## is used. This suffices because Windows' console already provides the
  13. ## wanted functionality.
  14. runnableExamples("-r:off"):
  15. echo readLineFromStdin("Is Nim awesome? (Y/n): ")
  16. var line: string
  17. while true:
  18. let ok = readLineFromStdin("How are you? ", line)
  19. if not ok: break # ctrl-C or ctrl-D will cause a break
  20. if line.len > 0: echo line
  21. echo "exiting"
  22. when defined(windows):
  23. when defined(nimPreviewSlimSystem):
  24. import std/syncio
  25. proc readLineFromStdin*(prompt: string): string {.
  26. tags: [ReadIOEffect, WriteIOEffect].} =
  27. ## Reads a line from stdin.
  28. stdout.write(prompt)
  29. stdout.flushFile()
  30. result = readLine(stdin)
  31. proc readLineFromStdin*(prompt: string, line: var string): bool {.
  32. tags: [ReadIOEffect, WriteIOEffect].} =
  33. ## Reads a `line` from stdin. `line` must not be
  34. ## `nil`! May throw an IO exception.
  35. ## A line of text may be delimited by `CR`, `LF` or
  36. ## `CRLF`. The newline character(s) are not part of the returned string.
  37. ## Returns `false` if the end of the file has been reached, `true`
  38. ## otherwise. If `false` is returned `line` contains no new data.
  39. stdout.write(prompt)
  40. result = readLine(stdin, line)
  41. elif defined(genode):
  42. proc readLineFromStdin*(prompt: string): string {.
  43. tags: [ReadIOEffect, WriteIOEffect].} =
  44. stdin.readLine()
  45. proc readLineFromStdin*(prompt: string, line: var string): bool {.
  46. tags: [ReadIOEffect, WriteIOEffect].} =
  47. stdin.readLine(line)
  48. else:
  49. import std/linenoise
  50. proc readLineFromStdin*(prompt: string, line: var string): bool {.
  51. tags: [ReadIOEffect, WriteIOEffect].} =
  52. var buffer = linenoise.readLine(prompt)
  53. if isNil(buffer):
  54. line.setLen(0)
  55. return false
  56. line = $buffer
  57. if line.len > 0:
  58. historyAdd(buffer)
  59. linenoise.free(buffer)
  60. result = true
  61. proc readLineFromStdin*(prompt: string): string {.inline.} =
  62. if not readLineFromStdin(prompt, result):
  63. raise newException(IOError, "Linenoise returned nil")