;;; d-electric.el --- An improved electric-buffer-list function

;; Copyright (C) 2006-2015 Davin Pearson

;; Emacs Lisp Archive Entry
;; Filename: d-electric.el
;; Author/Maintainer: m4_davin_pearson
;; Version: 1.17
;; Keywords: electric buffer list

;;; Commentary:

;; This file is not part of GNU Emacs.

;;; m4_limitation_of_warranty

;;; m4_install_instructions(d-electric)

;;; Known Bugs:

;; None so far!

;;; Code:

(setq prefs-advanced-user-p t)
(require 'diagnose)
;;(require 'd-groups)

(defun d-electric-buffer-list ()
  (interactive)
  (d-delete-speedbar-window)
  (delete-other-windows)
  (call-interactively 'electric-buffer-list)
  )

(global-set-key [insert]           'd-electric-buffer-list)
(global-set-key [(control insert)] 'd-electric-buffer-list)
(global-set-key [(shift insert)]   'd-electric-buffer-list)
(global-set-key [pause]            'd-electric-buffer-list)

(setq d-electric--buffer-to-choose nil)

(defadvice electric-buffer-list (before d-electric activate)
  (push-mark (point) 'no-msg)
  (let* ((list (mapcar 'buffer-name (buffer-list)))
         (ptr  list))
    (while (or (d-is-buffer-visible (car ptr)) (and (car ptr) (= ?\ (aref (car ptr) 0))))
      (setq ptr (cdr ptr)))
    (setq d-electric--buffer-to-choose (car ptr))
  ))

;; (d-ding)
(defun d-ding ()
  (let ((visible-bell nil))
    (ding)))

(defun d-electric-hook ()
  "My own Electric Buffer Menu stuff.  Currently binds some convenience keys."
  (save-match-data
    (if (fboundp 'd-delete-speedbar-window) (d-delete-speedbar-window))
    (delete-other-windows)
    (define-key electric-buffer-menu-mode-map [up]       'previous-line)
    (define-key electric-buffer-menu-mode-map [down]     'next-line)
    (define-key electric-buffer-menu-mode-map [next]     'scroll-up)
    (define-key electric-buffer-menu-mode-map [previous] 'scroll-down)
    (define-key electric-buffer-menu-mode-map [left]     'scroll-right)
    (define-key electric-buffer-menu-mode-map [right]    'scroll-left)
    (define-key electric-buffer-menu-mode-map [insert]   'd-Electric-buffer-menu-select)
    (define-key electric-buffer-menu-mode-map [f12]      'd-Electric-buffer-menu-select)
    (define-key electric-buffer-menu-mode-map [return]   'd-Electric-buffer-menu-select)
    (define-key electric-buffer-menu-mode-map [pause]    'd-Electric-buffer-menu-select)
    (define-key electric-buffer-menu-mode-map [kp-enter] 'kp-enter)
    ;;(assert (get-buffer "*Buffer List*"))
    (assert (string= (buffer-name) "*Buffer List*"))
    ;;(get-buffer)
    (goto-char 1)
    (read-only-mode -1)
    (flush-lines "TAGS")
    (goto-char 0)
    (d-quote re-search-forward (if emacs-dialect--xemacs-p
                           (concat "^....\"?" (regexp-quote d-electric--buffer-to-choose) "\"?\\s-") ;; varsity fix
                         (concat "^...." (regexp-quote d-electric--buffer-to-choose) "  "))
                       nil
                       t)
    (beginning-of-line)
    ;;(forward-line 2)
    ;;(insert "KKK")
    (read-only-mode 1)
    ;;(execute-kbd-macro "\C-n")
    (setq d-electric--foo t)
    ))

(setq d-electric--foo nil)

(defadvice electric-buffer-update-highlight (around d-speedbar-downdown activate)
  (when d-electric--foo
    (forward-line 1)
    (setq d-electric--foo nil))
  ad-do-it
  )

(add-hook 'electric-buffer-menu-mode-hook 'd-electric-hook)

(if emacs-dialect--xemacs-p
    (progn
      ;; patch for stupid bug
      (save-window-excursion
        (safe-command (execute-kbd-macro [insert]) 'QUIET))
      ))

(defun d-Electric-buffer-menu-select (&rest args)
  "This function is very clever"
  (interactive "P")
  ;;(d-beeps "foo")
  (unwind-protect
      (progn
        ;;(setq str (d-get-filename))
        ;;(if (= (aref str 0) ?*)
        ;;    (switch-to-buffer str)
        ;;  (d-find-file str))
        (call-interactively 'Electric-buffer-menu-select)
        )
    (setq d-old-method nil)
    (if (fboundp 'd-speedbar) (run-with-timer 0.01 nil 'd-speedbar))
    ))

;;(global-set-key [f5] 'd-get-filename)
(defun d-get-filename ()
  (interactive)
  (let ((line (d-current-line-as-string)))
    (cond
     ((string-match "  \\(/[-a-zA-Z0-9/_. ]*$\\)" line)
      (setq line (substring line (match-beginning 1) (match-end 1))))
     ((string-match "  \\(\\(~/[a-zA-Z0-9]*\\)/[-a-zA-Z0-9/_. ]*$\\)" line)
      (setq line (substring line (match-beginning 1) (match-end 1))))
     ((string-match "  \\([a-zA-Z]:/[-a-zA-Z0-9/_. ]*$\\)" line)
      (setq line (substring line (match-beginning 1) (match-end 1))))
     ((string-match "^....\\(\\*[-a-zA-Z0-9_]+\\*\\)" line)
      (setq line (substring line (match-beginning 1) (match-end 1))))
     (t
      (d-beeps "t")
      ))
    (message "line=%s" line)
    line))

(global-set-key [f5] 'd-major-mode)
(defun d-major-mode ()
  (interactive)
  (message "major-mode=%s" major-mode)
  ;;(message "current-line=%s" (d-current-line-as-string))
  )

(provide 'd-electric)
;;; d-electric.el ends here
