[gnu.emacs] A find-file Hack

daveemme@amdahl.uts.amdahl.com (Dave Emme) (10/25/88)

Here's a little bit of code to be run as a "find-file-hook".  It runs the
UNIX command "ls -l" on the filename being visited and places the result in
the message line.  This gives you the file size, date last modified,
file permissions, etc. automatically.

Enjoy.

-- Dave

------------------------------ cut here ------------------------------

;;; Place file information in the message line when a file is visited.

(defvar display-file-info-buffer "*display-file-info-buffer*")
 
(defun display-file-info ()
  "Run `ls -l <filename>' whenever a file is visited, placing the
output in the message line."
  (let ((temp-buffer-show-hook 'display-file-info-hook)
	(file (cdr (assq 'buffer-file-name (buffer-local-variables)))))
    (with-output-to-temp-buffer display-file-info-buffer
      (call-process "/bin/ls" nil standard-output nil
		    "-l" (expand-file-name file))
      )))

(defun display-file-info-hook (buffer)
  ;; This hook prevents the temporary buffer created by display-file-info
  ;; from being displayed.  Instead it `messages' the information.
  (save-excursion
    (set-buffer display-file-info-buffer)
    (let ((str (buffer-substring (point-min) (1- (point-max)))))
      (message str))
    (kill-buffer buffer)))

(if (not (memq 'display-file-info find-file-hooks))
    (setq find-file-hooks (cons 'display-file-info find-file-hooks)))


-- 
------------------------------------------------------------------------------
	(Insert disclaimer of your choice here)

Dave Emme  (M/S 316)                    daveemme@uts.amdahl.com
Amdahl Corporation            {ames, decwrl, sun, uunet}!amdahl!daveemme
1250 E. Arques Ave.
Sunnyvale, CA 94088

ram-ashwin@YALE.ARPA (Ashwin Ram) (10/25/88)

> From: amdahl!daveemme@AMES.ARC.NASA.GOV  (Dave Emme)
> 
> Here's a little bit of code to be run as a "find-file-hook".  It runs the
> UNIX command "ls -l" on the filename being visited and places the result in
> the message line.  This gives you the file size, date last modified,
> file permissions, etc. automatically.

This is a nice idea.  However, using call-process to invoke /bin/ls is, I
think, overkill; it is too slow and not portable to non-Unix systems.

You can get the same information by calling the file-attributes function and
formatting the result appropriately.  On my machine this is a lot faster.
This would also be portable if file-attributes has been written to call the
appropriate system functions on different systems, which I assume it has.

-- Ashwin.

ARPA:    Ram-Ashwin@cs.yale.edu
UUCP:    {decvax,ucbvax,harvard,cmcl2,...}!yale!Ram-Ashwin
BITNET:  Ram@yalecs

rberlin%birdland@Sun.COM (Rich Berlin) (10/26/88)

To simulate ls -l using file-attributes is certainly possible, but
since there doesn't seem to be an elisp-interface to getpwent, you
have to search /etc/passwd for the uid number (and punt or do
something else ugly if you're using a name server like NFS, where the
entry may not be in /etc/passwd....)  On my machine (a Sun 3/160,
12MB, running 4.0), using /bin/ls is acceptably fast and a lot easier.

But, now I am thinking about trying to support the getpwent function.
Opinions (especially from RMS) about the practice of adding interfaces
to system calls?  It certainly raises the risk of writing
system-specific emacs extensions!


By the way, I've had other occasions when I wanted the output of a command,
so I wrote a function which, rather than applying 'message to the buffer
contents, returns them as a string.  It's easy to then pass the string to
message:

(defun results-of-command (command &rest args)
  "Execute the given COMMAND with &rest ARGS, and return the resulting\n\
output as a string."
  (let (foo
	(temp-buffer-show-hook
	 '(lambda (buffer)
	    (set-buffer buffer)
	    (setq foo (buffer-substring (point-min) (1- (point-max))))
	    (kill-buffer buffer))))
    (save-excursion
      (with-output-to-temp-buffer "*results of command*"
	(apply 'call-process command nil standard-output nil args))
    foo)))


-- Rich

ram-ashwin@YALE.ARPA (Ashwin Ram) (10/26/88)

> From: birdland!rberlin@sun.com  (Rich Berlin)
> 
> To simulate ls -l using file-attributes is certainly possible, but
> since there doesn't seem to be an elisp-interface to getpwent, you
> have to search /etc/passwd for the uid number (and punt or do
> something else ugly if you're using a name server like NFS, where the
> entry may not be in /etc/passwd....)  On my machine (a Sun 3/160,
> 12MB, running 4.0), using /bin/ls is acceptably fast and a lot easier.
> 
> But, now I am thinking about trying to support the getpwent function.
> Opinions (especially from RMS) about the practice of adding interfaces
> to system calls?  It certainly raises the risk of writing
> system-specific emacs extensions!

In this particular case, it doesn't really matter since you don't usually
want to see the uid when you find a file.  Presumably the attributes you're
interested in are the file type, protections, write dates, etc.

But in general, I think it's a bad idea to write code that depends on stuff
like (call-process "/bin/ls" ...).  Invoking OS-dependent system commands is
non-portable, not to mention difficult to read and debug, esp. for non-OS-hackers.
I think Emacs should provide functions like file-write-date, file-type,
file-attributes, etc., which is what other functions should be written in
terms of.  Internally, these functions can invoke the appropriate system
functions.

If a well-defined, high-level and relatively complete interface to system
functions is provided, this _reduces_ the risk of users hacking up their own
system-specific Emacs extensions.

-- Ashwin.