readstr.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 870 行 · 第 1/2 页
C
870 行
* GetTextForSpecialKey - get text for ^D,^E,^W, ALT_L, ^L, ^R
*/
bool GetTextForSpecialKey( int str_max, int event, char *tmp )
{
int i, l;
#ifndef __WIN__
int str_len;
#endif
switch( event ) {
#ifndef __WIN__
/* these commands are no longer safe under windows, since events
* don't fit into a char any more
*/
case VI_KEY( CTRL_F ):
str_len = AltDotDigits;
if( str_len > str_max ) {
str_len = str_max;
}
for( i=0; i < str_len; i++ ) {
tmp[i] = (char)(AltDotBuffer[i]);
}
tmp[ str_len ] = 0;
break;
case VI_KEY( CTRL_D ):
str_len = DotCmdCount;
if( str_len > str_max ) {
str_len = str_max;
}
for( i=0; i < str_len; i++ ) {
tmp[i] = (char)(DotCmd[i]);
}
tmp[ str_len ] = 0;
break;
#endif
case VI_KEY( CTRL_E ):
case VI_KEY( CTRL_W ):
tmp[ 0 ] = 0;
GimmeCurrentWord( tmp, str_max, event == VI_KEY( CTRL_E ) );
tmp[ str_max ] = 0;
break;
case VI_KEY( ALT_L ):
i = CurrentColumn - 1;
i = ( i > 0 ) ? i : 0;
case VI_KEY( CTRL_L ):
if( CurrentLine == NULL ) {
break;
}
if( event == VI_KEY( CTRL_L ) ) {
i = 0;
}
ExpandTabsInABuffer( &CurrentLine->data[ i ], CurrentLine->len - i,
tmp, str_max );
break;
case VI_KEY( CTRL_R ):
if( CurrentLine == NULL ) {
break;
}
if( SelRgn.lines ) {
assert( SelRgn.start_line == SelRgn.end_line );
i = 1;
l = CurrentLine->len + 1;
} else {
if( SelRgn.start_col < SelRgn.end_col ) {
i = SelRgn.start_col;
l = SelRgn.end_col - SelRgn.start_col + 1;
} else {
i = SelRgn.end_col;
l = SelRgn.start_col - SelRgn.end_col + 1;
}
}
ExpandTabsInABuffer( &CurrentLine->data[ i - 1 ], l, tmp, str_max );
tmp[ l ] = 0;
default:
return( FALSE );
}
return( TRUE );
} /* GetTextForSpecialKey */
/*
* InsertTextForSpecialKey - insert text for ^O, ALT_O
*/
void InsertTextForSpecialKey( int event, char *buff )
{
linenum line;
int type;
if( CurrentFile == NULL ) {
return;
}
line = CurrentLineNumber;
type = INSERT_BEFORE;
if( event == VI_KEY( CTRL_O ) ) {
type = INSERT_AFTER;
line += 1;
}
Modified( TRUE );
StartUndoGroup( UndoStack );
UndoInsert( line, line, UndoStack );
AddNewLineAroundCurrent( buff, strlen( buff ), type );
EndUndoGroup( UndoStack );
DCDisplayAllLines();
DCUpdate();
} /* InsertTextForSpecialKey */
static int specialKeyFilter( input_buffer *input, int event )
{
char *tmp;
switch( event ) {
case VI_KEY( ALT_O ):
case VI_KEY( CTRL_O ):
InsertTextForSpecialKey( event, input->buffer );
break;
case VI_KEY( CTRL_R ):
if( !SelRgn.selected ||
( SelRgn.lines &&
( SelRgn.start_line != SelRgn.end_line ) ) ) {
MyBeep();
break;
}
case VI_KEY( CTRL_W ):
case VI_KEY( CTRL_E ):
case VI_KEY( ALT_L ):
case VI_KEY( CTRL_L ):
case VI_KEY( CTRL_D ):
case VI_KEY( CTRL_F ):
if( input->curr_pos != strlen( input->buffer ) ) {
MyBeep();
} else {
tmp = MemAlloc( input->buffer_length );
assert( tmp != NULL );
GetTextForSpecialKey( input->buffer_length - strlen( input->buffer ) - 1,
event, tmp );
saveStr( input );
insertString( input, tmp );
MemFree( tmp );
}
break;
default:
return( event );
break;
}
return( HANDLED );
} /* specialKeyFilter */
/*
* File Completion:
* fileComplete( input_buffer ) - performs the actual file complete
* by spinning in a loop getting characters until the user
* selects a file or cancels. Returns TRUE if the getString
* routine should exit with the current string.
*/
static bool fileComplete( input_buffer *input, int first_event )
{
bool exit, done;
int ret, event;
int old_len;
exit = FALSE;
if( input->curr_pos != strlen( input->buffer ) ) {
MyBeep();
} else {
saveStr( input );
old_len = strlen( input->buffer ) - 1;
ret = StartFileComplete( input->buffer, old_len,
input->buffer_length, first_event );
if( ret > 0 ) {
MyBeep();
} else {
if( ret != FILE_COMPLETE ) {
done = FALSE;
do {
endColumn( input );
displayLine( input );
event = GetNextEvent( TRUE );
switch( event ) {
case VI_KEY( FAKEMOUSE ):
case VI_KEY( MOUSEEVENT ):
case VI_KEY( TAB ):
case VI_KEY( SHIFT_TAB ):
case VI_KEY( UP ):
case VI_KEY( DOWN ):
case VI_KEY( LEFT ):
case VI_KEY( RIGHT ):
case VI_KEY( PAGEDOWN ):
case VI_KEY( PAGEUP ):
case VI_KEY( ALT_END ):
ret = ContinueFileComplete( input->buffer,
old_len, input->buffer_length, event );
if( ret ) {
FinishFileComplete();
if( ret == FILE_COMPLETE_ENTER ) {
exit = TRUE;
}
done = TRUE;
}
old_len = strlen( input->buffer );
break;
default:
KeyAdd( event );
PauseFileComplete();
done = TRUE;
}
} while( !done );
}
}
}
return( exit );
} /* fileComplete */
/*
* Setup and Initialization functions:
* mouseHandler() - the routine to handle mouse events.
* initInput( input_buffer ) - sets the buffer to empty and
* initializes variables.
* finiInput( input_buffer ) - restores the normal cursor and
* removes the mouse handler.
*/
static window_id thisWindow = -1;
static bool mouseHandler( window_id id, int x, int y )
{
x = x;
y = y;
if( id != thisWindow ) {
if( LastMouseEvent == MOUSE_PRESS ) {
KeyAdd( VI_KEY( ESC ) );
AddCurrentMouseEvent();
}
}
return( FALSE );
} /* mouseHandler */
static void initInput( input_buffer *input )
{
type_style *s;
window_id id;
memset( input->buffer, 0, input->buffer_length );
input->curr_pos = 0;
if( input->history != NULL ) {
input->curr_hist = input->history->curr;
}
input->left_column = 0;
input->overstrike = TRUE;
s = &input->window.style;
id = input->window.id;
thisWindow = id;
s->foreground = WindowAuxInfo( id, WIND_INFO_TEXT_COLOR );
s->background = WindowAuxInfo( id, WIND_INFO_BACKGROUND_COLOR );
s->font = WindowAuxInfo( id, WIND_INFO_TEXT_FONT );
input->window.width = WindowAuxInfo( id, WIND_INFO_TEXT_COLS );
PushMouseEventHandler( mouseHandler );
NewCursor( input->window.id, NormalCursorType );
displayLine( input );
} /* initInput */
static void finiInput( input_buffer *input )
{
input = input;
thisWindow = NO_WINDOW;
PopMouseEventHandler();
if( !EditFlags.NoInputWindow ) {
NewCursor( input->window.id, NormalCursorType );
}
} /* finiInput */
/*
* getStringInWindow: main routine
*/
static bool getStringInWindow( input_buffer *input )
{
int event;
int old_mode;
ReadingAString = TRUE;
initInput( input );
input->last_str = alloca( input->buffer_length );
memset( input->last_str, 0, input->buffer_length );
if( input->history != NULL ) {
input->curr_hist = input->history->curr;
}
while( TRUE ) {
event = GetNextEvent( FALSE );
event = cursorKeyFilter( input, event );
event = historyFilter( input, event );
event = specialKeyFilter( input, event );
switch( event ) {
case HANDLED:
break;
case VI_KEY( SHIFT_TAB ):
case VI_KEY( TAB ):
if( !fileComplete( input, event ) ) {
endColumn( input );
break;
}
/* fall through */
case VI_KEY( ENTER ):
if( input->buffer[ 0 ] == NO_ADD_TO_HISTORY_KEY ) {
strcpy( &input->buffer[ 0 ], &input->buffer[ 1 ] );
} else {
addHistory( input );
}
/* fall through */
case VI_KEY( ESC ):
finiInput( input );
/*
* this call may not be necessary if the file complete window has
* already closed of natural causes but it doesn't harm anything
* if called when not needed - so we leave it here.
*/
FinishFileComplete();
ReadingAString = FALSE;
return( event != VI_KEY( ESC ) );
case VI_KEY( INS ):
input->overstrike = !input->overstrike;
if( !EditFlags.NoInputWindow ) {
NewCursor( input->window.id,
input->overstrike ? NormalCursorType : InsertCursorType );
}
break;
case VI_KEY( CTRL_END ):
saveStr( input );
input->buffer[ input->curr_pos ] = 0;
break;
case VI_KEY( CTRL_X ):
case VI_KEY( CTRL_U ):
saveStr( input );
input->buffer[ 0 ] = 0;
endColumn( input );
break;
case VI_KEY( CTRL_INS ):
swapString( input );
break;
case VI_KEY( CTRL_V ):
case VI_KEY( CTRL_Q ):
insertChar( input, '^' );
displayLine( input );
// here we have a bit of a kluge
input->curr_pos -= 1;
event = GetNextEvent( FALSE );
saveStr( input );
old_mode = input->overstrike;
input->overstrike = TRUE;
insertChar( input, event );
input->overstrike = old_mode;
break;
case VI_KEY( ALT_END ):
/* just want to redraw the line - for windows */
break;
default:
if( (event >= 32 && event < 128) || event == VI_KEY( CTRL_A ) ) {
saveStr( input );
if( !insertChar( input, event ) ) {
MyBeep();
}
}
}
if( !EditFlags.NoInputWindow ) {
displayLine( input );
}
}
} /* getStringInWindow */
bool ReadStringInWindow( window_id id, int line, char *prompt, char *str,
int max_len, history_data *history )
{
input_buffer input;
int rc;
input.prompt = prompt;
input.buffer = str;
input.buffer_length = max_len;
input.history = history;
input.window.id = id;
input.window.line = line;
#ifdef __WIN__
input.cache = (char *)MemAlloc( max_len );
input.cache[ 0 ] = 0;
#endif
rc = getStringInWindow( &input );
#ifdef __WIN__
MemFree( input.cache );
#endif
return( rc );
} /* ReadStringInWindow */
int PromptForString( char *prompt, char *buffer,
int buffer_length, history_data *history )
{
int err;
window_id id;
if( !EditFlags.NoInputWindow ) {
err = NewWindow2( &id, &cmdlinew_info );
if( err ) {
return( err );
}
} else {
id = NO_WINDOW;
}
if( !EditFlags.NoInputWindow &&
strlen( prompt ) >= WindowAuxInfo( id, WIND_INFO_TEXT_COLS ) ) {
err = ERR_PROMPT_TOO_LONG;
} else {
err = NO_VALUE_ENTERED;
if( ReadStringInWindow( id, 1, prompt, buffer, buffer_length, history ) ) {
err = ERR_NO_ERR;
}
}
if( !EditFlags.NoInputWindow ) {
CloseAWindow( id );
SetWindowCursor();
} else {
EditFlags.NoInputWindow = FALSE;
}
return( err );
} /* PromptForString */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?