% -*- SLang -*- dired.sl
%
% Simple dired mode for JED.
%
%
% To invoke Dired, do `C-x d' or `M-x dired'.
%
% Moving around
% =============
%
% All the usual motion commands plus some extras:
%
% `C-n' `n' SPC
% move point to the next line (at the beginning of the file name)
%
% `C-p' `p'
% move point to the previous line (at the beginning of the file name)
%
% DEL
% move up and unflag
%
% `^K'
% dired_kill_line - removes a line from the dired buffer
% (This must be set from the dired hook)
%
% ==============
%
% The primary use of Dired is to "flag" files for deletion and then
% delete the previously flagged files.
%
% `d'
% Flag this file for deletion.
%
% `u'
% Remove deletion flag on this line.
%
% `DEL'
% Move point to previous line and remove the deletion flag on that
% line.
%
% `~'
% Flag all backup files (files whose names end with `~') for deletion
%
% `g'
% Update the entire contents of the Dired buffer
%
% Deleting Files
% ==============
%
% `x'
% expunge all flagged files. Displays a list of all the file names
% flagged for deletion, and requests confirmation with `yes'.
% After confirmation, all the flagged files are deleted and then
% their lines are deleted from the Dired buffer.
%
% File Manipulations
% ==================
%
% `f'
% Visit the file described on the current line, like typing `C-x C-f'
% and supplying that file name
%
% `v'
% View the file described on the current line
%
% `r'
% rename - prompts for a new name for the file on the current line
%
% 'm'
% move - move a group of flagged files to an new directory
%
% `M-x dired_search'
% use fsearch with the contents of LAST_SEARCH to perform a search
% through the files listed in the dired buffer from the current point
% forward. Since it stops in the file where the search string is
% encountered, it is structured so that `M-x dired_search' from the
% visited file will revert back to the dired buffer and continue the
% dired_search from the next file in the list.
%
variable Dired_Buffer = "*dired*";
variable Dired_Current_Directory;
!if (keymap_p (Dired_Buffer)) make_keymap (Dired_Buffer);
definekey ("dired_find", "\r", Dired_Buffer);
definekey ("dired_find", "f", Dired_Buffer);
definekey ("dired_view", "v", Dired_Buffer);
definekey ("dired_tag", "d", Dired_Buffer);
definekey (".1 dired_untag", "u", Dired_Buffer);
definekey ("dired_move", "m", Dired_Buffer);
definekey ("dired_delete", "x", Dired_Buffer);
definekey (".1 dired_point", "^N", Dired_Buffer);
definekey (".1 dired_point", "n", Dired_Buffer);
definekey (".1 dired_point", " ", Dired_Buffer);
definekey (".1 chs dired_point", "^P", Dired_Buffer);
definekey (".1 chs dired_point", "p", Dired_Buffer);
#ifdef UNIX
definekey (".1 chs dired_untag", "^?", Dired_Buffer); % DEL key
#elifdef IBMPC_SYSTEM
definekey (".1 chs dired_untag", "\xE0S",Dired_Buffer); % DELETE
definekey (".1 chs dired_untag", "\eOn", Dired_Buffer); % DELETE
#endif
definekey ("dired_flag_backup", "~", Dired_Buffer);
definekey ("dired_rename", "r", Dired_Buffer);
definekey ("dired_reread_dir", "g", Dired_Buffer);
definekey ("describe_mode", "h", Dired_Buffer);
definekey ("dired_quick_help", "?", Dired_Buffer);
definekey ("dired_quit", "q", Dired_Buffer);
define dired_quit ()
{
delbuf (Dired_Buffer);
}
#ifdef VMS
% takes somthing like dev:[a.b.c] and converts it to dev:[a.b]c.dir
define dired_vms_dir (dir)
{
variable cdir = Null_String, last = Null_String, this;
variable n, file, ch;
n = strlen (dir);
if (int (substr (dir, n, 1)) != ']') return dir;
forever
{
n--;
!if (n) break;
ch = int (substr (dir, n, 1));
if ((ch == '.') or (ch == '[')) break;
}
if (ch == '[')
substr (dir, 1, n) + "000000]";
else
substr (dir, 1, n - 1) + "]";
cdir = ();
file = substr (dir, n + 1, strlen (dir));
file = substr (file, 1, strlen (file) - 1) + ".dir";
cdir + file;
}
#endif
define dired_read_dir (dir)
{
variable file, flags, spaces = " ";
#ifdef VMS
dir = dired_vms_dir (dir);
#elifdef IBMPC_SYSTEM
dir = expand_filename (dir);
# ifdef MSDOS MSWINDOWS
dir = msdos_fixup_dirspec (dir);
# endif
#endif
if ( file_status (dir) == 2 )
{
(Dired_Current_Directory,) = parse_filename (dircat (dir, Dired_Buffer));
#ifdef VMS
dir = Dired_Current_Directory;
#endif
}
else
{
(Dired_Current_Directory,dir) = parse_filename (dir);
}
if ( change_default_dir (Dired_Current_Directory) )
error ("Failed to chdir.");
sw2buf (Dired_Buffer);
(file,,,flags) = getbuf_info ();
setbuf_info (file, Dired_Current_Directory, Dired_Buffer, flags);
set_status_line (" DIRED: %b (%m%n) (%p) | press '?' for help.", 0);
set_readonly (0);
erase_buffer ();
use_keymap (Dired_Buffer);
set_mode ("dired", 0);
#ifdef UNIX
shell_cmd (sprintf ("ls -al %s 2>/dev/null", dir));
#elifdef MSDOS WIN16
shell_cmd (sprintf ("dir %s /l/ogne", dir));
#elifdef WIN32
shell_cmd (sprintf ("dir %s /ogne", dir));
% shell_cmd (Sprintf ("(dir %s /l/ogne) 2>&1", dir, 1));
#elifdef OS2
shell_cmd ("dir /n " + dir);
#elifdef VMS
shell_cmd ("directory/size/date/prot/notrail " + dir);
#endif
bob ();
#ifdef OS2
% kill 4 lines of header junk and 2 lines of trailer junk
push_mark (); go_down (4);
if ( eolp () )
go_down_1 ();
del_region ();
eob (); push_mark ();
go_up (3); % implicit eol();
del_region ();
bob ();
#elifdef MSDOS MSWINDOWS
push_mark (); go_down (5); del_region (); % header junk
eob (); push_mark (); % trailer junk
if ( bsearch ("bytes free") )
{
go_down_1 ();
del_region ();
}
else
{
pop_mark_0 ();
}
bob ();
#elifdef VMS
push_mark (); go_down (3); del_region ();
#endif
do
{
insert (spaces);
}
while (down_1 ());
bob ();
#ifdef UNIX
if ( looking_at (" total "))
delete_line ();
#endif
insert ("== ");
insert (Dired_Current_Directory);
newline ();
set_buffer_modified_flag (0); set_readonly(1);
flush ("");
}
variable Dired_Quick_Help;
Dired_Quick_Help = "d:tag file, u:untag, x:delete tagged files, r:rename, h:more help, ?:this help";
define dired_quick_help ()
{
message (Dired_Quick_Help);
}
define dired_reread_dir ()
{
dired_read_dir (Dired_Current_Directory);
}
% set the point at the start of the file name
define dired_point (dirn)
{
if (dirn > 0) go_down_1 (); else if (dirn < 0) go_up_1 ();
#ifdef UNIX
bol_skip_white ();
if (looking_at_char ('l'))
{
() = ffind ("->");
bskip_white ();
}
else eol ();
bskip_chars ("^ ");
#elifdef OS2
eol ();
if (bfind_char (' ')) go_right_1 ();
#elifdef VMS MSDOS WIN16
bol (); go_right (2);
#elifdef WIN32
eol ();
bskip_chars ("^ ");
#endif
}
#ifndef VMS
define dired_kill_line ()
{
bol ();
if ( bobp () ) return; % do not remove top line
set_readonly (0);
push_mark (); go_down_1 ();
del_region ();
set_buffer_modified_flag (0);
set_readonly (1);
dired_point (0);
}
#endif
% (name, type) = dired_getfile ()
%
% name = name of file or directory
%
% type = 0 : nothing
% type = 1 : file
% type = 2 : directory
% type = 3 : link
define dired_getfile ()
{
variable name, type, ext, stat_buf;
bol ();
type = not (bobp ()); % assume it will be a file
#ifdef UNIX
if (type)
{
go_right (2);
if (looking_at_char ('l')) type = 3;
else if (looking_at_char ('d')) type = 2;
else
{
skip_white ();
if ( what_column () > 3 ) type = 0;
}
}
!if ( type )
{
bol ();
return (Null_String, type);
}
dired_point (0);
if (type != 3)
{
push_mark_eol (); % extract the name
name = bufsubstr (); % the name
}
else
{
go_right (ffind (" ->"));
skip_white ();
push_mark_eol ();
name = bufsubstr ();
stat_buf = stat_file (name);
if (stat_buf != NULL)
{
if (stat_is ("dir", stat_buf.st_mode)) type = 2;
else if (stat_is ("reg", stat_buf.st_mode)) type = 1;
}
}
#elifdef VMS
if (type)
{
go_right (2);
if ( ffind ( ".DIR" ) )
{
type = 2;
}
else
{
skip_white ();
if ( what_column () > 3 )
type = 0;
}
}
!if ( type )
{
bol ();
return (Null_String, type);
}
dired_point (0);
push_mark ();
() = ffind_char (';');
skip_chars (";0-9");
name = bufsubstr (); % leave on the stack
#elifdef IBMPC_SYSTEM
if ( type )
{
go_right (2);
if ( ffind ("
") )
{
type = 2;
}
else
{
% Following used to just be what was in the #ifndef OS2..#endif. Prolly
% can be changed to just whats in the #ifdef OS2..#endif. This is a fix
% for OS/2 handling MDJ 06/11/95
# ifdef OS2
if ( eolp () or what_column () > 4 )
type = 0;
# else
if ( eolp () or what_column () > 3 )
type = 0;
# endif
}
}
!if ( type )
{
bol ();
return (Null_String, type);
}
# ifdef OS2
eol (); bskip_white ();
push_mark ();
() = bfind_char (' ');
go_right_1 (); % Added to fix space at start of filename MDJ 06/11/95
name = bufsubstr ();
# elifdef WIN32
dired_point (0);
push_mark_eol ();
name = bufsubstr ();
# else
dired_point (0);
push_mark (); % extract the name
skip_chars ("^ "); % skip past name
name = bufsubstr (); % the name
skip_white ();
if ( what_column () <= 12 )
{
push_mark ();
skip_chars ("^ "); % skip past ext
ext = bufsubstr ();
if (strlen (ext) or (type != 2))
name = sprintf ("%s.%s", name, ext);
}
# endif
#endif
dired_point (0);
return (name, type);
}
define dired_tag ()
{
variable type;
EXIT_BLOCK { dired_point (1); }
(, type) = dired_getfile ();
if ( type != 1 ) return; % only files!
set_readonly (0);
bol ();
insert_char ('D'); del ();
set_buffer_modified_flag (0);
set_readonly (1);
}
define dired_untag (dirn)
{
if ( dirn < 0 )
{
!if ( up_1 () ) error ("Top of Buffer.");
}
bol ();
if ( looking_at_char ('D') )
{
set_readonly (0);
insert_char (32); del ();
set_buffer_modified_flag (0);
set_readonly (1);
}
if ( dirn > 0 )
dired_point (1);
}
% perform operation on tagged files--- 4 parameters
define dired_xop_tagged_files (prompt, msg, op_function)
{
variable lbuf = " *Deletions*";
variable stack, n, fails = Null_String;
variable file;
setbuf (Dired_Buffer);
push_spot_bob ();
stack = _stkdepth; % save stack depth
ERROR_BLOCK
{
_pop_n ( _stkdepth - stack );
sw2buf (Dired_Buffer);
set_readonly (0);
bob ();
while ( bol_fsearch_char ('%') )
{
insert_char ('D'); del ();
}
pop_spot ();
set_buffer_modified_flag (0); set_readonly (1);
}
set_readonly (0);
while ( bol_fsearch_char ('D') )
{
insert_char ('%'); del ();
dired_getfile ();
pop (); % pop type, leave name on stack
}
n = _stkdepth - stack;
!if (n) error ("No tags!");
sw2buf (lbuf);
erase_buffer ();
loop (n)
{
insert (); % tagged files on stack
newline ();
}
bob ();
buffer_format_in_columns ();
if ( get_yes_no (prompt) == 1)
{
sw2buf (Dired_Buffer);
bob ();
while ( bol_fsearch_char ('%') )
{
(file,) = dired_getfile ();
bol ();
push_spot ();
file = dircat (Dired_Current_Directory, file);
if (@op_function (file) )
{
pop_spot ();
flush (msg + file);
push_mark ();
go_down_1 ();
del_region (); go_left_1 ();
}
else
{
pop_spot ();
fails += " " + file;
insert_char (32); del ();
}
}
}
EXECUTE_ERROR_BLOCK;
if ( strlen (fails) )
message ("Operation Failed:" + fails);
}
define dired_delete ()
{
dired_xop_tagged_files ("Delete these files", "Deleted ", &delete_file);
}
variable Dired_Move_Target_Dir;
define dired_do_move (file)
{
variable name;
(name,) = dired_getfile ();
name = dircat (Dired_Move_Target_Dir, name);
not (rename_file (file, name));
}
define dired_move ()
{
Dired_Move_Target_Dir = read_file_from_mini ("Move to dir");
if ( file_status (Dired_Move_Target_Dir) != 2 )
error ("Expecting directory name");
"Move these to " + Dired_Move_Target_Dir;
dired_xop_tagged_files ((), "Moved ", &dired_do_move);
}
#ifndef VMS
define dired_flag_backup ()
{
variable name, type;
push_spot_bob (); set_readonly (0);
while ( fsearch_char ( '~' ) )
{
(name, type) = dired_getfile ();
if ( (type == 1) and (string_match (name, "~", strlen(name))) )
{
bol ();
insert_char ('D'); del (); % is a backup file
}
eol ();
}
pop_spot ();
set_buffer_modified_flag (0);
set_readonly (1);
}
#endif
define dired_rename ()
{
variable oldf, type, len, f, n, nf, nd, od, status;
(oldf, type) = dired_getfile ();
!if ( type ) return;
sprintf ("Rename %s to", oldf);
n = read_file_from_mini (());
%
% If new name is a dir, move it to the dir with oldname.
% If file is not a directory and exists, signal error.
%
status = file_status (n);
if ( status == 1 ) error ("File exists. Not renamed.");
else if ( status == 2 ) n = dircat (n, oldf);
%
% Check to see if rename to new directory
%
(nd,nf) = parse_filename (n);
f = dircat (Dired_Current_Directory, oldf);
(od,) = parse_filename (f);
if ( rename_file (f, n) ) error ("Operation Failed!");
set_readonly (0);
#ifdef UNIX
if ( strcmp (od, nd) )
#elifdef VMS IBMPC_SYSTEM
if ( strcmp (strup (od), strup (nd)) )
#endif
{
delete_line ();
}
else
{
dired_point (0);
push_mark ();
#ifdef MSDOS MSWINDOWS
go_right (12); del_region ();
variable nf1 = extract_element (nf, 1, '.');
if (nf1 == NULL) nf1 = "";
vinsert ("%-8s %-3s",
extract_element (nf, 0, '.'),
nf1);
#else
go_right (strlen (oldf)); del_region ();
insert (nf);
#endif
}
dired_point (1);
set_buffer_modified_flag (0);
set_readonly (1);
}
%!%+
%\function{dired}
%\synopsis{dired}
%\description
% Mode designed for maintaining and editing a directory.
%
% To invoke Dired, do \var{M-x dired} or \var{C-x d} (emacs)
%
% Dired will prompt for a directory name and get a listing of files in the
% requested directory.
%
% The primary use of Dired is to "flag" files for deletion and then delete
% the previously flagged files.
%
% \var{d} Flag this file for deletion.
% \var{u} Remove deletion flag on this line.
% DEL Move point to previous line and remove deletion flag.
% \var{~} Flag all backup files for deletion.
%
% \var{x} eXpunge all flagged files. Dired will show a list of the
% files tagged for deletion and ask for confirmation before actually
% deleting the files.
%
% \var{r} Rename file on the current line; prompts for a newname
% \var{m} Move tagged files to a new dir; prompts for dir name
%
% \var{g} Update the entire contents of the Dired buffer
%
% \var{f} Visit the file described on the current line, like typing
% \var{M-x find_file} and supplying that file name. If current line is a
% directory, runs dired on the directory and the old buffer is killed.
%
% \var{v} View the file described on the current line in MOST mode.
%
% \var{q} Quit dired mode.
%
% \var{M-x dired_search}
% use fsearch to perform a search through the files listed in the
% dired buffer from the current point forward. \var{M-x dired_search}
% from the visited file will revert to the dired buffer and continue
% the search from the next file in the list.
%
% all the usual motion commands plus some extras:
%
% \var{C-n} \var{n} SPC
% move point to the next line (at the beginning of the file name)
%
% \var{C-p} \var{p}
% move point to the previous line (at the beginning of the file name)
%
% \var{M-x dired_kill_line} \var{^K} (emacs)
% removes a line from the dired buffer
%!%-
define dired ()
{
dired_read_dir (read_file_from_mini ("Directory:"));
dired_quick_help ();
run_mode_hooks ("dired_hook");
}
define dired_find ()
{
variable name, type;
(name, type) = dired_getfile ();
name = dircat (Dired_Current_Directory, name);
if ( type == 1 )
{
!if ( read_file (name) ) error ("Unable to read file.");
pop2buf (whatbuf ());
}
else if ( type == 2 )
{
dired_read_dir (name);
}
}
define dired_view ()
{
variable name, type;
(name, type) = dired_getfile ();
name = dircat (Dired_Current_Directory, name);
if ( type == 1 )
{
!if ( read_file (name) ) error ("Unable to read file.");
pop2buf (whatbuf ());
most_mode ();
}
}
#ifndef VMS
define dired_search_files ()
{
go_right_1 (); % start after this one
if ( fsearch (LAST_SEARCH) )
return (1); % found - stop search
if ( buffer_modified () ) error ("buffer has been modified");
delbuf (whatbuf ());
pop2buf (Dired_Buffer);
return 0;
}
define dired_search ()
{
variable str, name, type;
!if ( bufferp (Dired_Buffer) ) error ( "*dired* not available.");
if ( strcmp (Dired_Buffer, whatbuf () ) ) % continue last search
{
!if ( strlen (LAST_SEARCH) ) error ("No specified search string");
if ( dired_search_files () ) return;
go_down_1 (); % do the next file!
}
else
{
str = read_mini ("dired_search:", Null_String, LAST_SEARCH);
!if ( strlen (str) ) error ("Specify search string");
save_search_string (str);
}
do
{
(name, type) = dired_getfile ();
if ( type == 1 ) % only search files
{
name = dircat (Dired_Current_Directory, name);
!if ( read_file (name) ) error ("Unable to read file.");
if ( dired_search_files () )
{
pop2buf (whatbuf ());
return;
}
}
}
while ( down_1 () );
}
#endif