home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
p2demo21.exe
/
PEL
/
WP.PEL
< prev
next >
Wrap
Text File
|
1995-03-28
|
26KB
|
1,053 lines
# $Header: P:\source\wmacros\wp.pev 1.41 28 Mar 1995 12:51:12 pfhmlw0 $
##############################################################################
#
# Compuware Corporation
# 31440 Northwestern Highway
# Farmington Hills, Michigan 48334-2564
#
# This source code listing contains information that is
# proprietary to Compuware Corporation and may not be copied
# duplicated, translated, transmitted, stored, retrieved
# or in any manner or by any method conveyed or disclosed
# to a third party or parties without express written
# permission from Compuware Corporation.
#
#
##############################################################################
#### $Workfile: wp.pel $: word processing support
local ALT_KEY = 0x08
#local wp_priorContextLeft
### toggle word processing (word-wrap) mode for the current buffer
global function toggle_wp( on ) #PUBLIC #VOID
{
if ( argcount() )
wp( on )
else
wp()
}
global function wp( onOff, wrap_continuous, carry_comments )
{
local wrap_str
local flow_str
local carry_str
local count = argcount()
if ( count < 3 )
{
carry_comments = !and( buffer_flags, BUFFER_WP_CARRY_COMMENTS );
if ( count < 2 )
{
wrap_continuous = !and( buffer_flags, BUFFER_WP_WRAP_CONTINUOUS );
if ( count < 1 )
onOff = !and( buffer_flags, BUFFER_WP_ENABLED );
else
onOff = 0+onOff
}
else
wrap_continuous = wrap_continuous+0
}
else
carry_comments = carry_comments+0
if ( onOff )
{
auto_indent_mode = 0;
buffer_flags = or( buffer_flags, BUFFER_WP_ENABLED )
wrap_str = "Word processing enabled"
if ( wrap_continuous )
{
buffer_flags = or( buffer_flags, BUFFER_WP_WRAP_CONTINUOUS )
flow_str = "continuous wrapping"
}
else
buffer_flags = and( buffer_flags, not(BUFFER_WP_WRAP_CONTINUOUS) )
if ( carry_comments )
{
buffer_flags = or( buffer_flags, BUFFER_WP_CARRY_COMMENTS )
carry_str = "carry-down comments"
}
else
buffer_flags = and( buffer_flags, not(BUFFER_WP_CARRY_COMMENTS) )
if ( wrap_str )
{
if ( flow_str || carry_str )
wrap_str = wrap_str ", with "
wrap_str = wrap_str flow_str
if ( flow_str && carry_str )
wrap_str = wrap_str " and "
wrap_str = wrap_str carry_str
message( wrap_str )
}
}
else
{
buffer_flags = and( buffer_flags, not(BUFFER_WP_ENABLED ) )
buffer_flags = and( buffer_flags, not(BUFFER_WP_WRAP_CONTINUOUS) )
buffer_flags = and( buffer_flags, not(BUFFER_WP_CARRY_COMMENTS) )
message( "Word processing disabled." )
}
}
### column and tab-stop shifts left and right
local function next_non_white()
{
local str = ""
local offset
str = read_buffer()
offset = match( str, "[^ \t]" )
if ( offset )
goto_buffer_offset( buffer_offset + offset - 1 )
return( offset > 0 )
}
# DWM 4/29/94
# Note: this function outdents from the
# current cursor position to either the
# previous tab stop, the first non-white
# char before that tab stop, or the column
# specified
local function delete_to_prev_tab( boundary_column )
{
local start
local end
local len
if ( !argcount() || boundary_column > current_column )
boundary_column = 1
# get the number of chars to the prev tab
start = buffer_offset
goto_prev_tab()
end = buffer_offset
if ( current_column < boundary_column )
{
current_column = boundary_column
end = buffer_offset
}
# if there are non-white chars
# before tab, move to last one
len = length( trim( read_buffer(start-end) ) )
current_column += len
# outdent by deleting the appropriate chars
delete_chars( start - end - len )
}
global function outdent_lines()
{
local selection[]
local startcol = 1
local line
save_position()
if ( selection_type() && current_column > 0 )
{
selection = get_selection_info()
remove_selection()
update_current_view()
if ( selection.type == LINE_SELECTION )
startcol = 1
else
startcol = selection.startcol
# loop through the lines selected
for ( line = selection.startline; line <= selection.endline; line++ )
{
goto_pos( line, startcol )
if ( next_non_white() && current_column > startcol )
delete_to_prev_tab( startcol ) # don't delete past startcol
}
restore_selection_info( selection )
}
else
{
goto_pos( current_line, startcol )
if ( next_non_white() && current_column > startcol )
delete_to_prev_tab( startcol ) # don't delete past startcol
}
restore_position(1)
}
global function indent_lines()
{
local selection[]
save_position()
if ( selection_type() && current_column > 0 )
{
selection = get_selection_info()
end_selection()
}
skip_whitespace()
if ( and(buffer_flags, BUFFER_TABS_TO_SPACES) )
indent_columns( distance_next_tab )
else
indent_tabs()
if ( selection.type && current_column > 0 )
restore_selection_info( selection )
restore_position(TRUE)
}
global function indent_tab_maybe()
{
if ( selection_type() && current_column > 0 )
indent_lines()
else
insert_key()
}
global function outdent_tab_maybe()
{
if ( selection_type() && current_column > 0 )
outdent_lines()
else
goto_prev_tab()
}
global function indent_space_maybe()
{
if( selection_type() && current_column > 0 )
{
if( and( keyboard_flags, ALT_KEY ))
outdent_columns()
else
indent_columns()
}
else
insert_key(32)
}
global function outdent_space_maybe()
{
if( selection_type() && current_column > 0 )
outdent_columns()
else
backspace()
}
### delete_word()
function delete_word( n )
{
local srchstr = word_delimiter
local srchchar = read_buffer(1)
begin_selection( NORMAL_SELECTION )
if ( isspace(srchchar) ||
match( srchstr, quote_regex(srchchar) ) ||
and(buffer_flags, BUFFER_IN_VIRTUAL_SPACE) )
next_word( n, "<|$" )
else
next_word( n, ">|$" )
delete_chars()
}
### delete_word()
function delete_prev_word( n )
{
local srchstr = word_delimiter
local srchchar
if (current_column == 1)
{
if ( current_line != 1 )
{
current_line = current_line - 1
goto_eol()
current_column = current_column + 1
}
else
return
}
srchchar = read_buffer(-1)
begin_selection( NORMAL_SELECTION )
search_count = n+0
if ( isspace(srchchar) ||
match( srchstr, quote_regex(srchchar) ) ||
and(buffer_flags, BUFFER_IN_VIRTUAL_SPACE) )
search("^|>", SEARCH_BKWD_REGEX )
else
search("^|<", SEARCH_BKWD_REGEX )
delete_chars()
}
### sentence and paragraph motions:
local function s_forw( p, n )
{
local old = search_count
local result
search_count = n ? n : 1
result = search( p, SEARCH_FWD_REGEX_MAX + SEARCH_ADVANCE )
search_count = old
return result
}
local function s_back( p, n )
{
local old = search_count, result;
search_count = n ? n : 1
result = search( p, SEARCH_BKWD_REGEX_MAX + SEARCH_ADVANCE )
search_count = old
return result;
}
#global sentence_pattern = "[.!?]( |$)+\\c"
#global sentence_pattern = "(\\.|!|\\?)[)\"'\\]]*(\t| |$|^)+\\c"
global sentence_pattern = "(\\.|!|\\?|(^[ \t]*$))[)\"'\\]]*\\c([ \t]|$|^)+"
global paragraph_pattern = "^[ \t]*$|^\\.PP|^\\.LP"
global section_pattern = "^\\{" #}
global section_end_pattern = "^\\}" #}
function line_empty()
{
local result = TRUE
result = trim(read_line()) ? FALSE : TRUE
return result
}
# Go to the first character of the next sentence or the next blank line.
# Skips multiple blank lines.
function next_sentence( n, patt )
{
local result = TRUE
if (!patt)
patt = sentence_pattern
if (!n)
n = 1
if (line_empty())
{
# skip all blank lines
next_word(0, "[^ \t]")
n--
}
while (n > 0)
{
n--
if (line_empty())
next_word()
else if (!(result = s_forw( patt )) )
break;
# The following will move forward to the beginning of the next word or
# the beginning of the next empty line.
else if (!line_empty())
next_word(0, "<|(^[ \t]*$)")
}
return result
}
# Go to the first character of the current or previous sentence or the previous blank line.
# Skips multiple blank lines.
function prev_sentence( n, patt )
{
local moved = FALSE
local ch
local result = FALSE
local start_line = current_line
local start_empty = line_empty()
if (!patt)
patt = sentence_pattern
# save initial position;
save_position();
if (!n)
n = 1
if (line_empty())
{
while(line_empty())
current_line--
goto_eol()
prev_word(0,"<|^")
}
else
{
# move backward in buffer so we don't find the same sentence again.
prev_word(0,"<|$")
if (line_empty())
{
goto_bol()
n--
result = TRUE
}
else if (current_line != start_line)
{
prev_word(0, "<|^")
goto_eol()
}
}
while (n > 0)
{
n--
if (line_empty())
{
prev_word()
}
if (!(result = s_back( patt )))
break
if (!n)
next_word(0, "[^ \t]")
else if (line_empty())
{
n--
goto_bol()
}
else if (!line_empty())
prev_word(0,"<|^")
}
# go back to our old position if another sentence not found
restore_position(!result);
return result
}
function next_paragraph( n, patt )
{
local result
if (!patt)
patt = paragraph_pattern
save_position()
while (line_empty() && current_line < buffer_last_line)
current_line++
result = s_forw( patt, n )
restore_position(!result);
return result
}
function prev_paragraph( n, patt )
{
local result
if (!patt)
patt = paragraph_pattern
save_position()
while (line_empty() && current_line > 1)
current_line--
result = s_back( patt, n )
restore_position(!result);
return result
}
function next_section( n, patt )
{
if (!patt)
patt = section_pattern
return s_forw( patt, n )
}
function prev_section( n, patt )
{
if (!patt)
patt = section_pattern
return s_back( patt, n )
}
## reverse case of characters a string, upper to lower and lower to upper
# non-alphabetic characters are unaffected
#
function toreverse( s ) #PUBLIC #STR
{
local ch, r = ""
while( s )
{
ch = substr( s, 1, 1 )
s = substr( s, 2 )
if( islower( ch ))
ch = toupper( ch )
else if( isupper( ch ))
ch = tolower( ch )
r = r ch
}
return r
}
## alter case sense of ranges in the current buffer
# non-alphabetic characters are unaffected
#
function upper() #PUBLIC #VOID
{
local ch
rgetc_init()
while(( ch = rgetc() ))
{
if( islower( ch ))
{
ch = toupper( ch )
rputc( ch )
}
}
rgetc_done()
}
function lower() #PUBLIC #VOID
{
local ch
rgetc_init()
while(( ch = rgetc() ))
{
if( isupper( ch ))
{
ch = tolower( ch )
rputc( ch )
}
}
rgetc_done()
}
function reverse() #PUBLIC #VOID
{
local ch
rgetc_init()
while(( ch = rgetc() ))
{
if( islower( ch ))
{
ch = toupper( ch )
rputc( ch )
}
else if( isupper( ch ))
{
ch = tolower( ch )
rputc( ch )
}
}
rgetc_done()
}
## capitalize the first letter of each word in a selection
# if there is no selection, capitalize the first letter
# of the next word. If the selection starts in the middle
# of a word, alas, the middle character gets capitalized.
function capitalize() #PUBLIC #VOID
{
local ch
rgetc_init()
while(( ch = rgetc()))
{
if( isalpha( ch ))
{
if( islower( ch ))
rputc( toupper( ch ))
if( !next_word( 1 ))
break
}
}
rgetc_done()
}
## rgetc(), rputc( ch ), rgetc_init(), rgetc_done()
#
# This collection of functions facilitates the sequential replacement
# of all characters within a selected region. If no selection is active,
# operate on the single character under the cursor.
#
# Normal usage:
#
# rgetc_init()
# while (( ch = rgetc())
# if ( P( ch ))
# rputc( F( ch ))
# rgetc_done()
#
# Revision 1.14 of this file included a different implementation
# that cut the selection to a second buffer, processed the entire
# buffer and then reinserted the result. I thought it would be simpler
# and faster, but it turned out to be more complex, and rather slow.
#
local rgetc_x0, rgetc_y0
local rgetc_x1, rgetc_y1
local rgetc_st, rgetc_columnar, rgetc_offset
local function rgetc()
{
local ch
local pastEol
local targetLine
restore_position( 0 ) # pop previously saved
# if column selection, wrap at end of current row
#
if ( rgetc_columnar )
{
while ( (pastEol = ( current_column >= rgetc_x1 )) ||
current_column < rgetc_x0 )
{
targetLine = current_line + pastEol
if ( !goto_pos( targetLine, rgetc_x0 ) || current_line != targetLine )
{
return ""
}
else if ( !and( buffer_flags, BUFFER_IN_VIRTUAL_SPACE )){
break
}
next_char()
}
}
# test for past end of selection
if( buffer_offset >= rgetc_offset )
return ""
ch = read_buffer( 1 )
save_position()
next_char()
if( !ch )
ch = "\n"
return ch
}
# replace the character in the buffer most recently returned by rgetc
#
local function rputc( ch )
{
restore_position( 1 )
insert_string( ch )
delete_chars(1)
save_position()
}
# initialize a collection of variables for rgetc()/rputc() usage.
# Places the cursor at the upper left corner, and saves the
# original position on the save_position stack.
#
# No selection => process a single character.
#
local function rgetc_init()
{
local tmp
save_position() # original position of selection
# if no region is marked we behave as if a single char is marked
#
rgetc_st = selection_type()
if ( rgetc_st == NO_SELECTION )
{
rgetc_x1 = current_column
rgetc_y1 = current_line
rgetc_x0 = rgetc_x1++
rgetc_y0 = rgetc_y1
}
else
{
# get and remember starting & ending marks & normalize
# their locations
#
end_selection()
goto_mark( selection_mark_top() )
rgetc_x0 = current_column
rgetc_y0 = current_line
goto_mark( selection_mark_bottom() )
rgetc_x1 = current_column
rgetc_y1 = current_line
# remove the selection
#
remove_selection()
# per-selection-type fine-tuning
#
rgetc_columnar = 0
if( rgetc_st == COLUMN_SELECTION )
{
rgetc_columnar = 1
if( rgetc_x1 < rgetc_x0 )
{
tmp = rgetc_x0
rgetc_x0 = rgetc_x1
rgetc_x1 = tmp
}
rgetc_x1++
}
else if( rgetc_st == INCLUSIVE_SELECTION )
rgetc_x1++
else if( rgetc_st == LINE_SELECTION )
{
rgetc_x0 = rgetc_x1 = 1
rgetc_y1++
}
}
# save first byte offset past selection
if ( rgetc_st == LINE_SELECTION && rgetc_y1 > buffer_last_line )
rgetc_offset = buffer_size
else
{
goto_pos( rgetc_y1, rgetc_x1 )
rgetc_offset = buffer_offset
}
goto_pos( rgetc_y0, rgetc_x0 )
if ( and( buffer_flags, BUFFER_IN_VIRTUAL_SPACE ))
next_char()
update_current_view()
# rgetc() expects to discard a previously saved position:
save_position()
}
# clean up the save_position stack and restore the original cursor position
#
local function rgetc_done()
{
# WGN 3/13/95 - Removed the following condition since the position is NOT
# restored only in the case of a normal selection. This caused capitalize()
# to always end up on the word after the selection.
# if( rgetc_st == 1 )
# {
# restore_position( 0 )
# # (can be used to reselect marked region)
# }
restore_position( 1 )
}
## get_region_as_string
#
# Read the characters in a region and return them as a string.
# For columnar selections, the two parameters "sep" and "term"
# specify a string to be used to separate each of the lines of
# the selection and to terminate the last line of the selection,
# respectively. A suggestion for the values of these strings
# is " " and "\n" or, alternatively, "\n" and "\n".
#
global function get_region_as_str(sep, term)
{
local x0, y0, x1, y1
local str, st, len, line
local end # buffer offset at end of selection. Can't use columns if
# there are tabs in line.
# if no region is marked we return a null string
st = selection_type()
if ( st == NO_SELECTION )
return ""
save_position()
#
# determine the extent of the marked block
#
end_selection()
goto_mark( selection_mark_top() )
x0 = current_column
y0 = current_line
goto_mark( selection_mark_bottom() )
x1 = current_column
y1 = current_line
# we no longer need the selection
remove_selection()
# adjust region coordinates depending on type
if (st == INCLUSIVE_SELECTION)
x1++
else if (st == LINE_SELECTION)
{
x0 = x1 = 1
y1++
}
# read the characters in the selection
goto_pos(y0, x0)
line = current_line
if (st == COLUMN_SELECTION)
{
# read characters in the selection, add separators, terminator
len = x1 - x0 + 1
for (str = ""; line <= y1; line++)
{
# next five lines added to get the actual number of characters
save_position()
current_column = x1
end = buffer_offset
restore_position(1)
len = end - buffer_offset + 1
str = str read_buffer(len) ((current_line < y1) ? sep : term)
current_column = x0
current_line++
}
}
else
{
# read the lines in the selection, add newlines
for (str = ""; line <= y1; line++)
{
if (current_line < y1)
str = str read_buffer() "\n"
else if (x1 > current_column)
{
#str = str read_buffer(x1 - current_column)
save_position()
current_column = x1
end = buffer_offset
restore_position(1)
str = str read_buffer(end - buffer_offset)
}
current_column = 1
current_line++
}
}
# clean up
restore_position(1)
return str
}
### auto indent mode: automatically indent newly-entered lines to match
# the leading whitespace on the previous non-blank line.
#
# One key, normally Enter, causes auto-indent to occur.
# Another key, normally Control-Enter causes auto-indent to
# occur after a line is "opened".
#
# The automatically-indented line is initially composed of virtual
# space. This means that consecutive lines that are indented but
# also left blank do not contain any superfluous characters.
#function ai( on ) #PUBLIC #VOID
#{
# if (argcount())
# toggle_auto_indent( on )
# else
# toggle_auto_indent()
#}
## toggle auto-indent mode
# when enabled auto_indent_cr does auto-indenting;
# when disabled auto_indent_cr merely inserts a "\n".
#
# if selection is present it causes the mode to be set to its value
# rather than toggled
function toggle_auto_indent( on ) #PUBLIC #VOID
{
local verbose = 0
if( argcount() < 1 )
{
on = !auto_indent_mode
verbose = 1
}
auto_indent_mode = on
if(auto_indent_mode)
buffer_flags = and(buffer_flags, not(BUFFER_WP_ENABLED ))
if( verbose )
message( on ? "Auto-indent enabled." : "Auto-indent disabled." )
}
# open line and auto-indent
function auto_indent_nl()
{
goto_eol()
auto_indent_cr()
}
# insert a new line and auto-indent
function auto_indent_cr(first_one)
{
if( auto_indent_mode )
insert_auto_indent()
else
insert_newline()
}
# this function turns off real_space_only. it then cuts the text from the
# current cursor position and places it on the next line based on the spacing
# of the previous line
function insert_auto_indent(first_one)
{
# check to see if real space is on
local real_space = and(buffer_flags, BUFFER_REAL_SPACE_ONLY)
local overtype = and(buffer_flags, BUFFER_OVERTYPE_MODE)
local line, trailing, indent, col, follow, ret, ch
# turn off real space so we can move around more freely
buffer_flags = and( buffer_flags, not(BUFFER_REAL_SPACE_ONLY))
# if first_one is not passed, determine if this function was the last
# one called, added the = on current_line_offset <=... to fix a bug
# with expanding templates
if (!argcount())
first_one = (prev_command != current_command) || \
(current_line_offset <= current_line_length)
if( first_one || overtype)
{
# THEN this is the first auto-indent of a possible sequence.
# We insert a newline and figure out if there's trailing
# text which needs to be indented. If so we have to copy
# indented text; else we just position the cursor in virtual
# space on the new blank line.
if (!overtype)
{
follow = read_buffer()
delete_to_eol()
}
ret = insert_newline()
if (current_column >= 1)
{
line = current_line
trailing = ( current_line_offset < current_line_length )
if (overtype)
{
if ((ch = read_buffer(1)))
{
# find indent of this line:
while (ch == " " || ch == "\t")
{
next_char()
ch = read_buffer(1)
}
}
else
{
# or last non-blank line:
do {
prev_line()
} while( current_line > 1 && !read_buffer( 1 ))
}
}
else
{
# find indent of last non-blank line:
do {
prev_line()
} while( current_line > 1 && !read_buffer( 1 ))
}
col = current_column
goto_pos( line, col )
if (length(follow))
{
# copy indent whitespace if there is trailing text:
insert_string( follow )
goto_pos( line, col )
}
}
}
else
{
# ELSE this is another in a sequence of consecutive
# auto-indent commands. Thus we know that current_column
# reflects the proper indentation; all we need to do is
# insert a blank line before the current one and restore
# cursor position on the newly positioned line.
col = current_column
ret = insert_newline()
if (current_column >= 1)
current_column = col
}
# restore what we may have turned off up above
if ( real_space )
buffer_flags = or( buffer_flags, BUFFER_REAL_SPACE_ONLY )
return ret
}
# # insert and auto-indent a newline before the current line
#
# function auto_indent_before(){
# if( current_line == 1 ){
# goto_bol()
# insert_newline_ai()
# up()
# } else {
# up()
# auto_indent_nl()
# }
# }