From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Emanuel Berg Newsgroups: gmane.emacs.help Subject: Re: browsing files in huge projects emacs Date: Sat, 28 Sep 2013 00:30:05 +0200 Organization: Aioe.org NNTP Server Message-ID: <87a9ixnbi1.fsf@nl106-137-194.student.uu.se> References: <704d4725-e0e6-4097-83dc-8c0e2fc1be82@googlegroups.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1380321327 8387 80.91.229.3 (27 Sep 2013 22:35:27 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 27 Sep 2013 22:35:27 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Sat Sep 28 00:35:30 2013 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1VPgdG-000346-B5 for geh-help-gnu-emacs@m.gmane.org; Sat, 28 Sep 2013 00:35:30 +0200 Original-Received: from localhost ([::1]:38850 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VPgdF-0008TQ-Ue for geh-help-gnu-emacs@m.gmane.org; Fri, 27 Sep 2013 18:35:29 -0400 Original-Path: usenet.stanford.edu!goblin2!goblin.stu.neva.ru!aioe.org!.POSTED!not-for-mail Original-Newsgroups: gnu.emacs.help Original-Lines: 311 Original-NNTP-Posting-Host: VVbyYd/iFZoeWNmD9i++cQ.user.speranza.aioe.org Original-X-Complaints-To: abuse@aioe.org User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.4 (gnu/linux) X-Notice: Filtered by postfilter v. 0.8.2 Cancel-Lock: sha1:bC9oYa/YkqlNn/xOGCJM3b/Akbk= Original-Xref: usenet.stanford.edu gnu.emacs.help:201407 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:93677 Archived-At: anurag Ramdasan writes: > I have been using Vim for a while although I would > shift to E..macs for Org-mode and Slime. When I end up > working on a huge project with hundreds or even > thousands of files, I found the nerdtree vim plugin to > be the best thing to suit my ways. Also I find dired a > little difficult to browse through. > > So when I recently gave thoughts to completely moving > to emacs, I couldn't find anything as good as > Nerdtree. I did find dirtree but it didn't seem as > easy to use as nerdtree. This made me wonder, how do > most emacs users navigate through huge projects? Is > there some common practice or some plugin that I > haven't heard of yet? Also I use both vim and emacs > from the terminal and not the GUI client. This has always been a challenge for me, although I never worked with as many files as did you. You will get better answers as to what specific tool to use, but I thought I'd show some of the things that I setup, that I have found useful. This post turned out huge! I'll put it here [1], if you don't like to digest it all right now. Although I made a text file of it, I think Elisp mode would be beneficial as there is so much code, and you probably want highlight and such to be able to read/interact with it. As *always*, any fixes and suggestions are welcome. I use the stuff below every day, so if anything could be improved I am very appreciative. 1. Find files Go to a file that is mentioned - let's say, in a comment (it requires the ~ notation for your home directory, and not /home/username/... ). Will prompt for super user privileges if needed. (defun goto-file () (interactive) (let*((file (thing-at-point 'filename)) (in-home (string= "~" (car (split-string file "/")))) (final-file (if in-home file (format "%s%s" "/sudo::" file) ))) (find-file final-file) )) Open a script that you know by name, that is in ~/scripts. (defun cats (script) (interactive "s script: ") (find-file (format "%s/scripts/%s" (getenv "HOME") script)) ) 2. Buffer menus and some useful shortcuts In /etc/console-setup/remap.inc # caps keycode 58 = U+0111 # caps shift keycode 58 = U+0113 # S-caps Get the keycode with the shell tool showkey. (It doesn't matter what goofy Unicode chars you use.) Update (for *all* Linux VTs): loadkeys -c -s key_map_file or, in .zshrc lkeys () { sudo loadkeys --clearcompose --clearstrings /etc/console-setup/remap.inc > /dev/null } Sometimes it is necessary to delete a cached keymap in /etc/console-setup. Also, I'm on Debian. I don't know if those paths are the same for other distros. On altogether other systems, probably something similar would still work. Then, in ~/.emacs (or a file loaded from there), put (define-key input-decode-map [?\u0114] [M-tab]) (global-set-key (kbd "") 'switch-buffer) (define-key input-decode-map [?\u0111] [caps]) (global-set-key (kbd "") 'buffer-menu-files-only) (define-key input-decode-map [?\u0113] [S-caps]) (global-set-key (kbd "") 'buffer-menu) (defun switch-buffer () (interactive) (switch-to-buffer nil) ) (defun buffer-menu-files-only () (interactive) (buffer-menu t) ) Fast keys in the buffer menu that won't require you to move your hands: (let ((the-map Buffer-menu-mode-map)) (define-key the-map (kbd "i") 'previous-line) (define-key the-map (kbd "k") 'next-line) (define-key the-map (kbd "w") 'kill-this-buffer) ) 3. Some integration with bash/zsh, in another Linux VT: Again, in /etc/console-setup/remap.inc, setup minimal/close shortcuts: # J - Emacs alt keycode 36 = Console_1 ctrll alt keycode 36 = Console_1 # L - tmux and more alt keycode 38 = Incr_Console ctrll alt keycode 38 = Incr_Console Then the script #!/bin/zsh DIR=`pwd` LS_PATH="${DIR/$HOME/~}/`\ls -dl $1 | tr -s ' ' | cut -d' ' -f 9`" echo -n $LS_PATH | xclip -d ":0" -selection clipboard -in echo "(find-file \"$LS_PATH\")" > ~/.lsp_file Usage: lsp filename.extension Get back to Emacs by hitting M-j, then find the file with the same command (M-x lsp RET, or assign a shortcut). (defun lsp () (interactive) (load-file "~/.lsp_file") ) Note: Wouldn't it be cool to get back to Emacs immediately on lsp? The shell tool chvt could do it from a basic Linux VT, but I run tmux on top of them, so I get "Couldn't get a file descriptor referring to the console". 4. Kill and yank filenames and their paths (defun kill-name () (interactive) (let ((name (buffer-name))) (message (format " Killed %s" name)) (kill-new name) )) (defun kill-path () (interactive) (require 'cl) (labels ((print-kill-path (killed) (message (format "killed %s" killed)) (kill-new killed) ) (print-kill-home-path (killed) (print-kill-path (format "~%s" (substring file-name home-prefix-len)) ))) (let*((file-name (buffer-file-name)) (file-name-len (length file-name)) (home-prefix (getenv "HOME")) (home-prefix-len (length home-prefix)) (sudo-prefix "/sudo:") (sudo-prefix-len (length sudo-prefix)) (root-prefix (format "%sroot@%s:" sudo-prefix (message-make-domain)) ) (root-prefix-len (length root-prefix)) ) (if (< file-name-len sudo-prefix-len) (print-kill-home-path file-name) (if (string= (substring file-name 0 sudo-prefix-len) sudo-prefix) (let ((stripped-file-name (substring file-name root-prefix-len) )) (print-kill-path stripped-file-name) ) (progn (if (string= (substring file-name 0 home-prefix-len) home-prefix) (print-kill-home-path file-name) (print-kill-path file-name) ))))))) (defun yank-path () (interactive) (kill-path) (yank) ) 5. Update file (defun refresh-file () (interactive) (revert-buffer t t nil) ; ignore-auto(-save), noconfirm, preserve-modes (message "Up to date.") ) 6. Jump between configuration files (global-set-key (kbd "C-j") 'jump-to-register) (set-register ?a (cons 'file "/sudo::/etc/apt/sources.list")) (set-register ?b (cons 'file "~/News/KILL")) (set-register ?C (cons 'file "/sudo::/etc/default/console-setup")) (set-register ?c (cons 'file "~/.irssi/config")) (set-register ?d (cons 'file "~/.emacs-dired")) ; etc. 7. Make a script executable, from the buffer in which you edit it (defun make-executable () (interactive) (shell-command (concat "chmod +x " buffer-file-name)) ) 8. Edit the current file as super user (defun su-edit () (interactive) (let ((window-start (window-start)) (point (point)) (mark (if mark-active (region-beginning) nil)) ) (find-alternate-file (format "/sudo::%s" (buffer-file-name))) (if mark (set-mark mark)) (goto-char point) (set-window-start nil window-start) ; nil - the selected window )) 9. Dired Shorter and closer, and thus faster and more ergonomic, shortcuts: (defun scroll-up-other-window () (interactive) (scroll-other-window-down 1) ) (defun scroll-down-other-window () (interactive) (scroll-other-window 1) ) (setq dired-deletion-confirmer '(lambda (x) t)) (let ((map dired-mode-map)) (define-key map (kbd "C-d") 'dired-do-delete) ;; navigate (define-key map (kbd "w") 'dired-up-directory) (define-key map (kbd "s") 'dired-find-file-other-window) (define-key map (kbd "i") 'dired-previous-line) (define-key map (kbd "k") 'dired-next-line) ;; scroll (define-key map (kbd "d") 'scroll-up-other-window) (define-key map (kbd "f") 'scroll-down-other-window) ) 10. Get a new prefix key to get more small and close shortcuts, that can be setup to reach files, navigate buffers, etc. (defun init-C-o-prefix () (interactive) (define-prefix-command 'C-o-prefix) (global-set-key "\C-o" 'C-o-prefix) (init-C-o-keys) ) (add-hook 'after-init-hook 'init-C-o-prefix) (defun init-C-o-keys () (interactive) (let ((the-map (current-global-map))) (define-key the-map "\C-oo" 'split-window-vertically-shift) ; etc )) (defun split-window-vertically-shift () (interactive) (split-window-vertically) (other-window 1) ) 11. Split windows (sometimes) The way I use Emacs, in a Linux VT with a huge font, more than two windows is seldom useful. (I use a projector, that's why I can't have it any other way.) So, I setup M-o to split the window, only - if it is already split - don't split, jump. (Also, M-p will maximize the current window.) (defun other-window-or-split () (interactive) (if (= 1 (count-windows)) (split-window-vertically)) (other-window 1) ) (let ((the-map (current-global-map))) (define-key the-map "\M-o" 'other-window-or-split) (define-key the-map "\M-p" 'delete-other-windows) ) 12. Jumping to files mentioned in the man pages (let ((the-map Man-mode-map)) (define-key the-map (kbd "M-RET") 'goto-file) ; mentioned above (define-key the-map (kbd "w") 'kill-this-buffer) ; etc. ) [1] http://user.it.uu.se/~embe8573/emacs_files.txt -- Emanuel Berg - programmer (hire me! CV below) computer projects: http://user.it.uu.se/~embe8573 internet activity: http://home.student.uu.se/embe8573