Recognise wrap when moving backwards

BS/CUB/HPB will move back to previous line(s) if the line has wrapped.
This commit is contained in:
Jason Hood 2017-12-18 11:30:27 +10:00
parent 80d9e7da78
commit 9242785570
3 changed files with 50 additions and 22 deletions

65
ANSI.c
View File

@ -152,7 +152,7 @@
remove wcstok, avoiding potential interference with the host; remove wcstok, avoiding potential interference with the host;
similarly, use a private heap instead of malloc. similarly, use a private heap instead of malloc.
v1.80, 26 October to 17 December, 2017: v1.80, 26 October to 19 December, 2017:
fix unloading; fix unloading;
revert back to (re)storing buffer cursor position; revert back to (re)storing buffer cursor position;
increase cache to five handles; increase cache to five handles;
@ -173,7 +173,8 @@
restrict parameters to a maximum value of 32767; restrict parameters to a maximum value of 32767;
added tab handling; added tab handling;
added the bright SGR colors, recognised the system indices; added the bright SGR colors, recognised the system indices;
added insert mode. added insert mode;
BS/CUB/HPB after wrap will move back to the previous line(s).
*/ */
#include "ansicon.h" #include "ansicon.h"
@ -544,7 +545,17 @@ BOOL search_env( LPCTSTR var, LPCTSTR val )
int nCharInBuffer; int nCharInBuffer;
WCHAR ChBuffer[BUFFER_SIZE]; WCHAR ChBuffer[BUFFER_SIZE];
WCHAR ChPrev; WCHAR ChPrev;
BOOL fWrapped; int nWrapped;
// Set the cursor position, resetting the wrap flag.
void set_pos( int x, int y )
{
COORD pos = { x, y };
SetConsoleCursorPosition( hConOut, pos );
nWrapped = 0;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// FlushBuffer() // FlushBuffer()
@ -580,7 +591,7 @@ void FlushBuffer( void )
{ {
GetConsoleScreenBufferInfo( hConOut, &csbi ); GetConsoleScreenBufferInfo( hConOut, &csbi );
if (csbi.dwCursorPosition.X == 0) if (csbi.dwCursorPosition.X == 0)
fWrapped = TRUE; ++nWrapped;
} }
} while (++b, --nCharInBuffer); } while (++b, --nCharInBuffer);
} }
@ -609,10 +620,9 @@ void FlushBuffer( void )
SetConsoleMode( hConWrap, ENABLE_WRAP_AT_EOL_OUTPUT ); SetConsoleMode( hConWrap, ENABLE_WRAP_AT_EOL_OUTPUT );
WriteConsole( hConWrap, ChBuffer, nCharInBuffer, &nWritten, NULL ); WriteConsole( hConWrap, ChBuffer, nCharInBuffer, &nWritten, NULL );
GetConsoleScreenBufferInfo( hConWrap, &csbi ); GetConsoleScreenBufferInfo( hConWrap, &csbi );
if (csbi.dwCursorPosition.Y != 0) nWrapped += csbi.dwCursorPosition.Y;
fWrapped = TRUE;
CloseHandle( hConWrap ); CloseHandle( hConWrap );
if (im && !fWrapped) if (im && !nWrapped)
{ {
SMALL_RECT sr, cr; SMALL_RECT sr, cr;
CHAR_INFO ci; // unused, but necessary CHAR_INFO ci; // unused, but necessary
@ -666,7 +676,7 @@ void PushBuffer( WCHAR c )
else else
{ {
LPCWSTR nl = L"\n"; LPCWSTR nl = L"\n";
if (fWrapped) if (nWrapped)
{ {
// It's wrapped, but was anything more written? Look at the current // It's wrapped, but was anything more written? Look at the current
// row, checking that each character is space in current attributes. // row, checking that each character is space in current attributes.
@ -699,12 +709,31 @@ void PushBuffer( WCHAR c )
} }
HeapFree( hHeap, 0, row ); HeapFree( hHeap, 0, row );
} }
fWrapped = FALSE; nWrapped = 0;
} }
if (nl) if (nl)
WriteConsole( hConOut, nl, 1, &nWritten, NULL ); WriteConsole( hConOut, nl, 1, &nWritten, NULL );
} }
} }
else if (c == '\b')
{
BOOL bs = FALSE;
FlushBuffer();
if (nWrapped)
{
GetConsoleScreenBufferInfo( hConOut, &csbi );
if (csbi.dwCursorPosition.X == 0)
{
csbi.dwCursorPosition.X = csbi.dwSize.X - 1;
csbi.dwCursorPosition.Y--;
SetConsoleCursorPosition( hConOut, csbi.dwCursorPosition );
--nWrapped;
bs = TRUE;
}
}
if (!bs)
ChBuffer[nCharInBuffer++] = c;
}
else else
{ {
if (shifted && c >= FIRST_G1 && c <= LAST_G1) if (shifted && c >= FIRST_G1 && c <= LAST_G1)
@ -772,15 +801,6 @@ void init_tabs( int size )
} }
// Set the cursor position, resetting the wrap flag.
void set_pos( SHORT x, SHORT y )
{
COORD pos = { x, y };
SetConsoleCursorPosition( hConOut, pos );
fWrapped = FALSE;
}
// ========== Print functions // ========== Print functions
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -894,7 +914,7 @@ void InterpretEscSeq( void )
if (pState->noclear && if (pState->noclear &&
(suffix2 == '+' || (TOP == screen_top && CUR.Y != LAST))) (suffix2 == '+' || (TOP == screen_top && CUR.Y != LAST)))
{ {
set_pos( LEFT, (SHORT)(suffix2 == '+' ? 0 : TOP) ); set_pos( LEFT, (suffix2 == '+') ? 0 : TOP );
break; break;
} }
prefix2 = 0; prefix2 = 0;
@ -1235,7 +1255,13 @@ void InterpretEscSeq( void )
case 'j': // ESC[#j case 'j': // ESC[#j
case 'D': // ESC[#D Moves cursor back # spaces case 'D': // ESC[#D Moves cursor back # spaces
if (es_argc > 1) return; // ESC[D == ESC[1D if (es_argc > 1) return; // ESC[D == ESC[1D
cub:
Pos.X = CUR.X - p1; Pos.X = CUR.X - p1;
while (Pos.X < LEFT && nWrapped-- && CUR.Y != top)
{
Pos.X += WIDTH;
CUR.Y--;
}
if (Pos.X < LEFT) Pos.X = LEFT; if (Pos.X < LEFT) Pos.X = LEFT;
set_pos( Pos.X, CUR.Y ); set_pos( Pos.X, CUR.Y );
return; return;
@ -1336,6 +1362,7 @@ void InterpretEscSeq( void )
case 'b': // ESC[#b Repeat character case 'b': // ESC[#b Repeat character
if (es_argc > 1) return; // ESC[b == ESC[1b if (es_argc > 1) return; // ESC[b == ESC[1b
if (ChPrev == '\b') goto cub;
while (--p1 >= 0) while (--p1 >= 0)
PushBuffer( ChPrev ); PushBuffer( ChPrev );
return; return;

