Allow non-inserting prediction.
This may be useful for users who find prediction's activity right of the cursor distracting. Prediction underscoring is still a little weird sometimes, it replays a history of known/unknown changes as acks come in from the server.
This commit is contained in:
@@ -175,6 +175,10 @@ int main( int argc, char *argv[] )
|
||||
char *predict_mode = getenv( "MOSH_PREDICTION_DISPLAY" );
|
||||
/* can be NULL */
|
||||
|
||||
/* Read prediction insertion preference */
|
||||
char *predict_overwrite = getenv( "MOSH_PREDICTION_OVERWRITE" );
|
||||
/* can be NULL */
|
||||
|
||||
char *key = strdup( env_key );
|
||||
if ( key == NULL ) {
|
||||
perror( "strdup" );
|
||||
@@ -191,7 +195,7 @@ int main( int argc, char *argv[] )
|
||||
|
||||
bool success = false;
|
||||
try {
|
||||
STMClient client( ip, desired_port, key, predict_mode, verbose );
|
||||
STMClient client( ip, desired_port, key, predict_mode, verbose, predict_overwrite );
|
||||
client.init();
|
||||
|
||||
try {
|
||||
|
||||
@@ -84,7 +84,7 @@ private:
|
||||
void resume( void ); /* restore state after SIGCONT */
|
||||
|
||||
public:
|
||||
STMClient( const char *s_ip, const char *s_port, const char *s_key, const char *predict_mode, unsigned int s_verbose )
|
||||
STMClient( const char *s_ip, const char *s_port, const char *s_key, const char *predict_mode, unsigned int s_verbose, const char *predict_overwrite )
|
||||
: ip( s_ip ? s_ip : "" ), port( s_port ? s_port : "" ),
|
||||
key( s_key ? s_key : "" ),
|
||||
escape_key( 0x1E ), escape_pass_key( '^' ), escape_pass_key2( '^' ),
|
||||
@@ -117,6 +117,9 @@ public:
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
if ( predict_overwrite && !strcmp( predict_overwrite, "yes" ) ) {
|
||||
overlays.get_prediction_engine().set_predict_overwrite( true );
|
||||
}
|
||||
}
|
||||
|
||||
void init( void );
|
||||
|
||||
@@ -698,32 +698,45 @@ void PredictionEngine::new_user_byte( char the_byte, const Framebuffer &fb )
|
||||
cursor().col--;
|
||||
cursor().expire( local_frame_sent + 1, now );
|
||||
|
||||
for ( int i = cursor().col; i < fb.ds.get_width(); i++ ) {
|
||||
ConditionalOverlayCell &cell = the_row.overlay_cells[ i ];
|
||||
|
||||
if ( predict_overwrite ) {
|
||||
ConditionalOverlayCell &cell = the_row.overlay_cells[ cursor().col ];
|
||||
cell.reset_with_orig();
|
||||
cell.active = true;
|
||||
cell.tentative_until_epoch = prediction_epoch;
|
||||
cell.expire( local_frame_sent + 1, now );
|
||||
cell.original_contents.push_back( *fb.get_cell( cursor().row, i ) );
|
||||
|
||||
if ( i + 2 < fb.ds.get_width() ) {
|
||||
ConditionalOverlayCell &next_cell = the_row.overlay_cells[ i + 1 ];
|
||||
const Cell *next_cell_actual = fb.get_cell( cursor().row, i + 1 );
|
||||
const Cell orig_cell = *fb.get_cell();
|
||||
cell.original_contents.push_back( orig_cell );
|
||||
cell.replacement = orig_cell;
|
||||
cell.replacement.clear();
|
||||
cell.replacement.append(' ');
|
||||
} else {
|
||||
for ( int i = cursor().col; i < fb.ds.get_width(); i++ ) {
|
||||
ConditionalOverlayCell &cell = the_row.overlay_cells[ i ];
|
||||
|
||||
if ( next_cell.active ) {
|
||||
if ( next_cell.unknown ) {
|
||||
cell.unknown = true;
|
||||
cell.reset_with_orig();
|
||||
cell.active = true;
|
||||
cell.tentative_until_epoch = prediction_epoch;
|
||||
cell.expire( local_frame_sent + 1, now );
|
||||
cell.original_contents.push_back( *fb.get_cell( cursor().row, i ) );
|
||||
|
||||
if ( i + 2 < fb.ds.get_width() ) {
|
||||
ConditionalOverlayCell &next_cell = the_row.overlay_cells[ i + 1 ];
|
||||
const Cell *next_cell_actual = fb.get_cell( cursor().row, i + 1 );
|
||||
|
||||
if ( next_cell.active ) {
|
||||
if ( next_cell.unknown ) {
|
||||
cell.unknown = true;
|
||||
} else {
|
||||
cell.unknown = false;
|
||||
cell.replacement = next_cell.replacement;
|
||||
}
|
||||
} else {
|
||||
cell.unknown = false;
|
||||
cell.replacement = next_cell.replacement;
|
||||
cell.replacement = *next_cell_actual;
|
||||
}
|
||||
} else {
|
||||
cell.unknown = false;
|
||||
cell.replacement = *next_cell_actual;
|
||||
cell.unknown = true;
|
||||
}
|
||||
} else {
|
||||
cell.unknown = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -746,7 +759,8 @@ void PredictionEngine::new_user_byte( char the_byte, const Framebuffer &fb )
|
||||
}
|
||||
|
||||
/* do the insert */
|
||||
for ( int i = fb.ds.get_width() - 1; i > cursor().col; i-- ) {
|
||||
int rightmost_column = predict_overwrite ? cursor().col + 1 : fb.ds.get_width() - 1;
|
||||
for ( int i = rightmost_column; i > cursor().col; i-- ) {
|
||||
ConditionalOverlayCell &cell = the_row.overlay_cells[ i ];
|
||||
cell.reset_with_orig();
|
||||
cell.active = true;
|
||||
|
||||
@@ -262,6 +262,7 @@ namespace Overlay {
|
||||
|
||||
private:
|
||||
DisplayPreference display_preference;
|
||||
bool predict_overwrite;
|
||||
|
||||
bool active( void ) const;
|
||||
|
||||
@@ -272,6 +273,7 @@ namespace Overlay {
|
||||
|
||||
public:
|
||||
void set_display_preference( DisplayPreference s_pref ) { display_preference = s_pref; }
|
||||
void set_predict_overwrite( bool overwrite ) { predict_overwrite = overwrite; }
|
||||
|
||||
void apply( Framebuffer &fb ) const;
|
||||
void new_user_byte( char the_byte, const Framebuffer &fb );
|
||||
@@ -302,7 +304,8 @@ namespace Overlay {
|
||||
last_quick_confirmation( 0 ),
|
||||
send_interval( 250 ),
|
||||
last_height( 0 ), last_width( 0 ),
|
||||
display_preference( Adaptive )
|
||||
display_preference( Adaptive ),
|
||||
predict_overwrite( false )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user