home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
m
/
msh21.zip
/
MSHFILES.ZIP
/
STDDEFS.MSH
< prev
next >
Wrap
Text File
|
1992-08-19
|
19KB
|
634 lines
| file: STDDEF.MSH Standard definitions for Mi-Shell
|───────────────────────────────────────────────────────────
|
| ┌─────────────────────────────────────────────┐
| │ utilities to get various parts of a pathname│
| └─────────────────────────────────────────────┘
|
("."cutlast drop)basename!
("."cutlast swap drop)extension!
|
| the following definition tests if top is a substring of top+1
|
(swap dup 3 roll cutfirst drop = not )belong!
|
| Cut a pathname into its unit and the rest.
|
(dup ":"cutfirst dup
(3 roll drop swap":"&swap)
(drop 2 pick =
(false swap)
(false)
ifelse
)
ifelse
)unit_and_name!
|
| Get the directory of a pathname. It is hard because of DOS's dumb syntax.
| examples: "a:x\y" -> "a:x", "a:x\" -> "a:x\.", "a:" -> "a:.", etc...
|
(unit_and_name
dup"\\"cutlast
(dup(swap drop)
(drop drop "\\")
ifelse
)
(drop &".")
ifelse
&
)directory!
|
| A simpler variant which gives the directory part of a pathname, so
| that dirpart&filepart=initial pathname.
| examples: "a:x\y" -> "a:x\", "a:x\" -> "a:x\", "a:" -> "a:", etc...
|
(dup "\\"endsby("."&)if
unit_and_name"\\"cutlast
("\\"&)
(drop"")
ifelse
&
)dirpart!
|
| Get the filename part of a pathname.
|
(unit_and_name swap drop
"\\"cutlast dup
(swap drop)
(drop)
ifelse
)filepart!
|
| makename puts together a directory and a filename. The difficulty is
| to add a '\' when necessary.
|
(2 pick swap cutlast (drop drop false)(match not)ifelse)endsby!
|
(swap
dup "\\" endsby
(dup ":" endsby
("\\"&)ifnot
)
ifnot
swap &
)makename!
|
| ┌─────────────────────────────────┐
| │ various kind of loops on a panel│
| └─────────────────────────────────┘
|
| panels creation
|
(
| display directory panels & main menu
| there is some complicated arithmetic in order to start with
| 3 panels when you have 132 columns!
|
linescols 40 / nb_panels! drop | nb_panels gets 2 if 80 cols, 3 if 132 cols
cwd "*.*" makename dup panel.pattern! | start with pattern:
| current_directory/*.*
1 cnt! | loop from 1 to nb_panels-1 (one panel already exists)
(cnt nb_panels <)
(cnt 1+ cnt! dup panel.install cur_pn!)
while
drop
cur_pn 1+ nb_panels- cur_pn! next_panel | we were on last panel, goback to 1st
)create_panels!
|
| loop_panel: general loop operator. Assumes top is a piece of code and
| executes it for each entry in the panel
|
( action! current.pos oldpos! 0 current.pos!
panel.nbfiles 0 >
((action current.pos 1+ dup current.pos! panel.nbfiles = not)()while)if
oldpos current.pos!
)loop_panel!
|
| deselect: deselect all selected files.
|
((current.selected(false current.selected!)if)loop_panel)deselect!
|
| foreachselected: supposes <Top> is a piece of code taking 1 argument,
| and execute for each selected file that code with the selected
| file as argument (uses current if no file was selected)
|
( s_action! false found!(current.selected(true found! current.name s_action)if)
loop_panel
found (panel.nbfiles 0 >(current.name s_action)if)ifnot
)foreachselected!
|
| foreachbase: same as foreachselected but use the basename as argument.
|
( s_action! false found!
(current.selected(true found! current.name basename s_action)if)loop_panel
found (panel.nbfiles 0 >(current.name basename s_action)if)ifnot
)foreachbase!
|
| selected_list: <Push> the list of selected files, catenated with blanks
| as separators. If nothing was selected, <Push> current.
|
(false slist! (slist swap&" "&slist!)foreachselected slist)selected_list!
|
| next: circular version of down to be used in circular searches
|
(current.pos 1+ dup current.pos! panel.nbfiles=(0 current.pos!)if)next!
|
| search: positions to the first file matching <Top>
|
( current.name
(2 pick current.name match
(false)
(next dup current.name = not)
ifelse
)
()
while
drop
)search!
|
| ┌──────────────────────┐
| │ updates of the panels│
| └──────────────────────┘
|
| refresh refills the panel with the contents of the current directory
|
(cwd panel.pattern filepart makename panel.pattern!)refresh!
|
| reread updates the current panel by rereading from disk (but doesn't
| change its directory to the current one: use refresh for that)
|
(panel.pattern panel.pattern!)reread!
|
| variants which deal with the next panel
|
("panel.on_activate"@oa! ()panel.on_activate! next_panel
#prev_panel oa "panel.on_activate!")in_next_panel!
((reread) in_next_panel)reread_next!
((panel.pattern directory)in_next_panel)next_dir!
|
|
| ┌──────────────────────┐
| │ variants of 'execute'│
| └──────────────────────┘
|
| execshow: show the command in a message window before executing it
|
(dup 600 swap"Executing..." swap flash execute)execshow!
|
| exec: usual variant: just reread after 'execute'
|
(execute reread)exec!
|
| with_magic: do something with `magic' swap enabled
| with_nomagic: do something with magic off
| with_magicnoxms: do something with swap to disk enabled but swap to xms disabled
|
(magic oldmagic!"*"magic! # oldmagic magic!)with_nomagic!
(magic oldmagic!tmp_dir magic! # oldmagic magic!)with_magic!
(magic oldmagic!"*"tmp_dir& magic! # oldmagic magic!)with_magicnoxms!
|
| confirm: ask confirmation before executing command
|
(act! dup ok(act)(drop)ifelse)confirm!
|
| execsave: variant executed by Enter which saves the command on the circular
| list of saved commands before execution
|
( cmd dup cmdlist nl&swap&cmdlist! dup
" "cutfirst drop"."cutfirst drop"*"nl&swap&nl&"*"& dup magic_list match
( drop(execute)with_magic)
( nl"set"&match
("="cutfirst dup(swap " " cutlast swap drop "$"swap& !)
(drop execute)ifelse)
(execute)ifelse
)ifelse
cmd.clear refresh
)execsave!
|
| below is part of the code for Enter.
|
( current.isdir
( current.name cwd! refresh)
( "extension_" current.name extension)
ifelse
)cur_action!
|
("cur_action"panel.type)act_on_cur!
|
(current.isdir
(current.name cwd! refresh)
("extension2_" current.name extension)
ifelse
)act2_on_cur!
|
| ┌───────────────────────────────┐
| │ now, the actions on the panels│
| └───────────────────────────────┘
|
| wide_narrow: flip between complete/name only listing of entries
|
(panel.size(false panel.size! false panel.attrs!
false panel.date! false panel.time!)
(true panel.size! true panel.attrs!
true panel.date! true panel.time!)
ifelse
)wide_narrow!
|
( linescols drop 4/ nb_pn_lines! menu_line 1+ 0 panel.startrc!
nb_pn_lines 79 panel.rc!
(nb_pn_lines menu_line 1++ 0 panel.startrc! nb_pn_lines 79 panel.rc!)
in_next_panel
)top_bottom!
|
(linescols drop 2/ 1- nb_pn_lines! 0 startcol!
( menu_line 1+ startcol panel.startrc!
nb_pn_lines 40 panel.rc! true panel.on!
normal_att current_att selected_att current_selected_att panel.att!
startcol 40+startcol!
)
loop_panels
)side_by_side!
|
(linescols drop 1- nb_pn_lines! 0 startcol!
( menu_line 1+ startcol panel.startrc!
nb_pn_lines 40 panel.rc!
true panel.on!
normal_att current_att selected_att current_selected_att panel.att!
startcol 40+startcol!
)
loop_panels
)full_screen_panels!
|
| the next code executes the action <top> for each panel
|
("panel.on_activate"@oa! ()panel.on_activate!
0 cnt!
(cnt nb_panels <)
(cnt 1+ cnt! dup # next_panel)
while
drop
oa "panel.on_activate!"
)loop_panels!
|
| switches panels on/off
| adapt the following code if you get rid of some of the panels or menus
|
(panel.on
((false panel.on!)loop_panels main_menu_no window.uninstall
drive_menu_no window.uninstall)
((true panel.on!)loop_panels show_menu drive_menu clock)
ifelse
)hide_all!
|
| swap the panels
|
(panel.startrc (panel.startrc 4 roll 4 roll panel.startrc!)in_next_panel
panel.startrc!)swap_panels!
|
|
| Up/Down: move up/down; note that they do prevcmd/nextcmd if panels are off
|
(panel.on(current.pos 0=(beep)(current.pos 1 - current.pos!)ifelse)
(prevcmd)
ifelse
)Up_panel!
|
(panel.on(current.pos panel.nbfiles 1- =(beep)(current.pos 1 + current.pos!)
ifelse)
(nextcmd)
ifelse
)Down_panel!
|
| go up/down one panel-windowfull
|
(current.pos panel.rc drop 2 - - current.pos!)PageUp_panel!
(panel.rc drop 2 - current.pos + current.pos!)PageDown_panel!
|
| goto next/previous panel
|
(panel_directory cwd!)panel.on_activate!
(cur_pn 1 + dup nb_panels>(nb_panels -)if dup cur_pn! window.activate)
next_panel!
(cur_pn 1 - dup 0 le(nb_panels +)if dup cur_pn! window.activate)
prev_panel!
|
( panel.type
(panel.pattern panel.type cutfirst drop panel.type&)
(panel.pattern)
ifelse
directory
)panel_directory!
|
| Expand/Trim current panel
|
(panel.rc swap 3+ swap panel.rc!)expand_panel!
(panel.rc swap 2- swap panel.rc!)trim_panel!
|
| search first file whose beginning matches contents of command line
|
(cmd cmd.clear file_to_search! find_again)find_file!
(file_to_search "*.*"&dup next drop search current.name match(beep)ifnot)find_again!
|
| Replace selection pattern of current.name panel from command line contents
|
(cmd () ("*.*" cmd!) ifelse
panel.pattern dirpart cmd&cmd.clear panel.pattern!)filter_files!
|
| select all files matching command line contents; if the command
| line is empty, select all.
|
(cmd cmd.clear dup(drop "*.*")ifnot
(dup current.name match
(current.isdir (true current.selected!)ifnot)if)loop_panel
drop
)sel_match!
|
| deselect all selected files matching pattern
|
(cmd cmd.clear dup(drop "*.*")ifnot
(dup current.name match(false current.selected!)if)loop_panel
drop
)desel_match!
|
| select/deselect current entry
|
(current.selected not current.selected!)select_on_off!
|
| go up one level in directory hierarchy
|
(".."cwd! refresh)go_up!
|
("go_up"panel.type)up_one_level!
|
| go home
|
(0 current.pos!)go_home!
|
| go to end of list of entries
|
(panel.nbfiles current.pos!)go_end!
|
|
| ┌─────────────────────────────┐
| │ actions on the command line │
| └─────────────────────────────┘
|
| prevcmd/nextcmd: replace command line with previous/next item in circular
| list of saved commands.
|
| first, the variable nl is set to a newline.
"
"nl!
|
(cmdlist nl cutfirst swap drop nl cutfirst nl swap & swap dup the_cmd!
swap nl&swap&cmdlist! cmd.clear the_cmd cmd!)nextcmd!
|
(cmdlist nl cutlast dup the_cmd! nl swap&swap&cmdlist!cmd.clear the_cmd cmd!)
prevcmd!
|
| show the command stack.
|
(tmp!"tmp"@)quote!
(
cmdlist temp!""cmd2!
(temp nl cutlast dup)
(dup "%"swap&"%"&nl&cmd2 swap&cmd2!
quote"("swap&"cmd!)"swap
temp!
)while
drop drop
cmd2 () "-1" "-1" "hv: Command Stack "temp_menu)view_cmdlist!
|
| write 'current' to the command line
|
(current.name " "&cmd!)write_current!
|
| write the selected list to the command line
|
(selected_list deselect cmd!)write_all_selected!
|
| write complete pathname of 'current' of next panel to the command line
|
((panel.pattern dirpart current.name&" "&cmd!)in_next_panel)write_other_current!
|
| add in turn to the command line the basename of each selected file
| and execute the resulting command
|
(cmd CMD!(CMD " "& swap &execshow)foreachbase)run_on_selected!
|
| execute as an MSH script instruction the contents of the command line
|
(cmd cmd.clear#)exec_msh!
|
| display on the command line, ready to be edited, the definition of
| the identifier whose name was on the command line
|
(cmd @cmd&"!"&cmd.clear cmd!)definition!
|
| toggle insert mode
|
(cmd.imode(false cmd.imode!)(true cmd.imode!)ifelse)insert_toggle!
|
|
| ┌───────────────┐
| │ Miscellaneous │
| └───────────────┘
|
|
| the next instruction defines the name of the config file
|
(prog_dir"config.msh"&)cfg_filename!
|
(0 0 linescols page_att page_status_att page_empty_att page_tab_att page)pager!
|
| express a fraction as a percentage
|
(swap 1000 * swap / dup 10 / dup 10 * 3 roll swap - "%" & "." swap &&)percent!
|
|
( cwd "" disk_stats 3 roll bytes_per_cluster!
0 (bytes_per_cluster dup current.size + 1- 2 pick / * +)
loop_panel " bytes occupied by "&panel.nbfiles&" files"&nl&
0 (current.selected(1 +)if)loop_panel | get nr of selected files
dup 0 > | any selected ?
(
0 (current.selected(current.size +)if)loop_panel
" bytes in " & swap &
" selected files"&nl&&
)
(drop) | don't need nr anymore
ifelse
3 pick bytes_per_cluster*" free bytes on drive "&cwd unit_and_name drop&
" ("&4 roll 4 roll percent
")"&&&
message
)panel_stats!
|
|
| ┌─────────────────────────────────────┐
| │ Various kinds of menus and messages │
| └─────────────────────────────────────┘
|
| creates (using a menu) a message window left until deleted
|
(swap title! () "-1" "-1" alert_att alert_att current_selected_att ":"title&
true menu.install)permanent_message!
|
(alert_att save_att! page_att alert_att!message save_att alert_att!)
normal_message!
|
(normal_att current_att current_selected_att 4 roll true menu.install)
permanent_menu!
|
(normal_att current_att current_selected_att 4 roll false menu.install)
temp_menu!
|
((true)(false)3 roll nl&" %yes% %no%"&
(false)"-1" 5 alert_att alert_att current_selected_att true false menu.install)
my_ok!
|
(dup 32 / dup 32 * 3 roll swap - " "&swap
dup 64 / dup 64 * 3 roll swap - dup 10 < ("0"swap&)if":"& 3 roll&swap
dup 32 / dup 32 * 3 roll swap - dup 10 < (" "swap&)if":"& 3 roll&swap
dup 32 / dup 32 * 3 roll swap - dup 10 < (" "swap&)if"/"&swap
dup 16 / dup 16 * 3 roll swap - dup 10 < ("0"swap&)if"/"&swap 80 +&&&
)time_convert!
|
| The next code rereads the config file; this allows you to see the effect
| of any changes you make in it|
|
("config.msh" loaddefs)reconfig!
|
("ascii table" prog_dir"ascii.hlp" makename read normal_message)ascii!
|
("do you want the captured screen to keep video attributes
as ANSI escapes (or a plain text file)" ok
"Please input the filename where the captured screen will be appended
(default is file 'screen' in MSH program directory)" 60 input dup
(drop prog_dir"screen" makename)ifnot
swap capture_screen swap write refresh)capt_screen!
|
(current.name": "¤t.size&" bytes -- last modified "¤t.time
time_convert &)file_stats!
|
(editor selected_list deselect &exec)edit_selected!
|
|
| flip on/off Debug switch
|
(debug not debug!)debug_toggle!
|
((stack_size 0 > ) (drop) while)clean_stack!
|
( "time_menu_no"isdefined(time_menu_no window.uninstall)if
time time_convert ":" cutlast drop () menu_line 0=(73)(75)ifelse menu_line
"" permanent_menu time_menu_no!)show_clock!
("enter time when you want to ring (e.g. 22:13)" 5 input entered_time!
time
dup 32 / dup 32 * 3 roll swap - swap
dup 64 / dup 64 * 3 roll swap - drop entered_time ":" cutfirst! swap drop swap
dup 32 / dup 32 * 3 roll swap - drop entered_time ":" cutfirst! drop swap
dup 32 / dup 32 * 3 roll swap - swap
dup 16 / dup 16 * 3 roll swap - swap
16 * + 32 * + 32 * + 64 * + 32 * + alarm_time!
)set_alarm!
2000000000 alarm_time!
( show_clock
| see if time is larger than alarm_time
alarm_time time < ( beep "alarm" "the alarm you requested for " alarm_time
time_convert & " is up!"&message 2000000000 alarm_time!) if
1000 (clock)timer)clock!
|( show_clock 1000 (clock)timer)clock!
|
| the following extend conveniently the dos commands
|
("copy"panel.type&"to"&(panel.type)in_next_panel)copy_files!
("move"panel.type&"to"&(panel.type)in_next_panel)move_files!
("delete"panel.type)delete_files!
("browse"panel.type)browse_current!
|
(current.name pager)browse!
|
|
( "delete "selected_list& ok
((current.isdir
("rd "swap&(execshow)with_nomagic)
("Deleting..." file_stats permanent_message swap unlink
window.uninstall) ifelse
false current.selected!
)foreachselected reread
)
if
)delete!
( dup testfile dup
(time_convert " bytes -- last modified "swap&
next_bytes_per_cluster dup 4 pick + 1 - swap / size!
&": "swap&&
"overwrite"nl&swap &ok(size)(false)ifelse)(drop drop 0)ifelse
)test_overwrite!
(next_dir dup unit_and_name drop other_drive! panel.pattern directory=
( "warning" "cannot copy files: next panel is the same directory" message)
( "copy "selected_list&" to "&next_dir& ok
( other_drive disk_stats drop next_avail! next_bytes_per_cluster!
( dup next_dir swap makename
"copying..." file_stats permanent_message
3 roll 3 roll dup test_overwrite dup
( next_avail dup 3 roll + next_bytes_per_cluster dup current.size
+ 1 - swap / - dup 0 ge
( next_avail! drop copy)
( drop "warning" swap next_bytes_per_cluster *
": not enough bytes left on drive "&other_drive&" to copy "&
current.name& message drop drop false
)
ifelse
(false current.selected!)if
)
(drop drop drop)
ifelse
window.uninstall
)
foreachselected reread_next
)if
)ifelse
)copyto!
(next_dir dup unit_and_name drop other_drive! panel.pattern directory=
("warning" "cannot move files: next panel is the same directory" message)
( panel.pattern unit_and_name drop other_drive = not different_drives!
"move "selected_list&" to "&next_dir& ok
( other_drive disk_stats drop next_avail! next_bytes_per_cluster!
( dup next_dir swap makename
"moving..." file_stats permanent_message
3 roll 3 roll dup test_overwrite dup
( different_drives
( next_avail dup 3 roll + next_bytes_per_cluster dup current.size
+ 1 - swap / - dup 0 ge
( next_avail! drop copy
( window.uninstall
"deleting..." file_stats permanent_message
current.name unlink
false current.selected!
)if
)
( drop "warning" swap next_bytes_per_cluster *
": not enough bytes left on drive "&other_drive&" to copy "&
current.name& message drop drop
)
ifelse
)
( drop dup unlink rename
(false current.selected!)if
)ifelse
)
(drop drop drop)
ifelse
window.uninstall
)
foreachselected reread reread_next
)if
)ifelse
)moveto!
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||