summaryrefslogtreecommitdiff
path: root/src/mongo/shell
diff options
context:
space:
mode:
authoryeaji.shin <bloodevil4@gmail.com>2014-07-22 21:49:28 +0900
committerBenety Goh <benety@mongodb.com>2014-07-29 22:31:30 -0400
commitf58fbec3e4418adc6a266f41ad2872451fab760a (patch)
tree60027998ae3d4b28a5e943102fa8c4d185646d9f /src/mongo/shell
parentc91a2c3392fc95be3ed07ba98a4d98b4db754b58 (diff)
downloadmongo-f58fbec3e4418adc6a266f41ad2872451fab760a.tar.gz
SERVER-6086 fixed shell to handle zero-width and double-width characters
recompute character width when refresh line. use existing function mk_wcswidth. add fall back when mk_wcswidth return -1 on calculateColumnPosition. before set position, calculate width of characters. Closes #717 Signed-off-by: Benety Goh <benety@mongodb.com>
Diffstat (limited to 'src/mongo/shell')
-rw-r--r--src/mongo/shell/linenoise.cpp41
-rw-r--r--src/mongo/shell/mk_wcwidth.h1
2 files changed, 38 insertions, 4 deletions
diff --git a/src/mongo/shell/linenoise.cpp b/src/mongo/shell/linenoise.cpp
index d836eecc6aa..8cdbecb75aa 100644
--- a/src/mongo/shell/linenoise.cpp
+++ b/src/mongo/shell/linenoise.cpp
@@ -184,6 +184,19 @@ static void calculateScreenPosition( int x, int y, int screenColumns, int charCo
}
}
+/**
+ * Calculate a column width using mk_wcswidth()
+ * @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 )
+ return len;
+ else
+ return width;
+}
+
static bool isControlChar( UChar32 testChar ) {
return ( testChar < ' ' ) || // C0 controls
( testChar >= 0x7F && testChar <= 0x9F ); // DEL and C1 controls
@@ -640,11 +653,21 @@ static void dynamicRefresh( PromptBase& pi, UChar32* buf32, int len, int pos ) {
// calculate the position of the end of the input line
int xEndOfInput, yEndOfInput;
- calculateScreenPosition( xEndOfPrompt, yEndOfPrompt, pi.promptScreenColumns, 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, 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
@@ -739,11 +762,21 @@ void InputBuffer::refreshLine( PromptBase& pi ) {
// calculate the position of the end of the input line
int xEndOfInput, yEndOfInput;
- calculateScreenPosition( pi.promptIndentation, 0, pi.promptScreenColumns, 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, 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
diff --git a/src/mongo/shell/mk_wcwidth.h b/src/mongo/shell/mk_wcwidth.h
index 822fd280f44..fa81dc61af2 100644
--- a/src/mongo/shell/mk_wcwidth.h
+++ b/src/mongo/shell/mk_wcwidth.h
@@ -62,3 +62,4 @@
*/
extern int mk_wcwidth(int ucs);
+extern int mk_wcswidth(const int *pwcs, size_t n);