Use "ANSI-mode" cursor keys only on actual cursor keys (A through D).

Fixes #161.
This commit is contained in:
Keith Winstein
2012-04-16 03:44:07 -04:00
parent cca925e020
commit c15d3d0c48
2 changed files with 49 additions and 16 deletions
+39 -13
View File
@@ -16,33 +16,59 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <assert.h>
#include "terminaluserinput.h" #include "terminaluserinput.h"
using namespace Terminal; using namespace Terminal;
using namespace std;
std::string UserInput::input( const Parser::UserByte *act, string UserInput::input( const Parser::UserByte *act,
bool application_mode_cursor_keys ) bool application_mode_cursor_keys )
{ {
char translated_str[ 2 ] = { act->c, 0 }; act->handled = true;
/* The user will always be in application mode. If stm is not in /* The user will always be in application mode. If stm is not in
application mode, convert user's cursor control function to an application mode, convert user's cursor control function to an
ANSI cursor control sequence */ ANSI cursor control sequence */
/* We don't need lookahead to do this for 7-bit. */ /* We need to look ahead one byte in the SS3 state to see if
the next byte will be A, B, C, or D (cursor control keys). */
if ( (!application_mode_cursor_keys) switch ( state ) {
&& (last_byte == 0x1b) /* ESC */ case Ground:
&& (act->c == 'O') ) { /* ESC O = 7-bit SS3 = application mode */ if ( act->c == 0x1b ) { /* ESC */
translated_str[ 0 ] = '['; state = ESC;
}
return string( &act->c, 1 );
break;
case ESC:
if ( act->c == 'O' ) { /* ESC O = 7-bit SS3 */
state = SS3;
return string();
} else {
state = Ground;
return string( &act->c, 1 );
}
break;
case SS3:
state = Ground;
if ( (!application_mode_cursor_keys)
&& (act->c >= 'A')
&& (act->c <= 'D') ) {
char translated_cursor[ 2 ] = { '[', act->c };
return string( translated_cursor, 2 );
} else {
char original_cursor[ 2 ] = { 'O', act->c };
return string( original_cursor, 2 );
}
break;
} }
/* This doesn't handle the 8-bit SS3 C1 control, which would be /* This doesn't handle the 8-bit SS3 C1 control, which would be
two octets in UTF-8. Fortunately nobody seems to send this. */ two octets in UTF-8. Fortunately nobody seems to send this. */
last_byte = act->c; assert( false );
return string();
act->handled = true;
return std::string( translated_str, 1 );
} }
+10 -3
View File
@@ -24,18 +24,25 @@
namespace Terminal { namespace Terminal {
class UserInput { class UserInput {
public:
enum UserInputState {
Ground,
ESC,
SS3
};
private: private:
wchar_t last_byte; UserInputState state;
public: public:
UserInput() UserInput()
: last_byte( -1 ) : state( Ground )
{} {}
std::string input( const Parser::UserByte *act, std::string input( const Parser::UserByte *act,
bool application_mode_cursor_keys ); bool application_mode_cursor_keys );
bool operator==( const UserInput &x ) const { return last_byte == x.last_byte; } bool operator==( const UserInput &x ) const { return state == x.state; }
}; };
} }