home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
p2demo21.exe
/
PEL
/
HISTORY.PEL
< prev
next >
Wrap
Text File
|
1995-03-31
|
28KB
|
1,005 lines
# $Header: P:\source\wmacros\history.pev 1.63.1.0 31 Mar 1995 16:23:52 WALKER $
## $Tabs:4 7$
##############################################################################
#
# 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: history.pel $: Response history support
local historyArray
local historyName
local historyElement
local historyPromptString # current prompt string displayed by prompt_history
local writeConfigArray[]
global edit_file_dir = 1 # set to 1 to display dir list from edit_file_key()
global MAX_HISTORY = 10
global history_font = -1 # Font to use for History List,
# Default is FONT_MODERN8
# This function will return an array containing the history of a
# specified type of history given an index into the history array,
function history_config( index )
{
local i = 0
local end = (index 0 in historyArray) ? historyArray[index 0] : 0
local data_index = 1
local data[]
local word = "";
if (writeConfigArray[index] != 1)
return;
#
# check to make sure something is in array
#
if (!(index i in historyArray))
historyArray[ index i ] = i;
#
# Write list to file
#
if ( end > MAX_HISTORY )
i = end - MAX_HISTORY
while ( (i=i+1) <= end )
{
# gsub("\"", "'", historyArray[index i] )
word = historyArray[index i];
# Although this line appears to be pointless, it fixes the problem
# of actual new lines being written to the config file.
gsub("\\n", "\\n", word);
data[ data_index++ ] = sprintf( "add_prompt_history %s \"%s\"\n",
index,
quote_quote(quote_regex( word )) )
}
data[ data_index++ ] = sprintf( "\n" )
return data
}
global function get_history_list(history_name)
{
local end
local i = 0
local data[]
local retval = ""
setup_prompt_history( history_name )
end = (history_name 0 in historyArray) ? historyArray[history_name 0] : 0
if (history_name i in historyArray)
{
data = history_config( history_name )
for ( i = 1; i < end; i++ )
{
retval = retval historyArray[history_name i] "^"
}
}
return retval
}
local IDM_ADD_EDITFILE = 0x300
global function add_editfile_to_menu()
{
local main_menu = menu_info(0, MI_MENUHANDLE)
local menu = menu_info( main_menu, MI_MENUHANDLE, IDM_FILE )
local menu_id = IDM_ADD_EDITFILE
local MAX_ITEMS = 5
local history_name = "EDITFILE"
local end
local i = 0
local count = 1
local data[]
delete_event(EVENT.NEW_EDIT_FILE, "add_editfile_to_menu")
attach_event_handler(EVENT.NEW_EDIT_FILE, "add_editfile_to_menu")
setup_prompt_history( history_name )
end = (history_name 0 in historyArray) ? historyArray[history_name 0] : 0
if (!(history_name i in historyArray))
return
data = history_config( history_name )
for ( i = menu_id; i <= menu_id + MAX_ITEMS; i++ )
delete_menuitem(main_menu, i)
for ( i = end; i > 0 && i > end - MAX_ITEMS; i-- )
{
insert_menuitem(menu, menu_id, IDM_EXIT, MI_MENUITEM, "~" count++ " " historyArray[history_name i] )
menu_functions[menu_id] = "create_buf_and_win " historyArray[history_name i]
menu_id++
}
insert_menuitem(menu, menu_id++, IDM_EXIT, MI_SEPARATOR )
}
#------------------------------------------------------------------#
## prompt_history()
#
# Prompt the user for a string and process all illegally typed characters
# through the _bad_prompt_key() function. The parameters passed are as
# follows:
#
# index - a string identifying which history stack to use
# promptstr - first parameter to prompt()
# defaultstr- second parameter to prompt()
# usehistory- if defaultstr == "" and usehistory == 1, use the
# last history item
#
# Example:
# prompt_history( "SEARCH", "Search for: ", "noname" )
#
# Each time this is called an a valid input string is entered
# and returned by prompt(), it is added to the history stack
# and subsequent calls can access this stack.
#
global function setup_prompt_history(index, element)
{
local patt
local i = 0;
local id = function_id( "_bad_prompt_key" );
# don't setup a history twice
#
if ( index == historyName)
return
#
# initialize historyArray in need to
#
if (!(index i in historyArray))
{
historyArray[ index i ] = i;
writeConfigArray[index] = 1
read_config_section("$" index "_HISTORY$")
}
#
# let the command history functions know where to find
# the command history for this specified call.
#
historyName = index;
historyElement = element ? -1 : 0;
# install an event handler to make history
# available to the prompt function.
# only needs to be installed once
#
delete_event( EVENT.INVALID_PCHAR, id )
attach_event_handler( EVENT.INVALID_PCHAR, id )
}
global function prompt_history( index, promptstr, defaultstr, usehistory, highlight, helpid )
{
local patt
if ( argcount() < 5 )
highlight = TRUE
setup_prompt_history( index )
historyElement = defaultstr ? -1 : 0;
#
# prompt for the search pattern and provide command history
#
if ((historyElement == 0) && (usehistory))
{
defaultstr = current_history_item( index );
historyElement = -1;
}
if (!helpid)
helpid = "default_prompt"
patt = prompt( historyPromptString = promptstr, defaultstr, helpid, highlight )
cleanup_prompt_history();
return patt;
}
global function cleanup_prompt_history()
{
delete_event( EVENT.INVALID_PCHAR, function_id( "_bad_prompt_key" ) )
if ( historyName == "SEARCH" )
optional_function("delete_regex_table")
historyName = ""
}
# This function is useful for those edit controls in dialogs that may
# cause a DM_INVALID_PCHAR message because they want to use history
# features
#
function dialog_history( dlgHand, dlgId, histName )
{
local old_prompt_response
prompt_response = query_dialog_item(dlgHand, dlgId, DAC_EDIT_TEXT)
# save prompt_response before the we execute the event
#
old_prompt_response = prompt_response
setup_prompt_history( histName, prompt_response )
execute_event_handler( EVENT.INVALID_PCHAR )
# only update edit box if any event handlers for EVENT.INVALID_PCHAR
# have changed the prompt_response variable. Every time an edit box
# is updated the cursor is positioned at the end of the line.
if ( prompt_response != old_prompt_response )
{
set_dialog_item(dlgHand, dlgId, DAC_EDIT_TEXT, prompt_response "", 1)
}
}
## _bad_prompt_key()
#
# This is the event handler used to handle bad keys entered from the prompt
# primitive.
#
# A few notes:
#
# o This function will receive any key which is not a simple upper
# or lower case letter, including <Enter>, <Spacebar>, <Ctrl-A> etc.
#
# o The "prompt_response" variable contains the current input string
# at the prompt. This string can be modified in any manner and will
# be reflected at the prompt line.
#
# o The value of "current_key" will be processed when this function
# returns as if this function was never called. If you wish that
# the key not be processed, set "current_key = 0"; or if you wish to
# replace it with a different key, set "current_key = <your_keycode>".
# For example, setting current_key to "KEYCODE_HOME" will cause the
# cursor to move to the beginning of the prompt response.
#
# o Setting current_key to the magic value -1 resets prompt() to its
# initial state, i.e. it highlights the current prompt_response value
# and places the cursor at the end of the response. If the
# prompt_response variable is changed without setting current_key
# to -1, the cursor position will be left unchanged.
#
global function _bad_prompt_key()
{
local min = 0;
local max, i
local buffer;
local tempArray[]
local width = 20
local response
local help_word, start, end, parent
if ( current_key == KEYCODE_TAB )
{
#
# if we are performing an invoke_function (F10) and a TAB
# was pressed, then display function listing
#
if (historyName == "XMACRO" || historyName == "ISPF")
{
displayFunctionList(historyName)
current_key = 0
return
}
# if we are performing an edit_file
else if (historyName == "EDITFILE" || historyName == "SRCHFILES")
{
# save the prompt_display_handle since the following loop could
# bring up several dialogs and change the prompt_display_handle
parent = prompt_display_handle
# continue displaying directory information as long as a directory
# is selected
while ( displayDirContents() && prompt_response ~ /\\$/ )
{}
current_key = 0
return
}
else if(historyName == "BOOKMARKS")
{
displayMatchingBookmark();
current_key = 0;
return;
}
}
else if (current_key == KEYCODE_PAGEUP || current_key == KEYCODE_PAGEDOWN ||
current_key == KEYCODE_NUM_PAGEUP || current_key == KEYCODE_NUM_PAGEDOWN )
{
# display history list
tempArray = get_history( historyName )
for ( i in tempArray )
width = max(width, length(tempArray[i]))
# i will be set to the last element and our list box is 0 based
select_index = i - 1
response = prompt_selection( historyName " History List", width, tempArray )
# reset select_index back to 0
select_index = 0
if ( !response )
prompt_response = old_response
else
prompt_response = response
delete( tempArray )
current_key = -1 # highlight the string
return
}
# else if ( current_key == help_key )
else if ( current_key == 0x9020 ) # CTRL-F1
{
if ( historyName == "XMACRO" )
{
# initialize start to beginning of word
start = 1
# if "?" is found, then start after it
if ( match(prompt_response, "\\?") == 1 )
start = 2
# end the word at either a space or EOL
end = match(prompt_response, " |$") - 1
help_word = trim(substr(prompt_response, start, end))
display_help_item( help_word )
}
else if ( historyName == "SEARCH" )
display_help_item( "regexpr" )
current_key = 0;
return;
}
else if (current_key == KEYCODE_ESC)
{
if ( status_bar_flags )
message("Command cancelled.")
return;
}
else if (current_key == KEYCODE_CTRL_R && historyName == "SEARCH" )
optional_function("display_regex_table")
#
# is there something in the list?
#
max = historyArray[ historyName min ];
if (current_key == KEYCODE_DOWN || current_key == KEYCODE_NUM_DOWN)
{
# get previous command
if (max)
historyElement = (historyElement + 1) % max
}
else if (current_key == KEYCODE_UP || current_key == KEYCODE_NUM_UP)
{
# get next command
if (max)
{
if (historyElement <= 0) # skip first entry if < 0
historyElement = max + historyElement;
if (historyElement)
historyElement--;
}
}
else if (int_to_key(current_key) == "<Alt-L>" || int_to_key(current_key) == "<Ctrl-L>" )
{
current_key = -1 # highlight the string
return
}
else if (int_to_key(current_key) == "<Alt-D>" || int_to_key(current_key) == "<Ctrl-D>" )
{
# remove the current item from the history list
#
delete_history_item( historyName, prompt_response )
# then just fall through and allow the prompt_response to change
}
else if (int_to_key(current_key) == "<Enter>" )
{
if ( prompt_response )
add_prompt_history( historyName, prompt_response )
return
}
else
{
#
# Didn't find any keys that we want to handle so
# just return.
#
return;
}
#
# read the response out of the buffer
#
# index was 0..n-1, it should be 1..n
current_key = 0;
if (max <= 0)
return;
else
{
prompt_response = historyArray[ historyName (historyElement + 1) ];
current_key = -1 # highlight the new prompt response
}
}
# these function are here so historyElement doesn't need to be global
#
function get_history_element()
{
return historyElement
}
## find an item in the command history array
#
global function current_history_item( index, i )
{
i += 0
if (index i in historyArray)
{
i = historyArray[ index i ];
if (i)
return historyArray[ index i ];
}
return "";
}
## add an item to the command history array
#
global function add_prompt_history( index, patt )
{
local i = 0;
local j = 0;
local promptCount = 0;
local found = 0;
setup_prompt_history( index )
# remove the item from list and just add it to the bottom
delete_history_item( index, patt )
promptCount = historyArray[ index i ];
historyArray[ index 0 ] = ++promptCount;
# add patten to end of list
historyArray[ index promptCount ] = patt;
cleanup_prompt_history()
return patt
}
# removes the specified pattern from the history list
function delete_history_item( histName, pattern )
{
local j, i = 1
local promptCount = 0;
local found = 0;
if (histName 0 in historyArray)
promptCount = historyArray[ histName 0 ] + 0
# search the history list for the pattern
#
while (histName i in historyArray && i <= promptCount)
{
if (historyArray[ histName i ] == pattern)
{
found = i;
break
}
i = i + 1;
}
# if the pattern was found, move the item after it up one place
#
if ( found )
{
i = found
while (i < promptCount)
{
j = 1 + i
historyArray[histName i] = historyArray[histName j]
i = i + 1
}
delete historyArray[ histName promptCount ]
historyArray[ histName 0 ] = --promptCount
}
return found
}
function get_history( index )
{
local temp
local i = 0
while ( ++i <= historyArray[index 0] )
{
temp[i] = historyArray[index i]
}
return temp
}
#--------- display list of functions and allow movement within it --------#
## displayFunctionList()
#
# Display all of the functions available which start with
# the pattern specified of at least two characters (zero or one might
# take too long)
#
global symbol_list
local function displayFunctionList(historyName)
{
local i
local fid
local prefix
local result
local searchFor
local numOfEntries
local sorted_symbol_list
local symbolMatchFlag = PRIMITIVE_ALL + GLOBAL_ALL
local width = 20
local listdlg
current_key = 0
# extract question mark
if ( substr( prompt_response, 1, 1 ) == "?" )
{
prefix = "?"
searchFor = substr( prompt_response, 2 )
}
else
{
searchFor = prompt_response
# uncomment the following line to omit variables from
# <F10> command completion (if no "?" is present)
# symbolMatchFlag = PRIMITIVE_FUN + GLOBAL_FUN
}
# in case symbol_match takes a long time
if ( status_bar_flags )
message( "Working..." )
# read a list of all symbols beginning with the specified pattern
if ( length( searchFor ) < 2 )
{
if ( status_bar_flags )
message( "Must type at least two characters." )
beep()
return
}
else if (!(symbol_list = symbol_match( searchFor, symbolMatchFlag )) )
{
if ( status_bar_flags )
message( "no matching symbols found." )
beep()
return
}
if ( status_bar_flags )
message( "" )
# Add emulation-specific commands.
optional_function( tolower(historyName) "_commands", searchFor )
# how many did we get?
for (i in symbol_list)
{
sorted_symbol_list[ symbol_list[i] ] = numOfEntries++
width = max(width, length(symbol_list[i]))
}
if ( numOfEntries == 0 ) # no match
beep()
else if ( numOfEntries == 1 ) # only one match
{
new_response = prefix symbol_list[i]
current_key = KEYCODE_END
}
else
{
# create a dialog box for the list
listdlg = create_selection_dialog( "Command List", width )
# fill the list box
for (i in sorted_symbol_list)
{
#add items to list box
set_dialog_item( listdlg, IDL_LIST, DAC_ADD_ITEM, prefix i )
}
begin_dialog(listdlg)
delete_dialog(listdlg)
}
if ( !new_response )
prompt_response = old_response
else
prompt_response = new_response
delete( symbol_list ) # deallocate the arrays
delete( sorted_symbol_list )
}
#--------- display directory specified and allow movement within it --------#
## displayDirContents()
#
# Display all of the files in the current directory which start with
# the pattern specified of *.* if none.
#
# Maybe add changing directories and other items later.
#
local function displayDirContents( parent )
{
local fname
local numOfEntries = 0 # number of files in current directory
local lastname
local prompt_start
local l,r,c,i
local srchname, tmp
local insert_prev_dir = FALSE
local find_flags, dir_list, file_list
local dirInfo = ""
local maxWidth = 20
local ft, status
local listdlg
prompt_start = prompt_response
l = rindex( prompt_start, "\\" )
r = rindex( prompt_start, "/" )
c = rindex( prompt_start, ":" )
l = l > r ? l : r
l = l > c ? l : c
prompt_start = prefix( prompt_start, l )
#
# read in all of normal file names from the current directory
# and insert them into the current_buffer
#
srchname = prompt_response
if ( (!srchname) || (rindex(srchname, "?") != length( srchname )))
{
tmp = path_ext( srchname )
if ( !tmp )
{
if ( length(path_fname(srchname)) >= 8 )
srchname = srchname ".*"
else
srchname = srchname "*.*"
}
else
{
if ( length(tmp) < 4 )
srchname = srchname "*"
}
}
find_flags = ONLY_SUBDIR # include only directories
# in case directory search takes a long time
if (status_bar_flags)
message( "Working..." )
for (i=0; i < 2; i++)
{
fname = findfirst( srchname, find_flags )
fname = path_fname( fname ) path_ext( fname )
while (fname)
{
if (i == 0)
{
lastname = fname "\\"
if ( edit_file_dir )
{
ft = filetime()
dirInfo = sprintf( " <DIR> %8s %8s %s", dos_date(ft), dos_time(ft), lastname)
}
else
dirInfo = lastname
dir_list[ toupper(lastname) ] = dirInfo
maxWidth = max(length(dirInfo), maxWidth)
}
else
{
lastname = tolower(fname)
if ( edit_file_dir )
{
if ( filesize() >= 0 )
{
ft = filetime()
dirInfo = sprintf( "%7d %8s %8s %s", filesize(), dos_date(ft), dos_time(ft), lastname)
}
}
else
dirInfo = lastname
file_list[ lastname ] = dirInfo
maxWidth = max(length(file_list[lastname]), maxWidth)
}
numOfEntries++
fname = findnext()
}
find_flags = _NORMAL # include normal files
}
if (".\\" in dir_list){
numOfEntries--;
delete( dir_list[ ".\\" ] )
}
if ( numOfEntries == 0 )
{
# no files match the file pattern
if ( status_bar_flags )
message( "No match found." )
current_key = 0;
beep();
return;
}
else if ((numOfEntries == 1) && (!insert_prev_dir))
{
if ( status_bar_flags )
message( "" )
#
# only one file that matched, just set the prompt response
# and return
#
prompt_response = prompt_start lastname;
current_key = KEYCODE_END
return;
}
if ( status_bar_flags )
message( "" )
if (status_bar_flags)
message( "File: " prompt_response )
# create a dialog box with the dir list
listdlg = create_selection_dialog( "File List", maxWidth, dir_list, parent )
# for (i in dir_list)
# {
# # fill the list box
# set_dialog_item( listdlg, IDL_LIST, DAC_ADD_ITEM, dir_list[i] )
# }
# now add the file_list
for (i in file_list)
{
# fill the list box
set_dialog_item( listdlg, IDL_LIST, DAC_ADD_ITEM, file_list[i])
}
begin_dialog(listdlg)
delete_dialog(listdlg)
# new_response won't have a value if we cancelled from
# the above dialog. We will save this value and return it
status = !!new_response
if ( edit_file_dir )
{
if(!status)
prompt_response = old_response
else
prompt_response = prompt_start substr(new_response, 30)
}
else
prompt_response = prompt_start new_response
delete dir_list
delete file_list
return status
}
function displayMatchingBookmark()
{
local count = 0, i, name, pos;
local length = length(prompt_response);
local dhMark, mark_list;
mark_list = build_bookmark_list()
for(name in mark_list)
{
if(substr(name, 1, length) == prompt_response)
{
count++;
}
else
delete mark_list[name]
}
if(count == 1)
{
current_key = KEYCODE_END;
new_response = mark_list[name];
}
else if(count > 1)
{
dhMark = create_selection_dialog("Bookmarks", 0, mark_list);
begin_dialog(dhMark);
delete_dialog(dhMark);
}
else
beep();
if ( !new_response )
prompt_response = old_response
else
{
pos = match(new_response, ":");
prompt_response = substr(new_response, 1, pos-1);
}
}
function prompt_selection(title, width, list, parent, sort)
{
local dlgid = create_selection_dialog(title, width, list, parent, sort)
begin_dialog( dlgid )
delete_dialog( dlgid )
return new_response
}
# The following variables are used as storing results from the
# history list selection dialog. These values are later used
# to set prompt_response depending on how the dialog box was
# ended.
local old_response # response before dialog was invoked
global new_response # response selected from dialog box
function create_selection_dialog(title, width, list, parent, sort)
{
local cursize, i
local dhFile
# if no parent is specified, default to the the prompt_display_handle
if ( !parent )
parent = prompt_display_handle
new_response = ""
old_response = prompt_response
# create a dialog box for the list
#
dhFile = create_dialog( function_id("selection_list_callback"),
parent, IDD_LIST, resource_dll, title )
#add the list box
add_dialog_item( dhFile, IDL_LIST, DCTRL_LIST_BOX )
if (sort == 2)
set_dialog_item( dhFile, IDL_LIST, DAC_SORT_DESCENDING )
else if (sort)
set_dialog_item( dhFile, IDL_LIST, DAC_SORT_ASCENDING )
add_dialog_item( dhFile, DI_OK, DCTRL_DEFAULT_PUSH_BUTTON )
add_dialog_item( dhFile, DI_CANCEL, DCTRL_PUSH_BUTTON )
save_button_positions(dhFile)
if (history_font)
set_dialog_item( dhFile, IDL_LIST, DAC_FONT, history_font+0, FONT_NORMAL)
set_dialog_window( dhFile, DWC_SIZEBORDER )
if ( width )
{
width = min(500, width * 12)
cursize = query_dialog_window(dhFile, DWC_SIZE)
set_dialog_window(dhFile, DWC_SIZE, width, cursize % 65536 )
}
# fill the list box
if ( list )
for (i in list)
set_dialog_item( dhFile, IDL_LIST, DAC_ADD_ITEM, list[i])
return dhFile
}
local select_index = 0
function selection_list_callback()
{
local new_width, new_height
if ( callback_msg == DM_INIT )
{
set_dialog_item(callback_dialog_handle, IDL_LIST, DAC_SETFOCUS)
set_dialog_item(callback_dialog_handle, IDL_LIST, DAC_SELECT_INDEX, select_index)
}
else if ( callback_msg == DM_OK || callback_msg == DM_DOUBLE_CLICK )
{
# get the response from the list box and store in temporary spot
# so we can clean it up if we have to
new_response = query_dialog_item(callback_dialog_handle, IDL_LIST, DAC_SELECT_ITEM )
return DRC_EXIT
}
else if ( ( callback_msg == DM_CLICK && callback_index == DI_CANCEL ) \
|| callback_msg == DM_CANCEL)
{
new_response = ""
return DRC_EXIT
}
else if ( callback_msg == DM_RESIZE )
{
# new size is stored in a long as (short width)(short height)
new_width = callback_data / 65536
new_height = callback_data % 65536
if ( new_width && new_height )
{
# resize list box to match new dialog size
set_dialog_item(callback_dialog_handle, IDL_LIST, DAC_SIZE,
new_width - 40, new_height - 120 )
# Move the buttons for Windows.
if (isWindows())
{
set_dialog_item(callback_dialog_handle, DI_OK, DAC_POSITION,
button_pos[DI_OK] / 65536,
button_pos[DI_OK] % 65536)
set_dialog_item(callback_dialog_handle, DI_CANCEL, DAC_POSITION,
button_pos[DI_CANCEL] / 65536,
button_pos[DI_CANCEL] % 65536)
}
}
return DRC_MSG_PROCESSED
}
return DRC_CONTINUE
}
local button_pos[]
local function save_button_positions(handle)
{
if (isWindows())
{
button_pos[DI_OK] = query_dialog_item( handle, DI_OK, DAC_POSITION)
button_pos[DI_CANCEL] = query_dialog_item( handle, DI_CANCEL, DAC_POSITION)
}
}