(defvar rails-speedbar:roots '(("Controllers" rails-core:controllers rails-core:controller-file) ("Helpers" rails-core:helpers rails-core:helper-file) ("Models" rails-core:models rails-core:model-file) ("Observers" rails-core:observers rails-core:observer-file) ("Mailers" rails-core:mailers rails-core:mailer-file) ("Functional Tests" rails-core:functional-tests rails-core:functional-test-file) ("Unit Tests" rails-core:unit-tests rails-core:unit-test-file) ("Fixtures" rails-core:fixtures rails-core:fixture-file))) (defvar rails-speedbar:menu-items nil) (defvar rails-speedbar:key-map (let ((map (speedbar-make-specialized-keymap))) (define-key map " " 'speedbar-toggle-line-expansion) (define-key map "+" 'speedbar-expand-line) (define-key map "=" 'speedbar-expand-line) (define-key map "-" 'speedbar-contract-line) (define-key map "e" 'speedbar-edit-line) (define-key map "\C-m" 'speedbar-edit-line) map)) (defun rails-speedbar:display (directory depth) (setq speedbar-update-flag nil) (speedbar-with-writable (insert (rails-project:root) "\n")) (dolist (i rails-speedbar:roots) (speedbar-make-tag-line 'angle ?+ 'rails-speedbar:expand-group (car i) (car i) nil nil nil depth)) (speedbar-make-tag-line 'angle ?+ 'rails-speedbar:expand-directory (concat (rails-speedbar:root) "app/views") "Views" nil nil nil depth)) (defun rails-speedbar:expand-directory (text token indent) (cond ((string-match "+" text) (speedbar-change-expand-button-char ?-) (let ((files (directory-files token nil "^[^.]"))) (save-excursion (end-of-line) (forward-char 1) (speedbar-with-writable (dolist (i files) (if (file-directory-p (format "%s/%s" token i)) (speedbar-make-tag-line 'curly ?+ 'rails-speedbar:expand-directory (format "%s/%s" token i) i nil nil nil (+ 1 indent)) (speedbar-make-tag-line 'statictag ?? nil nil i 'rails-speedbar:find-file (format "%s/%s" token i) nil (+ 1 indent)))))))) ((string-match "-" text) (speedbar-change-expand-button-char ?+) (speedbar-delete-subblock indent)))) (defun rails-speedbar:expand-group (text token indent) (cond ((string-match "+" text) (speedbar-change-expand-button-char ?-) (let* ((fn (find-if #'(lambda(i) (string= token (car i))) rails-speedbar:roots)) (lst (apply (nth 1 fn) (list))) (find (nth 2 fn))) (speedbar-with-writable (save-excursion (end-of-line) (forward-char 1) (dolist (i lst) (speedbar-make-tag-line 'bracket ?+ 'rails-speedbar:expand-tags (rails-speedbar:in-root (rails-core:file (apply find (list i)))) i 'rails-speedbar:find-file (rails-speedbar:in-root (rails-core:file (apply find (list i)))) nil (+ indent 1))))))) ((string-match "-" text) (speedbar-change-expand-button-char ?+) (speedbar-delete-subblock indent)))) (defun rails-speedbar:expand-tags (text token indent) (cond ((string-match "+" text) (let ((lst (speedbar-fetch-dynamic-tags token))) (if (not lst) (speedbar-change-expand-button-char ??) (progn (speedbar-change-expand-button-char ?-) (speedbar-with-writable (save-excursion (end-of-line) (forward-char 1) (speedbar-insert-generic-list indent (cdr lst) 'speedbar-tag-expand 'speedbar-tag-find))))))) ((string-match "-" text) (speedbar-change-expand-button-char ?+) (speedbar-delete-subblock indent)))) (defun rails-speedbar:line-directory (&optional depth) (save-excursion (end-of-line) (let ((start (point))) (when (search-backward "[-]" nil t) (end-of-line) (skip-syntax-backward "w") (get-text-property (point) 'speedbar-token))))) (defun rails-speedbar:find-file (text token indent) (typecase token (string (speedbar-find-file-in-frame token)))) (defun rails-speedbar:root () (save-excursion (goto-char (point-min)) (let* ((root (current-line-string)) (root (if (file-directory-p root) root (rails-project:root)))) root))) (defmacro rails-speedbar:in-root (&rest body) `(flet ((rails-project:root () ,(rails-speedbar:root))) ,@body)) (defun rails-speedbar:get-focus () (interactive) (speedbar-change-initial-expansion-list "Ruby On Rails") (let ((default-directory (rails-project:root))) (speedbar-get-focus))) (defun rails-speedbar-feature:install () (speedbar-add-expansion-list '("Ruby On Rails" rails-speedbar:menu-items rails-speedbar:key-map rails-speedbar:display)) (speedbar-add-mode-functions-list '("Ruby On Rails" (speedbar-line-directory . rails-speedbar:line-directory))) (define-key rails-minor-mode-map (kbd "") 'rails-speedbar:get-focus) (define-key-after (lookup-key rails-minor-mode-map [menu-bar rails]) [speedbar] '("Toggle Speedbar" . rails-speedbar:get-focus) 'svn-status)) (provide 'rails-speedbar-feature)