summaryrefslogtreecommitdiff
path: root/src/mongo/shell/linenoise.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/shell/linenoise.cpp')
-rw-r--r--src/mongo/shell/linenoise.cpp2839
1 files changed, 1465 insertions, 1374 deletions
diff --git a/src/mongo/shell/linenoise.cpp b/src/mongo/shell/linenoise.cpp
index 43b42b9f028..5fd3371f374 100644
--- a/src/mongo/shell/linenoise.cpp
+++ b/src/mongo/shell/linenoise.cpp
@@ -32,7 +32,7 @@
* line editing lib needs to be 20,000 lines of C code.
*
* You can find the latest source code at:
- *
+ *
* http://github.com/antirez/linenoise
*
* Does a number of crazy assumptions that happen to be true in 99.9999% of
@@ -80,7 +80,7 @@
* ED2 (Clear entire screen)
* Sequence: ESC [ 2 J
* Effect: clear the whole screen
- *
+ *
*/
#ifdef _WIN32
@@ -144,7 +144,7 @@ struct linenoiseCompletions {
#define LINENOISE_MAX_LINE 4096
// make control-characters more readable
-#define ctrlChar( upperCaseASCII ) ( upperCaseASCII - 0x40 )
+#define ctrlChar(upperCaseASCII) (upperCaseASCII - 0x40)
/**
* Recompute widths of all characters in a UChar32 buffer
@@ -152,9 +152,9 @@ struct linenoiseCompletions {
* @param widths output buffer of character widths
* @param charCount number of characters in buffer
*/
-static void recomputeCharacterWidths( const UChar32* text, char* widths, int charCount ) {
- for ( int i = 0; i < charCount; ++i ) {
- widths[ i ] = mk_wcwidth( text[ i ] );
+static void recomputeCharacterWidths(const UChar32* text, char* widths, int charCount) {
+ for (int i = 0; i < charCount; ++i) {
+ widths[i] = mk_wcwidth(text[i]);
}
}
@@ -167,19 +167,21 @@ static void recomputeCharacterWidths( const UChar32* text, char* widths, int cha
* @param xOut returned x position (zero-based)
* @param yOut returned y position (zero-based)
*/
-static void calculateScreenPosition( int x, int y, int screenColumns, int charCount, int& xOut, int& yOut ) {
+static void calculateScreenPosition(
+ int x, int y, int screenColumns, int charCount, int& xOut, int& yOut) {
xOut = x;
yOut = y;
int charsRemaining = charCount;
- while ( charsRemaining > 0 ) {
- int charsThisRow = ( x + charsRemaining < screenColumns ) ? charsRemaining : screenColumns - x;
+ while (charsRemaining > 0) {
+ int charsThisRow =
+ (x + charsRemaining < screenColumns) ? charsRemaining : screenColumns - x;
xOut = x + charsThisRow;
yOut = y;
charsRemaining -= charsThisRow;
x = 0;
++y;
}
- if ( xOut == screenColumns ) { // we have to special-case line wrap
+ if (xOut == screenColumns) { // we have to special-case line wrap
xOut = 0;
++yOut;
}
@@ -190,50 +192,49 @@ static void calculateScreenPosition( int x, int y, int screenColumns, int charCo
* @param buf32 text to calculate
* @param len length of text to calculate
*/
-static int calculateColumnPosition( UChar32* buf32, int len) {
- int width = mk_wcswidth( reinterpret_cast<const int*>( buf32 ), len );
- if ( width == -1 )
+static int calculateColumnPosition(UChar32* buf32, int len) {
+ int width = mk_wcswidth(reinterpret_cast<const int*>(buf32), len);
+ if (width == -1)
return len;
else
return width;
}
-static bool isControlChar( UChar32 testChar ) {
- return ( testChar < ' ' ) || // C0 controls
- ( testChar >= 0x7F && testChar <= 0x9F ); // DEL and C1 controls
+static bool isControlChar(UChar32 testChar) {
+ return (testChar < ' ') || // C0 controls
+ (testChar >= 0x7F && testChar <= 0x9F); // DEL and C1 controls
}
-struct PromptBase { // a convenience struct for grouping prompt info
- Utf32String promptText; // our copy of the prompt text, edited
- char* promptCharWidths; // character widths from mk_wcwidth()
- int promptChars; // chars in promptText
- int promptExtraLines; // extra lines (beyond 1) occupied by prompt
- int promptIndentation; // column offset to end of prompt
- int promptLastLinePosition; // index into promptText where last line begins
- int promptPreviousInputLen; // promptChars of previous input line, for clearing
- int promptCursorRowOffset; // where the cursor is relative to the start of the prompt
- int promptScreenColumns; // width of screen in columns
- int promptPreviousLen; // help erasing
- int promptErrorCode; // error code (invalid UTF-8) or zero
-
- PromptBase() : promptPreviousInputLen( 0 ) { }
+struct PromptBase { // a convenience struct for grouping prompt info
+ Utf32String promptText; // our copy of the prompt text, edited
+ char* promptCharWidths; // character widths from mk_wcwidth()
+ int promptChars; // chars in promptText
+ int promptExtraLines; // extra lines (beyond 1) occupied by prompt
+ int promptIndentation; // column offset to end of prompt
+ int promptLastLinePosition; // index into promptText where last line begins
+ int promptPreviousInputLen; // promptChars of previous input line, for clearing
+ int promptCursorRowOffset; // where the cursor is relative to the start of the prompt
+ int promptScreenColumns; // width of screen in columns
+ int promptPreviousLen; // help erasing
+ int promptErrorCode; // error code (invalid UTF-8) or zero
+
+ PromptBase() : promptPreviousInputLen(0) {}
};
struct PromptInfo : public PromptBase {
-
- PromptInfo( const UChar8* textPtr, int columns ) {
+ PromptInfo(const UChar8* textPtr, int columns) {
promptExtraLines = 0;
promptLastLinePosition = 0;
promptPreviousLen = 0;
promptScreenColumns = columns;
- Utf32String tempUnicode( textPtr );
+ Utf32String tempUnicode(textPtr);
// strip control characters from the prompt -- we do allow newline
UChar32* pIn = tempUnicode.get();
UChar32* pOut = pIn;
- while ( *pIn ) {
+ while (*pIn) {
UChar32 c = *pIn;
- if ( '\n' == c || !isControlChar( c ) ) {
+ if ('\n' == c || !isControlChar(c)) {
*pOut = c;
++pOut;
}
@@ -244,16 +245,15 @@ struct PromptInfo : public PromptBase {
promptText = tempUnicode;
int x = 0;
- for ( int i = 0; i < promptChars; ++i ) {
+ for (int i = 0; i < promptChars; ++i) {
UChar32 c = promptText[i];
- if ( '\n' == c ) {
+ if ('\n' == c) {
x = 0;
++promptExtraLines;
promptLastLinePosition = i + 1;
- }
- else {
+ } else {
++x;
- if ( x >= promptScreenColumns ) {
+ if (x >= promptScreenColumns) {
x = 0;
++promptExtraLines;
promptLastLinePosition = i + 1;
@@ -267,52 +267,62 @@ struct PromptInfo : public PromptBase {
// Used with DynamicPrompt (history search)
//
-static const Utf32String forwardSearchBasePrompt( reinterpret_cast<const UChar8*>( "(i-search)`" ) );
-static const Utf32String reverseSearchBasePrompt( reinterpret_cast<const UChar8*>( "(reverse-i-search)`" ) );
-static const Utf32String endSearchBasePrompt( reinterpret_cast<const UChar8*>( "': " ) );
-static Utf32String previousSearchText; // remembered across invocations of linenoise()
+static const Utf32String forwardSearchBasePrompt(reinterpret_cast<const UChar8*>("(i-search)`"));
+static const Utf32String reverseSearchBasePrompt(
+ reinterpret_cast<const UChar8*>("(reverse-i-search)`"));
+static const Utf32String endSearchBasePrompt(reinterpret_cast<const UChar8*>("': "));
+static Utf32String previousSearchText; // remembered across invocations of linenoise()
// changing prompt for "(reverse-i-search)`text':" etc.
//
struct DynamicPrompt : public PromptBase {
- Utf32String searchText; // text we are searching for
- char* searchCharWidths; // character widths from mk_wcwidth()
- int searchTextLen; // chars in searchText
- int direction; // current search direction, 1=forward, -1=reverse
+ Utf32String searchText; // text we are searching for
+ char* searchCharWidths; // character widths from mk_wcwidth()
+ int searchTextLen; // chars in searchText
+ int direction; // current search direction, 1=forward, -1=reverse
- DynamicPrompt( PromptBase& pi, int initialDirection ) : searchTextLen( 0 ), direction( initialDirection ) {
+ DynamicPrompt(PromptBase& pi, int initialDirection)
+ : searchTextLen(0), direction(initialDirection) {
promptScreenColumns = pi.promptScreenColumns;
promptCursorRowOffset = 0;
- Utf32String emptyString( 1 );
+ Utf32String emptyString(1);
searchText = emptyString;
- const Utf32String* basePrompt = ( direction > 0 ) ? &forwardSearchBasePrompt : &reverseSearchBasePrompt;
+ const Utf32String* basePrompt =
+ (direction > 0) ? &forwardSearchBasePrompt : &reverseSearchBasePrompt;
size_t promptStartLength = basePrompt->length();
promptChars = promptStartLength + endSearchBasePrompt.length();
- promptLastLinePosition = promptChars; // TODO fix this, we are asssuming that the history prompt won't wrap (!)
+ promptLastLinePosition =
+ promptChars; // TODO fix this, we are asssuming that the history prompt won't wrap (!)
promptPreviousLen = promptChars;
- Utf32String tempUnicode( promptChars + 1 );
- memcpy( tempUnicode.get(), basePrompt->get(), sizeof( UChar32 ) * promptStartLength );
- memcpy( &tempUnicode[promptStartLength], endSearchBasePrompt.get(), sizeof( UChar32 ) * ( endSearchBasePrompt.length() + 1 ) );
+ Utf32String tempUnicode(promptChars + 1);
+ memcpy(tempUnicode.get(), basePrompt->get(), sizeof(UChar32) * promptStartLength);
+ memcpy(&tempUnicode[promptStartLength],
+ endSearchBasePrompt.get(),
+ sizeof(UChar32) * (endSearchBasePrompt.length() + 1));
tempUnicode.initFromBuffer();
promptText = tempUnicode;
- calculateScreenPosition( 0, 0, pi.promptScreenColumns, promptChars, promptIndentation, promptExtraLines );
+ calculateScreenPosition(
+ 0, 0, pi.promptScreenColumns, promptChars, promptIndentation, promptExtraLines);
}
- void updateSearchPrompt( void ) {
- const Utf32String* basePrompt = ( direction > 0 ) ? &forwardSearchBasePrompt : &reverseSearchBasePrompt;
+ void updateSearchPrompt(void) {
+ const Utf32String* basePrompt =
+ (direction > 0) ? &forwardSearchBasePrompt : &reverseSearchBasePrompt;
size_t promptStartLength = basePrompt->length();
promptChars = promptStartLength + searchTextLen + endSearchBasePrompt.length();
- Utf32String tempUnicode( promptChars + 1 );
- memcpy( tempUnicode.get(), basePrompt->get(), sizeof( UChar32 ) * promptStartLength );
- memcpy( &tempUnicode[promptStartLength], searchText.get(), sizeof( UChar32 ) * searchTextLen );
+ Utf32String tempUnicode(promptChars + 1);
+ memcpy(tempUnicode.get(), basePrompt->get(), sizeof(UChar32) * promptStartLength);
+ memcpy(&tempUnicode[promptStartLength], searchText.get(), sizeof(UChar32) * searchTextLen);
size_t endIndex = promptStartLength + searchTextLen;
- memcpy( &tempUnicode[endIndex], endSearchBasePrompt.get(), sizeof( UChar32 ) * ( endSearchBasePrompt.length() + 1 ) );
+ memcpy(&tempUnicode[endIndex],
+ endSearchBasePrompt.get(),
+ sizeof(UChar32) * (endSearchBasePrompt.length() + 1));
tempUnicode.initFromBuffer();
promptText = tempUnicode;
}
- void updateSearchText( const UChar32* textPtr ) {
- Utf32String tempUnicode( textPtr );
+ void updateSearchText(const UChar32* textPtr) {
+ Utf32String tempUnicode(textPtr);
searchTextLen = tempUnicode.chars();
searchText = tempUnicode;
updateSearchPrompt();
@@ -320,56 +330,53 @@ struct DynamicPrompt : public PromptBase {
};
class KillRing {
- static const int capacity = 10;
- int size;
- int index;
- char indexToSlot[10];
+ static const int capacity = 10;
+ int size;
+ int index;
+ char indexToSlot[10];
vector<Utf32String> theRing;
public:
- enum action { actionOther, actionKill, actionYank };
- action lastAction;
- size_t lastYankSize;
+ enum action { actionOther, actionKill, actionYank };
+ action lastAction;
+ size_t lastYankSize;
- KillRing() : size( 0 ), index( 0 ), lastAction( actionOther ) {
- theRing.reserve( capacity );
+ KillRing() : size(0), index(0), lastAction(actionOther) {
+ theRing.reserve(capacity);
}
- void kill( const UChar32* text, int textLen, bool forward ) {
- if ( textLen == 0 ) {
+ void kill(const UChar32* text, int textLen, bool forward) {
+ if (textLen == 0) {
return;
}
- Utf32String killedText( text, textLen );
- if ( lastAction == actionKill && size > 0 ) {
+ Utf32String killedText(text, textLen);
+ if (lastAction == actionKill && size > 0) {
int slot = indexToSlot[0];
int currentLen = theRing[slot].length();
int resultLen = currentLen + textLen;
- Utf32String temp( resultLen + 1 );
- if ( forward ) {
- memcpy( temp.get(), theRing[slot].get(), currentLen * sizeof( UChar32 ) );
- memcpy( &temp[currentLen], killedText.get(), textLen * sizeof( UChar32 ) );
- }
- else {
- memcpy( temp.get(), killedText.get(), textLen * sizeof( UChar32 ) );
- memcpy( &temp[textLen], theRing[slot].get(), currentLen * sizeof( UChar32 ) );
+ Utf32String temp(resultLen + 1);
+ if (forward) {
+ memcpy(temp.get(), theRing[slot].get(), currentLen * sizeof(UChar32));
+ memcpy(&temp[currentLen], killedText.get(), textLen * sizeof(UChar32));
+ } else {
+ memcpy(temp.get(), killedText.get(), textLen * sizeof(UChar32));
+ memcpy(&temp[textLen], theRing[slot].get(), currentLen * sizeof(UChar32));
}
temp[resultLen] = 0;
temp.initFromBuffer();
theRing[slot] = temp;
- }
- else {
- if ( size < capacity ) {
- if ( size > 0 ) {
- memmove( &indexToSlot[1], &indexToSlot[0], size );
+ } else {
+ if (size < capacity) {
+ if (size > 0) {
+ memmove(&indexToSlot[1], &indexToSlot[0], size);
}
indexToSlot[0] = size;
size++;
- theRing.push_back( killedText );
- }
- else {
+ theRing.push_back(killedText);
+ } else {
int slot = indexToSlot[capacity - 1];
theRing[slot] = killedText;
- memmove( &indexToSlot[1], &indexToSlot[0], capacity - 1 );
+ memmove(&indexToSlot[1], &indexToSlot[0], capacity - 1);
indexToSlot[0] = slot;
}
index = 0;
@@ -377,48 +384,50 @@ public:
}
Utf32String* yank() {
- return ( size > 0 ) ? &theRing[indexToSlot[index]] : 0;
+ return (size > 0) ? &theRing[indexToSlot[index]] : 0;
}
Utf32String* yankPop() {
- if ( size == 0 ) {
+ if (size == 0) {
return 0;
}
++index;
- if ( index == size ) {
+ if (index == size) {
index = 0;
}
return &theRing[indexToSlot[index]];
}
-
};
class InputBuffer {
- UChar32* buf32; // input buffer
- char* charWidths; // character widths from mk_wcwidth()
- int buflen; // buffer size in characters
- int len; // length of text in input buffer
- int pos; // character position in buffer ( 0 <= pos <= len )
+ UChar32* buf32; // input buffer
+ char* charWidths; // character widths from mk_wcwidth()
+ int buflen; // buffer size in characters
+ int len; // length of text in input buffer
+ int pos; // character position in buffer ( 0 <= pos <= len )
- void clearScreen( PromptBase& pi );
- int incrementalHistorySearch( PromptBase& pi, int startChar );
- int completeLine( PromptBase& pi );
- void refreshLine( PromptBase& pi );
+ void clearScreen(PromptBase& pi);
+ int incrementalHistorySearch(PromptBase& pi, int startChar);
+ int completeLine(PromptBase& pi);
+ void refreshLine(PromptBase& pi);
public:
- InputBuffer( UChar32* buffer, char* widthArray, int bufferLen ) : buf32( buffer ), charWidths( widthArray ), buflen( bufferLen - 1 ), len( 0 ), pos( 0 ) {
+ InputBuffer(UChar32* buffer, char* widthArray, int bufferLen)
+ : buf32(buffer), charWidths(widthArray), buflen(bufferLen - 1), len(0), pos(0) {
buf32[0] = 0;
}
- void preloadBuffer( const UChar8* preloadText ) {
+ void preloadBuffer(const UChar8* preloadText) {
size_t ucharCount;
int errorCode;
- copyString8to32( buf32, preloadText, buflen + 1, ucharCount, errorCode );
- recomputeCharacterWidths( buf32, charWidths, ucharCount );
+ copyString8to32(buf32, preloadText, buflen + 1, ucharCount, errorCode);
+ recomputeCharacterWidths(buf32, charWidths, ucharCount);
len = ucharCount;
pos = ucharCount;
}
- int getInputLine( PromptBase& pi );
- int length( void ) const { return len; }
+ int getInputLine(PromptBase& pi);
+ int length(void) const {
+ return len;
+ }
};
// Special codes for keyboard input:
@@ -444,20 +453,20 @@ public:
//
// Maximum unsigned 32-bit value = 0xFFFFFFFF; // For reference, max 32-bit value
// Highest allocated Unicode char = 0x001FFFFF; // For reference, max Unicode value
-static const int META = 0x40000000; // Meta key combination
-static const int CTRL = 0x20000000; // Ctrl key combination
-static const int SPECIAL_KEY = 0x10000000; // Common bit for all special keys
-static const int UP_ARROW_KEY = 0x10200000; // Special keys
-static const int DOWN_ARROW_KEY = 0x10400000;
-static const int RIGHT_ARROW_KEY = 0x10600000;
-static const int LEFT_ARROW_KEY = 0x10800000;
-static const int HOME_KEY = 0x10A00000;
-static const int END_KEY = 0x10C00000;
-static const int DELETE_KEY = 0x10E00000;
-static const int PAGE_UP_KEY = 0x11000000;
-static const int PAGE_DOWN_KEY = 0x11200000;
-
-static const char* unsupported_term[] = { "dumb", "cons25", "emacs", NULL };
+static const int META = 0x40000000; // Meta key combination
+static const int CTRL = 0x20000000; // Ctrl key combination
+static const int SPECIAL_KEY = 0x10000000; // Common bit for all special keys
+static const int UP_ARROW_KEY = 0x10200000; // Special keys
+static const int DOWN_ARROW_KEY = 0x10400000;
+static const int RIGHT_ARROW_KEY = 0x10600000;
+static const int LEFT_ARROW_KEY = 0x10800000;
+static const int HOME_KEY = 0x10A00000;
+static const int END_KEY = 0x10C00000;
+static const int DELETE_KEY = 0x10E00000;
+static const int PAGE_UP_KEY = 0x11000000;
+static const int PAGE_DOWN_KEY = 0x11200000;
+
+static const char* unsupported_term[] = {"dumb", "cons25", "emacs", NULL};
static linenoiseCompletionCallback* completionCallback = NULL;
#ifdef _WIN32
@@ -470,7 +479,7 @@ static struct termios orig_termios; /* in order to restore at exit */
static KillRing killRing;
-static int rawmode = 0; /* for atexit() function to check if restore is needed*/
+static int rawmode = 0; /* for atexit() function to check if restore is needed*/
static int atexit_registered = 0; /* register atexit just 1 time */
static int historyMaxLen = LINENOISE_DEFAULT_HISTORY_MAX_LEN;
static int historyLen = 0;
@@ -483,72 +492,77 @@ static UChar8** history = NULL;
static int historyPreviousIndex = -2;
static bool historyRecallMostRecent = false;
-static void linenoiseAtExit( void );
+static void linenoiseAtExit(void);
-static bool isUnsupportedTerm( void ) {
- char* term = getenv( "TERM" );
- if ( term == NULL )
+static bool isUnsupportedTerm(void) {
+ char* term = getenv("TERM");
+ if (term == NULL)
return false;
- for ( int j = 0; unsupported_term[j]; ++j )
- if ( ! strcasecmp( term, unsupported_term[j] ) ) {
+ for (int j = 0; unsupported_term[j]; ++j)
+ if (!strcasecmp(term, unsupported_term[j])) {
return true;
}
return false;
}
static void beep() {
- fprintf( stderr, "\x7" ); // ctrl-G == bell/beep
- fflush( stderr );
+ fprintf(stderr, "\x7"); // ctrl-G == bell/beep
+ fflush(stderr);
}
-void linenoiseHistoryFree( void ) {
- if ( history ) {
- for ( int j = 0; j < historyLen; ++j )
- free( history[j] );
+void linenoiseHistoryFree(void) {
+ if (history) {
+ for (int j = 0; j < historyLen; ++j)
+ free(history[j]);
historyLen = 0;
- free( history );
+ free(history);
history = 0;
}
}
-static int enableRawMode( void ) {
+static int enableRawMode(void) {
#ifdef _WIN32
- if ( ! console_in ) {
- console_in = GetStdHandle( STD_INPUT_HANDLE );
- console_out = GetStdHandle( STD_OUTPUT_HANDLE );
+ if (!console_in) {
+ console_in = GetStdHandle(STD_INPUT_HANDLE);
+ console_out = GetStdHandle(STD_OUTPUT_HANDLE);
- GetConsoleMode( console_in, &oldMode );
- SetConsoleMode( console_in, oldMode & ~( ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT ) );
+ GetConsoleMode(console_in, &oldMode);
+ SetConsoleMode(console_in,
+ oldMode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT));
}
return 0;
#else
struct termios raw;
- if ( ! isatty( 0 ) ) goto fatal;
- if ( ! atexit_registered ) {
- atexit( linenoiseAtExit );
+ if (!isatty(0))
+ goto fatal;
+ if (!atexit_registered) {
+ atexit(linenoiseAtExit);
atexit_registered = 1;
}
- if ( tcgetattr( 0, &orig_termios ) == -1 ) goto fatal;
+ if (tcgetattr(0, &orig_termios) == -1)
+ goto fatal;
- raw = orig_termios; /* modify the original mode */
- /* input modes: no break, no CR to NL, no parity check, no strip char,
- * no start/stop output control. */
- raw.c_iflag &= ~( BRKINT | ICRNL | INPCK | ISTRIP | IXON );
+ raw = orig_termios; /* modify the original mode */
+ /* input modes: no break, no CR to NL, no parity check, no strip char,
+ * no start/stop output control. */
+ raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
/* output modes - disable post processing */
// this is wrong, we don't want raw output, it turns newlines into straight linefeeds
- //raw.c_oflag &= ~(OPOST);
+ // raw.c_oflag &= ~(OPOST);
/* control modes - set 8 bit chars */
- raw.c_cflag |= ( CS8 );
+ raw.c_cflag |= (CS8);
/* local modes - echoing off, canonical off, no extended functions,
* no signal chars (^Z,^C) */
- raw.c_lflag &= ~( ECHO | ICANON | IEXTEN | ISIG );
+ raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
/* control chars - set return condition: min number of bytes and timer.
* We want read to return every single byte, without timeout. */
- raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; /* 1 byte, no timer */
+ raw.c_cc[VMIN] = 1;
+ raw.c_cc[VTIME] = 0; /* 1 byte, no timer */
/* put terminal in raw mode after flushing */
- if ( tcsetattr( 0, TCSADRAIN, &raw ) < 0 ) goto fatal;
+ if (tcsetattr(0, TCSADRAIN, &raw) < 0)
+ goto fatal;
rawmode = 1;
return 0;
@@ -558,82 +572,83 @@ fatal:
#endif
}
-static void disableRawMode( void ) {
+static void disableRawMode(void) {
#ifdef _WIN32
- SetConsoleMode( console_in, oldMode );
+ SetConsoleMode(console_in, oldMode);
console_in = 0;
console_out = 0;
#else
- if ( rawmode && tcsetattr ( 0, TCSADRAIN, &orig_termios ) != -1 )
+ if (rawmode && tcsetattr(0, TCSADRAIN, &orig_termios) != -1)
rawmode = 0;
#endif
}
// At exit we'll try to fix the terminal to the initial conditions
-static void linenoiseAtExit( void ) {
+static void linenoiseAtExit(void) {
disableRawMode();
}
-static int getScreenColumns( void ) {
+static int getScreenColumns(void) {
int cols;
#ifdef _WIN32
CONSOLE_SCREEN_BUFFER_INFO inf;
- GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &inf );
+ GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &inf);
cols = inf.dwSize.X;
#else
struct winsize ws;
- cols = ( ioctl( 1, TIOCGWINSZ, &ws ) == -1 ) ? 80 : ws.ws_col;
+ cols = (ioctl(1, TIOCGWINSZ, &ws) == -1) ? 80 : ws.ws_col;
#endif
// cols is 0 in certain circumstances like inside debugger, which creates further issues
return (cols > 0) ? cols : 80;
}
-static int getScreenRows( void ) {
+static int getScreenRows(void) {
int rows;
#ifdef _WIN32
CONSOLE_SCREEN_BUFFER_INFO inf;
- GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &inf );
+ GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &inf);
rows = 1 + inf.srWindow.Bottom - inf.srWindow.Top;
#else
struct winsize ws;
- rows = ( ioctl( 1, TIOCGWINSZ, &ws ) == -1 ) ? 24 : ws.ws_row;
+ rows = (ioctl(1, TIOCGWINSZ, &ws) == -1) ? 24 : ws.ws_row;
#endif
return (rows > 0) ? rows : 24;
}
-static void setDisplayAttribute( bool enhancedDisplay ) {
+static void setDisplayAttribute(bool enhancedDisplay) {
#ifdef _WIN32
- if ( enhancedDisplay ) {
+ if (enhancedDisplay) {
CONSOLE_SCREEN_BUFFER_INFO inf;
- GetConsoleScreenBufferInfo( console_out, &inf );
+ GetConsoleScreenBufferInfo(console_out, &inf);
oldDisplayAttribute = inf.wAttributes;
BYTE oldLowByte = oldDisplayAttribute & 0xFF;
BYTE newLowByte;
- switch ( oldLowByte ) {
- case 0x07:
- //newLowByte = FOREGROUND_BLUE | FOREGROUND_INTENSITY; // too dim
- //newLowByte = FOREGROUND_BLUE; // even dimmer
- newLowByte = FOREGROUND_BLUE | FOREGROUND_GREEN; // most similar to xterm appearance
- break;
- case 0x70:
- newLowByte = BACKGROUND_BLUE | BACKGROUND_INTENSITY;
- break;
- default:
- newLowByte = oldLowByte ^ 0xFF; // default to inverse video
- break;
+ switch (oldLowByte) {
+ case 0x07:
+ // newLowByte = FOREGROUND_BLUE | FOREGROUND_INTENSITY; // too dim
+ // newLowByte = FOREGROUND_BLUE; // even dimmer
+ newLowByte =
+ FOREGROUND_BLUE | FOREGROUND_GREEN; // most similar to xterm appearance
+ break;
+ case 0x70:
+ newLowByte = BACKGROUND_BLUE | BACKGROUND_INTENSITY;
+ break;
+ default:
+ newLowByte = oldLowByte ^ 0xFF; // default to inverse video
+ break;
}
- inf.wAttributes = ( inf.wAttributes & 0xFF00 ) | newLowByte;
- SetConsoleTextAttribute( console_out, inf.wAttributes );
- }
- else {
- SetConsoleTextAttribute( console_out, oldDisplayAttribute );
+ inf.wAttributes = (inf.wAttributes & 0xFF00) | newLowByte;
+ SetConsoleTextAttribute(console_out, inf.wAttributes);
+ } else {
+ SetConsoleTextAttribute(console_out, oldDisplayAttribute);
}
#else
- if ( enhancedDisplay ) {
- if ( write( 1, "\x1b[1;34m", 7 ) == -1 ) return; /* bright blue (visible with both B&W bg) */
- }
- else {
- if ( write( 1, "\x1b[0m", 4 ) == -1 ) return; /* reset */
+ if (enhancedDisplay) {
+ if (write(1, "\x1b[1;34m", 7) == -1)
+ return; /* bright blue (visible with both B&W bg) */
+ } else {
+ if (write(1, "\x1b[0m", 4) == -1)
+ return; /* reset */
}
#endif
}
@@ -645,84 +660,97 @@ static void setDisplayAttribute( bool enhancedDisplay ) {
* @param len count of characters in the buffer
* @param pos current cursor position within the buffer (0 <= pos <= len)
*/
-static void dynamicRefresh( PromptBase& pi, UChar32* buf32, int len, int pos ) {
-
+static void dynamicRefresh(PromptBase& pi, UChar32* buf32, int len, int pos) {
// calculate the position of the end of the prompt
int xEndOfPrompt, yEndOfPrompt;
- calculateScreenPosition( 0, 0, pi.promptScreenColumns, pi.promptChars, xEndOfPrompt, yEndOfPrompt );
+ calculateScreenPosition(
+ 0, 0, pi.promptScreenColumns, pi.promptChars, xEndOfPrompt, yEndOfPrompt);
pi.promptIndentation = xEndOfPrompt;
// calculate the position of the end of the input line
int xEndOfInput, yEndOfInput;
- calculateScreenPosition( xEndOfPrompt,
- yEndOfPrompt,
- pi.promptScreenColumns,
- calculateColumnPosition( buf32, len ),
- xEndOfInput,
- yEndOfInput );
+ calculateScreenPosition(xEndOfPrompt,
+ yEndOfPrompt,
+ pi.promptScreenColumns,
+ calculateColumnPosition(buf32, len),
+ xEndOfInput,
+ yEndOfInput);
// calculate the desired position of the cursor
int xCursorPos, yCursorPos;
- calculateScreenPosition( xEndOfPrompt,
- yEndOfPrompt,
- pi.promptScreenColumns,
- calculateColumnPosition( buf32, pos ),
- xCursorPos,
- yCursorPos );
+ calculateScreenPosition(xEndOfPrompt,
+ yEndOfPrompt,
+ pi.promptScreenColumns,
+ calculateColumnPosition(buf32, pos),
+ xCursorPos,
+ yCursorPos);
#ifdef _WIN32
// position at the start of the prompt, clear to end of previous input
CONSOLE_SCREEN_BUFFER_INFO inf;
- GetConsoleScreenBufferInfo( console_out, &inf );
+ GetConsoleScreenBufferInfo(console_out, &inf);
inf.dwCursorPosition.X = 0;
inf.dwCursorPosition.Y -= pi.promptCursorRowOffset /*- pi.promptExtraLines*/;
- SetConsoleCursorPosition( console_out, inf.dwCursorPosition );
+ SetConsoleCursorPosition(console_out, inf.dwCursorPosition);
DWORD count;
- FillConsoleOutputCharacterA( console_out, ' ', pi.promptPreviousLen + pi.promptPreviousInputLen, inf.dwCursorPosition, &count );
+ FillConsoleOutputCharacterA(console_out,
+ ' ',
+ pi.promptPreviousLen + pi.promptPreviousInputLen,
+ inf.dwCursorPosition,
+ &count);
pi.promptPreviousLen = pi.promptIndentation;
pi.promptPreviousInputLen = len;
// display the prompt
- if ( write32( 1, pi.promptText.get(), pi.promptChars ) == -1 ) return;
+ if (write32(1, pi.promptText.get(), pi.promptChars) == -1)
+ return;
// display the input line
- if ( write32( 1, buf32, len ) == -1 ) return;
+ if (write32(1, buf32, len) == -1)
+ return;
// position the cursor
- GetConsoleScreenBufferInfo( console_out, &inf );
+ GetConsoleScreenBufferInfo(console_out, &inf);
inf.dwCursorPosition.X = xCursorPos; // 0-based on Win32
inf.dwCursorPosition.Y -= yEndOfInput - yCursorPos;
- SetConsoleCursorPosition( console_out, inf.dwCursorPosition );
-#else // _WIN32
+ SetConsoleCursorPosition(console_out, inf.dwCursorPosition);
+#else // _WIN32
char seq[64];
int cursorRowMovement = pi.promptCursorRowOffset - pi.promptExtraLines;
- if ( cursorRowMovement > 0 ) { // move the cursor up as required
- snprintf( seq, sizeof seq, "\x1b[%dA", cursorRowMovement );
- if ( write( 1, seq, strlen( seq ) ) == -1 ) return;
+ if (cursorRowMovement > 0) { // move the cursor up as required
+ snprintf(seq, sizeof seq, "\x1b[%dA", cursorRowMovement);
+ if (write(1, seq, strlen(seq)) == -1)
+ return;
}
// position at the start of the prompt, clear to end of screen
- snprintf( seq, sizeof seq, "\x1b[1G\x1b[J" ); // 1-based on VT100
- if ( write( 1, seq, strlen( seq ) ) == -1 ) return;
+ snprintf(seq, sizeof seq, "\x1b[1G\x1b[J"); // 1-based on VT100
+ if (write(1, seq, strlen(seq)) == -1)
+ return;
// display the prompt
- if ( write32( 1, pi.promptText.get(), pi.promptChars ) == -1 ) return;
+ if (write32(1, pi.promptText.get(), pi.promptChars) == -1)
+ return;
// display the input line
- if ( write32( 1, buf32, len ) == -1 ) return;
+ if (write32(1, buf32, len) == -1)
+ return;
// we have to generate our own newline on line wrap
- if ( xEndOfInput == 0 && yEndOfInput > 0 )
- if ( write( 1, "\n", 1 ) == -1 ) return;
+ if (xEndOfInput == 0 && yEndOfInput > 0)
+ if (write(1, "\n", 1) == -1)
+ return;
// position the cursor
cursorRowMovement = yEndOfInput - yCursorPos;
- if ( cursorRowMovement > 0 ) { // move the cursor up as required
- snprintf( seq, sizeof seq, "\x1b[%dA", cursorRowMovement );
- if ( write( 1, seq, strlen( seq ) ) == -1 ) return;
+ if (cursorRowMovement > 0) { // move the cursor up as required
+ snprintf(seq, sizeof seq, "\x1b[%dA", cursorRowMovement);
+ if (write(1, seq, strlen(seq)) == -1)
+ return;
}
// position the cursor within the line
- snprintf( seq, sizeof seq, "\x1b[%dG", xCursorPos + 1 ); // 1-based on VT100
- if ( write( 1, seq, strlen( seq ) ) == -1 ) return;
+ snprintf(seq, sizeof seq, "\x1b[%dG", xCursorPos + 1); // 1-based on VT100
+ if (write(1, seq, strlen(seq)) == -1)
+ return;
#endif
pi.promptCursorRowOffset = pi.promptExtraLines + yCursorPos; // remember row for next pass
@@ -732,28 +760,27 @@ static void dynamicRefresh( PromptBase& pi, UChar32* buf32, int len, int pos ) {
* Refresh the user's input line: the prompt is already onscreen and is not redrawn here
* @param pi PromptBase struct holding information about the prompt and our screen position
*/
-void InputBuffer::refreshLine( PromptBase& pi ) {
-
+void InputBuffer::refreshLine(PromptBase& pi) {
// check for a matching brace/bracket/paren, remember its position if found
int highlight = -1;
- if ( pos < len ) {
+ if (pos < len) {
/* this scans for a brace matching buf32[pos] to highlight */
int scanDirection = 0;
- if ( strchr( "}])", buf32[pos] ) )
+ if (strchr("}])", buf32[pos]))
scanDirection = -1; /* backwards */
- else if ( strchr( "{[(", buf32[pos] ) )
+ else if (strchr("{[(", buf32[pos]))
scanDirection = 1; /* forwards */
- if ( scanDirection ) {
+ if (scanDirection) {
int unmatched = scanDirection;
- for ( int i = pos + scanDirection; i >= 0 && i < len; i += scanDirection ) {
+ for (int i = pos + scanDirection; i >= 0 && i < len; i += scanDirection) {
/* TODO: the right thing when inside a string */
- if ( strchr( "}])", buf32[i] ) )
+ if (strchr("}])", buf32[i]))
--unmatched;
- else if ( strchr( "{[(", buf32[i] ) )
+ else if (strchr("{[(", buf32[i]))
++unmatched;
- if ( unmatched == 0 ) {
+ if (unmatched == 0) {
highlight = i;
break;
}
@@ -763,86 +790,98 @@ void InputBuffer::refreshLine( PromptBase& pi ) {
// calculate the position of the end of the input line
int xEndOfInput, yEndOfInput;
- calculateScreenPosition( pi.promptIndentation,
- 0,
- pi.promptScreenColumns,
- calculateColumnPosition( buf32, len ),
- xEndOfInput,
- yEndOfInput );
+ calculateScreenPosition(pi.promptIndentation,
+ 0,
+ pi.promptScreenColumns,
+ calculateColumnPosition(buf32, len),
+ xEndOfInput,
+ yEndOfInput);
// calculate the desired position of the cursor
int xCursorPos, yCursorPos;
- calculateScreenPosition( pi.promptIndentation,
- 0,
- pi.promptScreenColumns,
- calculateColumnPosition( buf32, pos ),
- xCursorPos,
- yCursorPos );
+ calculateScreenPosition(pi.promptIndentation,
+ 0,
+ pi.promptScreenColumns,
+ calculateColumnPosition(buf32, pos),
+ xCursorPos,
+ yCursorPos);
#ifdef _WIN32
// position at the end of the prompt, clear to end of previous input
CONSOLE_SCREEN_BUFFER_INFO inf;
- GetConsoleScreenBufferInfo( console_out, &inf );
+ GetConsoleScreenBufferInfo(console_out, &inf);
inf.dwCursorPosition.X = pi.promptIndentation; // 0-based on Win32
inf.dwCursorPosition.Y -= pi.promptCursorRowOffset - pi.promptExtraLines;
- SetConsoleCursorPosition( console_out, inf.dwCursorPosition );
+ SetConsoleCursorPosition(console_out, inf.dwCursorPosition);
DWORD count;
- if ( len < pi.promptPreviousInputLen )
- FillConsoleOutputCharacterA( console_out, ' ', pi.promptPreviousInputLen, inf.dwCursorPosition, &count );
+ if (len < pi.promptPreviousInputLen)
+ FillConsoleOutputCharacterA(
+ console_out, ' ', pi.promptPreviousInputLen, inf.dwCursorPosition, &count);
pi.promptPreviousInputLen = len;
// display the input line
if (highlight == -1) {
- if ( write32( 1, buf32, len ) == -1 ) return;
- }
- else {
- if (write32( 1, buf32, highlight ) == -1 ) return;
- setDisplayAttribute( true ); /* bright blue (visible with both B&W bg) */
- if ( write32( 1, &buf32[highlight], 1 ) == -1 ) return;
- setDisplayAttribute( false );
- if ( write32( 1, buf32 + highlight + 1, len - highlight - 1 ) == -1 ) return;
+ if (write32(1, buf32, len) == -1)
+ return;
+ } else {
+ if (write32(1, buf32, highlight) == -1)
+ return;
+ setDisplayAttribute(true); /* bright blue (visible with both B&W bg) */
+ if (write32(1, &buf32[highlight], 1) == -1)
+ return;
+ setDisplayAttribute(false);
+ if (write32(1, buf32 + highlight + 1, len - highlight - 1) == -1)
+ return;
}
// position the cursor
- GetConsoleScreenBufferInfo( console_out, &inf );
+ GetConsoleScreenBufferInfo(console_out, &inf);
inf.dwCursorPosition.X = xCursorPos; // 0-based on Win32
inf.dwCursorPosition.Y -= yEndOfInput - yCursorPos;
- SetConsoleCursorPosition( console_out, inf.dwCursorPosition );
-#else // _WIN32
+ SetConsoleCursorPosition(console_out, inf.dwCursorPosition);
+#else // _WIN32
char seq[64];
int cursorRowMovement = pi.promptCursorRowOffset - pi.promptExtraLines;
- if ( cursorRowMovement > 0 ) { // move the cursor up as required
- snprintf( seq, sizeof seq, "\x1b[%dA", cursorRowMovement );
- if ( write( 1, seq, strlen( seq ) ) == -1 ) return;
+ if (cursorRowMovement > 0) { // move the cursor up as required
+ snprintf(seq, sizeof seq, "\x1b[%dA", cursorRowMovement);
+ if (write(1, seq, strlen(seq)) == -1)
+ return;
}
// position at the end of the prompt, clear to end of screen
- snprintf( seq, sizeof seq, "\x1b[%dG\x1b[J", pi.promptIndentation + 1 ); // 1-based on VT100
- if ( write( 1, seq, strlen( seq ) ) == -1 ) return;
+ snprintf(seq, sizeof seq, "\x1b[%dG\x1b[J", pi.promptIndentation + 1); // 1-based on VT100
+ if (write(1, seq, strlen(seq)) == -1)
+ return;
- if ( highlight == -1 ) { // write unhighlighted text
- if ( write32( 1, buf32, len ) == -1 ) return;
- }
- else { // highlight the matching brace/bracket/parenthesis
- if ( write32( 1, buf32, highlight ) == -1 ) return;
- setDisplayAttribute( true );
- if ( write32( 1, &buf32[highlight], 1 ) == -1 ) return;
- setDisplayAttribute( false );
- if ( write32( 1, buf32 + highlight + 1, len - highlight - 1 ) == -1 ) return;
+ if (highlight == -1) { // write unhighlighted text
+ if (write32(1, buf32, len) == -1)
+ return;
+ } else { // highlight the matching brace/bracket/parenthesis
+ if (write32(1, buf32, highlight) == -1)
+ return;
+ setDisplayAttribute(true);
+ if (write32(1, &buf32[highlight], 1) == -1)
+ return;
+ setDisplayAttribute(false);
+ if (write32(1, buf32 + highlight + 1, len - highlight - 1) == -1)
+ return;
}
// we have to generate our own newline on line wrap
- if ( xEndOfInput == 0 && yEndOfInput > 0 )
- if ( write( 1, "\n", 1 ) == -1 ) return;
+ if (xEndOfInput == 0 && yEndOfInput > 0)
+ if (write(1, "\n", 1) == -1)
+ return;
// position the cursor
cursorRowMovement = yEndOfInput - yCursorPos;
- if ( cursorRowMovement > 0 ) { // move the cursor up as required
- snprintf( seq, sizeof seq, "\x1b[%dA", cursorRowMovement );
- if ( write( 1, seq, strlen( seq ) ) == -1 ) return;
+ if (cursorRowMovement > 0) { // move the cursor up as required
+ snprintf(seq, sizeof seq, "\x1b[%dA", cursorRowMovement);
+ if (write(1, seq, strlen(seq)) == -1)
+ return;
}
// position the cursor within the line
- snprintf( seq, sizeof seq, "\x1b[%dG", xCursorPos + 1 ); // 1-based on VT100
- if ( write( 1, seq, strlen( seq ) ) == -1 ) return;
+ snprintf(seq, sizeof seq, "\x1b[%dG", xCursorPos + 1); // 1-based on VT100
+ if (write(1, seq, strlen(seq)) == -1)
+ return;
#endif
pi.promptCursorRowOffset = pi.promptExtraLines + yCursorPos; // remember row for next pass
@@ -855,35 +894,34 @@ void InputBuffer::refreshLine( PromptBase& pi ) {
*
* @return UChar32 Unicode character
*/
-static UChar32 readUnicodeCharacter( void ) {
+static UChar32 readUnicodeCharacter(void) {
static UChar8 utf8String[5];
static size_t utf8Count = 0;
- while ( true ) {
+ while (true) {
UChar8 c;
- if ( read( 0, &c, 1 ) <= 0 ) return 0;
- if ( c <= 0x7F ) { // short circuit ASCII
+ if (read(0, &c, 1) <= 0)
+ return 0;
+ if (c <= 0x7F) { // short circuit ASCII
utf8Count = 0;
return c;
- }
- else if ( utf8Count < sizeof( utf8String ) - 1 ) {
- utf8String[ utf8Count++ ] = c;
- utf8String[ utf8Count ] = 0;
+ } else if (utf8Count < sizeof(utf8String) - 1) {
+ utf8String[utf8Count++] = c;
+ utf8String[utf8Count] = 0;
UChar32 unicodeChar[2];
size_t ucharCount;
int errorCode;
- copyString8to32( unicodeChar, utf8String, 2, ucharCount, errorCode );
- if ( ucharCount && errorCode == 0 ) {
+ copyString8to32(unicodeChar, utf8String, 2, ucharCount, errorCode);
+ if (ucharCount && errorCode == 0) {
utf8Count = 0;
return unicodeChar[0];
}
- }
- else {
+ } else {
utf8Count = 0; // this shouldn't happen: got four bytes but no UTF-8 character
}
}
}
-namespace EscapeSequenceProcessing { // move these out of global namespace
+namespace EscapeSequenceProcessing { // move these out of global namespace
// This chunk of code does parsing of the escape sequences sent by various Linux terminals.
//
@@ -907,16 +945,16 @@ namespace EscapeSequenceProcessing { // move these out of global namespace
// as input, does any required processing including reading more characters and calling other
// dispatch routines, then eventually returns the final (possibly extended or special) character.
//
-typedef UChar32 ( *CharacterDispatchRoutine )( UChar32 );
+typedef UChar32 (*CharacterDispatchRoutine)(UChar32);
// This structure is used by doDispatch() to hold a list of characters to test for and
// a list of routines to call if the character matches. The dispatch routine list is one
// longer than the character list; the final entry is used if no character matches.
//
struct CharacterDispatch {
- unsigned int len; // length of the chars list
- const char* chars; // chars to test
- CharacterDispatchRoutine* dispatch; // array of routines to call
+ unsigned int len; // length of the chars list
+ const char* chars; // chars to test
+ CharacterDispatchRoutine* dispatch; // array of routines to call
};
// This dispatch routine is given a dispatch table and then farms work out to routines
@@ -924,266 +962,279 @@ struct CharacterDispatch {
// read more input characters to decide what should eventually be returned. Eventually,
// a called routine returns either a character or -1 to indicate parsing failure.
//
-static UChar32 doDispatch( UChar32 c, CharacterDispatch& dispatchTable ) {
- for ( unsigned int i = 0; i < dispatchTable.len ; ++i ) {
- if ( static_cast<unsigned char>( dispatchTable.chars[i] ) == c ) {
- return dispatchTable.dispatch[i]( c );
+static UChar32 doDispatch(UChar32 c, CharacterDispatch& dispatchTable) {
+ for (unsigned int i = 0; i < dispatchTable.len; ++i) {
+ if (static_cast<unsigned char>(dispatchTable.chars[i]) == c) {
+ return dispatchTable.dispatch[i](c);
}
}
- return dispatchTable.dispatch[dispatchTable.len]( c );
+ return dispatchTable.dispatch[dispatchTable.len](c);
}
-static UChar32 thisKeyMetaCtrl = 0; // holds pre-set Meta and/or Ctrl modifiers
+static UChar32 thisKeyMetaCtrl = 0; // holds pre-set Meta and/or Ctrl modifiers
// Final dispatch routines -- return something
//
-static UChar32 normalKeyRoutine( UChar32 c ) { return thisKeyMetaCtrl | c; }
-static UChar32 upArrowKeyRoutine( UChar32 c ) { return thisKeyMetaCtrl | UP_ARROW_KEY; }
-static UChar32 downArrowKeyRoutine( UChar32 c ) { return thisKeyMetaCtrl | DOWN_ARROW_KEY; }
-static UChar32 rightArrowKeyRoutine( UChar32 c ) { return thisKeyMetaCtrl | RIGHT_ARROW_KEY; }
-static UChar32 leftArrowKeyRoutine( UChar32 c ) { return thisKeyMetaCtrl | LEFT_ARROW_KEY; }
-static UChar32 homeKeyRoutine( UChar32 c ) { return thisKeyMetaCtrl | HOME_KEY; }
-static UChar32 endKeyRoutine( UChar32 c ) { return thisKeyMetaCtrl | END_KEY; }
-static UChar32 pageUpKeyRoutine( UChar32 c ) { return thisKeyMetaCtrl | PAGE_UP_KEY; }
-static UChar32 pageDownKeyRoutine( UChar32 c ) { return thisKeyMetaCtrl | PAGE_DOWN_KEY; }
-static UChar32 deleteCharRoutine( UChar32 c ) { return thisKeyMetaCtrl | ctrlChar( 'H' ); } // key labeled Backspace
-static UChar32 deleteKeyRoutine( UChar32 c ) { return thisKeyMetaCtrl | DELETE_KEY; } // key labeled Delete
-static UChar32 ctrlUpArrowKeyRoutine( UChar32 c ) { return thisKeyMetaCtrl | CTRL | UP_ARROW_KEY; }
-static UChar32 ctrlDownArrowKeyRoutine( UChar32 c ) { return thisKeyMetaCtrl | CTRL | DOWN_ARROW_KEY; }
-static UChar32 ctrlRightArrowKeyRoutine( UChar32 c ) { return thisKeyMetaCtrl | CTRL | RIGHT_ARROW_KEY; }
-static UChar32 ctrlLeftArrowKeyRoutine( UChar32 c ) { return thisKeyMetaCtrl | CTRL | LEFT_ARROW_KEY; }
-static UChar32 escFailureRoutine( UChar32 c ) { beep(); return -1; }
+static UChar32 normalKeyRoutine(UChar32 c) {
+ return thisKeyMetaCtrl | c;
+}
+static UChar32 upArrowKeyRoutine(UChar32 c) {
+ return thisKeyMetaCtrl | UP_ARROW_KEY;
+}
+static UChar32 downArrowKeyRoutine(UChar32 c) {
+ return thisKeyMetaCtrl | DOWN_ARROW_KEY;
+}
+static UChar32 rightArrowKeyRoutine(UChar32 c) {
+ return thisKeyMetaCtrl | RIGHT_ARROW_KEY;
+}
+static UChar32 leftArrowKeyRoutine(UChar32 c) {
+ return thisKeyMetaCtrl | LEFT_ARROW_KEY;
+}
+static UChar32 homeKeyRoutine(UChar32 c) {
+ return thisKeyMetaCtrl | HOME_KEY;
+}
+static UChar32 endKeyRoutine(UChar32 c) {
+ return thisKeyMetaCtrl | END_KEY;
+}
+static UChar32 pageUpKeyRoutine(UChar32 c) {
+ return thisKeyMetaCtrl | PAGE_UP_KEY;
+}
+static UChar32 pageDownKeyRoutine(UChar32 c) {
+ return thisKeyMetaCtrl | PAGE_DOWN_KEY;
+}
+static UChar32 deleteCharRoutine(UChar32 c) {
+ return thisKeyMetaCtrl | ctrlChar('H');
+} // key labeled Backspace
+static UChar32 deleteKeyRoutine(UChar32 c) {
+ return thisKeyMetaCtrl | DELETE_KEY;
+} // key labeled Delete
+static UChar32 ctrlUpArrowKeyRoutine(UChar32 c) {
+ return thisKeyMetaCtrl | CTRL | UP_ARROW_KEY;
+}
+static UChar32 ctrlDownArrowKeyRoutine(UChar32 c) {
+ return thisKeyMetaCtrl | CTRL | DOWN_ARROW_KEY;
+}
+static UChar32 ctrlRightArrowKeyRoutine(UChar32 c) {
+ return thisKeyMetaCtrl | CTRL | RIGHT_ARROW_KEY;
+}
+static UChar32 ctrlLeftArrowKeyRoutine(UChar32 c) {
+ return thisKeyMetaCtrl | CTRL | LEFT_ARROW_KEY;
+}
+static UChar32 escFailureRoutine(UChar32 c) {
+ beep();
+ return -1;
+}
// Handle ESC [ 1 ; 3 (or 5) <more stuff> escape sequences
//
-static CharacterDispatchRoutine escLeftBracket1Semicolon3or5Routines[] = {
- upArrowKeyRoutine,
- downArrowKeyRoutine,
- rightArrowKeyRoutine,
- leftArrowKeyRoutine,
- escFailureRoutine
-};
-static CharacterDispatch escLeftBracket1Semicolon3or5Dispatch = { 4, "ABCD", escLeftBracket1Semicolon3or5Routines };
+static CharacterDispatchRoutine escLeftBracket1Semicolon3or5Routines[] = {upArrowKeyRoutine,
+ downArrowKeyRoutine,
+ rightArrowKeyRoutine,
+ leftArrowKeyRoutine,
+ escFailureRoutine};
+static CharacterDispatch escLeftBracket1Semicolon3or5Dispatch = {
+ 4, "ABCD", escLeftBracket1Semicolon3or5Routines};
// Handle ESC [ 1 ; <more stuff> escape sequences
//
-static UChar32 escLeftBracket1Semicolon3Routine( UChar32 c ) {
+static UChar32 escLeftBracket1Semicolon3Routine(UChar32 c) {
c = readUnicodeCharacter();
- if ( c == 0 ) return 0;
+ if (c == 0)
+ return 0;
thisKeyMetaCtrl |= META;
- return doDispatch( c, escLeftBracket1Semicolon3or5Dispatch );
+ return doDispatch(c, escLeftBracket1Semicolon3or5Dispatch);
}
-static UChar32 escLeftBracket1Semicolon5Routine( UChar32 c ) {
+static UChar32 escLeftBracket1Semicolon5Routine(UChar32 c) {
c = readUnicodeCharacter();
- if ( c == 0 ) return 0;
+ if (c == 0)
+ return 0;
thisKeyMetaCtrl |= CTRL;
- return doDispatch( c, escLeftBracket1Semicolon3or5Dispatch );
+ return doDispatch(c, escLeftBracket1Semicolon3or5Dispatch);
}
static CharacterDispatchRoutine escLeftBracket1SemicolonRoutines[] = {
- escLeftBracket1Semicolon3Routine,
- escLeftBracket1Semicolon5Routine,
- escFailureRoutine
-};
-static CharacterDispatch escLeftBracket1SemicolonDispatch = { 2, "35", escLeftBracket1SemicolonRoutines };
+ escLeftBracket1Semicolon3Routine, escLeftBracket1Semicolon5Routine, escFailureRoutine};
+static CharacterDispatch escLeftBracket1SemicolonDispatch = {
+ 2, "35", escLeftBracket1SemicolonRoutines};
// Handle ESC [ 1 <more stuff> escape sequences
//
-static UChar32 escLeftBracket1SemicolonRoutine( UChar32 c ) {
+static UChar32 escLeftBracket1SemicolonRoutine(UChar32 c) {
c = readUnicodeCharacter();
- if ( c == 0 ) return 0;
- return doDispatch( c, escLeftBracket1SemicolonDispatch );
+ if (c == 0)
+ return 0;
+ return doDispatch(c, escLeftBracket1SemicolonDispatch);
}
static CharacterDispatchRoutine escLeftBracket1Routines[] = {
- homeKeyRoutine,
- escLeftBracket1SemicolonRoutine,
- escFailureRoutine
-};
-static CharacterDispatch escLeftBracket1Dispatch = { 2, "~;", escLeftBracket1Routines };
+ homeKeyRoutine, escLeftBracket1SemicolonRoutine, escFailureRoutine};
+static CharacterDispatch escLeftBracket1Dispatch = {2, "~;", escLeftBracket1Routines};
// Handle ESC [ 3 <more stuff> escape sequences
//
-static CharacterDispatchRoutine escLeftBracket3Routines[] = {
- deleteKeyRoutine,
- escFailureRoutine
-};
-static CharacterDispatch escLeftBracket3Dispatch = { 1, "~", escLeftBracket3Routines };
+static CharacterDispatchRoutine escLeftBracket3Routines[] = {deleteKeyRoutine, escFailureRoutine};
+static CharacterDispatch escLeftBracket3Dispatch = {1, "~", escLeftBracket3Routines};
// Handle ESC [ 4 <more stuff> escape sequences
//
-static CharacterDispatchRoutine escLeftBracket4Routines[] = {
- endKeyRoutine,
- escFailureRoutine
-};
-static CharacterDispatch escLeftBracket4Dispatch = { 1, "~", escLeftBracket4Routines };
+static CharacterDispatchRoutine escLeftBracket4Routines[] = {endKeyRoutine, escFailureRoutine};
+static CharacterDispatch escLeftBracket4Dispatch = {1, "~", escLeftBracket4Routines};
// Handle ESC [ 5 <more stuff> escape sequences
//
-static CharacterDispatchRoutine escLeftBracket5Routines[] = {
- pageUpKeyRoutine,
- escFailureRoutine
-};
-static CharacterDispatch escLeftBracket5Dispatch = { 1, "~", escLeftBracket5Routines };
+static CharacterDispatchRoutine escLeftBracket5Routines[] = {pageUpKeyRoutine, escFailureRoutine};
+static CharacterDispatch escLeftBracket5Dispatch = {1, "~", escLeftBracket5Routines};
// Handle ESC [ 6 <more stuff> escape sequences
//
-static CharacterDispatchRoutine escLeftBracket6Routines[] = {
- pageDownKeyRoutine,
- escFailureRoutine
-};
-static CharacterDispatch escLeftBracket6Dispatch = { 1, "~", escLeftBracket6Routines };
+static CharacterDispatchRoutine escLeftBracket6Routines[] = {pageDownKeyRoutine, escFailureRoutine};
+static CharacterDispatch escLeftBracket6Dispatch = {1, "~", escLeftBracket6Routines};
// Handle ESC [ 7 <more stuff> escape sequences
//
-static CharacterDispatchRoutine escLeftBracket7Routines[] = {
- homeKeyRoutine,
- escFailureRoutine
-};
-static CharacterDispatch escLeftBracket7Dispatch = { 1, "~", escLeftBracket7Routines };
+static CharacterDispatchRoutine escLeftBracket7Routines[] = {homeKeyRoutine, escFailureRoutine};
+static CharacterDispatch escLeftBracket7Dispatch = {1, "~", escLeftBracket7Routines};
// Handle ESC [ 8 <more stuff> escape sequences
//
-static CharacterDispatchRoutine escLeftBracket8Routines[] = {
- endKeyRoutine,
- escFailureRoutine
-};
-static CharacterDispatch escLeftBracket8Dispatch = { 1, "~", escLeftBracket8Routines };
+static CharacterDispatchRoutine escLeftBracket8Routines[] = {endKeyRoutine, escFailureRoutine};
+static CharacterDispatch escLeftBracket8Dispatch = {1, "~", escLeftBracket8Routines};
// Handle ESC [ <digit> escape sequences
//
-static UChar32 escLeftBracket0Routine( UChar32 c ) {
- return escFailureRoutine( c );
+static UChar32 escLeftBracket0Routine(UChar32 c) {
+ return escFailureRoutine(c);
}
-static UChar32 escLeftBracket1Routine( UChar32 c ) {
+static UChar32 escLeftBracket1Routine(UChar32 c) {
c = readUnicodeCharacter();
- if ( c == 0 ) return 0;
- return doDispatch( c, escLeftBracket1Dispatch );
+ if (c == 0)
+ return 0;
+ return doDispatch(c, escLeftBracket1Dispatch);
}
-static UChar32 escLeftBracket2Routine( UChar32 c ) {
- return escFailureRoutine( c ); // Insert key, unused
+static UChar32 escLeftBracket2Routine(UChar32 c) {
+ return escFailureRoutine(c); // Insert key, unused
}
-static UChar32 escLeftBracket3Routine( UChar32 c ) {
+static UChar32 escLeftBracket3Routine(UChar32 c) {
c = readUnicodeCharacter();
- if ( c == 0 ) return 0;
- return doDispatch( c, escLeftBracket3Dispatch );
+ if (c == 0)
+ return 0;
+ return doDispatch(c, escLeftBracket3Dispatch);
}
-static UChar32 escLeftBracket4Routine( UChar32 c ) {
+static UChar32 escLeftBracket4Routine(UChar32 c) {
c = readUnicodeCharacter();
- if ( c == 0 ) return 0;
- return doDispatch( c, escLeftBracket4Dispatch );
+ if (c == 0)
+ return 0;
+ return doDispatch(c, escLeftBracket4Dispatch);
}
-static UChar32 escLeftBracket5Routine( UChar32 c ) {
+static UChar32 escLeftBracket5Routine(UChar32 c) {
c = readUnicodeCharacter();
- if ( c == 0 ) return 0;
- return doDispatch( c, escLeftBracket5Dispatch );
+ if (c == 0)
+ return 0;
+ return doDispatch(c, escLeftBracket5Dispatch);
}
-static UChar32 escLeftBracket6Routine( UChar32 c ) {
+static UChar32 escLeftBracket6Routine(UChar32 c) {
c = readUnicodeCharacter();
- if ( c == 0 ) return 0;
- return doDispatch( c, escLeftBracket6Dispatch );
+ if (c == 0)
+ return 0;
+ return doDispatch(c, escLeftBracket6Dispatch);
}
-static UChar32 escLeftBracket7Routine( UChar32 c ) {
+static UChar32 escLeftBracket7Routine(UChar32 c) {
c = readUnicodeCharacter();
- if ( c == 0 ) return 0;
- return doDispatch( c, escLeftBracket7Dispatch );
+ if (c == 0)
+ return 0;
+ return doDispatch(c, escLeftBracket7Dispatch);
}
-static UChar32 escLeftBracket8Routine( UChar32 c ) {
+static UChar32 escLeftBracket8Routine(UChar32 c) {
c = readUnicodeCharacter();
- if ( c == 0 ) return 0;
- return doDispatch( c, escLeftBracket8Dispatch );
+ if (c == 0)
+ return 0;
+ return doDispatch(c, escLeftBracket8Dispatch);
}
-static UChar32 escLeftBracket9Routine( UChar32 c ) {
- return escFailureRoutine( c );
+static UChar32 escLeftBracket9Routine(UChar32 c) {
+ return escFailureRoutine(c);
}
// Handle ESC [ <more stuff> escape sequences
//
-static CharacterDispatchRoutine escLeftBracketRoutines[] = {
- upArrowKeyRoutine,
- downArrowKeyRoutine,
- rightArrowKeyRoutine,
- leftArrowKeyRoutine,
- homeKeyRoutine,
- endKeyRoutine,
- escLeftBracket0Routine,
- escLeftBracket1Routine,
- escLeftBracket2Routine,
- escLeftBracket3Routine,
- escLeftBracket4Routine,
- escLeftBracket5Routine,
- escLeftBracket6Routine,
- escLeftBracket7Routine,
- escLeftBracket8Routine,
- escLeftBracket9Routine,
- escFailureRoutine
-};
-static CharacterDispatch escLeftBracketDispatch = { 16, "ABCDHF0123456789", escLeftBracketRoutines };
+static CharacterDispatchRoutine escLeftBracketRoutines[] = {upArrowKeyRoutine,
+ downArrowKeyRoutine,
+ rightArrowKeyRoutine,
+ leftArrowKeyRoutine,
+ homeKeyRoutine,
+ endKeyRoutine,
+ escLeftBracket0Routine,
+ escLeftBracket1Routine,
+ escLeftBracket2Routine,
+ escLeftBracket3Routine,
+ escLeftBracket4Routine,
+ escLeftBracket5Routine,
+ escLeftBracket6Routine,
+ escLeftBracket7Routine,
+ escLeftBracket8Routine,
+ escLeftBracket9Routine,
+ escFailureRoutine};
+static CharacterDispatch escLeftBracketDispatch = {16, "ABCDHF0123456789", escLeftBracketRoutines};
// Handle ESC O <char> escape sequences
//
-static CharacterDispatchRoutine escORoutines[] = {
- upArrowKeyRoutine,
- downArrowKeyRoutine,
- rightArrowKeyRoutine,
- leftArrowKeyRoutine,
- homeKeyRoutine,
- endKeyRoutine,
- ctrlUpArrowKeyRoutine,
- ctrlDownArrowKeyRoutine,
- ctrlRightArrowKeyRoutine,
- ctrlLeftArrowKeyRoutine,
- escFailureRoutine
-};
-static CharacterDispatch escODispatch = { 10, "ABCDHFabcd", escORoutines };
+static CharacterDispatchRoutine escORoutines[] = {upArrowKeyRoutine,
+ downArrowKeyRoutine,
+ rightArrowKeyRoutine,
+ leftArrowKeyRoutine,
+ homeKeyRoutine,
+ endKeyRoutine,
+ ctrlUpArrowKeyRoutine,
+ ctrlDownArrowKeyRoutine,
+ ctrlRightArrowKeyRoutine,
+ ctrlLeftArrowKeyRoutine,
+ escFailureRoutine};
+static CharacterDispatch escODispatch = {10, "ABCDHFabcd", escORoutines};
// Initial ESC dispatch -- could be a Meta prefix or the start of an escape sequence
//
-static UChar32 escLeftBracketRoutine( UChar32 c ) {
+static UChar32 escLeftBracketRoutine(UChar32 c) {
c = readUnicodeCharacter();
- if ( c == 0 ) return 0;
- return doDispatch( c, escLeftBracketDispatch );
+ if (c == 0)
+ return 0;
+ return doDispatch(c, escLeftBracketDispatch);
}
-static UChar32 escORoutine( UChar32 c ) {
+static UChar32 escORoutine(UChar32 c) {
c = readUnicodeCharacter();
- if ( c == 0 ) return 0;
- return doDispatch( c, escODispatch );
+ if (c == 0)
+ return 0;
+ return doDispatch(c, escODispatch);
}
-static UChar32 setMetaRoutine( UChar32 c ); // need forward reference
+static UChar32 setMetaRoutine(UChar32 c); // need forward reference
static CharacterDispatchRoutine escRoutines[] = {
- escLeftBracketRoutine,
- escORoutine,
- setMetaRoutine
-};
-static CharacterDispatch escDispatch = { 2, "[O", escRoutines };
+ escLeftBracketRoutine, escORoutine, setMetaRoutine};
+static CharacterDispatch escDispatch = {2, "[O", escRoutines};
// Initial dispatch -- we are not in the middle of anything yet
//
-static UChar32 escRoutine( UChar32 c ) {
+static UChar32 escRoutine(UChar32 c) {
c = readUnicodeCharacter();
- if ( c == 0 ) return 0;
- return doDispatch( c, escDispatch );
+ if (c == 0)
+ return 0;
+ return doDispatch(c, escDispatch);
}
static CharacterDispatchRoutine initialRoutines[] = {
- escRoutine,
- deleteCharRoutine,
- normalKeyRoutine
-};
-static CharacterDispatch initialDispatch = { 2, "\x1B\x7F", initialRoutines };
+ escRoutine, deleteCharRoutine, normalKeyRoutine};
+static CharacterDispatch initialDispatch = {2, "\x1B\x7F", initialRoutines};
// Special handling for the ESC key because it does double duty
//
-static UChar32 setMetaRoutine( UChar32 c ) {
+static UChar32 setMetaRoutine(UChar32 c) {
thisKeyMetaCtrl = META;
- if ( c == 0x1B ) { // another ESC, stay in ESC processing mode
+ if (c == 0x1B) { // another ESC, stay in ESC processing mode
c = readUnicodeCharacter();
- if ( c == 0 ) return 0;
- return doDispatch( c, escDispatch );
+ if (c == 0)
+ return 0;
+ return doDispatch(c, escDispatch);
}
- return doDispatch( c, initialDispatch );
+ return doDispatch(c, initialDispatch);
}
-} // namespace EscapeSequenceProcessing // move these out of global namespace
+} // namespace EscapeSequenceProcessing // move these out of global namespace
-#endif // #ifndef _WIN32
+#endif // #ifndef _WIN32
// linenoiseReadChar -- read a keystroke or keychord from the keyboard, and translate it
// into an encoded "keystroke". When convenient, extended keys are translated into their
@@ -1191,16 +1242,16 @@ static UChar32 setMetaRoutine( UChar32 c ) {
//
// A return value of zero means "no input available", and a return value of -1 means "invalid key".
//
-static UChar32 linenoiseReadChar( void ) {
+static UChar32 linenoiseReadChar(void) {
#ifdef _WIN32
INPUT_RECORD rec;
DWORD count;
int modifierKeys = 0;
bool escSeen = false;
- while ( true ) {
- ReadConsoleInputW( console_in, &rec, 1, &count );
-#if 0 // helper for debugging keystrokes, display info in the debug "Output" window in the debugger
+ while (true) {
+ ReadConsoleInputW(console_in, &rec, 1, &count);
+#if 0 // helper for debugging keystrokes, display info in the debug "Output" window in the debugger
{
if ( rec.EventType == KEY_EVENT ) {
//if ( rec.Event.KeyEvent.uChar.UnicodeChar ) {
@@ -1223,49 +1274,59 @@ static UChar32 linenoiseReadChar( void ) {
}
}
#endif
- if ( rec.EventType != KEY_EVENT ) {
+ if (rec.EventType != KEY_EVENT) {
continue;
}
// Windows provides for entry of characters that are not on your keyboard by sending the Unicode
// characters as a "key up" with virtual keycode 0x12 (VK_MENU == Alt key) ... accept these characters,
// otherwise only process characters on "key down"
- if ( !rec.Event.KeyEvent.bKeyDown && rec.Event.KeyEvent.wVirtualKeyCode != VK_MENU ) {
+ if (!rec.Event.KeyEvent.bKeyDown && rec.Event.KeyEvent.wVirtualKeyCode != VK_MENU) {
continue;
}
modifierKeys = 0;
// AltGr is encoded as ( LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED ), so don't treat this combination as either CTRL or META
// we just turn off those two bits, so it is still possible to combine CTRL and/or META with an AltGr key by using right-Ctrl and/or left-Alt
- if ( ( rec.Event.KeyEvent.dwControlKeyState & ( LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED ) ) == ( LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED ) ) {
- rec.Event.KeyEvent.dwControlKeyState &= ~( LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED );
+ if ((rec.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED)) ==
+ (LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED)) {
+ rec.Event.KeyEvent.dwControlKeyState &= ~(LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED);
}
- if ( rec.Event.KeyEvent.dwControlKeyState & ( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED ) ) {
+ if (rec.Event.KeyEvent.dwControlKeyState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) {
modifierKeys |= CTRL;
}
- if ( rec.Event.KeyEvent.dwControlKeyState & ( RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED ) ) {
+ if (rec.Event.KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) {
modifierKeys |= META;
}
- if ( escSeen ) {
+ if (escSeen) {
modifierKeys |= META;
}
- if ( rec.Event.KeyEvent.uChar.UnicodeChar == 0 ) {
- switch ( rec.Event.KeyEvent.wVirtualKeyCode ) {
- case VK_LEFT: return modifierKeys | LEFT_ARROW_KEY;
- case VK_RIGHT: return modifierKeys | RIGHT_ARROW_KEY;
- case VK_UP: return modifierKeys | UP_ARROW_KEY;
- case VK_DOWN: return modifierKeys | DOWN_ARROW_KEY;
- case VK_DELETE: return modifierKeys | DELETE_KEY;
- case VK_HOME: return modifierKeys | HOME_KEY;
- case VK_END: return modifierKeys | END_KEY;
- case VK_PRIOR: return modifierKeys | PAGE_UP_KEY;
- case VK_NEXT: return modifierKeys | PAGE_DOWN_KEY;
- default: continue; // in raw mode, ReadConsoleInput shows shift, ctrl ...
- } // ... ignore them
- }
- else if ( rec.Event.KeyEvent.uChar.UnicodeChar == ctrlChar( '[' ) ) { // ESC, set flag for later
+ if (rec.Event.KeyEvent.uChar.UnicodeChar == 0) {
+ switch (rec.Event.KeyEvent.wVirtualKeyCode) {
+ case VK_LEFT:
+ return modifierKeys | LEFT_ARROW_KEY;
+ case VK_RIGHT:
+ return modifierKeys | RIGHT_ARROW_KEY;
+ case VK_UP:
+ return modifierKeys | UP_ARROW_KEY;
+ case VK_DOWN:
+ return modifierKeys | DOWN_ARROW_KEY;
+ case VK_DELETE:
+ return modifierKeys | DELETE_KEY;
+ case VK_HOME:
+ return modifierKeys | HOME_KEY;
+ case VK_END:
+ return modifierKeys | END_KEY;
+ case VK_PRIOR:
+ return modifierKeys | PAGE_UP_KEY;
+ case VK_NEXT:
+ return modifierKeys | PAGE_DOWN_KEY;
+ default:
+ continue; // in raw mode, ReadConsoleInput shows shift, ctrl ...
+ } // ... ignore them
+ } else if (rec.Event.KeyEvent.uChar.UnicodeChar ==
+ ctrlChar('[')) { // ESC, set flag for later
escSeen = true;
continue;
- }
- else {
+ } else {
// we got a real character, return it
return modifierKeys | rec.Event.KeyEvent.uChar.UnicodeChar;
}
@@ -1274,71 +1335,67 @@ static UChar32 linenoiseReadChar( void ) {
#else
UChar32 c;
c = readUnicodeCharacter();
- if ( c == 0 ) return 0;
+ if (c == 0)
+ return 0;
- // If _DEBUG_LINUX_KEYBOARD is set, then ctrl-^ puts us into a keyboard debugging mode
- // where we print out decimal and decoded values for whatever the "terminal" program
- // gives us on different keystrokes. Hit ctrl-C to exit this mode.
- //
+// If _DEBUG_LINUX_KEYBOARD is set, then ctrl-^ puts us into a keyboard debugging mode
+// where we print out decimal and decoded values for whatever the "terminal" program
+// gives us on different keystrokes. Hit ctrl-C to exit this mode.
+//
#define _DEBUG_LINUX_KEYBOARD
#if defined(_DEBUG_LINUX_KEYBOARD)
- if ( c == ctrlChar( '^' ) ) { // ctrl-^, special debug mode, prints all keys hit, ctrl-C to get out
- printf( "\nEntering keyboard debugging mode (on ctrl-^), press ctrl-C to exit this mode\n" );
- while ( true ) {
+ if (c == ctrlChar('^')) { // ctrl-^, special debug mode, prints all keys hit, ctrl-C to get out
+ printf("\nEntering keyboard debugging mode (on ctrl-^), press ctrl-C to exit this mode\n");
+ while (true) {
unsigned char keys[10];
- int ret = read( 0, keys, 10 );
+ int ret = read(0, keys, 10);
- if ( ret <= 0 ) {
- printf( "\nret: %d\n", ret );
+ if (ret <= 0) {
+ printf("\nret: %d\n", ret);
}
- for ( int i = 0; i < ret; ++i ) {
- UChar32 key = static_cast<UChar32>( keys[i] );
+ for (int i = 0; i < ret; ++i) {
+ UChar32 key = static_cast<UChar32>(keys[i]);
char* friendlyTextPtr;
char friendlyTextBuf[10];
const char* prefixText = (key < 0x80) ? "" : "0x80+";
UChar32 keyCopy = (key < 0x80) ? key : key - 0x80;
- if ( keyCopy >= '!' && keyCopy <= '~' ) { // printable
+ if (keyCopy >= '!' && keyCopy <= '~') { // printable
friendlyTextBuf[0] = '\'';
friendlyTextBuf[1] = keyCopy;
friendlyTextBuf[2] = '\'';
friendlyTextBuf[3] = 0;
friendlyTextPtr = friendlyTextBuf;
- }
- else if ( keyCopy == ' ' ) {
- friendlyTextPtr = const_cast<char*>( "space" );
- }
- else if (keyCopy == 27 ) {
- friendlyTextPtr = const_cast<char*>( "ESC" );
- }
- else if (keyCopy == 0 ) {
- friendlyTextPtr = const_cast<char*>( "NUL" );
- }
- else if (keyCopy == 127 ) {
- friendlyTextPtr = const_cast<char*>( "DEL" );
- }
- else {
+ } else if (keyCopy == ' ') {
+ friendlyTextPtr = const_cast<char*>("space");
+ } else if (keyCopy == 27) {
+ friendlyTextPtr = const_cast<char*>("ESC");
+ } else if (keyCopy == 0) {
+ friendlyTextPtr = const_cast<char*>("NUL");
+ } else if (keyCopy == 127) {
+ friendlyTextPtr = const_cast<char*>("DEL");
+ } else {
friendlyTextBuf[0] = '^';
friendlyTextBuf[1] = keyCopy + 0x40;
friendlyTextBuf[2] = 0;
friendlyTextPtr = friendlyTextBuf;
}
- printf( "%d x%02X (%s%s) ", key, key, prefixText, friendlyTextPtr );
+ printf("%d x%02X (%s%s) ", key, key, prefixText, friendlyTextPtr);
}
- printf( "\x1b[1G\n" ); // go to first column of new line
+ printf("\x1b[1G\n"); // go to first column of new line
// drop out of this loop on ctrl-C
- if ( keys[0] == ctrlChar( 'C' ) ) {
- printf( "Leaving keyboard debugging mode (on ctrl-C)\n" );
- fflush( stdout );
+ if (keys[0] == ctrlChar('C')) {
+ printf("Leaving keyboard debugging mode (on ctrl-C)\n");
+ fflush(stdout);
return -2;
}
}
}
#endif // _DEBUG_LINUX_KEYBOARD
- EscapeSequenceProcessing::thisKeyMetaCtrl = 0; // no modifiers yet at initialDispatch
- return EscapeSequenceProcessing::doDispatch( c, EscapeSequenceProcessing::initialDispatch );
-#endif // #_WIN32
+ EscapeSequenceProcessing::thisKeyMetaCtrl = 0; // no modifiers yet at initialDispatch
+ return EscapeSequenceProcessing::doDispatch(c, EscapeSequenceProcessing::initialDispatch);
+#endif // #_WIN32
}
/**
@@ -1346,7 +1403,7 @@ static UChar32 linenoiseReadChar( void ) {
*
* @param lc pointer to a linenoiseCompletions struct
*/
-static void freeCompletions( linenoiseCompletions* lc ) {
+static void freeCompletions(linenoiseCompletions* lc) {
lc->completionStrings.clear();
}
@@ -1357,16 +1414,16 @@ static void freeCompletions( linenoiseCompletions* lc ) {
* @param c character to clean up
* @return cleaned-up character
*/
-static int cleanupCtrl( int c ) {
- if ( c & CTRL ) {
+static int cleanupCtrl(int c) {
+ if (c & CTRL) {
int d = c & 0x1FF;
- if ( d >= 'a' && d <= 'z' ) {
- c = ( c + ( 'a' - ctrlChar( 'A' ) ) ) & ~CTRL;
+ if (d >= 'a' && d <= 'z') {
+ c = (c + ('a' - ctrlChar('A'))) & ~CTRL;
}
- if ( d >= 'A' && d <= 'Z' ) {
- c = ( c + ( 'A' - ctrlChar( 'A' ) ) ) & ~CTRL;
+ if (d >= 'A' && d <= 'Z') {
+ c = (c + ('A' - ctrlChar('A'))) & ~CTRL;
}
- if ( d >= ctrlChar( 'A' ) && d <= ctrlChar( 'Z' ) ) {
+ if (d >= ctrlChar('A') && d <= ctrlChar('Z')) {
c = c & ~CTRL;
}
}
@@ -1385,254 +1442,266 @@ static const size_t completionCountCutoff = 100;
* text as the user selects a proposed completion string, or cancels the completion attempt.
* @param pi PromptBase struct holding information about the prompt and our screen position
*/
-int InputBuffer::completeLine( PromptBase& pi ) {
+int InputBuffer::completeLine(PromptBase& pi) {
linenoiseCompletions lc;
char c = 0;
// completionCallback() expects a parsable entity, so find the previous break character and extract
// a copy to parse. we also handle the case where tab is hit while not at end-of-line.
int startIndex = pos;
- while ( --startIndex >= 0 ) {
- if ( strchr( breakChars, buf32[startIndex] ) ) {
+ while (--startIndex >= 0) {
+ if (strchr(breakChars, buf32[startIndex])) {
break;
}
}
++startIndex;
int itemLength = pos - startIndex;
- Utf32String unicodeCopy( &buf32[startIndex], itemLength );
- Utf8String parseItem( unicodeCopy );
+ Utf32String unicodeCopy(&buf32[startIndex], itemLength);
+ Utf8String parseItem(unicodeCopy);
// get a list of completions
- completionCallback( reinterpret_cast< char * >( parseItem.get() ), &lc );
+ completionCallback(reinterpret_cast<char*>(parseItem.get()), &lc);
// if no completions, we are done
- if ( lc.completionStrings.size() == 0 ) {
+ if (lc.completionStrings.size() == 0) {
beep();
- freeCompletions( &lc );
+ freeCompletions(&lc);
return 0;
}
// at least one completion
int longestCommonPrefix = 0;
int displayLength = 0;
- if ( lc.completionStrings.size() == 1 ) {
+ if (lc.completionStrings.size() == 1) {
longestCommonPrefix = lc.completionStrings[0].length();
- }
- else {
+ } else {
bool keepGoing = true;
- while ( keepGoing ) {
- for ( size_t j = 0; j < lc.completionStrings.size() - 1; ++j ) {
+ while (keepGoing) {
+ for (size_t j = 0; j < lc.completionStrings.size() - 1; ++j) {
char c1 = lc.completionStrings[j][longestCommonPrefix];
char c2 = lc.completionStrings[j + 1][longestCommonPrefix];
- if ( ( 0 == c1 ) || ( 0 == c2 ) || ( c1 != c2 ) ) {
+ if ((0 == c1) || (0 == c2) || (c1 != c2)) {
keepGoing = false;
break;
}
}
- if ( keepGoing ) {
+ if (keepGoing) {
++longestCommonPrefix;
}
}
}
- if ( lc.completionStrings.size() != 1 ) { // beep if ambiguous
+ if (lc.completionStrings.size() != 1) { // beep if ambiguous
beep();
}
// if we can extend the item, extend it and return to main loop
- if ( longestCommonPrefix > itemLength ) {
+ if (longestCommonPrefix > itemLength) {
displayLength = len + longestCommonPrefix - itemLength;
- if ( displayLength > buflen ) {
+ if (displayLength > buflen) {
longestCommonPrefix -= displayLength - buflen; // don't overflow buffer
- displayLength = buflen; // truncate the insertion
- beep(); // and make a noise
+ displayLength = buflen; // truncate the insertion
+ beep(); // and make a noise
}
- Utf32String displayText( displayLength + 1 );
- memcpy( displayText.get(), buf32, sizeof( UChar32 ) * startIndex );
- memcpy( &displayText[startIndex], &lc.completionStrings[0][0], sizeof( UChar32 ) * longestCommonPrefix );
+ Utf32String displayText(displayLength + 1);
+ memcpy(displayText.get(), buf32, sizeof(UChar32) * startIndex);
+ memcpy(&displayText[startIndex],
+ &lc.completionStrings[0][0],
+ sizeof(UChar32) * longestCommonPrefix);
int tailIndex = startIndex + longestCommonPrefix;
- memcpy( &displayText[tailIndex], &buf32[pos], sizeof( UChar32 ) * ( displayLength - tailIndex + 1 ) );
- copyString32( buf32, displayText.get(), buflen + 1 );
+ memcpy(&displayText[tailIndex],
+ &buf32[pos],
+ sizeof(UChar32) * (displayLength - tailIndex + 1));
+ copyString32(buf32, displayText.get(), buflen + 1);
pos = startIndex + longestCommonPrefix;
len = displayLength;
- refreshLine( pi );
+ refreshLine(pi);
return 0;
}
// we can't complete any further, wait for second tab
do {
c = linenoiseReadChar();
- c = cleanupCtrl( c );
- } while ( c == static_cast<char>( -1 ) );
+ c = cleanupCtrl(c);
+ } while (c == static_cast<char>(-1));
// if any character other than tab, pass it to the main loop
- if ( c != ctrlChar( 'I' ) ) {
- freeCompletions( &lc );
+ if (c != ctrlChar('I')) {
+ freeCompletions(&lc);
return c;
}
// we got a second tab, maybe show list of possible completions
bool showCompletions = true;
bool onNewLine = false;
- if ( lc.completionStrings.size() > completionCountCutoff ) {
+ if (lc.completionStrings.size() > completionCountCutoff) {
int savePos = pos; // move cursor to EOL to avoid overwriting the command line
pos = len;
- refreshLine( pi );
+ refreshLine(pi);
pos = savePos;
- printf( "\nDisplay all %u possibilities? (y or n)",
- static_cast<unsigned int>( lc.completionStrings.size() ) );
- fflush( stdout );
+ printf("\nDisplay all %u possibilities? (y or n)",
+ static_cast<unsigned int>(lc.completionStrings.size()));
+ fflush(stdout);
onNewLine = true;
- while ( c != 'y' && c != 'Y' && c != 'n' && c != 'N' && c != ctrlChar( 'C' ) ) {
+ while (c != 'y' && c != 'Y' && c != 'n' && c != 'N' && c != ctrlChar('C')) {
do {
c = linenoiseReadChar();
- c = cleanupCtrl( c );
- } while ( c == static_cast<char>( -1 ) );
+ c = cleanupCtrl(c);
+ } while (c == static_cast<char>(-1));
}
- switch ( c ) {
- case 'n':
- case 'N':
- showCompletions = false;
- freeCompletions( &lc );
- break;
- case ctrlChar( 'C' ):
- showCompletions = false;
- freeCompletions( &lc );
- if ( write( 1, "^C", 2 ) == -1 ) return -1; // Display the ^C we got
- c = 0;
- break;
+ switch (c) {
+ case 'n':
+ case 'N':
+ showCompletions = false;
+ freeCompletions(&lc);
+ break;
+ case ctrlChar('C'):
+ showCompletions = false;
+ freeCompletions(&lc);
+ if (write(1, "^C", 2) == -1)
+ return -1; // Display the ^C we got
+ c = 0;
+ break;
}
}
// if showing the list, do it the way readline does it
bool stopList = false;
- if ( showCompletions ) {
+ if (showCompletions) {
int longestCompletion = 0;
- for ( size_t j = 0; j < lc.completionStrings.size(); ++j) {
+ for (size_t j = 0; j < lc.completionStrings.size(); ++j) {
itemLength = lc.completionStrings[j].length();
- if ( itemLength > longestCompletion ) {
+ if (itemLength > longestCompletion) {
longestCompletion = itemLength;
}
}
longestCompletion += 2;
int columnCount = pi.promptScreenColumns / longestCompletion;
- if ( columnCount < 1) {
+ if (columnCount < 1) {
columnCount = 1;
}
- if ( ! onNewLine ) { // skip this if we showed "Display all %d possibilities?"
+ if (!onNewLine) { // skip this if we showed "Display all %d possibilities?"
int savePos = pos; // move cursor to EOL to avoid overwriting the command line
pos = len;
- refreshLine( pi );
+ refreshLine(pi);
pos = savePos;
}
size_t pauseRow = getScreenRows() - 1;
- size_t rowCount = ( lc.completionStrings.size() + columnCount - 1) / columnCount;
- for ( size_t row = 0; row < rowCount; ++row ) {
- if ( row == pauseRow ) {
- printf( "\n--More--" );
- fflush( stdout );
+ size_t rowCount = (lc.completionStrings.size() + columnCount - 1) / columnCount;
+ for (size_t row = 0; row < rowCount; ++row) {
+ if (row == pauseRow) {
+ printf("\n--More--");
+ fflush(stdout);
c = 0;
bool doBeep = false;
- while ( c != ' ' && c != '\r' && c != '\n' && c != 'y' && c != 'Y' && c != 'n' && c != 'N' && c != 'q' && c != 'Q' && c != ctrlChar( 'C' ) ) {
- if ( doBeep ) {
+ while (c != ' ' && c != '\r' && c != '\n' && c != 'y' && c != 'Y' && c != 'n' &&
+ c != 'N' && c != 'q' && c != 'Q' && c != ctrlChar('C')) {
+ if (doBeep) {
beep();
}
doBeep = true;
do {
c = linenoiseReadChar();
- c = cleanupCtrl( c );
- } while ( c == static_cast<char>( -1 ) );
+ c = cleanupCtrl(c);
+ } while (c == static_cast<char>(-1));
}
- switch ( c ) {
- case ' ':
- case 'y':
- case 'Y':
- printf( "\r \r" );
- pauseRow += getScreenRows() - 1;
- break;
- case '\r':
- case '\n':
- printf( "\r \r" );
- ++pauseRow;
- break;
- case 'n':
- case 'N':
- case 'q':
- case 'Q':
- printf( "\r \r" );
- stopList = true;
- break;
- case ctrlChar( 'C' ):
- if ( write( 1, "^C", 2 ) == -1 ) return -1; // Display the ^C we got
- stopList = true;
- break;
+ switch (c) {
+ case ' ':
+ case 'y':
+ case 'Y':
+ printf("\r \r");
+ pauseRow += getScreenRows() - 1;
+ break;
+ case '\r':
+ case '\n':
+ printf("\r \r");
+ ++pauseRow;
+ break;
+ case 'n':
+ case 'N':
+ case 'q':
+ case 'Q':
+ printf("\r \r");
+ stopList = true;
+ break;
+ case ctrlChar('C'):
+ if (write(1, "^C", 2) == -1)
+ return -1; // Display the ^C we got
+ stopList = true;
+ break;
}
+ } else {
+ printf("\n");
}
- else {
- printf( "\n" );
- }
- if ( stopList ) {
+ if (stopList) {
break;
}
- for ( int column = 0; column < columnCount; ++column ) {
- size_t index = ( column * rowCount ) + row;
- if ( index < lc.completionStrings.size() ) {
+ for (int column = 0; column < columnCount; ++column) {
+ size_t index = (column * rowCount) + row;
+ if (index < lc.completionStrings.size()) {
itemLength = lc.completionStrings[index].length();
- fflush( stdout );
- if ( write32( 1, lc.completionStrings[index].get(), itemLength ) == -1 ) return -1;
- if ( ( ( column + 1 ) * rowCount ) + row < lc.completionStrings.size() ) {
- for ( int k = itemLength; k < longestCompletion; ++k ) {
- printf( " " );
+ fflush(stdout);
+ if (write32(1, lc.completionStrings[index].get(), itemLength) == -1)
+ return -1;
+ if (((column + 1) * rowCount) + row < lc.completionStrings.size()) {
+ for (int k = itemLength; k < longestCompletion; ++k) {
+ printf(" ");
}
}
}
}
}
- fflush( stdout );
- freeCompletions( &lc );
+ fflush(stdout);
+ freeCompletions(&lc);
}
// display the prompt on a new line, then redisplay the input buffer
- if ( ! stopList || c == ctrlChar( 'C' ) ) {
- if ( write( 1, "\n", 1 ) == -1 ) return 0;
+ if (!stopList || c == ctrlChar('C')) {
+ if (write(1, "\n", 1) == -1)
+ return 0;
}
- if ( write32( 1, pi.promptText.get(), pi.promptChars ) == -1 ) return 0;
+ if (write32(1, pi.promptText.get(), pi.promptChars) == -1)
+ return 0;
#ifndef _WIN32
// we have to generate our own newline on line wrap on Linux
- if ( pi.promptIndentation == 0 && pi.promptExtraLines > 0 )
- if ( write( 1, "\n", 1 ) == -1 ) return 0;
+ if (pi.promptIndentation == 0 && pi.promptExtraLines > 0)
+ if (write(1, "\n", 1) == -1)
+ return 0;
#endif
pi.promptCursorRowOffset = pi.promptExtraLines;
- refreshLine( pi );
+ refreshLine(pi);
return 0;
}
/**
* Clear the screen ONLY (no redisplay of anything)
*/
-void linenoiseClearScreen( void ) {
+void linenoiseClearScreen(void) {
#ifdef _WIN32
COORD coord = {0, 0};
CONSOLE_SCREEN_BUFFER_INFO inf;
- HANDLE screenHandle = GetStdHandle( STD_OUTPUT_HANDLE );
- GetConsoleScreenBufferInfo( screenHandle, &inf );
- SetConsoleCursorPosition( screenHandle, coord );
+ HANDLE screenHandle = GetStdHandle(STD_OUTPUT_HANDLE);
+ GetConsoleScreenBufferInfo(screenHandle, &inf);
+ SetConsoleCursorPosition(screenHandle, coord);
DWORD count;
- FillConsoleOutputCharacterA( screenHandle, ' ', inf.dwSize.X * inf.dwSize.Y, coord, &count );
+ FillConsoleOutputCharacterA(screenHandle, ' ', inf.dwSize.X * inf.dwSize.Y, coord, &count);
#else
- if ( write( 1, "\x1b[H\x1b[2J", 7 ) <= 0 ) return;
+ if (write(1, "\x1b[H\x1b[2J", 7) <= 0)
+ return;
#endif
}
-void InputBuffer::clearScreen( PromptBase& pi ) {
+void InputBuffer::clearScreen(PromptBase& pi) {
linenoiseClearScreen();
- if ( write32( 1, pi.promptText.get(), pi.promptChars ) == -1 ) return;
+ if (write32(1, pi.promptText.get(), pi.promptChars) == -1)
+ return;
#ifndef _WIN32
// we have to generate our own newline on line wrap on Linux
- if ( pi.promptIndentation == 0 && pi.promptExtraLines > 0 )
- if ( write( 1, "\n", 1 ) == -1 ) return;
+ if (pi.promptIndentation == 0 && pi.promptExtraLines > 0)
+ if (write(1, "\n", 1) == -1)
+ return;
#endif
pi.promptCursorRowOffset = pi.promptExtraLines;
- refreshLine( pi );
+ refreshLine(pi);
}
/**
@@ -1642,30 +1711,32 @@ void InputBuffer::clearScreen( PromptBase& pi ) {
* @param pi PromptBase struct holding information about the (old, static) prompt and our screen position
* @param startChar the character that began the search, used to set the initial direction
*/
-int InputBuffer::incrementalHistorySearch( PromptBase& pi, int startChar ) {
+int InputBuffer::incrementalHistorySearch(PromptBase& pi, int startChar) {
size_t bufferSize;
size_t ucharCount;
int errorCode;
// if not already recalling, add the current line to the history list so we don't have to special case it
- if ( historyIndex == historyLen - 1 ) {
- free( history[historyLen - 1] );
- bufferSize = sizeof( UChar32 ) * len + 1;
- unique_ptr< UChar8 []> tempBuffer( new UChar8[ bufferSize ] );
- copyString32to8( tempBuffer.get(), buf32, bufferSize );
- history[ historyLen - 1 ] = reinterpret_cast< UChar8 * >( strdup( reinterpret_cast< const char * >( tempBuffer.get() ) ) );
+ if (historyIndex == historyLen - 1) {
+ free(history[historyLen - 1]);
+ bufferSize = sizeof(UChar32) * len + 1;
+ unique_ptr<UChar8[]> tempBuffer(new UChar8[bufferSize]);
+ copyString32to8(tempBuffer.get(), buf32, bufferSize);
+ history[historyLen - 1] =
+ reinterpret_cast<UChar8*>(strdup(reinterpret_cast<const char*>(tempBuffer.get())));
}
int historyLineLength = len;
int historyLinePosition = pos;
UChar32 emptyBuffer[1];
char emptyWidths[1];
- InputBuffer empty( emptyBuffer, emptyWidths, 1 );
- empty.refreshLine( pi ); // erase the old input first
- DynamicPrompt dp( pi, ( startChar == ctrlChar( 'R' ) ) ? -1 : 1 );
+ InputBuffer empty(emptyBuffer, emptyWidths, 1);
+ empty.refreshLine(pi); // erase the old input first
+ DynamicPrompt dp(pi, (startChar == ctrlChar('R')) ? -1 : 1);
dp.promptPreviousLen = pi.promptPreviousLen;
dp.promptPreviousInputLen = pi.promptPreviousInputLen;
- dynamicRefresh( dp, buf32, historyLineLength, historyLinePosition ); // draw user's text with our prompt
+ dynamicRefresh(
+ dp, buf32, historyLineLength, historyLinePosition); // draw user's text with our prompt
// loop until we get an exit character
int c;
@@ -1673,187 +1744,199 @@ int InputBuffer::incrementalHistorySearch( PromptBase& pi, int startChar ) {
bool useSearchedLine = true;
bool searchAgain = false;
UChar32* activeHistoryLine = 0;
- while ( keepLooping ) {
+ while (keepLooping) {
c = linenoiseReadChar();
- c = cleanupCtrl( c ); // convert CTRL + <char> into normal ctrl
-
- switch ( c ) {
-
- // these characters keep the selected text but do not execute it
- case ctrlChar( 'A' ): // ctrl-A, move cursor to start of line
- case HOME_KEY:
- case ctrlChar( 'B' ): // ctrl-B, move cursor left by one character
- case LEFT_ARROW_KEY:
- case META + 'b': // meta-B, move cursor left by one word
- case META + 'B':
- case CTRL + LEFT_ARROW_KEY:
- case META + LEFT_ARROW_KEY: // Emacs allows Meta, bash & readline don't
- case ctrlChar( 'D' ):
- case META + 'd': // meta-D, kill word to right of cursor
- case META + 'D':
- case ctrlChar( 'E' ): // ctrl-E, move cursor to end of line
- case END_KEY:
- case ctrlChar( 'F' ): // ctrl-F, move cursor right by one character
- case RIGHT_ARROW_KEY:
- case META + 'f': // meta-F, move cursor right by one word
- case META + 'F':
- case CTRL + RIGHT_ARROW_KEY:
- case META + RIGHT_ARROW_KEY: // Emacs allows Meta, bash & readline don't
- case META + ctrlChar( 'H' ):
- case ctrlChar( 'J' ):
- case ctrlChar( 'K' ): // ctrl-K, kill from cursor to end of line
- case ctrlChar( 'M' ):
- case ctrlChar( 'N' ): // ctrl-N, recall next line in history
- case ctrlChar( 'P' ): // ctrl-P, recall previous line in history
- case DOWN_ARROW_KEY:
- case UP_ARROW_KEY:
- case ctrlChar( 'T' ): // ctrl-T, transpose characters
- case ctrlChar( 'U' ): // ctrl-U, kill all characters to the left of the cursor
- case ctrlChar( 'W' ):
- case META + 'y': // meta-Y, "yank-pop", rotate popped text
- case META + 'Y':
- case 127:
- case DELETE_KEY:
- case META + '<': // start of history
- case PAGE_UP_KEY:
- case META + '>': // end of history
- case PAGE_DOWN_KEY:
- keepLooping = false;
- break;
+ c = cleanupCtrl(c); // convert CTRL + <char> into normal ctrl
+
+ switch (c) {
+ // these characters keep the selected text but do not execute it
+ case ctrlChar('A'): // ctrl-A, move cursor to start of line
+ case HOME_KEY:
+ case ctrlChar('B'): // ctrl-B, move cursor left by one character
+ case LEFT_ARROW_KEY:
+ case META + 'b': // meta-B, move cursor left by one word
+ case META + 'B':
+ case CTRL + LEFT_ARROW_KEY:
+ case META + LEFT_ARROW_KEY: // Emacs allows Meta, bash & readline don't
+ case ctrlChar('D'):
+ case META + 'd': // meta-D, kill word to right of cursor
+ case META + 'D':
+ case ctrlChar('E'): // ctrl-E, move cursor to end of line
+ case END_KEY:
+ case ctrlChar('F'): // ctrl-F, move cursor right by one character
+ case RIGHT_ARROW_KEY:
+ case META + 'f': // meta-F, move cursor right by one word
+ case META + 'F':
+ case CTRL + RIGHT_ARROW_KEY:
+ case META + RIGHT_ARROW_KEY: // Emacs allows Meta, bash & readline don't
+ case META + ctrlChar('H'):
+ case ctrlChar('J'):
+ case ctrlChar('K'): // ctrl-K, kill from cursor to end of line
+ case ctrlChar('M'):
+ case ctrlChar('N'): // ctrl-N, recall next line in history
+ case ctrlChar('P'): // ctrl-P, recall previous line in history
+ case DOWN_ARROW_KEY:
+ case UP_ARROW_KEY:
+ case ctrlChar('T'): // ctrl-T, transpose characters
+ case ctrlChar('U'): // ctrl-U, kill all characters to the left of the cursor
+ case ctrlChar('W'):
+ case META + 'y': // meta-Y, "yank-pop", rotate popped text
+ case META + 'Y':
+ case 127:
+ case DELETE_KEY:
+ case META + '<': // start of history
+ case PAGE_UP_KEY:
+ case META + '>': // end of history
+ case PAGE_DOWN_KEY:
+ keepLooping = false;
+ break;
- // these characters revert the input line to its previous state
- case ctrlChar( 'C' ): // ctrl-C, abort this line
- case ctrlChar( 'G' ):
- case ctrlChar( 'L' ): // ctrl-L, clear screen and redisplay line
- keepLooping = false;
- useSearchedLine = false;
- if ( c != ctrlChar( 'L' ) ) {
- c = -1; // ctrl-C and ctrl-G just abort the search and do nothing else
- }
- break;
+ // these characters revert the input line to its previous state
+ case ctrlChar('C'): // ctrl-C, abort this line
+ case ctrlChar('G'):
+ case ctrlChar('L'): // ctrl-L, clear screen and redisplay line
+ keepLooping = false;
+ useSearchedLine = false;
+ if (c != ctrlChar('L')) {
+ c = -1; // ctrl-C and ctrl-G just abort the search and do nothing else
+ }
+ break;
- // these characters stay in search mode and update the display
- case ctrlChar( 'S' ):
- case ctrlChar( 'R' ):
- if ( dp.searchTextLen == 0 ) { // if no current search text, recall previous text
- if ( previousSearchText.length() ) {
- dp.updateSearchText( previousSearchText.get() );
+ // these characters stay in search mode and update the display
+ case ctrlChar('S'):
+ case ctrlChar('R'):
+ if (dp.searchTextLen == 0) { // if no current search text, recall previous text
+ if (previousSearchText.length()) {
+ dp.updateSearchText(previousSearchText.get());
+ }
}
- }
- if ( ( dp.direction == 1 && c == ctrlChar( 'R' ) ) ||
- ( dp.direction == -1 && c == ctrlChar( 'S' ) ) ) {
- dp.direction = 0 - dp.direction; // reverse direction
- dp.updateSearchPrompt(); // change the prompt
- }
- else {
- searchAgain = true; // same direction, search again
- }
- break;
+ if ((dp.direction == 1 && c == ctrlChar('R')) ||
+ (dp.direction == -1 && c == ctrlChar('S'))) {
+ dp.direction = 0 - dp.direction; // reverse direction
+ dp.updateSearchPrompt(); // change the prompt
+ } else {
+ searchAgain = true; // same direction, search again
+ }
+ break;
- // job control is its own thing
+// job control is its own thing
#ifndef _WIN32
- case ctrlChar( 'Z' ): // ctrl-Z, job control
- disableRawMode(); // Returning to Linux (whatever) shell, leave raw mode
- raise( SIGSTOP ); // Break out in mid-line
- enableRawMode(); // Back from Linux shell, re-enter raw mode
- {
- bufferSize = historyLineLength + 1;
- unique_ptr< UChar32 []> tempUnicode( new UChar32[ bufferSize ] );
- copyString8to32( tempUnicode.get(), history[ historyIndex ], bufferSize, ucharCount, errorCode );
- dynamicRefresh( dp, tempUnicode.get(), historyLineLength, historyLinePosition );
- }
- continue;
- break;
+ case ctrlChar('Z'): // ctrl-Z, job control
+ disableRawMode(); // Returning to Linux (whatever) shell, leave raw mode
+ raise(SIGSTOP); // Break out in mid-line
+ enableRawMode(); // Back from Linux shell, re-enter raw mode
+ {
+ bufferSize = historyLineLength + 1;
+ unique_ptr<UChar32[]> tempUnicode(new UChar32[bufferSize]);
+ copyString8to32(tempUnicode.get(),
+ history[historyIndex],
+ bufferSize,
+ ucharCount,
+ errorCode);
+ dynamicRefresh(dp, tempUnicode.get(), historyLineLength, historyLinePosition);
+ }
+ continue;
+ break;
#endif
- // these characters update the search string, and hence the selected input line
- case ctrlChar( 'H' ): // backspace/ctrl-H, delete char to left of cursor
- if ( dp.searchTextLen > 0 ) {
- unique_ptr<UChar32[]> tempUnicode( new UChar32[ dp.searchTextLen ] );
- --dp.searchTextLen;
- dp.searchText[ dp.searchTextLen ] = 0;
- copyString32( tempUnicode.get(), dp.searchText.get(), dp.searchTextLen + 1 );
- dp.updateSearchText( tempUnicode.get() );
- }
- else {
- beep();
- }
- break;
+ // these characters update the search string, and hence the selected input line
+ case ctrlChar('H'): // backspace/ctrl-H, delete char to left of cursor
+ if (dp.searchTextLen > 0) {
+ unique_ptr<UChar32[]> tempUnicode(new UChar32[dp.searchTextLen]);
+ --dp.searchTextLen;
+ dp.searchText[dp.searchTextLen] = 0;
+ copyString32(tempUnicode.get(), dp.searchText.get(), dp.searchTextLen + 1);
+ dp.updateSearchText(tempUnicode.get());
+ } else {
+ beep();
+ }
+ break;
- case ctrlChar( 'Y' ): // ctrl-Y, yank killed text
- break;
+ case ctrlChar('Y'): // ctrl-Y, yank killed text
+ break;
- default:
- if ( !isControlChar( c ) && c <= 0x0010FFFF ) { // not an action character
- unique_ptr< UChar32 []> tempUnicode( new UChar32[ dp.searchTextLen + 2 ] );
- copyString32( tempUnicode.get(), dp.searchText.get(), dp.searchTextLen + 2 );
- tempUnicode[ dp.searchTextLen ] = c;
- tempUnicode[ dp.searchTextLen + 1 ] = 0;
- dp.updateSearchText( tempUnicode.get() );
- }
- else {
- beep();
- }
- } // switch
+ default:
+ if (!isControlChar(c) && c <= 0x0010FFFF) { // not an action character
+ unique_ptr<UChar32[]> tempUnicode(new UChar32[dp.searchTextLen + 2]);
+ copyString32(tempUnicode.get(), dp.searchText.get(), dp.searchTextLen + 2);
+ tempUnicode[dp.searchTextLen] = c;
+ tempUnicode[dp.searchTextLen + 1] = 0;
+ dp.updateSearchText(tempUnicode.get());
+ } else {
+ beep();
+ }
+ } // switch
// if we are staying in search mode, search now
- if ( keepLooping ) {
+ if (keepLooping) {
bufferSize = historyLineLength + 1;
- activeHistoryLine = new UChar32[ bufferSize ];
- copyString8to32( activeHistoryLine, history[ historyIndex ], bufferSize, ucharCount, errorCode );
- if ( dp.searchTextLen > 0 ) {
+ activeHistoryLine = new UChar32[bufferSize];
+ copyString8to32(
+ activeHistoryLine, history[historyIndex], bufferSize, ucharCount, errorCode);
+ if (dp.searchTextLen > 0) {
bool found = false;
int historySearchIndex = historyIndex;
int lineLength = ucharCount;
int lineSearchPos = historyLinePosition;
- if ( searchAgain ) {
+ if (searchAgain) {
lineSearchPos += dp.direction;
}
searchAgain = false;
- while ( true ) {
- while ( ( dp.direction > 0 ) ? ( lineSearchPos < lineLength ) : ( lineSearchPos >= 0 ) ) {
- if ( strncmp32( dp.searchText.get(), &activeHistoryLine[ lineSearchPos ], dp.searchTextLen) == 0 ) {
+ while (true) {
+ while ((dp.direction > 0) ? (lineSearchPos < lineLength)
+ : (lineSearchPos >= 0)) {
+ if (strncmp32(dp.searchText.get(),
+ &activeHistoryLine[lineSearchPos],
+ dp.searchTextLen) == 0) {
found = true;
break;
}
lineSearchPos += dp.direction;
}
- if ( found ) {
+ if (found) {
historyIndex = historySearchIndex;
historyLineLength = lineLength;
historyLinePosition = lineSearchPos;
break;
- }
- else if ( ( dp.direction > 0 ) ? ( historySearchIndex < historyLen - 1 ) : ( historySearchIndex > 0 ) ) {
+ } else if ((dp.direction > 0) ? (historySearchIndex < historyLen - 1)
+ : (historySearchIndex > 0)) {
historySearchIndex += dp.direction;
- bufferSize = strlen( reinterpret_cast< char* >( history[ historySearchIndex ] ) ) + 1;
- delete [] activeHistoryLine;
- activeHistoryLine = new UChar32[ bufferSize ];
- copyString8to32( activeHistoryLine, history[ historySearchIndex ], bufferSize, ucharCount, errorCode );
+ bufferSize =
+ strlen(reinterpret_cast<char*>(history[historySearchIndex])) + 1;
+ delete[] activeHistoryLine;
+ activeHistoryLine = new UChar32[bufferSize];
+ copyString8to32(activeHistoryLine,
+ history[historySearchIndex],
+ bufferSize,
+ ucharCount,
+ errorCode);
lineLength = ucharCount;
- lineSearchPos = ( dp.direction > 0 ) ? 0 : ( lineLength - dp.searchTextLen );
- }
- else {
+ lineSearchPos = (dp.direction > 0) ? 0 : (lineLength - dp.searchTextLen);
+ } else {
beep();
break;
}
- }; // while
+ }; // while
}
- if ( activeHistoryLine ) {
- delete [] activeHistoryLine;
+ if (activeHistoryLine) {
+ delete[] activeHistoryLine;
}
bufferSize = historyLineLength + 1;
- activeHistoryLine = new UChar32[ bufferSize ];
- copyString8to32( activeHistoryLine, history[ historyIndex ], bufferSize, ucharCount, errorCode );
- dynamicRefresh( dp, activeHistoryLine, historyLineLength, historyLinePosition ); // draw user's text with our prompt
+ activeHistoryLine = new UChar32[bufferSize];
+ copyString8to32(
+ activeHistoryLine, history[historyIndex], bufferSize, ucharCount, errorCode);
+ dynamicRefresh(dp,
+ activeHistoryLine,
+ historyLineLength,
+ historyLinePosition); // draw user's text with our prompt
}
- } // while
+ } // while
// leaving history search, restore previous prompt, maybe make searched line current
PromptBase pb;
pb.promptChars = pi.promptIndentation;
- Utf32String tempUnicode( pb.promptChars + 1 );
- copyString32( tempUnicode.get(), &pi.promptText[ pi.promptLastLinePosition ], pb.promptChars + 1 );
+ Utf32String tempUnicode(pb.promptChars + 1);
+ copyString32(tempUnicode.get(), &pi.promptText[pi.promptLastLinePosition], pb.promptChars + 1);
tempUnicode.initFromBuffer();
pb.promptText = tempUnicode;
pb.promptExtraLines = 0;
@@ -1863,48 +1946,48 @@ int InputBuffer::incrementalHistorySearch( PromptBase& pi, int startChar ) {
pb.promptCursorRowOffset = dp.promptCursorRowOffset;
pb.promptScreenColumns = pi.promptScreenColumns;
pb.promptPreviousLen = dp.promptChars;
- if ( useSearchedLine && activeHistoryLine ) {
+ if (useSearchedLine && activeHistoryLine) {
historyRecallMostRecent = true;
- copyString32( buf32, activeHistoryLine, buflen + 1 );
+ copyString32(buf32, activeHistoryLine, buflen + 1);
len = historyLineLength;
pos = historyLinePosition;
}
- if ( activeHistoryLine ) {
- delete [] activeHistoryLine;
+ if (activeHistoryLine) {
+ delete[] activeHistoryLine;
}
- dynamicRefresh( pb, buf32, len, pos ); // redraw the original prompt with current input
+ dynamicRefresh(pb, buf32, len, pos); // redraw the original prompt with current input
pi.promptPreviousInputLen = len;
pi.promptCursorRowOffset = pi.promptExtraLines + pb.promptCursorRowOffset;
- previousSearchText = dp.searchText; // save search text for possible reuse on ctrl-R ctrl-R
- return c; // pass a character or -1 back to main loop
+ previousSearchText = dp.searchText; // save search text for possible reuse on ctrl-R ctrl-R
+ return c; // pass a character or -1 back to main loop
}
-static bool isCharacterAlphanumeric( UChar32 testChar ) {
- return iswalnum( testChar );
+static bool isCharacterAlphanumeric(UChar32 testChar) {
+ return iswalnum(testChar);
}
-int InputBuffer::getInputLine( PromptBase& pi ) {
-
+int InputBuffer::getInputLine(PromptBase& pi) {
// The latest history entry is always our current buffer
- if ( len > 0 ) {
- size_t bufferSize = sizeof( UChar32 ) * len + 1;
- unique_ptr< char []> tempBuffer( new char[ bufferSize ] );
- copyString32to8( reinterpret_cast< UChar8 * >( tempBuffer.get() ), buf32, bufferSize );
- linenoiseHistoryAdd( tempBuffer.get() );
- }
- else {
- linenoiseHistoryAdd( "" );
+ if (len > 0) {
+ size_t bufferSize = sizeof(UChar32) * len + 1;
+ unique_ptr<char[]> tempBuffer(new char[bufferSize]);
+ copyString32to8(reinterpret_cast<UChar8*>(tempBuffer.get()), buf32, bufferSize);
+ linenoiseHistoryAdd(tempBuffer.get());
+ } else {
+ linenoiseHistoryAdd("");
}
historyIndex = historyLen - 1;
historyRecallMostRecent = false;
// display the prompt
- if ( write32( 1, pi.promptText.get(), pi.promptChars ) == -1 ) return -1;
+ if (write32(1, pi.promptText.get(), pi.promptChars) == -1)
+ return -1;
#ifndef _WIN32
// we have to generate our own newline on line wrap on Linux
- if ( pi.promptIndentation == 0 && pi.promptExtraLines > 0 )
- if ( write( 1, "\n", 1 ) == -1 ) return -1;
+ if (pi.promptIndentation == 0 && pi.promptExtraLines > 0)
+ if (write(1, "\n", 1) == -1)
+ return -1;
#endif
// the cursor starts out at the end of the prompt
@@ -1917,538 +2000,549 @@ int InputBuffer::getInputLine( PromptBase& pi ) {
int terminatingKeystroke = -1;
// if there is already text in the buffer, display it first
- if ( len > 0 ) {
- refreshLine( pi );
+ if (len > 0) {
+ refreshLine(pi);
}
// loop collecting characters, respond to line editing characters
- while ( true ) {
+ while (true) {
int c;
- if ( terminatingKeystroke == -1 ) {
- c = linenoiseReadChar(); // get a new keystroke
- }
- else {
+ if (terminatingKeystroke == -1) {
+ c = linenoiseReadChar(); // get a new keystroke
+ } else {
c = terminatingKeystroke; // use the terminating keystroke from search
terminatingKeystroke = -1; // clear it once we've used it
}
- c = cleanupCtrl( c ); // convert CTRL + <char> into normal ctrl
+ c = cleanupCtrl(c); // convert CTRL + <char> into normal ctrl
- if ( c == 0 ) {
+ if (c == 0) {
return len;
}
- if ( c == -1 ) {
- refreshLine( pi );
+ if (c == -1) {
+ refreshLine(pi);
continue;
}
- if ( c == -2 ) {
- if ( write32( 1, pi.promptText.get(), pi.promptChars ) == -1 ) return -1;
- refreshLine( pi );
+ if (c == -2) {
+ if (write32(1, pi.promptText.get(), pi.promptChars) == -1)
+ return -1;
+ refreshLine(pi);
continue;
}
// ctrl-I/tab, command completion, needs to be before switch statement
- if ( c == ctrlChar( 'I' ) && completionCallback ) {
-
- if ( pos == 0 ) // SERVER-4967 -- in earlier versions, you could paste previous output
- continue; // back into the shell ... this output may have leading tabs.
- // This hack (i.e. what the old code did) prevents command completion
- // on an empty line but lets users paste text with leading tabs.
+ if (c == ctrlChar('I') && completionCallback) {
+ if (pos == 0) // SERVER-4967 -- in earlier versions, you could paste previous output
+ continue; // back into the shell ... this output may have leading tabs.
+ // This hack (i.e. what the old code did) prevents command completion
+ // on an empty line but lets users paste text with leading tabs.
killRing.lastAction = KillRing::actionOther;
historyRecallMostRecent = false;
// completeLine does the actual completion and replacement
- c = completeLine( pi );
+ c = completeLine(pi);
- if ( c < 0 ) // return on error
+ if (c < 0) // return on error
return len;
- if ( c == 0 ) // read next character when 0
+ if (c == 0) // read next character when 0
continue;
// deliberate fall-through here, so we use the terminating character
}
- switch ( c ) {
-
- case ctrlChar( 'A' ): // ctrl-A, move cursor to start of line
- case HOME_KEY:
- killRing.lastAction = KillRing::actionOther;
- pos = 0;
- refreshLine( pi );
- break;
-
- case ctrlChar( 'B' ): // ctrl-B, move cursor left by one character
- case LEFT_ARROW_KEY:
- killRing.lastAction = KillRing::actionOther;
- if ( pos > 0 ) {
- --pos;
- refreshLine( pi );
- }
- break;
+ switch (c) {
+ case ctrlChar('A'): // ctrl-A, move cursor to start of line
+ case HOME_KEY:
+ killRing.lastAction = KillRing::actionOther;
+ pos = 0;
+ refreshLine(pi);
+ break;
- case META + 'b': // meta-B, move cursor left by one word
- case META + 'B':
- case CTRL + LEFT_ARROW_KEY:
- case META + LEFT_ARROW_KEY: // Emacs allows Meta, bash & readline don't
- killRing.lastAction = KillRing::actionOther;
- if ( pos > 0 ) {
- while ( pos > 0 && !isCharacterAlphanumeric( buf32[pos - 1] ) ) {
- --pos;
- }
- while ( pos > 0 && isCharacterAlphanumeric( buf32[pos - 1] ) ) {
+ case ctrlChar('B'): // ctrl-B, move cursor left by one character
+ case LEFT_ARROW_KEY:
+ killRing.lastAction = KillRing::actionOther;
+ if (pos > 0) {
--pos;
+ refreshLine(pi);
}
- refreshLine( pi );
- }
- break;
-
- case ctrlChar( 'C' ): // ctrl-C, abort this line
- killRing.lastAction = KillRing::actionOther;
- historyRecallMostRecent = false;
- errno = EAGAIN;
- --historyLen;
- free( history[historyLen] );
- // we need one last refresh with the cursor at the end of the line
- // so we don't display the next prompt over the previous input line
- pos = len; // pass len as pos for EOL
- refreshLine( pi );
- if ( write( 1, "^C", 2 ) == -1 ) return -1; // Display the ^C we got
- return -1;
+ break;
- case META + 'c': // meta-C, give word initial Cap
- case META + 'C':
- killRing.lastAction = KillRing::actionOther;
- historyRecallMostRecent = false;
- if ( pos < len ) {
- while ( pos < len && !isCharacterAlphanumeric( buf32[pos] ) ) {
- ++pos;
- }
- if ( pos < len && isCharacterAlphanumeric( buf32[pos] ) ) {
- if ( buf32[pos] >= 'a' && buf32[pos] <= 'z' ) {
- buf32[pos] += 'A' - 'a';
+ case META + 'b': // meta-B, move cursor left by one word
+ case META + 'B':
+ case CTRL + LEFT_ARROW_KEY:
+ case META + LEFT_ARROW_KEY: // Emacs allows Meta, bash & readline don't
+ killRing.lastAction = KillRing::actionOther;
+ if (pos > 0) {
+ while (pos > 0 && !isCharacterAlphanumeric(buf32[pos - 1])) {
+ --pos;
}
- ++pos;
- }
- while ( pos < len && isCharacterAlphanumeric( buf32[pos] ) ) {
- if ( buf32[pos] >= 'A' && buf32[pos] <= 'Z' ) {
- buf32[pos] += 'a' - 'A';
+ while (pos > 0 && isCharacterAlphanumeric(buf32[pos - 1])) {
+ --pos;
}
- ++pos;
+ refreshLine(pi);
}
- refreshLine( pi );
- }
- break;
+ break;
- // ctrl-D, delete the character under the cursor
- // on an empty line, exit the shell
- case ctrlChar( 'D' ):
- killRing.lastAction = KillRing::actionOther;
- if ( len > 0 && pos < len ) {
+ case ctrlChar('C'): // ctrl-C, abort this line
+ killRing.lastAction = KillRing::actionOther;
historyRecallMostRecent = false;
- memmove( buf32 + pos, buf32 + pos + 1, sizeof( UChar32 ) * ( len - pos ) );
- --len;
- refreshLine( pi );
- }
- else if ( len == 0 ) {
+ errno = EAGAIN;
--historyLen;
- free( history[historyLen] );
+ free(history[historyLen]);
+ // we need one last refresh with the cursor at the end of the line
+ // so we don't display the next prompt over the previous input line
+ pos = len; // pass len as pos for EOL
+ refreshLine(pi);
+ if (write(1, "^C", 2) == -1)
+ return -1; // Display the ^C we got
return -1;
- }
- break;
- case META + 'd': // meta-D, kill word to right of cursor
- case META + 'D':
- if ( pos < len ) {
+ case META + 'c': // meta-C, give word initial Cap
+ case META + 'C':
+ killRing.lastAction = KillRing::actionOther;
historyRecallMostRecent = false;
- int endingPos = pos;
- while ( endingPos < len && !isCharacterAlphanumeric( buf32[endingPos] ) ) {
- ++endingPos;
+ if (pos < len) {
+ while (pos < len && !isCharacterAlphanumeric(buf32[pos])) {
+ ++pos;
+ }
+ if (pos < len && isCharacterAlphanumeric(buf32[pos])) {
+ if (buf32[pos] >= 'a' && buf32[pos] <= 'z') {
+ buf32[pos] += 'A' - 'a';
+ }
+ ++pos;
+ }
+ while (pos < len && isCharacterAlphanumeric(buf32[pos])) {
+ if (buf32[pos] >= 'A' && buf32[pos] <= 'Z') {
+ buf32[pos] += 'a' - 'A';
+ }
+ ++pos;
+ }
+ refreshLine(pi);
}
- while ( endingPos < len && isCharacterAlphanumeric( buf32[endingPos] ) ) {
- ++endingPos;
+ break;
+
+ // ctrl-D, delete the character under the cursor
+ // on an empty line, exit the shell
+ case ctrlChar('D'):
+ killRing.lastAction = KillRing::actionOther;
+ if (len > 0 && pos < len) {
+ historyRecallMostRecent = false;
+ memmove(buf32 + pos, buf32 + pos + 1, sizeof(UChar32) * (len - pos));
+ --len;
+ refreshLine(pi);
+ } else if (len == 0) {
+ --historyLen;
+ free(history[historyLen]);
+ return -1;
}
- killRing.kill( &buf32[pos], endingPos - pos, true );
- memmove( buf32 + pos, buf32 + endingPos, sizeof( UChar32 ) * ( len - endingPos + 1 ) );
- len -= endingPos - pos;
- refreshLine( pi );
- }
- killRing.lastAction = KillRing::actionKill;
- break;
+ break;
- case ctrlChar( 'E' ): // ctrl-E, move cursor to end of line
- case END_KEY:
- killRing.lastAction = KillRing::actionOther;
- pos = len;
- refreshLine( pi );
- break;
+ case META + 'd': // meta-D, kill word to right of cursor
+ case META + 'D':
+ if (pos < len) {
+ historyRecallMostRecent = false;
+ int endingPos = pos;
+ while (endingPos < len && !isCharacterAlphanumeric(buf32[endingPos])) {
+ ++endingPos;
+ }
+ while (endingPos < len && isCharacterAlphanumeric(buf32[endingPos])) {
+ ++endingPos;
+ }
+ killRing.kill(&buf32[pos], endingPos - pos, true);
+ memmove(
+ buf32 + pos, buf32 + endingPos, sizeof(UChar32) * (len - endingPos + 1));
+ len -= endingPos - pos;
+ refreshLine(pi);
+ }
+ killRing.lastAction = KillRing::actionKill;
+ break;
- case ctrlChar( 'F' ): // ctrl-F, move cursor right by one character
- case RIGHT_ARROW_KEY:
- killRing.lastAction = KillRing::actionOther;
- if ( pos < len ) {
- ++pos;
- refreshLine( pi );
- }
- break;
+ case ctrlChar('E'): // ctrl-E, move cursor to end of line
+ case END_KEY:
+ killRing.lastAction = KillRing::actionOther;
+ pos = len;
+ refreshLine(pi);
+ break;
- case META + 'f': // meta-F, move cursor right by one word
- case META + 'F':
- case CTRL + RIGHT_ARROW_KEY:
- case META + RIGHT_ARROW_KEY: // Emacs allows Meta, bash & readline don't
- killRing.lastAction = KillRing::actionOther;
- if ( pos < len ) {
- while ( pos < len && !isCharacterAlphanumeric( buf32[pos] ) ) {
+ case ctrlChar('F'): // ctrl-F, move cursor right by one character
+ case RIGHT_ARROW_KEY:
+ killRing.lastAction = KillRing::actionOther;
+ if (pos < len) {
++pos;
+ refreshLine(pi);
}
- while ( pos < len && isCharacterAlphanumeric( buf32[pos] ) ) {
- ++pos;
- }
- refreshLine( pi );
- }
- break;
+ break;
- case ctrlChar( 'H' ): // backspace/ctrl-H, delete char to left of cursor
- killRing.lastAction = KillRing::actionOther;
- if ( pos > 0 ) {
- historyRecallMostRecent = false;
- memmove( buf32 + pos - 1, buf32 + pos, sizeof( UChar32 ) * ( 1 + len - pos ) );
- --pos;
- --len;
- refreshLine( pi );
- }
- break;
+ case META + 'f': // meta-F, move cursor right by one word
+ case META + 'F':
+ case CTRL + RIGHT_ARROW_KEY:
+ case META + RIGHT_ARROW_KEY: // Emacs allows Meta, bash & readline don't
+ killRing.lastAction = KillRing::actionOther;
+ if (pos < len) {
+ while (pos < len && !isCharacterAlphanumeric(buf32[pos])) {
+ ++pos;
+ }
+ while (pos < len && isCharacterAlphanumeric(buf32[pos])) {
+ ++pos;
+ }
+ refreshLine(pi);
+ }
+ break;
- // meta-Backspace, kill word to left of cursor
- case META + ctrlChar( 'H' ):
- if ( pos > 0 ) {
- historyRecallMostRecent = false;
- int startingPos = pos;
- while ( pos > 0 && !isCharacterAlphanumeric( buf32[pos - 1] ) ) {
+ case ctrlChar('H'): // backspace/ctrl-H, delete char to left of cursor
+ killRing.lastAction = KillRing::actionOther;
+ if (pos > 0) {
+ historyRecallMostRecent = false;
+ memmove(buf32 + pos - 1, buf32 + pos, sizeof(UChar32) * (1 + len - pos));
--pos;
+ --len;
+ refreshLine(pi);
}
- while ( pos > 0 && isCharacterAlphanumeric( buf32[pos - 1] ) ) {
- --pos;
+ break;
+
+ // meta-Backspace, kill word to left of cursor
+ case META + ctrlChar('H'):
+ if (pos > 0) {
+ historyRecallMostRecent = false;
+ int startingPos = pos;
+ while (pos > 0 && !isCharacterAlphanumeric(buf32[pos - 1])) {
+ --pos;
+ }
+ while (pos > 0 && isCharacterAlphanumeric(buf32[pos - 1])) {
+ --pos;
+ }
+ killRing.kill(&buf32[pos], startingPos - pos, false);
+ memmove(buf32 + pos,
+ buf32 + startingPos,
+ sizeof(UChar32) * (len - startingPos + 1));
+ len -= startingPos - pos;
+ refreshLine(pi);
}
- killRing.kill( &buf32[pos], startingPos - pos, false );
- memmove( buf32 + pos, buf32 + startingPos, sizeof( UChar32 ) * ( len - startingPos + 1 ) );
- len -= startingPos - pos;
- refreshLine( pi );
- }
- killRing.lastAction = KillRing::actionKill;
- break;
+ killRing.lastAction = KillRing::actionKill;
+ break;
- case ctrlChar( 'J' ): // ctrl-J/linefeed/newline, accept line
- case ctrlChar( 'M' ): // ctrl-M/return/enter
- killRing.lastAction = KillRing::actionOther;
- // we need one last refresh with the cursor at the end of the line
- // so we don't display the next prompt over the previous input line
- pos = len; // pass len as pos for EOL
- refreshLine( pi );
- historyPreviousIndex = historyRecallMostRecent ? historyIndex : -2;
- --historyLen;
- free( history[historyLen] );
- return len;
+ case ctrlChar('J'): // ctrl-J/linefeed/newline, accept line
+ case ctrlChar('M'): // ctrl-M/return/enter
+ killRing.lastAction = KillRing::actionOther;
+ // we need one last refresh with the cursor at the end of the line
+ // so we don't display the next prompt over the previous input line
+ pos = len; // pass len as pos for EOL
+ refreshLine(pi);
+ historyPreviousIndex = historyRecallMostRecent ? historyIndex : -2;
+ --historyLen;
+ free(history[historyLen]);
+ return len;
- case ctrlChar( 'K' ): // ctrl-K, kill from cursor to end of line
- killRing.kill( &buf32[pos], len - pos, true );
- buf32[pos] = '\0';
- len = pos;
- refreshLine( pi );
- killRing.lastAction = KillRing::actionKill;
- historyRecallMostRecent = false;
- break;
+ case ctrlChar('K'): // ctrl-K, kill from cursor to end of line
+ killRing.kill(&buf32[pos], len - pos, true);
+ buf32[pos] = '\0';
+ len = pos;
+ refreshLine(pi);
+ killRing.lastAction = KillRing::actionKill;
+ historyRecallMostRecent = false;
+ break;
- case ctrlChar( 'L' ): // ctrl-L, clear screen and redisplay line
- clearScreen( pi );
- break;
+ case ctrlChar('L'): // ctrl-L, clear screen and redisplay line
+ clearScreen(pi);
+ break;
- case META + 'l': // meta-L, lowercase word
- case META + 'L':
- killRing.lastAction = KillRing::actionOther;
- if ( pos < len ) {
- historyRecallMostRecent = false;
- while ( pos < len && !isCharacterAlphanumeric( buf32[pos] ) ) {
- ++pos;
- }
- while ( pos < len && isCharacterAlphanumeric( buf32[pos] ) ) {
- if ( buf32[pos] >= 'A' && buf32[pos] <= 'Z' ) {
- buf32[pos] += 'a' - 'A';
+ case META + 'l': // meta-L, lowercase word
+ case META + 'L':
+ killRing.lastAction = KillRing::actionOther;
+ if (pos < len) {
+ historyRecallMostRecent = false;
+ while (pos < len && !isCharacterAlphanumeric(buf32[pos])) {
+ ++pos;
}
- ++pos;
+ while (pos < len && isCharacterAlphanumeric(buf32[pos])) {
+ if (buf32[pos] >= 'A' && buf32[pos] <= 'Z') {
+ buf32[pos] += 'a' - 'A';
+ }
+ ++pos;
+ }
+ refreshLine(pi);
}
- refreshLine( pi );
- }
- break;
+ break;
- case ctrlChar( 'N' ): // ctrl-N, recall next line in history
- case ctrlChar( 'P' ): // ctrl-P, recall previous line in history
- case DOWN_ARROW_KEY:
- case UP_ARROW_KEY:
- killRing.lastAction = KillRing::actionOther;
- // if not already recalling, add the current line to the history list so we don't have to special case it
- if ( historyIndex == historyLen - 1 ) {
- free( history[historyLen - 1] );
- size_t tempBufferSize = sizeof( UChar32 ) * len + 1;
- unique_ptr< UChar8 []> tempBuffer( new UChar8[ tempBufferSize ] );
- copyString32to8( tempBuffer.get(), buf32, tempBufferSize );
- history[historyLen - 1] = reinterpret_cast< UChar8 * >( strdup( reinterpret_cast< const char * >( tempBuffer.get() ) ) );
- }
- if ( historyLen > 1 ) {
- if ( c == UP_ARROW_KEY ) {
- c = ctrlChar( 'P' );
- }
- if ( historyPreviousIndex != -2 && c != ctrlChar( 'P' ) ) {
- historyIndex = 1 + historyPreviousIndex; // emulate Windows down-arrow
- }
- else {
- historyIndex += ( c == ctrlChar( 'P' ) ) ? -1 : 1;
- }
- historyPreviousIndex = -2;
- if ( historyIndex < 0 ) {
- historyIndex = 0;
- break;
+ case ctrlChar('N'): // ctrl-N, recall next line in history
+ case ctrlChar('P'): // ctrl-P, recall previous line in history
+ case DOWN_ARROW_KEY:
+ case UP_ARROW_KEY:
+ killRing.lastAction = KillRing::actionOther;
+ // if not already recalling, add the current line to the history list so we don't have to special case it
+ if (historyIndex == historyLen - 1) {
+ free(history[historyLen - 1]);
+ size_t tempBufferSize = sizeof(UChar32) * len + 1;
+ unique_ptr<UChar8[]> tempBuffer(new UChar8[tempBufferSize]);
+ copyString32to8(tempBuffer.get(), buf32, tempBufferSize);
+ history[historyLen - 1] = reinterpret_cast<UChar8*>(
+ strdup(reinterpret_cast<const char*>(tempBuffer.get())));
}
- else if ( historyIndex >= historyLen ) {
- historyIndex = historyLen - 1;
- break;
+ if (historyLen > 1) {
+ if (c == UP_ARROW_KEY) {
+ c = ctrlChar('P');
+ }
+ if (historyPreviousIndex != -2 && c != ctrlChar('P')) {
+ historyIndex = 1 + historyPreviousIndex; // emulate Windows down-arrow
+ } else {
+ historyIndex += (c == ctrlChar('P')) ? -1 : 1;
+ }
+ historyPreviousIndex = -2;
+ if (historyIndex < 0) {
+ historyIndex = 0;
+ break;
+ } else if (historyIndex >= historyLen) {
+ historyIndex = historyLen - 1;
+ break;
+ }
+ historyRecallMostRecent = true;
+ size_t ucharCount;
+ int errorCode;
+ copyString8to32(buf32, history[historyIndex], buflen, ucharCount, errorCode);
+ len = pos = ucharCount;
+ refreshLine(pi);
}
- historyRecallMostRecent = true;
- size_t ucharCount;
- int errorCode;
- copyString8to32( buf32, history[historyIndex], buflen, ucharCount, errorCode );
- len = pos = ucharCount;
- refreshLine( pi );
- }
- break;
-
- case ctrlChar( 'R' ): // ctrl-R, reverse history search
- case ctrlChar( 'S' ): // ctrl-S, forward history search
- terminatingKeystroke = incrementalHistorySearch( pi, c );
- break;
-
- case ctrlChar( 'T' ): // ctrl-T, transpose characters
- killRing.lastAction = KillRing::actionOther;
- if ( pos > 0 && len > 1 ) {
- historyRecallMostRecent = false;
- size_t leftCharPos = ( pos == len ) ? pos - 2 : pos - 1;
- char aux = buf32[leftCharPos];
- buf32[leftCharPos] = buf32[leftCharPos+1];
- buf32[leftCharPos+1] = aux;
- if ( pos != len )
- ++pos;
- refreshLine( pi );
- }
- break;
+ break;
- case ctrlChar( 'U' ): // ctrl-U, kill all characters to the left of the cursor
- if ( pos > 0 ) {
- historyRecallMostRecent = false;
- killRing.kill( &buf32[0], pos, false );
- len -= pos;
- memmove( buf32, buf32 + pos, sizeof( UChar32 ) * ( len + 1 ) );
- pos = 0;
- refreshLine( pi );
- }
- killRing.lastAction = KillRing::actionKill;
- break;
+ case ctrlChar('R'): // ctrl-R, reverse history search
+ case ctrlChar('S'): // ctrl-S, forward history search
+ terminatingKeystroke = incrementalHistorySearch(pi, c);
+ break;
- case META + 'u': // meta-U, uppercase word
- case META + 'U':
- killRing.lastAction = KillRing::actionOther;
- if ( pos < len ) {
- historyRecallMostRecent = false;
- while ( pos < len && !isCharacterAlphanumeric( buf32[pos] ) ) {
- ++pos;
- }
- while ( pos < len && isCharacterAlphanumeric( buf32[pos] ) ) {
- if ( buf32[pos] >= 'a' && buf32[pos] <= 'z' ) {
- buf32[pos] += 'A' - 'a';
- }
- ++pos;
+ case ctrlChar('T'): // ctrl-T, transpose characters
+ killRing.lastAction = KillRing::actionOther;
+ if (pos > 0 && len > 1) {
+ historyRecallMostRecent = false;
+ size_t leftCharPos = (pos == len) ? pos - 2 : pos - 1;
+ char aux = buf32[leftCharPos];
+ buf32[leftCharPos] = buf32[leftCharPos + 1];
+ buf32[leftCharPos + 1] = aux;
+ if (pos != len)
+ ++pos;
+ refreshLine(pi);
}
- refreshLine( pi );
- }
- break;
+ break;
- // ctrl-W, kill to whitespace (not word) to left of cursor
- case ctrlChar( 'W' ):
- if ( pos > 0 ) {
- historyRecallMostRecent = false;
- int startingPos = pos;
- while ( pos > 0 && buf32[pos - 1] == ' ' ) {
- --pos;
- }
- while ( pos > 0 && buf32[pos - 1] != ' ' ) {
- --pos;
+ case ctrlChar('U'): // ctrl-U, kill all characters to the left of the cursor
+ if (pos > 0) {
+ historyRecallMostRecent = false;
+ killRing.kill(&buf32[0], pos, false);
+ len -= pos;
+ memmove(buf32, buf32 + pos, sizeof(UChar32) * (len + 1));
+ pos = 0;
+ refreshLine(pi);
}
- killRing.kill( &buf32[pos], startingPos - pos, false );
- memmove( buf32 + pos, buf32 + startingPos, sizeof( UChar32 ) * ( len - startingPos + 1 ) );
- len -= startingPos - pos;
- refreshLine( pi );
- }
- killRing.lastAction = KillRing::actionKill;
- break;
+ killRing.lastAction = KillRing::actionKill;
+ break;
- case ctrlChar( 'Y' ): // ctrl-Y, yank killed text
- historyRecallMostRecent = false;
- {
- Utf32String* restoredText = killRing.yank();
- if ( restoredText ) {
- bool truncated = false;
- size_t ucharCount = restoredText->length();
- if (ucharCount > static_cast<size_t>(buflen - len)) {
- ucharCount = buflen - len;
- truncated = true;
+ case META + 'u': // meta-U, uppercase word
+ case META + 'U':
+ killRing.lastAction = KillRing::actionOther;
+ if (pos < len) {
+ historyRecallMostRecent = false;
+ while (pos < len && !isCharacterAlphanumeric(buf32[pos])) {
+ ++pos;
}
- memmove( buf32 + pos + ucharCount, buf32 + pos, sizeof( UChar32 ) * ( len - pos + 1 ) );
- memmove( buf32 + pos, restoredText->get(), sizeof( UChar32 ) * ucharCount );
- pos += ucharCount;
- len += ucharCount;
- refreshLine( pi );
- killRing.lastAction = KillRing::actionYank;
- killRing.lastYankSize = ucharCount;
- if (truncated) {
- beep();
+ while (pos < len && isCharacterAlphanumeric(buf32[pos])) {
+ if (buf32[pos] >= 'a' && buf32[pos] <= 'z') {
+ buf32[pos] += 'A' - 'a';
+ }
+ ++pos;
}
+ refreshLine(pi);
}
- else {
- beep();
- }
- }
- break;
+ break;
- case META + 'y': // meta-Y, "yank-pop", rotate popped text
- case META + 'Y':
- if ( killRing.lastAction == KillRing::actionYank ) {
- historyRecallMostRecent = false;
- Utf32String* restoredText = killRing.yankPop();
- if ( restoredText ) {
- bool truncated = false;
- size_t ucharCount = restoredText->length();
- if (ucharCount > static_cast<size_t>(killRing.lastYankSize + buflen - len)) {
- ucharCount = killRing.lastYankSize + buflen - len;
- truncated = true;
- }
- if ( ucharCount > killRing.lastYankSize ) {
- memmove( buf32 + pos + ucharCount - killRing.lastYankSize, buf32 + pos, sizeof( UChar32 ) * ( len - pos + 1 ) );
- memmove( buf32 + pos - killRing.lastYankSize, restoredText->get(), sizeof( UChar32 ) * ucharCount );
+ // ctrl-W, kill to whitespace (not word) to left of cursor
+ case ctrlChar('W'):
+ if (pos > 0) {
+ historyRecallMostRecent = false;
+ int startingPos = pos;
+ while (pos > 0 && buf32[pos - 1] == ' ') {
+ --pos;
}
- else {
- memmove( buf32 + pos - killRing.lastYankSize, restoredText->get(), sizeof( UChar32 ) * ucharCount );
- memmove( buf32 + pos + ucharCount - killRing.lastYankSize, buf32 + pos, sizeof( UChar32 ) * ( len - pos + 1 ) );
+ while (pos > 0 && buf32[pos - 1] != ' ') {
+ --pos;
}
- pos += ucharCount - killRing.lastYankSize;
- len += ucharCount - killRing.lastYankSize;
- killRing.lastYankSize = ucharCount;
- refreshLine( pi );
- if (truncated) {
+ killRing.kill(&buf32[pos], startingPos - pos, false);
+ memmove(buf32 + pos,
+ buf32 + startingPos,
+ sizeof(UChar32) * (len - startingPos + 1));
+ len -= startingPos - pos;
+ refreshLine(pi);
+ }
+ killRing.lastAction = KillRing::actionKill;
+ break;
+
+ case ctrlChar('Y'): // ctrl-Y, yank killed text
+ historyRecallMostRecent = false;
+ {
+ Utf32String* restoredText = killRing.yank();
+ if (restoredText) {
+ bool truncated = false;
+ size_t ucharCount = restoredText->length();
+ if (ucharCount > static_cast<size_t>(buflen - len)) {
+ ucharCount = buflen - len;
+ truncated = true;
+ }
+ memmove(buf32 + pos + ucharCount,
+ buf32 + pos,
+ sizeof(UChar32) * (len - pos + 1));
+ memmove(buf32 + pos, restoredText->get(), sizeof(UChar32) * ucharCount);
+ pos += ucharCount;
+ len += ucharCount;
+ refreshLine(pi);
+ killRing.lastAction = KillRing::actionYank;
+ killRing.lastYankSize = ucharCount;
+ if (truncated) {
+ beep();
+ }
+ } else {
beep();
}
- break;
}
- }
- beep();
- break;
+ break;
+
+ case META + 'y': // meta-Y, "yank-pop", rotate popped text
+ case META + 'Y':
+ if (killRing.lastAction == KillRing::actionYank) {
+ historyRecallMostRecent = false;
+ Utf32String* restoredText = killRing.yankPop();
+ if (restoredText) {
+ bool truncated = false;
+ size_t ucharCount = restoredText->length();
+ if (ucharCount >
+ static_cast<size_t>(killRing.lastYankSize + buflen - len)) {
+ ucharCount = killRing.lastYankSize + buflen - len;
+ truncated = true;
+ }
+ if (ucharCount > killRing.lastYankSize) {
+ memmove(buf32 + pos + ucharCount - killRing.lastYankSize,
+ buf32 + pos,
+ sizeof(UChar32) * (len - pos + 1));
+ memmove(buf32 + pos - killRing.lastYankSize,
+ restoredText->get(),
+ sizeof(UChar32) * ucharCount);
+ } else {
+ memmove(buf32 + pos - killRing.lastYankSize,
+ restoredText->get(),
+ sizeof(UChar32) * ucharCount);
+ memmove(buf32 + pos + ucharCount - killRing.lastYankSize,
+ buf32 + pos,
+ sizeof(UChar32) * (len - pos + 1));
+ }
+ pos += ucharCount - killRing.lastYankSize;
+ len += ucharCount - killRing.lastYankSize;
+ killRing.lastYankSize = ucharCount;
+ refreshLine(pi);
+ if (truncated) {
+ beep();
+ }
+ break;
+ }
+ }
+ beep();
+ break;
#ifndef _WIN32
- case ctrlChar( 'Z' ): // ctrl-Z, job control
- disableRawMode(); // Returning to Linux (whatever) shell, leave raw mode
- raise( SIGSTOP ); // Break out in mid-line
- enableRawMode(); // Back from Linux shell, re-enter raw mode
- if ( write32( 1, pi.promptText.get(), pi.promptChars ) == -1 ) break; // Redraw prompt
- refreshLine( pi ); // Refresh the line
- break;
+ case ctrlChar('Z'): // ctrl-Z, job control
+ disableRawMode(); // Returning to Linux (whatever) shell, leave raw mode
+ raise(SIGSTOP); // Break out in mid-line
+ enableRawMode(); // Back from Linux shell, re-enter raw mode
+ if (write32(1, pi.promptText.get(), pi.promptChars) == -1)
+ break; // Redraw prompt
+ refreshLine(pi); // Refresh the line
+ break;
#endif
- // DEL, delete the character under the cursor
- case 127:
- case DELETE_KEY:
- killRing.lastAction = KillRing::actionOther;
- if ( len > 0 && pos < len ) {
- historyRecallMostRecent = false;
- memmove( buf32 + pos, buf32 + pos + 1, sizeof( UChar32 ) * ( len - pos ) );
- --len;
- refreshLine( pi );
- }
- break;
-
- case META + '<': // meta-<, beginning of history
- case PAGE_UP_KEY: // Page Up, beginning of history
- case META + '>': // meta->, end of history
- case PAGE_DOWN_KEY: // Page Down, end of history
- killRing.lastAction = KillRing::actionOther;
- // if not already recalling, add the current line to the history list so we don't have to special case it
- if ( historyIndex == historyLen - 1 ) {
- free( history[historyLen - 1] );
- size_t tempBufferSize = sizeof( UChar32 ) * len + 1;
- unique_ptr< UChar8 []> tempBuffer( new UChar8[ tempBufferSize ] );
- copyString32to8( tempBuffer.get(), buf32, tempBufferSize );
- history[historyLen - 1] = reinterpret_cast< UChar8 * >( strdup( reinterpret_cast< const char * >( tempBuffer.get() ) ) );
- }
- if ( historyLen > 1 ) {
- historyIndex = ( c == META + '<' || c == PAGE_UP_KEY ) ? 0 : historyLen - 1;
- historyPreviousIndex = -2;
- historyRecallMostRecent = true;
- size_t ucharCount;
- int errorCode;
- copyString8to32( buf32, history[historyIndex], buflen, ucharCount, errorCode );
- len = pos = ucharCount;
- refreshLine( pi );
- }
- break;
+ // DEL, delete the character under the cursor
+ case 127:
+ case DELETE_KEY:
+ killRing.lastAction = KillRing::actionOther;
+ if (len > 0 && pos < len) {
+ historyRecallMostRecent = false;
+ memmove(buf32 + pos, buf32 + pos + 1, sizeof(UChar32) * (len - pos));
+ --len;
+ refreshLine(pi);
+ }
+ break;
- // not one of our special characters, maybe insert it in the buffer
- default:
- killRing.lastAction = KillRing::actionOther;
- historyRecallMostRecent = false;
- if ( c & ( META | CTRL ) ) { // beep on unknown Ctrl and/or Meta keys
- beep();
+ case META + '<': // meta-<, beginning of history
+ case PAGE_UP_KEY: // Page Up, beginning of history
+ case META + '>': // meta->, end of history
+ case PAGE_DOWN_KEY: // Page Down, end of history
+ killRing.lastAction = KillRing::actionOther;
+ // if not already recalling, add the current line to the history list so we don't have to special case it
+ if (historyIndex == historyLen - 1) {
+ free(history[historyLen - 1]);
+ size_t tempBufferSize = sizeof(UChar32) * len + 1;
+ unique_ptr<UChar8[]> tempBuffer(new UChar8[tempBufferSize]);
+ copyString32to8(tempBuffer.get(), buf32, tempBufferSize);
+ history[historyLen - 1] = reinterpret_cast<UChar8*>(
+ strdup(reinterpret_cast<const char*>(tempBuffer.get())));
+ }
+ if (historyLen > 1) {
+ historyIndex = (c == META + '<' || c == PAGE_UP_KEY) ? 0 : historyLen - 1;
+ historyPreviousIndex = -2;
+ historyRecallMostRecent = true;
+ size_t ucharCount;
+ int errorCode;
+ copyString8to32(buf32, history[historyIndex], buflen, ucharCount, errorCode);
+ len = pos = ucharCount;
+ refreshLine(pi);
+ }
break;
- }
- if ( len < buflen ) {
- if ( isControlChar( c ) ) { // don't insert control characters
+
+ // not one of our special characters, maybe insert it in the buffer
+ default:
+ killRing.lastAction = KillRing::actionOther;
+ historyRecallMostRecent = false;
+ if (c & (META | CTRL)) { // beep on unknown Ctrl and/or Meta keys
beep();
break;
}
- if ( len == pos ) { // at end of buffer
- buf32[pos] = c;
- ++pos;
- ++len;
- buf32[len] = '\0';
- int inputLen = calculateColumnPosition( buf32, len );
- if ( pi.promptIndentation + inputLen < pi.promptScreenColumns ) {
- if ( inputLen > pi.promptPreviousInputLen )
- pi.promptPreviousInputLen = inputLen;
- /* Avoid a full update of the line in the
- * trivial case. */
- if ( write32( 1, reinterpret_cast<UChar32 *>( &c ), 1) == -1 ) return -1;
+ if (len < buflen) {
+ if (isControlChar(c)) { // don't insert control characters
+ beep();
+ break;
}
- else {
- refreshLine( pi );
+ if (len == pos) { // at end of buffer
+ buf32[pos] = c;
+ ++pos;
+ ++len;
+ buf32[len] = '\0';
+ int inputLen = calculateColumnPosition(buf32, len);
+ if (pi.promptIndentation + inputLen < pi.promptScreenColumns) {
+ if (inputLen > pi.promptPreviousInputLen)
+ pi.promptPreviousInputLen = inputLen;
+ /* Avoid a full update of the line in the
+ * trivial case. */
+ if (write32(1, reinterpret_cast<UChar32*>(&c), 1) == -1)
+ return -1;
+ } else {
+ refreshLine(pi);
+ }
+ } else { // not at end of buffer, have to move characters to our right
+ memmove(buf32 + pos + 1, buf32 + pos, sizeof(UChar32) * (len - pos));
+ buf32[pos] = c;
+ ++len;
+ ++pos;
+ buf32[len] = '\0';
+ refreshLine(pi);
}
+ } else {
+ beep(); // buffer is full, beep on new characters
}
- else { // not at end of buffer, have to move characters to our right
- memmove( buf32 + pos + 1, buf32 + pos, sizeof( UChar32 ) * ( len - pos ) );
- buf32[pos] = c;
- ++len;
- ++pos;
- buf32[len] = '\0';
- refreshLine( pi );
- }
- }
- else {
- beep(); // buffer is full, beep on new characters
- }
- break;
+ break;
}
}
return len;
}
-string preloadedBufferContents; // used with linenoisePreloadBuffer
+string preloadedBufferContents; // used with linenoisePreloadBuffer
string preloadErrorMessage;
/**
@@ -2459,35 +2553,34 @@ string preloadErrorMessage;
*
* @param preloadText text to begin with on the next call to linenoise()
*/
-void linenoisePreloadBuffer( const char* preloadText ) {
-
- if ( ! preloadText ) {
+void linenoisePreloadBuffer(const char* preloadText) {
+ if (!preloadText) {
return;
}
- int bufferSize = strlen( preloadText ) + 1;
- unique_ptr< char []> tempBuffer( new char[ bufferSize ] );
- strncpy( &tempBuffer[0], preloadText, bufferSize );
+ int bufferSize = strlen(preloadText) + 1;
+ unique_ptr<char[]> tempBuffer(new char[bufferSize]);
+ strncpy(&tempBuffer[0], preloadText, bufferSize);
// remove characters that won't display correctly
char* pIn = &tempBuffer[0];
char* pOut = pIn;
bool controlsStripped = false;
bool whitespaceSeen = false;
- while ( *pIn ) {
- unsigned char c = *pIn++; // we need unsigned so chars 0x80 and above are allowed
- if ( '\r' == c ) { // silently skip CR
+ while (*pIn) {
+ unsigned char c = *pIn++; // we need unsigned so chars 0x80 and above are allowed
+ if ('\r' == c) { // silently skip CR
continue;
}
- if ( '\n' == c || '\t' == c ) { // note newline or tab
+ if ('\n' == c || '\t' == c) { // note newline or tab
whitespaceSeen = true;
continue;
}
- if ( isControlChar( c ) ) { // remove other control characters, flag for message
+ if (isControlChar(c)) { // remove other control characters, flag for message
controlsStripped = true;
*pOut++ = ' ';
continue;
}
- if ( whitespaceSeen ) { // convert whitespace to a single space
+ if (whitespaceSeen) { // convert whitespace to a single space
*pOut++ = ' ';
whitespaceSeen = false;
}
@@ -2496,18 +2589,18 @@ void linenoisePreloadBuffer( const char* preloadText ) {
*pOut = 0;
int processedLength = pOut - tempBuffer.get();
bool lineTruncated = false;
- if ( processedLength > ( LINENOISE_MAX_LINE - 1 ) ) {
+ if (processedLength > (LINENOISE_MAX_LINE - 1)) {
lineTruncated = true;
- tempBuffer[ LINENOISE_MAX_LINE - 1 ] = 0;
+ tempBuffer[LINENOISE_MAX_LINE - 1] = 0;
}
preloadedBufferContents = tempBuffer.get();
- if ( controlsStripped ) {
+ if (controlsStripped) {
preloadErrorMessage += " [Edited line: control characters were converted to spaces]\n";
}
- if ( lineTruncated ) {
+ if (lineTruncated) {
preloadErrorMessage += " [Edited line: the line length was reduced from ";
char buf[128];
- snprintf( buf, sizeof( buf ), "%d to %d]\n", processedLength, ( LINENOISE_MAX_LINE - 1 ) );
+ snprintf(buf, sizeof(buf), "%d to %d]\n", processedLength, (LINENOISE_MAX_LINE - 1));
preloadErrorMessage += buf;
}
}
@@ -2520,111 +2613,109 @@ void linenoisePreloadBuffer( const char* preloadText ) {
* @param prompt text of prompt to display to the user
* @return the returned string belongs to the caller on return and must be freed to prevent memory leaks
*/
-char* linenoise( const char* prompt ) {
- if ( isatty( STDIN_FILENO ) ) { // input is from a terminal
- UChar32 buf32[ LINENOISE_MAX_LINE ];
- char charWidths[ LINENOISE_MAX_LINE ];
- if ( ! preloadErrorMessage.empty() ) {
- printf( "%s", preloadErrorMessage.c_str() );
- fflush( stdout );
+char* linenoise(const char* prompt) {
+ if (isatty(STDIN_FILENO)) { // input is from a terminal
+ UChar32 buf32[LINENOISE_MAX_LINE];
+ char charWidths[LINENOISE_MAX_LINE];
+ if (!preloadErrorMessage.empty()) {
+ printf("%s", preloadErrorMessage.c_str());
+ fflush(stdout);
preloadErrorMessage.clear();
}
- PromptInfo pi( reinterpret_cast< const UChar8* >( prompt ), getScreenColumns() );
- if ( isUnsupportedTerm() ) {
- if ( write32( 1, pi.promptText.get(), pi.promptChars ) == -1 ) return 0;
- fflush( stdout );
- if ( preloadedBufferContents.empty() ) {
- unique_ptr<char[]> buf8( new char[ LINENOISE_MAX_LINE ] );
- if ( fgets( buf8.get(), LINENOISE_MAX_LINE, stdin ) == NULL ) {
+ PromptInfo pi(reinterpret_cast<const UChar8*>(prompt), getScreenColumns());
+ if (isUnsupportedTerm()) {
+ if (write32(1, pi.promptText.get(), pi.promptChars) == -1)
+ return 0;
+ fflush(stdout);
+ if (preloadedBufferContents.empty()) {
+ unique_ptr<char[]> buf8(new char[LINENOISE_MAX_LINE]);
+ if (fgets(buf8.get(), LINENOISE_MAX_LINE, stdin) == NULL) {
return NULL;
}
- size_t len = strlen( buf8.get() );
- while ( len && ( buf8[len - 1] == '\n' || buf8[len - 1] == '\r' ) ) {
+ size_t len = strlen(buf8.get());
+ while (len && (buf8[len - 1] == '\n' || buf8[len - 1] == '\r')) {
--len;
buf8[len] = '\0';
}
- return strdup( buf8.get() ); // caller must free buffer
- }
- else {
- char* buf8 = strdup( preloadedBufferContents.c_str() );
+ return strdup(buf8.get()); // caller must free buffer
+ } else {
+ char* buf8 = strdup(preloadedBufferContents.c_str());
preloadedBufferContents.clear();
- return buf8; // caller must free buffer
+ return buf8; // caller must free buffer
}
- }
- else {
- if ( enableRawMode() == -1 ) {
+ } else {
+ if (enableRawMode() == -1) {
return NULL;
}
- InputBuffer ib( buf32, charWidths, LINENOISE_MAX_LINE );
- if ( ! preloadedBufferContents.empty() ) {
- ib.preloadBuffer( reinterpret_cast< const UChar8 * >( preloadedBufferContents.c_str() ) );
+ InputBuffer ib(buf32, charWidths, LINENOISE_MAX_LINE);
+ if (!preloadedBufferContents.empty()) {
+ ib.preloadBuffer(reinterpret_cast<const UChar8*>(preloadedBufferContents.c_str()));
preloadedBufferContents.clear();
}
- int count = ib.getInputLine( pi );
+ int count = ib.getInputLine(pi);
disableRawMode();
- printf( "\n" );
- if ( count == -1 ) {
+ printf("\n");
+ if (count == -1) {
return NULL;
}
- size_t bufferSize = sizeof( UChar32 ) * ib.length() + 1;
- unique_ptr<UChar8[]> buf8( new UChar8[ bufferSize ] );
- copyString32to8( buf8.get(), buf32, bufferSize );
- return strdup( reinterpret_cast<char*>( buf8.get() ) ); // caller must free buffer
+ size_t bufferSize = sizeof(UChar32) * ib.length() + 1;
+ unique_ptr<UChar8[]> buf8(new UChar8[bufferSize]);
+ copyString32to8(buf8.get(), buf32, bufferSize);
+ return strdup(reinterpret_cast<char*>(buf8.get())); // caller must free buffer
}
- }
- else { // input not from a terminal, we should work with piped input, i.e. redirected stdin
- unique_ptr<char[]> buf8( new char[ LINENOISE_MAX_LINE ] );
- if ( fgets( buf8.get(), LINENOISE_MAX_LINE, stdin ) == NULL ) {
+ } else { // input not from a terminal, we should work with piped input, i.e. redirected stdin
+ unique_ptr<char[]> buf8(new char[LINENOISE_MAX_LINE]);
+ if (fgets(buf8.get(), LINENOISE_MAX_LINE, stdin) == NULL) {
return NULL;
}
// if fgets() gave us the newline, remove it
- int count = strlen( buf8.get() );
- if ( count > 0 && buf8[ count - 1 ] == '\n' ) {
+ int count = strlen(buf8.get());
+ if (count > 0 && buf8[count - 1] == '\n') {
--count;
- buf8[ count ] = '\0';
+ buf8[count] = '\0';
}
- return strdup( buf8.get() ); // caller must free buffer
+ return strdup(buf8.get()); // caller must free buffer
}
}
/* Register a callback function to be called for tab-completion. */
-void linenoiseSetCompletionCallback( linenoiseCompletionCallback* fn ) {
+void linenoiseSetCompletionCallback(linenoiseCompletionCallback* fn) {
completionCallback = fn;
}
-void linenoiseAddCompletion( linenoiseCompletions* lc, const char* str ) {
- lc->completionStrings.push_back( Utf32String( reinterpret_cast<const UChar8*>( str ) ) );
+void linenoiseAddCompletion(linenoiseCompletions* lc, const char* str) {
+ lc->completionStrings.push_back(Utf32String(reinterpret_cast<const UChar8*>(str)));
}
-int linenoiseHistoryAdd( const char* line ) {
- if ( historyMaxLen == 0 ) {
+int linenoiseHistoryAdd(const char* line) {
+ if (historyMaxLen == 0) {
return 0;
}
- if ( history == NULL ) {
- history = reinterpret_cast< UChar8** >( malloc( sizeof( UChar8* ) * historyMaxLen ) );
+ if (history == NULL) {
+ history = reinterpret_cast<UChar8**>(malloc(sizeof(UChar8*) * historyMaxLen));
if (history == NULL) {
return 0;
}
- memset( history, 0, ( sizeof( char* ) * historyMaxLen ) );
+ memset(history, 0, (sizeof(char*) * historyMaxLen));
}
- UChar8* linecopy = reinterpret_cast< UChar8* >( strdup( line ) );
- if ( ! linecopy ) {
+ UChar8* linecopy = reinterpret_cast<UChar8*>(strdup(line));
+ if (!linecopy) {
return 0;
}
- if ( historyLen == historyMaxLen ) {
- free( history[0] );
- memmove( history, history + 1, sizeof( char* ) * ( historyMaxLen - 1 ) );
+ if (historyLen == historyMaxLen) {
+ free(history[0]);
+ memmove(history, history + 1, sizeof(char*) * (historyMaxLen - 1));
--historyLen;
- if ( --historyPreviousIndex < -1 ) {
+ if (--historyPreviousIndex < -1) {
historyPreviousIndex = -2;
}
}
// convert newlines in multi-line code to spaces before storing
UChar8* p = linecopy;
- while ( *p ) {
- if ( *p == '\n' ) {
+ while (*p) {
+ if (*p == '\n') {
*p = ' ';
}
++p;
@@ -2634,25 +2725,25 @@ int linenoiseHistoryAdd( const char* line ) {
return 1;
}
-int linenoiseHistorySetMaxLen( int len ) {
- if ( len < 1 ) {
+int linenoiseHistorySetMaxLen(int len) {
+ if (len < 1) {
return 0;
}
- if ( history ) {
+ if (history) {
int tocopy = historyLen;
- UChar8** newHistory = reinterpret_cast< UChar8** >( malloc( sizeof( UChar8* ) * len ) );
- if ( newHistory == NULL ) {
+ UChar8** newHistory = reinterpret_cast<UChar8**>(malloc(sizeof(UChar8*) * len));
+ if (newHistory == NULL) {
return 0;
}
- if ( len < tocopy ) {
+ if (len < tocopy) {
tocopy = len;
}
- memcpy( newHistory, history + historyMaxLen - tocopy, sizeof( UChar8* ) * tocopy );
- free( history );
+ memcpy(newHistory, history + historyMaxLen - tocopy, sizeof(UChar8*) * tocopy);
+ free(history);
history = newHistory;
}
historyMaxLen = len;
- if ( historyLen > historyMaxLen ) {
+ if (historyLen > historyMaxLen) {
historyLen = historyMaxLen;
}
return 1;
@@ -2660,18 +2751,18 @@ int linenoiseHistorySetMaxLen( int len ) {
/* Save the history in the specified file. On success 0 is returned
* otherwise -1 is returned. */
-int linenoiseHistorySave( const char* filename ) {
- FILE* fp = fopen( filename, "wt" );
- if ( fp == NULL ) {
+int linenoiseHistorySave(const char* filename) {
+ FILE* fp = fopen(filename, "wt");
+ if (fp == NULL) {
return -1;
}
- for ( int j = 0; j < historyLen; ++j ) {
- if ( history[j][0] != '\0' ) {
- fprintf ( fp, "%s\n", history[j] );
+ for (int j = 0; j < historyLen; ++j) {
+ if (history[j][0] != '\0') {
+ fprintf(fp, "%s\n", history[j]);
}
}
- fclose( fp );
+ fclose(fp);
return 0;
}
@@ -2680,25 +2771,25 @@ int linenoiseHistorySave( const char* filename ) {
*
* If the file exists and the operation succeeded 0 is returned, otherwise
* on error -1 is returned. */
-int linenoiseHistoryLoad( const char* filename ) {
- FILE *fp = fopen( filename, "rt" );
- if ( fp == NULL ) {
+int linenoiseHistoryLoad(const char* filename) {
+ FILE* fp = fopen(filename, "rt");
+ if (fp == NULL) {
return -1;
}
char buf[LINENOISE_MAX_LINE];
- while ( fgets( buf, LINENOISE_MAX_LINE, fp ) != NULL ) {
- char* p = strchr( buf, '\r' );
- if ( ! p ) {
- p = strchr( buf, '\n' );
+ while (fgets(buf, LINENOISE_MAX_LINE, fp) != NULL) {
+ char* p = strchr(buf, '\r');
+ if (!p) {
+ p = strchr(buf, '\n');
}
- if ( p ) {
+ if (p) {
*p = '\0';
}
- if ( p != buf ) {
- linenoiseHistoryAdd( buf );
+ if (p != buf) {
+ linenoiseHistoryAdd(buf);
}
}
- fclose( fp );
+ fclose(fp);
return 0;
}