1 /******************************************************************************* 2 3 A D wrapper around the GNU readline/readline file 4 5 readline is a powerful library for reading the user input from the console. 6 7 For example if an application frequently asks for user-input during its 8 operation then using readline provides the following benefits: 9 - User can browse previous submitted lines using up/down arrows. 10 - Terminal shortcuts (e.g ctrl+r, ctrl+w, ctrl+y) are enabled by default. 11 - Providing text auto-completion, by default it is enabled to complete 12 files and directories for the path that the application was run from. 13 - Make the application use the customized configuration that the user 14 defined for readline on his machine. 15 16 There are much more functionalities that the readline library provides. 17 Please refer to the documentation for the more information: 18 - http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html 19 20 Notes: 21 Requires linking with -lreadline 22 23 Copyright: 24 Copyright (c) 2009-2016 dunnhumby Germany GmbH. 25 All rights reserved. 26 27 License: 28 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. 29 Alternatively, this file may be distributed under the terms of the Tango 30 3-Clause BSD License (see LICENSE_BSD.txt for details). 31 32 Bear in mind this module provides bindings to an external library that 33 has its own license, which might be more restrictive. Please check the 34 external library license to see which conditions apply for linking. 35 36 *******************************************************************************/ 37 38 module ocean.io.console.readline.Readline; 39 40 41 import C = ocean.io.console.readline.c.readline; 42 import ocean.core.Array : copy; 43 import ocean.text.util.StringC; 44 45 import core.stdc.string: strlen; 46 import core.stdc.stdlib : free; 47 48 import ocean.meta.types.Qualifiers; 49 50 /******************************************************************************* 51 52 Reads a line from the terminal and return it, using prompt as a prompt. 53 If prompt is NULL or the empty string, no prompt is issued. 54 The line returned has the final newline removed, so only the text of the 55 line remains. 56 57 Except for the note below, the documentation is taken from the manpage of 58 readline. Refer to the readline manpage for more extensive documentation. 59 60 Note: 61 If prompt isn't null-terminated and isn't null then it's converted to a 62 C null-terminated string before passing it to the C readline function. 63 Converting to C string might re-allocate the buffer. If you have tight 64 memory constraints, it is highly recommended to provide a null 65 terminated string or make sure that the GC block your buffer is stored 66 in has a spare byte at the end. 67 68 Params: 69 prompt = the string to be prompted to the user (see note above) 70 buffer = optional buffer to store the user input, if the buffer is null 71 then it would be allocated only if the user provided an input. 72 73 Returns: 74 Returns the text of the line read. A blank line returns empty string. 75 If EOF is encountered while reading a line, and the line is empty, null 76 is returned. If an EOF is read with a non-empty line, it is treated 77 as a newline. 78 79 *******************************************************************************/ 80 81 mstring readline(ref mstring prompt, ref mstring buffer) 82 { 83 char* prompt_ptr = null; 84 if (prompt != null) 85 { 86 prompt_ptr = StringC.toCString( prompt ); 87 } 88 89 char* c_buf = C.readline(prompt_ptr); 90 scope (exit) free(c_buf); 91 if (c_buf is null) 92 { 93 return null; 94 } 95 96 auto c_buf_len = strlen(c_buf); 97 if (buffer is null && c_buf_len == 0) 98 { 99 buffer.length = 1; //Allocate the pointer so we wouldn't return null 100 } 101 buffer.copy( c_buf[0..c_buf_len] ); 102 return buffer; 103 } 104 105 /******************************************************************************* 106 107 Function signature for functions used with the rl_bind_key functions and 108 various other functions. 109 110 *******************************************************************************/ 111 112 alias C.rl_command_func_t CommandFunc; 113 114 /******************************************************************************* 115 116 Bind a keyboard key to a function. 117 118 The function will be called when the user is prompted for input and he 119 presses the bound key. 120 121 Note that by default the tab key is bound to auto-complete the file names 122 that exist in the directory the application was run from. To disable this 123 bind the tab key with the abort function defined in this module: 124 bindKey('\t', abort); 125 126 Params: 127 key = ASCII int value of the key to be bound 128 func = the func triggered when they key is pressed 129 130 *******************************************************************************/ 131 132 void bindKey(char key, CommandFunc* func) 133 { 134 C.rl_bind_key(cast(int)key, func); 135 } 136 137 /******************************************************************************* 138 139 Completion functions to be used with key bindings 140 141 *******************************************************************************/ 142 143 alias C.rl_abort abort; // Binds a key do nothing (even not write itself) 144 alias C.rl_insert insert; // Binds a key to just write itself