开发者

Change "ls" from emacs dired to other app

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:

http://i.imgur.com/PfSq6.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 i开发者_Python百科s 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?


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.


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).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