2

I wrote some script in elisp, it merges ls -l and du (showing real folder size instead of what is written in ls). I named it lsd. Here is screenshot:

https://i.stack.imgur.com/x89K2.png

Now i'll list implementation. I am not a good coder, so I will appreciate any information about bugs and things that can be made better.

lsd.el

#!/usr/bin/emacs --script
(progn
  (setq argz command-line-args-left)
  (setq folder "./")
  (while argz
    ;; (message (car argz))
    (if (/= ?- (aref (car argz) 0))
      (setq folder (car argz)))
    (setq argz (cdr argz)))
  (if (/= ?/ (aref folder (1- (length folder)))) (setq folder (concat folder "/")))
  (switch-to-buffer " *lsd*")
  (erase-buffer)
  (shell-command (concat "ls -l -h --color=always " " " (apply 'concat (mapcar '(lambda(arg) (concat arg " ")) command-line-args-left))) (current-buffer))
  (switch-to-buffer " *du*")
  (erase-buffer)
  (shell-command (concat "du -h -d 1 " folder) (current-buffer))
  (goto-char 1)
  (while (search-forward "Permission denied" (point-max) t nil)
    (goto-char (point-at-bol))
    (let ((beg (point)))
      (forward-line)
      (delete-region beg (point)))) ; Remove all permission denied lines, thus show only permitted size.
  (goto-char 1)
  (while (and (search-forward folder (point-max) t nil) (/= (point-max) (1+ (point-at-eol)))) ; we do not need last line(the folder itself), so this line is something complex.
    (setq DIR (buffer-substring (point) (point-at-eol)))
    (goto-char (point-at-bol))
    (setq SIZE (buffer-substring (point) (1- (search-forward "  " (point-at-eol) nil nil))))
    (goto-char (point-at-eol))
    (switch-to-buffer " *lsd*")
    (goto-char 1)
    (if (search-forward DIR (point-max) t nil)
      (progn
        (goto-char (point-at-bol))
        (search-forward-regexp "[0-9]+" (point-at-eol) nil nil)
        (search-forward-regexp "  *[0-9]+[^ \n]*[ \n]*" (point-at-eol) nil nil)
        ;; If ls have options, that makes some numbers before size column - we are doomed. (-s, for example)
        (setq SIZE (concat SIZE " "))
        (while (< (length SIZE) (length (match-string 0))) (setq SIZE (concat " " SIZE)))
        (replace-match SIZE)))
    (switch-to-buffer " *du*"))
  (switch-to-buffer " *lsd*")
  (message "%s" (buffer-substring (point-min) (point-max)))
  (defun error(&rest args) args)
  (defun message(&rest args) args)) ; Do not show any messages.

lsd (I made this script to start emacs without loading anything but script. If it can be done easier, please point this)

#/bin/bash
emacs -Q --script /usr/local/bin/lsd.el $@

And here is the problem: how to use this lsd in dired?

Can I change something in dired to use lsd instead of ls?

Can I rename ls in oldls, and make some ls bash script that passes all arguments to ls if there no --lsd flag, and passing all arguments to lsd if --lsd is here?

Is it good idea at all?

desudesudesu
  • 2,185
  • 1
  • 15
  • 20
  • Uf, i found this http://stackoverflow.com/questions/6238331/emacs-shell-scripts-how-to-put-initial-options-into-the-script So, yes, one small question is gone, but the main question is still here. – desudesudesu Jun 29 '11 at 17:40

2 Answers2

3

In Emacs24 there is also `insert-directory-program' to set the ls executable. Put

(setq insert-directory-program "/usr/local/bin/lsd")

(adjust the path accordingly) in your .emacs or init.el and dired takes your lsd script.

rudolfo.christ
  • 1,432
  • 1
  • 11
  • 13
1

I don't know if this the most efficient way to do things, I'm still a bit of an Emacs beginner. But here's how I would do it.

  1. Since you're on Linux you should start by telling emacs to use its built-in ls emulation. A simple (require 'ls-lisp) in your init file should suffice.
  2. Set the variable ls-lisp-use-insert-directory-program to true. This tells emacs to use an external program for ls.
  3. The actual program it uses can be customized by setting the variable insert-directory-program to point to your lsd script.

Here's an example of how to do this:

;; Put this in your init file
(require 'ls-lisp)
(setq ls-lisp-use-insert-directory-program T)
(setq insert-directory-program "~/path/to/lsd")

Let me know if this works for you. I use emacs on Windows so I'm not sure how well this ports over to linux (the ls emulation part that is).

  • http://i.imgur.com/omh8A.png This works! Thanks for help. I am still getting some troubles with arguments passed and --dired option (what does this option mean? It gives me strange visible table under ls list). Anyways, dired works good, it still can open files or directories. And, also, what should I do to share this script? Of course, I will find it myself, but it will be awesome to get some useful links. – desudesudesu Jun 29 '11 at 19:49
  • No problem. Are you trying to pass your arguments to lsd via the insert-directory-program variable itself? That might not work. The correct way to send switches would be to set the variable dired-listing-switches. I'm unsure how you want to share the script. If you meant just putting it up somewhere that other people can download and use I recommend taking a look at [GitHub](https://github.com/) or [Bitbucket](https://bitbucket.org/). They allow you to host code on public repositories using Git and Mercurial respectively. – bridgeburner Jun 29 '11 at 20:08
  • No, that's not what I mean. I have problems when ls and emacs have the same arguments (example, -t). My script cannot accept -t as argument, because emacs try to use it. Is there any solution, except making --sortbytime (that was already made)? I stole some usefull things from there, and made it work with lsd. http://www.emacswiki.org/emacs/DiredSortBySizeAndExtension I am so happy, that I am even giving this screenshot http://i.imgur.com/FIJLp.png yep, sort by size do not work on folders(because lsd do not sort), but I think it could be fixed. I'll go to see how to use repository. Thanks. – desudesudesu Jun 29 '11 at 20:41
  • desudesudesu: You're having trouble with command line arguments because of http://stackoverflow.com/a/6807133/324105 . Please also note the comments to that answer, and see also http://stackoverflow.com/a/6259330/324105 – phils May 07 '15 at 00:09
  • @desudesudesu It would make more sense to redefine the ls-lisp function to invoke lsd ... then you wouldn't have to start up another emacs process every time you open a directory. – Jim Balter Nov 02 '18 at 02:49