!++++ ! Below is a slightly modified version of DIRED. ! 1) When you E[xamine] a DIRECTORY, instead of reading the .dir into a ! buffer, it does a DIR on that directory. ! 2) When deleting, it checks to make sure the delete works. ! 3) Format of $DIR command sent to subprocess changed (/nohead/notrail ! added) ! 4) Status line & message formats changed. ! 12-JAN-1987, A WATSON. Modified to become part of EVEPLUS, with errors ! in dired$quit and dired$return_to_DIRED corrected; name changed to ! eve_dired to allow execution with DO key. !---- ! ! Local init procedure to init dired$v_level to 0. ! To be effective, this procedure should be compiled by the EVE_BUILD.COM ! procedure that concatenates all init procs. ! procedure tpu$local_init dired$v_level := 0; endprocedure ! DIRED: a package of routines to delete, examine, etc files in a directory. ! ! GLOBAL VARIABLES REQUIRED: ! dired$v_level integer; must be init to 0 ! ! GLOBAL VARIABLES CREATED: ! dired$v_examining boolean;true when we are EXAMINING a file ! dired$v_temp_memory string; used when going to a new directory. ! dired$v_curpos mark; where you were before you invoked DIRED. ! dired$v_dired_buffer buffer; where the files are listed. ! dired$v_dired_window window; ditto. ! dired$v_deleted_files string; a list of the files you have marked for deletion. ! dired$v_dired_process process;a subprocess which does the DIR and DELETE. ! dired$v_default_dir string; filespec. Not really needed now since the directory command is /nohead/notrail. ! dired$v_help_prog program;what was bound to the help key before invoking DIRED. ! dired$v_help_comment string; the comment associated with the help key before invoking DIRED. ! dired$v_ctrl_z_prog program;what was bound to the ^Z key before invoking DIRED. ! dired$v_ctrl_z_comment string; the comment associated with the ^Z key before invoking DIRED. ! dired$v_dired_position mark; where we are before EXAMINING a file or performing HELP. ! dired$v_dired_view buffer; used to EXAMINE files. ! dired$v_status_line string; The contents of the status line. !- !+ ! dired ! ! DESCRIPTION: ! Invoke the dired directory editor. ! Prompt for a filespec. ! Set the user up in the dired buffer, giving a directory. ! Define the dired keys, and return control to the user. ! ! PARAMETERS: ! none ! ! KEY BINDING: ! none ! ! RETURN VALUE: ! none ! ! SIDE EFFECTS: ! keys are rebound ! a new window is mapped ! status line is changed !- procedure eve_dired local filespec,i,junk; on_error endon_error; if dired$v_level=0 then direde$v_examining := false; dired$v_temp_memory:=""; dired$v_orig_buffer := current_buffer; dired$v_curpos := mark(none); endif; ! get a filespec filespec := read_line("Dired of file? "); if (last_key <> ctrl_m_key) and (last_key <> do) and (last_key <> enter) then return; endif; filespec := file_parse(filespec, "*.*;*"); junk := file_search(' '); ! reset if (filespec = "") or (file_search(filespec)="") then message("DIRED: No files found"); return; endif; dired$v_level := dired$v_level+1; execute("dired$v_memory"+str(dired$v_level)+" := '"+filespec+"';"); ! show the directory dired$get_directory(filespec); endprocedure; ! eve_dired !+ ! dired$get_directory ! ! DESCRIPTION: ! Given a (possibly wild, no-probably wild) filespec, display it in ! dired$v_dired_window. ! ! If the filespec is invalid (that is, no files match the spec), then ! write an error message. ! ! Otherwise, display a directory, with FILES, SIZE=ALL, DATE, and PROTECTION. ! /NOHEAD/NOTRAIL (so that we can pass filespecs like [user...]) ! ! Insert three spaces before every filespec (room for flags.) ! ! PARAMETERS: ! filespec.string.in ! Possibly wildcarded filespec to show in the directory. ! ! KEY BINDING: ! none ! ! RETURN VALUE: ! Either ! null, if no file matches the filespec ! or ! A string in the form "Directory DEV:[DIR]", if some file does ! exactly equivalent to the header line. ! ! SIDE EFFECTS: ! dired$v_dired_window is mapped ! dired$v_dired_process, _window, and _buffer are created, if necessary !- procedure dired$get_directory(filespec) local retval, ! return value (directory string) junk, x; ! record count of dired_buffer on_error endon_error; ! suppress error messages ! create the buffer, if necessary if get_info(dired$v_dired_buffer,"type") <> buffer then dired$v_dired_buffer := create_buffer("DIRED$V_DIRED_BUFFER"); set(eob_text,dired$v_dired_buffer,"[END OF DIRECTORY]"); set(system,dired$v_dired_buffer); set(no_write,dired$v_dired_buffer); else erase(dired$v_dired_buffer); endif; ! create the window, if necessary if get_info(dired$v_dired_window,"type") <> window then dired$v_dired_window := create_window(1, get_info(SCREEN,"visible_length") - 3, on); endif; ! redefine the keys dired$bind_keys; dired$v_deleted_files := ""; ! create the process, if necessary if get_info(dired$v_dired_process,"type") <> process then dired$v_dired_process := create_process(dired$v_dired_buffer); endif; ! now, get a directory into the buffer send("$ dir/size=all/prot/date/notrail/nohead "+ filespec, dired$v_dired_process); retval := filespec ; dired$v_default_dir := filespec; position(beginning_of(dired$v_dired_buffer)); ! now insert three spaces before every line, for room to Flag x := get_info(dired$v_dired_buffer,"record_count"); loop; exitif x = 0; copy_text(" "); move_horizontal(-3); move_vertical(1); x := x - 1; endloop; position(beginning_of(dired$v_dired_buffer)); !now display the buffer map(dired$v_dired_window, dired$v_dired_buffer); dired$set_status_line( "[DIRED] "+retval ); endprocedure; ! dired$get_directory !+ ! dired$ bind_keys ! ! DESCRIPTION: ! Define all the keys to be used when in the dired buffer. ! They are: ! d dired$mark_deleted ! e dired$examine ! h, "?", help dired$help ! n dired$next_line ! p dired$previous_line ! q dired$quit ! u,space dired$unmark_deleted ! ! PARAMETERS: ! none ! ! KEY BINDING: ! none ! ! RETURN VALUE: ! none ! ! SIDE EFFECTS: ! none !- procedure dired$bind_keys local info; dired$v_help_prog := lookup_key(help, program); dired$v_help_comment := lookup_key(help, comment); dired$v_ctrl_z_prog := lookup_key(ctrl_z_key, program); dired$v_ctrl_z_comment := lookup_key(ctrl_z_key, comment); info := get_info(system,"informational"); set(informational, off); define_key("dired$help", help); define_key("dired$unmark_deleted", key_name(" ")); define_key("dired$help", key_name("?")); define_key("dired$mark_deleted", key_name("d")); define_key("dired$mark_deleted", key_name("D")); define_key("dired$examine", key_name("e")); define_key("dired$examine", key_name("E")); define_key("dired$help", key_name("h")); define_key("dired$help", key_name("H")); define_key("dired$next_line", key_name("n")); define_key("dired$next_line", key_name("N")); define_key("dired$previous_line", key_name("p")); define_key("dired$previous_line", key_name("P")); define_key("dired$quit", key_name("q")); define_key("dired$quit", key_name("Q")); define_key("dired$unmark_deleted", key_name("u")); define_key("dired$unmark_deleted", key_name("U")); define_key("dired$return_to_dired", ctrl_z_key); if info then set(informational, on); endif; message("DIRED: type ? for list of DIRED commands"); endprocedure; ! dired$ bind_keys; !+ ! dired$unbind_keys ! ! DESCRIPTION: ! Remove the bindings given by dired$ bind_keys ! ! PARAMETERS: ! none ! ! KEY BINDING: ! none ! ! RETURN VALUE: ! none ! ! SIDE EFFECTS: ! none !- procedure dired$unbind_keys local info; info := get_info(system,"informational"); set(informational, off); undefine_key(key_name(" ")); undefine_key(key_name("?")); undefine_key(key_name("d")); undefine_key(key_name("D")); undefine_key(key_name("e")); undefine_key(key_name("E")); undefine_key(key_name("h")); undefine_key(key_name("H")); undefine_key(key_name("n")); undefine_key(key_name("N")); undefine_key(key_name("p")); undefine_key(key_name("P")); undefine_key(key_name("q")); undefine_key(key_name("Q")); undefine_key(key_name("u")); undefine_key(key_name("U")); define_key(dired$v_help_prog, help, dired$v_help_comment); if info then set(informational, on); endif; endprocedure; ! dired$unbind_keys; !+ ! dired$quit ! ! DESCRIPTION: ! Invoked to exit from dired. ! Maybe delete the files marked for deletion. ! Unbind the keys. ! Position to where we were before invoking dired. ! ! PARAMETERS: ! none ! ! KEY BINDING: ! Q, q ! ! RETURN VALUE: ! none ! ! SIDE EFFECTS: ! none !- procedure dired$quit local temp; ! For name of buffer to return to dired$maybe_delete_files; dired$v_level := dired$v_level - 1; if dired$v_level<=0 then dired$unbind_keys; define_key("exit",ctrl_z_key,"Exit"); temp := get_info(dired$v_orig_buffer,"name"); eve_buffer(temp); ! unmap(dired$v_dired_window); position(dired$v_curpos); update(current_window); message("Returning to EVE editor"); else message("Returning to previous directory level"); execute("dired$v_temp_memory := dired$v_memory"+str(dired$v_level)+" ;"); dired$get_directory(dired$v_temp_memory); endif; endprocedure; ! dired$quit !+ ! dired$next_line ! ! DESCRIPTION: ! Move the next valid line on the screen. ! ! PARAMETERS: ! none ! ! KEY BINDING: ! N, n ! ! RETURN VALUE: ! none ! ! SIDE EFFECTS: ! none !- procedure dired$next_line local x; on_error endon_error; move_horizontal(-current_offset); ! go to beginning of line move_vertical(1); ! go down one line if end_of(dired$v_dired_buffer) = mark(none) then ! at end of buffer? move_vertical(-1); ! oops, go up one line return; ! and return endif; x := search(line_begin & " ", forward); ! at non-filespec line? if x = 0 then ! no, return return; endif; if beginning_of(x) = mark(none) then ! yes, so move_vertical(1); ! move down another line endif; if end_of(dired$v_dired_buffer) = mark(none) then ! at end of buffer? move_vertical(-2); ! oops, go up two lines return; ! and return endif; endprocedure; ! dired$next_line !+ ! dired$previous_line ! ! DESCRIPTION: ! Move to the previous valid line on the screen ! ! PARAMETERS: ! none ! ! KEY BINDING: ! P, p ! none ! ! RETURN VALUE: ! none ! ! SIDE EFFECTS: ! none !- procedure dired$previous_line local x; on_error endon_error; move_horizontal(-current_offset); ! go to beginning of line if beginning_of(dired$v_dired_buffer) = mark(none) then ! at beg. of buffer? return; ! return endif; move_vertical(-1); ! go up one line x := search(line_begin & " ", forward); ! at non-filespec line? if x = 0 then ! no, return return; endif; if beginning_of(x) = mark(none) then ! yes, so move_vertical(-1); ! move up another line endif; endprocedure; ! dired$previous_line !+ ! dired$current_line ! ! DESCRIPTION: ! Move to 'beginning' of current line (one with valid filespec on it.) ! ! PARAMETERS: ! none ! ! KEY BINDING: ! none ! ! RETURN VALUE: ! none ! ! SIDE EFFECTS: ! none !- procedure dired$current_line local x; on_error endon_error; move_horizontal(-current_offset); if end_of(dired$v_dired_buffer) = mark(none) then move_vertical(-1); endif; x := search(line_begin & " ", forward); if x <> 0 then if mark(none) = beginning_of(x) then move_vertical(-1); endif; endif; endprocedure; ! dired$current_line !+ ! dired$mark_deleted ! ! DESCRIPTION: ! Mark the file on the current line as deleted. ! Add the file's name to the list of those marked as deleted. ! ! PARAMETERS: ! none ! ! KEY BINDING: ! D, d ! none ! ! RETURN VALUE: ! none ! ! SIDE EFFECTS: ! none !- procedure dired$mark_deleted local filespec,junk; on_error endon_error; ! get the file dired$current_line; filespec := file_parse(dired$get_current_filespec,dired$v_default_dir); junk := file_search("sys$disk:[]."); ! reset search if file_search(filespec) = "" then message("DIRED: Directory listing corrupted(Mark)"); return; endif; junk := search("D", forward); if junk <> 0 then if beginning_of(junk) <> mark(none) then ! if it isn't deleted already erase_character(1); ! then mark it. copy_text("D"); dired$v_deleted_files := dired$v_deleted_files+filespec+" "; ! and add it to the list endif; endif; dired$next_line; endprocedure; ! dired$mark_deleted !+ ! dired$unmark_deleted ! ! DESCRIPTION: ! Remove the delete mark on the current line, if any. ! ! PARAMETERS: ! none ! ! KEY BINDING: ! U, u ! none ! ! RETURN VALUE: ! none ! ! SIDE EFFECTS: ! none !- procedure dired$unmark_deleted local filespec, junk, x; ! position of filespec in dired$v_deleted_files ! get a file dired$current_line; filespec := file_parse(dired$get_current_filespec,dired$v_default_dir); junk := file_search("sys$disk:[]."); ! reset search if file_search(filespec) = "" then message("DIRED: Directory listing corrupted(Unmark)"); return; endif; junk := search(" ", forward); if junk <> 0 then if beginning_of(junk) <> mark(none) then ! if it isn't unmarked, then erase_character(1); ! unmark it copy_text(" "); x := index(dired$v_deleted_files, filespec); if x <> 0 then ! and remove it from the list dired$v_deleted_files := substr(dired$v_deleted_files, 1, x-1) + substr(dired$v_deleted_files, x + length(filespec) + 1, 999); endif; endif; endif; dired$next_line; endprocedure; ! dired$unmark_deleted !+ ! dired$examine ! ! DESCRIPTION: ! Examine the file on the current line. ! Remove the keybindings, and bind ctrl-z to a return to dired function. ! Do a find file for the current filespec. ! Unmap the dired window. ! ! PARAMETERS: ! none ! ! KEY BINDING: ! E, e ! none ! ! RETURN VALUE: ! none ! ! SIDE EFFECTS: ! none !- procedure dired$examine local filenode, filedevi, filedire, filename, filetype, filevers, filespec, info, junk; ! get the filename we want to examine filespec := dired$get_current_filespec; junk := file_search("sys$disk:[]."); if file_search(file_parse(filespec, dired$v_default_dir)) = "" then message("DIRED: Directory listing corrupted(Examine)"); return; endif; !+ ! Here is the place to check the TYPE and VERSION of the ! file the user has asked to EXAMINE. If it is ".DIR;1", then PUSH ! the current file spec and do a DIRED instead of EXAMINE. !- filetype := file_parse(filespec,dired$v_default_dir,"",TYPE); filevers := file_parse(filespec,dired$v_default_dir,"",VERSION); if ( (filetype+filevers)=".DIR;1" ) then ! filespec is currently in the form: ! [node::]device:[directory]name.type;vers ! we want to change that to: ! [node::]device:[directory.name] filenode := file_parse(filespec,dired$v_default_dir,"",NODE); filedevi := file_parse(filespec,dired$v_default_dir,"",DEVICE); filedire := file_parse(filespec,dired$v_default_dir,"",DIRECTORY); filename := file_parse(filespec,dired$v_default_dir,"",NAME); filespec := substr(filedire,1,length(filedire)-1)+"."+filename+"]"; dired$v_level := dired$v_level + 1; execute("dired$v_memory"+str(dired$v_level)+":= '"+filespec+"';"); dired$get_directory(filespec); else dired$v_examining := true; ! get the normal keys back dired$unbind_keys; ! remember where we are in dired buffer dired$v_dired_position := mark(none); ! create the view buffer, if necessary if get_info(dired$v_dired_view,"type") <> buffer then dired$v_dired_view := create_buffer("DIRED$V_DIRED_VIEW"); set(eob_text,dired$v_dired_view,"[EOB]"); set(system,dired$v_dired_view); set(no_write,dired$v_dired_view); else erase(dired$v_dired_view); endif; ! get into the dired view buffer position(beginning_of(dired$v_dired_view)); filespec := read_file(file_parse(filespec, dired$v_default_dir)); position(beginning_of(dired$v_dired_view)); map(dired$v_dired_window, dired$v_dired_view); ! revamp the status line dired$v_status_line := get_info(dired$v_dired_window, "status_line"); set(output_file, dired$v_dired_view, filespec); dired$set_status_line("[DIRED View] File "+filespec); ! inform user that we are sub-dired message("DIRED: Use ^Z to return to DIRED"); endif; endprocedure; ! dired$examine !+ ! dired$return_to_dired ! ! DESCRIPTION: ! Restore the ^Z key definition. ! Restore the dired bindings. ! Map the dired window again, and position there. ! ! PARAMETERS: ! none ! ! KEY BINDING: ! ^Z when dired$examine is in effect ! ! RETURN VALUE: ! none ! ! SIDE EFFECTS: ! none !- procedure dired$return_to_dired !+ ! If we are actually doing an EXAMINE, then we want to rebind the keys. ! Otherwise, we just want to POP one level. If we are at 0, then this ! becomes the same as a QUIT. !- IF dired$v_examining then dired$v_examining := false ; ! re bind the keys dired$bind_keys; ! go back to dired window, position map(dired$v_dired_window, dired$v_dired_buffer); position(dired$v_dired_position); ! revamp status line dired$set_status_line( dired$v_status_line ); else !+ ! Just POP a level... We have to be at least 1. !- dired$v_level := dired$v_level - 1; if dired$v_level=0 then dired$quit; else execute("dired$v_temp_memory := dired$v_memory"+str(dired$v_level)+" ;"); dired$get_directory(dired$v_temp_memory); endif; endif; endprocedure; ! dired$return_to_dired !+ ! dired$get_current_filespec ! ! DESCRIPTION: ! Return the filespec on the current line. Used from dired$examine, ! dired$mark_deleted, and dired$unmark_deleted. ! ! PARAMETERS: ! none ! ! KEY BINDING: ! none ! ! RETURN VALUE: ! a string containing the filespec on the current 'valid' line ! ! SIDE EFFECTS: ! none !- procedure dired$get_current_filespec local x, ! temporary var y, junk, ! other temporaries retval; ! return value on_error endon_error; dired$current_line; move_horizontal(3); x := search(scan(" "),forward); y := search(line_begin, forward); if y <> 0 then if beginning_of(x) = beginning_of(y) then retval := substr(current_line, 4, 999); else retval := substr(x, 1, length(x)); endif; else retval := substr(x, 1, length(x)); endif; move_horizontal(-3); return retval; endprocedure; ! dired$get_current_filespec !+ ! dired$maybe_delete_files ! ! DESCRIPTION: ! If there are no files marked for deletion, then return. ! Display the list of files marked for deletion, in a nice format. ! If there are any files to be deleted, then ! ask for confirmation of deletion. ! If confirmed, then ! delete the files. ! ! PARAMETERS: ! none ! ! KEY BINDING: ! Q ! ! RETURN VALUE: ! none ! ! SIDE EFFECTS: ! possibly DELETES FILES!!!!!! Dangerous Function!!! !- procedure dired$maybe_delete_files local x, foo, ans, temp; if dired$v_deleted_files = "" then return; endif; erase(dired$v_dired_buffer); position(beginning_of(dired$v_dired_buffer)); copy_text("The following files have been marked as deleted: "); split_line; split_line; temp := dired$v_deleted_files; loop; x := index(temp, " "); copy_text(" " + substr(temp, 1, x-1)); split_line; temp := substr(temp, x+1, 999); exitif temp = ""; endloop; split_line; set(eob_text,dired$v_dired_buffer,"[END OF DELETED FILES]"); position(beginning_of(dired$v_dired_buffer)); update(dired$v_dired_window); ans := read_line("Delete files? ", 1); !+ ! I don't understand this stuff... !if get_info(ans, "type") <> integer then ! return; !endif; ! !if (ans <> key_name("Y")) and (ans <> key_name("y")) then ! return; !endif; !- if (ans <> "Y") and (ans <> "y") then return; endif; temp := dired$v_deleted_files; loop; x := index(temp, " "); message("DIRED: Deleting "+ substr(temp,1,x-1)); send("$ delete/nolog "+ substr(temp,1,x-1), dired$v_dired_process); foo := file_search(" "); foo := file_search(substr(temp,1,x-1)); if foo<>"" then message("DIRED: error deleting file: "+substr(temp,1,x-1)); endif; temp := substr(temp, x+1, 999); exitif temp = ""; endloop; endprocedure; ! dired$maybe_delete_files !+ ! dired$help ! ! DESCRIPTION: ! Give help to users for the DIRED functions. ! Uses DIRED_VIEW buffer. ! Help file is contained in copy_text statements.... ! Prompts for a key to return to DIRED. ! ! PARAMETERS: ! none ! ! KEY BINDING: ! ?, H, h, and Help_key ! ! RETURN VALUE: ! none ! ! SIDE EFFECTS: ! Trashes dired_view buffer. !- procedure dired$help local junk; ! remember where we are in dired buffer dired$v_dired_position := mark(none); ! create the view buffer, if necessary if get_info(dired$v_dired_view,"type") <> buffer then dired$v_dired_view := create_buffer("DIRED$V_DIRED_VIEW"); set(eob_text,dired$v_dired_view,"[No more help available]"); set(system,dired$v_dired_view); set(no_write,dired$v_dired_view); else erase(dired$v_dired_view); endif; ! get into the dired view buffer position(beginning_of(dired$v_dired_view)); ! create the text copy_text("DIRED: Directory Editor"); split_line;split_line; copy_text("n Next Line"); split_line; copy_text("p Previous Line"); split_line; copy_text("d Mark this line's file for deletion"); split_line; copy_text("u,space Undelete this line's file"); split_line; copy_text("e Examine this line's file"); split_line; copy_text("q Quit Dired (confirm deletions)"); split_line; copy_text("h,? Give help on dired(this text)"); split_line; split_line; copy_text("When you E[xamine] a file whose type and version are '.DIR;1',"); split_line; copy_text("you will, in effect, be doing a DIRED of that [sub]directory"); split_line; split_line; copy_text(" Other keys perform their usual functions."); split_line; ! map the window position(beginning_of(dired$v_dired_view)); map(dired$v_dired_window, dired$v_dired_view); ! revamp the status line dired$v_status_line := get_info(dired$v_dired_window, "status_line"); dired$set_status_line("[DIRED Help]"); ! display the window, and get a key update(dired$v_dired_window); junk := read_line("Press any key to return to DIRED",1); ! go back to dired window, position map(dired$v_dired_window, dired$v_dired_buffer); position(dired$v_dired_position); ! revamp status line dired$set_status_line(dired$v_status_line); endprocedure; ! dired$help !+ ! dired$set_status_line ! ! DESCRIPTION: ! Set the status line. ! ! PARAMETERS: ! buffername.string.in ! what to put on the status line. ! ! KEY BINDING: ! None. ! ! RETURN VALUE: ! None. ! ! SIDE EFFECTS: ! Status line updated. !- procedure dired$set_status_line( buffername ) !+ ! Changed slightly from original; made status line bold and reverse instead ! of just reverse !- set(status_line, dired$v_dired_window, none, buffername); set(status_line, dired$v_dired_window, bold, buffername); set(status_line, dired$v_dired_window, reverse, buffername); endprocedure