View File

@ -91,7 +91,7 @@
use -pu to unload from the parent. use -pu to unload from the parent.
*/ */
#define PDATE L"17 December, 2017" #define PDATE L"19 December, 2017"
#include "ansicon.h" #include "ansicon.h"
#include "version.h" #include "version.h"

View File

@ -312,7 +312,7 @@ Version History
Legend: + added, - bug-fixed, * changed. Legend: + added, - bug-fixed, * changed.
1.80 - 17 December, 2017: 1.80 - 19 December, 2017:
- fix unloading; - fix unloading;
- fix -e et al when redirecting to CON; - fix -e et al when redirecting to CON;
- hook CreateFile and CreateConsoleScreenBuffer to force read/write access - hook CreateFile and CreateConsoleScreenBuffer to force read/write access
@ -326,6 +326,7 @@ Version History
* preserve escape that isn't part of a sequence; * preserve escape that isn't part of a sequence;
* escaped control characters will display the control; * escaped control characters will display the control;
* change the graphics SCAN characters to their Unicode equivalents; * change the graphics SCAN characters to their Unicode equivalents;
* BS/CUB/HVP after wrap will move back to the previous line(s);
+ use the system default sound for the bell; + use the system default sound for the bell;
+ added Play Sound DECPS; + added Play Sound DECPS;
+ added '+' intermediate byte to use the buffer, rather than the window; + added '+' intermediate byte to use the buffer, rather than the window;
@ -564,4 +565,4 @@ Distribution
============================== ==============================
Jason Hood, 17 December, 2017. Jason Hood, 19 December, 2017.