https://github.com/jangko/nim-noise
Nim implementation of linenoise command line editor
https://github.com/jangko/nim-noise
command-line linenoise nim repl
Last synced: 20 days ago
JSON representation
Nim implementation of linenoise command line editor
- Host: GitHub
- URL: https://github.com/jangko/nim-noise
- Owner: jangko
- License: mit
- Created: 2018-09-25T15:14:55.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2024-10-23T13:45:17.000Z (6 months ago)
- Last Synced: 2025-04-09T16:19:05.371Z (20 days ago)
- Topics: command-line, linenoise, nim, repl
- Language: Nim
- Homepage:
- Size: 86.9 KB
- Stars: 63
- Watchers: 6
- Forks: 9
- Open Issues: 8
-
Metadata Files:
- Readme: readme.md
- License: LICENSE
Awesome Lists containing this project
README
# noise


Nim implementation of linenoise command line editor, inspired by
[replxx](https://github.com/AmokHuginnsson/replxx) and
[linenoise-ng](https://github.com/arangodb/linenoise-ng)## Features
* Line editing with emacs keybindings
* History handling
* Completion
* Unicode aware
* Intuitive ESC key sub menu escaping
* Incremental history search
* Support multiline editing out of the box
* Support multiline prompt with color and unicode characters
* A bunch of compile time switches to select which features you want to turn on/off
* Support Windows, Linux and Mac OS
* Disable all basic features, then you'll get a cross platform key stroke library## Planned Features
* Hints(work in progress)
* Syntax coloring(work in progress)## API
Primitive API(available when prompt_no_basic is defined):
* proc readChar(): char32Basic API:
* proc init(x: typedesc[Noise]): Noise
* proc getKeyType(self: Noise): KeyType
* proc getLine(self: var Noise): string
* proc readLine(self: var Noise): bool
* proc setPrompt(self: var Noise, text: Styler)
* proc setPrompt(self: var Noise, text: string)
* proc getPrompt(self: var Noise): StylerHistory API:
* proc historyAdd(self: var Noise, line: string)
* proc historySetMaxLen(self: var Noise, len: int)
* iterator histories(self: var Noise): string
* iterator historyPairs(self: var Noise): (int, string)
* proc historySave(self: var Noise, fileName: string): bool
* proc historyLoad(self: var Noise, fileName: string): bool
* proc historyClear(self: var Noise)Completion API:
* proc setCompletionHook(self: var Noise, prc: CompletionHook)
* proc addCompletion(self: var Noise, text: string)PreloadBuffer API:
* proc preloadBuffer(self: var Noise, preloadText: string)KillRing API:
* proc killSetMaxLen(self: var Noise, len: int)## Examples
```Nim
import noise, strutilsproc main() =
var noise = Noise.init()let prompt = Styler.init(fgRed, "Red ", fgGreen, "čšć> ")
noise.setPrompt(prompt)when promptPreloadBuffer:
noise.preloadBuffer("Superman")when promptHistory:
var file = "history"
discard noise.historyLoad(file)when promptCompletion:
proc completionHook(noise: var Noise, text: string): int =
const words = ["apple", "diamond", "diadem", "diablo", "horse", "home", "quartz", "quit"]
for w in words:
if w.find(text) != -1:
noise.addCompletion wnoise.setCompletionHook(completionHook)
while true:
let ok = noise.readLine()
if not ok: breaklet line = noise.getLine
case line
of ".help": printHelp()
of ".quit": break
else: discardwhen promptHistory:
if line.len > 0:
noise.historyAdd(line)when promptHistory:
discard noise.historySave(file)main()
```## Key Binding
```text
# Completion
CTRL-I/TAB activates completion
TAB again rotate between completion alternatives
ESC, CTRL-C undo changes and exit to normal editing
Other keys accept completion and resume to normal editing# History
CTRL-P, UP_ARROW_KEY recall previous line in history
CTRL-N, DOWN_ARROW_KEY recall next line in history
ALT-<, PAGE_UP_KEY beginning of history
ALT->, PAGE_DOWN_KEY end of history# Incremental history search
CTRL-R, CTRL-S forward/reverse interactive history search
TAB, DOWN_ARROW_KEY rotate between history alternatives(+)
UP_ARROW_KEY rotate between history alternatives(-)
ESC, CTRL-C cancel selection and exit to normal editing
Other keys accept selected history# Kill and yank
ALT-D kill word to right of cursor
ALT + Backspace kill word to left of cursor
CTRL-K kill from cursor to end of line
CTRL-U kill all characters to the left of the cursor
CTRL-W kill to whitespace (not word) to left of cursor
CTRL-Y yank killed text
ALT-Y 'yank-pop', rotate popped text# Word editing
ALT-C give word initial cap
ALT-L lowercase word
CTRL-T transpose characters
ALT-U uppercase word# Cursor navigation
CTRL-A, HOME_KEY move cursor to start of line
CTRL-E, END_KEY move cursor to end of line
CTRL-B, LEFT_ARROW_KEY move cursor left by one character
CTRL-F, RIGHT_ARROW_KEY move cursor right by one character
ALT-F,
CTRL + RIGHT_ARROW_KEY,
ALT + RIGHT_ARROW_KEY move cursor right by one word
ALT-B,
CTRL + LEFT_ARROW_KEY,
ALT + LEFT_ARROW_KEY move cursor left by one word# Basic Editing
CTRL-C abort this line
CTRL-H/backspace delete char to left of cursor
DELETE_KEY delete the character under the cursor
CTRL-D delete the character under the cursor
on an empty line, exit the shell
CTRL-J, CTRL-M/Enter accept line
CTRL-L clear screen and redisplay line
```## Compile time switches:
Please use `-d:` or `--define:` during build time.
* prompt_no_history
* prompt_no_kill
* prompt_no_completion
* prompt_no_word_editing
* prompt_no_preload_buffer
* prompt_no_incremental_history_search(if you disabled history, this one also disabled)
* prompt_no_basic(disable all features, you'll only have access to primitives API.)Altough you can use `killSetMaxLen` and `historySetMaxLen` at runtime,
there are compile time options to set them too. e.g. `-d:DefaultHistoryMaxLen=150`* DefaultHistoryMaxLen
* DefaultKillRingMaxLen* esc_exit_editing
While Ctrl-C perform hard abort, `esc_exit_editing` allow soft abort when ESC pressed.
You can get the key type using `getKeyType`.```Nim
while true:
let ok = noise.readLine()
if not ok: breakif noise.getKeyType == ktEsc:
echo "do something"
```* prompt_emacs_word_editing
By default case editing keys will change the case from the beginning of a
word, this switch will enable Emacs behavior, where the case is changed from
the cursor position until the end of the word.## Unicode awareness
On Posix OSes, everything is encoded in UTF-8. On Windows, the API dictates UTF-16 usage.
Internally, nim-noise use UTF-32 to encode the text and some homebrew encoding to encode keyboard keys.
Altough this is sound complicated, you as a user will only deal with UTF-8 when interacting with nim-noise.
If your application only use ASCII subset, then you will not to worry about anything.When you write your completion callback, add and retrieve history, preloaded buffer,
you will receive UTF-8 encoded string and give UTF-8/ASCII encoded string too.## Primitives API
Sometimes, when building a console UI, all you need is only a cross platform key stroke library.
You can use nim-noise like that by specifying `prompt_no_basic`.## Installation via nimble
> nimble install noise