Anonymous committed 54a90cf

*** empty log message ***

Comments (0)

Files changed (3)

+2002-02-16  John Paul Wallington  <>
+	* ibuffer.el (toplevel): require easymenu.
+	(ibuffer-use-fontification): removed function.
+	(ibuffer-use-fontification): new customizable variable.
+	(ibuffer-make-temp-file): new function - GNU 21's
+	make-temp-file.
+	(ibuffer-propertize): new function.
+	(ibuffer-event-position): new function.
+	(ibuffer-event-window): new function.
+	(ibuffer-line-beginning-position): new function.
+	(ibuffer-line-end-position): new function.
+	(ibuffer-window-buffer-height): new function.
+	(ibuffer-replace-regexp-in-string): new function - GNU 21's
+	replace-regexp-in-string.
+	(ibuffer-faces): new custom group.
+	(ibuffer-truncate-lines): new customizable variable.
+	(ibuffer-name-map): use [buttonx], not [(mouse-x)].
+	(ibuffer-mode-name-map): use [buttonx], not [(mouse-x)].
+	(ibuffer-immediate-menu): renamed from ibuffer-view-menu.
+	(ibuffer-immediate-menu): defined by easy-menu-define.
+	(ibuffer-mode-mark-menu): ditto.
+	(ibuffer-mode-immediate-menu): ditto.
+	(ibuffer-mode-sort-menu): ditto.
+	(ibuffer-mode-filter-menu): ditto.
+	(ibuffer-customize): new function.
+	(ibuffer-shrink-to-fit): use shrink-window-if-larger-than-buffer.
+	(ibuffer-compile-format): comment out pt.  Kludge.
+	(ibuffer-insert-buffers-and-marks): don't bind after-change-functions
+	to nil.
+	(ibuffer-mode): use ibuffer-truncate-lines.  Make fontification work.
+	* ibuf-ext.el (toggle-sorting-mode): rewrite.  Kludge.
+	(ibuffer-occur-props): make it buffer local.
+	(ibuffer-occur-mode-map): use [buttonx], not [(mouse-x)].
+	(ibuffer-occur-engine): use text property instead of overlay.
 2002-02-15  Steve Youngs  <>
 	* ibuffer.el (ibuffer-mode-map): Comment out all the
 			  (if buffer-file-name
-			    (make-temp-file
+			    (ibuffer-make-temp-file
 			     (substring (buffer-name) 0 (min 10 (length (buffer-name))))))))))
 (define-ibuffer-op eval (form)
 (defun ibuffer-toggle-sorting-mode ()
   "Toggle the current sorting mode.
-Possible sorting modes are:
+Default sorting modes are:
  Recency - the last time the buffer was viewed
  Name - the name of the buffer
  Major Mode - the name of the major mode of the buffer
  Size - the size of the buffer"
-  (let* ((keys (mapcar #'car ibuffer-sorting-functions-alist))
-	 (entry (memq ibuffer-sorting-mode keys))
-	 (next (or (cadr entry) (car keys)))
-	 (nextentry (assq next ibuffer-sorting-functions-alist)))
-    (if (and entry nextentry)
-	(progn
-	  (setq ibuffer-sorting-mode next)
-	  (message "Sorting by %s" (cadr nextentry)))
-      (progn
-	(setq ibuffer-sorting-mode 'recency)
-	(message "Sorting by last view time"))))
+  (let ((modes (mapcar 'car ibuffer-sorting-functions-alist)))
+    (add-to-list 'modes 'recency)
+    (setq modes (sort modes 'string-lessp))
+    (let ((next (or (find-if 
+		     (lambda (x) (string-lessp ibuffer-sorting-mode x)) modes)
+		    (car modes))))
+      (setq ibuffer-sorting-mode next)
+      (message "Sorting by %s" next)))
   (ibuffer-redisplay t))
       (with-current-buffer diff-buf
 	(setq buffer-read-only nil)
-      (let ((tempfile (make-temp-file "ibuffer-diff-")))
+      (let ((tempfile (ibuffer-make-temp-file "ibuffer-diff-")))
 	      (with-current-buffer buf
 ;;; An implementation of multi-buffer `occur'
 (defvar ibuffer-occur-props nil)
+(make-variable-buffer-local 'ibuffer-occur-props)
 (define-derived-mode ibuffer-occur-mode occur-mode "Ibuffer-Occur"
   "A special form of Occur mode for multiple buffers.
   (define-key ibuffer-occur-mode-map (kbd "p") 'previous-line)
   (define-key ibuffer-occur-mode-map (kbd "RET") 'ibuffer-occur-display-occurence)
   (define-key ibuffer-occur-mode-map (kbd "f") 'ibuffer-occur-goto-occurence)
-  (define-key ibuffer-occur-mode-map [(mouse-2)] 'ibuffer-occur-mouse-display-occurence)
+  (define-key ibuffer-occur-mode-map [button2] 'ibuffer-occur-mouse-display-occurence)
   (set (make-local-variable 'revert-buffer-function)
   (set (make-local-variable 'ibuffer-occur-props) nil)
 	    (if (or (and (< 21 emacs-major-version)
 		    (featurep 'mouse))
-	       "or mouse-2 ")
+	       "or button2 ")
 	    "to display an occurence.")))
 (defun ibuffer-occur-mouse-display-occurence (e)
   "Display occurence on this line in another window."
   (interactive "e")
-  (let* ((occurbuf (save-window-excursion (mouse-select-window e)
-					  (selected-window)))
+  (let* ((occurbuf (window-buffer (ibuffer-event-window e)))
 	 (target (with-current-buffer occurbuf
-		   (get-text-property (save-excursion
-					(mouse-set-point e)
-					(point))
+		   (get-text-property (ibuffer-event-position e)
     (unless target
       (error "No occurence on this line"))
 		 (insert ,@args)
-	     (maybe-put-overlay
-	      (over prop value)
-	      `(when (ibuffer-use-fontification)
-		 (overlay-put ,over ,prop ,value)))
+	     (maybe-put-text-property
+	      (beg end &rest args)
+	      `(when ibuffer-use-fontification
+		 (put-text-property ,beg ,end ,@args)))
 	      (obj &rest args)
 	      (let ((objsym (gensym "--maybe-ibuffer-propertize-")))
 		`(let ((,objsym ,obj))
-		   (if (ibuffer-use-fontification)
-		       (propertize ,objsym ,@args)
+		   (if ibuffer-use-fontification
+		       (ibuffer-propertize ,objsym ,@args)
     (with-current-buffer out-buf
 			(setq curline
 				(ibuffer-depropertize-string curline t)
-				(when (ibuffer-use-fontification)
+				(when ibuffer-use-fontification
 				  (let ((len (length curline))
 					(start 0))
 				    (while (and (< start len)
 			(end (insert-get-point
 			      (format "%d lines matching \"%s\" in buffer %s\n"
 				      c regexp (buffer-name buf)))))
-		    (let ((o (make-overlay beg end)))
-		      (maybe-put-overlay o 'face 'underline)))
+		    (maybe-put-text-property beg (1- end) 'face 'underline))
 		  (goto-char (point-max)))))))
 	(setq ibuffer-occur-props (list regexp buffers nlines))
 	;; Return the number of matches
 ;;; Code:
-  (require 'cl)
-  (require 'ibuf-macs)
-  (require 'dired))
+(require 'cl)
+(require 'easymenu)
+(require 'ibuf-macs)
+(require 'dired)
 ;;; Compatibility
 	(walk-windows #'(lambda (win) (push win ibuffer-window-list-result)) 'nomini)
 	(nreverse ibuffer-window-list-result))))
-  (cond ((boundp 'global-font-lock-mode)
-	 (defsubst ibuffer-use-fontification ()
-	   (when (boundp 'font-lock-mode)
-	     font-lock-mode)))
-	((boundp 'font-lock-auto-fontify)
-	 (defsubst ibuffer-use-fontification ()
-	   font-lock-auto-fontify))
-	(t
-	 (defsubst ibuffer-use-fontification ()
-	   nil))))
+  (if (fboundp 'make-temp-file)
+      (defalias 'ibuffer-make-temp-file 'make-temp-file)
+    (defun ibuffer-make-temp-file (prefix &optional dir-flag)
+  "Create a temporary file.
+The returned file name (created by appending some random characters at the end
+of PREFIX, and expanding against `temporary-file-directory' if necessary,
+is guaranteed to point to a newly created empty file.
+You can then use `write-region' to write new data into the file.
+If DIR-FLAG is non-nil, create a new empty directory instead of a file."
+  (let (file)
+    (while (condition-case ()
+	       (progn
+		 (setq file
+		       (make-temp-name
+			(expand-file-name prefix temporary-file-directory)))
+		 (if dir-flag
+		     (make-directory file)
+		   (write-region "" nil file nil 'silent nil 'excl))
+		 nil)
+	     (file-already-exists t))
+      ;; the file was somehow created by someone else between
+      ;; `make-temp-name' and `write-region', let's try again.
+      nil)
+    file)))
+  (if (fboundp 'propertize)
+      (defalias 'ibuffer-propertize 'propertize)
+    (defun ibuffer-propertize (string &rest properties)
+      "Return a copy of STRING with text properties added.
+First argument is the string to copy.
+Remaining arguments form a sequence of PROPERTY VALUE pairs for text
+properties to add to the result."
+    (let ((str (copy-sequence string)))
+      (add-text-properties 0 (length str)
+                           properties
+                           str)
+      str)))
+  ;; Deal with different interfaces to mouse events. Sigh.
+  (cond ((fboundp 'posn-point)
+ 	 ;; Emacs
+ 	 (defun ibuffer-event-position (event)
+ 	   (posn-point (event-start event))))
+ 	((or (featurep 'xemacs)
+	     (string-match "XEmacs\\|Lucid" (emacs-version)))
+ 	 (defun ibuffer-event-position (event)
+ 	   (event-point event)))
+ 	(t
+	 (error "Couldn't make a suitable definition of `ibuffer-event-position'")))
+  (cond ((fboundp 'posn-window)
+ 	 ;; Emacs
+ 	 (defun ibuffer-event-window (event)
+	   (posn-window (event-start event))))
+ 	((or (featurep 'xemacs)
+ 	     (string-match "XEmacs\\|Lucid" (emacs-version)))
+ 	 (defun ibuffer-event-window (event)
+ 	   (event-window event)))
+ 	(t
+ 	 (error "Couldn't make a suitable definition of `ibuffer-event-window'")))
+  (if (fboundp 'line-beginning-position)
+    (defalias 'ibuffer-line-beginning-position 'line-beginning-position)
+  (defun ibuffer-line-beginning-position ()
+    (save-excursion
+      (beginning-of-line)
+      (point))))
+(if (fboundp 'line-end-position)
+    (defalias 'ibuffer-line-end-position 'line-end-position)
+  (defun ibuffer-line-end-position ()
+    (save-excursion
+      (end-of-line)
+      (point))))
+(if (fboundp 'window-buffer-height)
+    (defalias 'ibuffer-window-buffer-height 'window-buffer-height)
+  (defalias 'ibuffer-window-buffer-height 'window-displayed-height))
+(if (fboundp 'fit-window-to-buffer)
+    (defun ibuffer-shrink-to-fit (&optional owin)
+      (fit-window-to-buffer nil (when owin (/ (frame-height)
+					      (length (window-list (selected-frame)))))))
+  (defun ibuffer-shrink-to-fit (&optional owin)
+    (shrink-window-if-larger-than-buffer owin)))
+(if (fboundp 'replace-regexp-in-string)
+    (defalias 'ibuffer-replace-regexp-in-string 'replace-regexp-in-string)
+  (defun ibuffer-replace-regexp-in-string (regexp rep string &optional
+					fixedcase literal subexp start)
+  "Replace all matches for REGEXP with REP in STRING.
+Return a new string containing the replacements.
+Optional arguments FIXEDCASE, LITERAL and SUBEXP are like the
+arguments with the same names of function `replace-match'.  If START
+is non-nil, start replacements at that index in STRING.
+REP is either a string used as the NEWTEXT arg of `replace-match' or a
+function.  If it is a function it is applied to each match to generate
+the replacement passed to `replace-match'; the match-data at this
+point are such that match 0 is the function's argument."
+  (let ((l (length string))
+	(start (or start 0))
+	matches str mb me)
+    (save-match-data
+      (while (and (< start l) (string-match regexp string start))
+	(setq mb (match-beginning 0)
+	      me (match-end 0))
+	(when (= me mb) (setq me (min l (1+ mb))))
+	(string-match regexp (setq str (substring string mb me)))
+	(setq matches
+	      (cons (replace-match (if (stringp rep)
+				       rep
+				     (funcall rep (match-string 0 str)))
+				   fixedcase literal str subexp)
+		    (cons (substring string start mb)
+			  matches)))
+	(setq start me))
+      (setq matches (cons (substring string start l) matches))
+      (apply #'concat (nreverse matches))))))
+  )
 (defgroup ibuffer nil
   "An advanced replacement for `buffer-menu'.
   :type 'boolean
   :group 'ibuffer)
+(defgroup ibuffer-faces nil
+  "Faces used by Ibuffer package."
+  :group 'ibuffer
+  :group 'faces)
+(defcustom ibuffer-marked-face 'font-lock-warning-face
+  "Face used for displaying marked buffers."
+  :type 'face
+  :group 'ibuffer-faces)
+(defcustom ibuffer-deletion-face 'font-lock-type-face
+  "Face used for displaying buffers marked for deletion."
+  :type 'face
+  :group 'ibuffer-faces)
+(defcustom ibuffer-title-face 'font-lock-type-face
+  "Face used for the title string."
+  :type 'face
+  :group 'ibuffer-faces)
+(defcustom ibuffer-read-only-buffer-face 'font-lock-keyword-face
+  "Face used for displaying read-only buffers."
+  :type 'face
+  :group 'ibuffer-faces)
+(defcustom ibuffer-special-buffer-face 'font-lock-keyword-face
+  "Face used for displaying \"special\" buffers."
+  :type 'face
+  :group 'ibuffer-faces)
+(defcustom ibuffer-hidden-buffer-face 'font-lock-keyword-face
+  "Face used for displaying normally hidden buffers."
+  :type 'face
+  :group 'ibuffer-faces)
+(defcustom ibuffer-help-buffer-face 'font-lock-keyword-face
+  "Face used for displaying help buffers \(info, apropos, help\)."
+  :type 'face
+  :group 'ibuffer-faces)
+(defcustom ibuffer-dired-buffer-face 'font-lock-keyword-face
+  "Face used for displaying dired buffers."
+  :type 'face
+  :group 'ibuffer-faces)
+(defcustom ibuffer-use-fontification (if (boundp 'font-lock-auto-fontify)
+					 font-lock-auto-fontify
+				       (if (boundp 'global-font-lock-mode)
+					   global-font-lock-mode
+					 nil))
+  "If non-nil, fontify contents of Ibuffer buffer."
+  :type 'boolean
+  :group 'ibuffer)
 (defcustom ibuffer-fontification-alist
-  `((10 buffer-read-only font-lock-reference-face)
-    (15 (string-match "^*" (buffer-name)) font-lock-keyword-face)
-    (20 (string-match "^ " (buffer-name)) font-lock-warning-face)
-    (25 (memq major-mode '(help-mode apropos-mode info-mode)) font-lock-comment-face)
-    (30 (eq major-mode 'dired-mode) font-lock-function-name-face))
+  `((10 buffer-read-only ,ibuffer-read-only-buffer-face)
+    (15 (string-match "^*" (buffer-name)) ,ibuffer-special-buffer-face)
+    (20 (string-match "^ " (buffer-name)) ,ibuffer-hidden-buffer-face)
+    (25 (memq major-mode '(help-mode apropos-mode info-mode)) ,ibuffer-help-buffer-face)
+    (30 (eq major-mode 'dired-mode) ,ibuffer-dired-buffer-face))
   "An alist describing how to fontify buffers.
 Each element should be of the form (PRIORITY FORM FACE), where
 PRIORITY is an integer, FORM is an arbitrary form to evaluate in the
 (defcustom ibuffer-always-show-last-buffer nil
   "If non-nil, always display the previous buffer.  This variable
-takes precedence over filtering, and even
+takes precedence over filtering, and even `ibuffer-never-show-predicates'."
   :type '(choice (const :tag "Always" :value t)
 		 (const :tag "Never" :value nil)
 		 (const :tag "Always except minibuffer" :value :nomini))
   :group 'ibuffer)
-(defcustom ibuffer-use-header-line (boundp 'header-line-format)
+(defcustom ibuffer-use-header-line nil
   "If non-nil, display a header line containing current filters.
-This feature only works on Emacs 21 or later."
+This feature only works on GNU Emacs 21 or later."
   :type 'boolean
   :group 'ibuffer)
   :type 'hook
   :group 'ibuffer)
-(defcustom ibuffer-marked-face 'font-lock-warning-face
-  "Face used for displaying marked buffers."
-  :type 'face
-  :group 'ibuffer)
-(defcustom ibuffer-deletion-face 'font-lock-type-face
-  "Face used for displaying buffers marked for deletion."
-  :type 'face
-  :group 'ibuffer)
-(defcustom ibuffer-title-face 'font-lock-type-face
-  "Face used for the title string."
-  :type 'face
-  :group 'ibuffer)
 (defcustom ibuffer-directory-abbrev-alist nil
   "An alist of file name abbreviations like `directory-abbrev-alist'."
   :type '(repeat (cons :format "%v"
 		       (regexp :tag "To")))
   :group 'ibuffer)
+(defcustom ibuffer-truncate-lines t
+  "If non-nil, do not display continuation lines within an Ibuffer buffer;
+give each line of text one frame line."
+  :type 'boolean
+  :group 'ibuffer)
+;; mode-map
 (defvar ibuffer-mode-map nil)
-(defvar ibuffer-mode-operate-map nil)
 (unless ibuffer-mode-map
-  (let ((map (make-sparse-keymap))
-	(operate-map (make-sparse-keymap "Operate")))
+  (let ((map (make-sparse-keymap)))
     (define-key map (kbd "0") 'digit-argument)
     (define-key map (kbd "1") 'digit-argument)
     (define-key map (kbd "2") 'digit-argument)
     (define-key map (kbd "|") 'ibuffer-do-shell-command-pipe)
     (define-key map (kbd "!") 'ibuffer-do-shell-command-file)
     (define-key map (kbd "~") 'ibuffer-do-toggle-modified)
     ;; marked operations
     (define-key map (kbd "A") 'ibuffer-do-view)
     (define-key map (kbd "D") 'ibuffer-do-delete)
     (define-key map (kbd "C-c C-a") 'ibuffer-auto-mode)
     (define-key map (kbd "C-x 4 RET") 'ibuffer-visit-buffer-other-window)
     (define-key map (kbd "C-x 5 RET") 'ibuffer-visit-buffer-other-frame)
-;; XEmacs change: XEmacs doesn't have 'define-key-after'
-;;     (define-key map [menu-bar view]
-;;       (cons "View" (make-sparse-keymap "View")))
-;;     (define-key-after map [menu-bar view visit-buffer]
-;;       '(menu-item "View this buffer" ibuffer-visit-buffer))
-;;     (define-key-after map [menu-bar view visit-buffer-other-window]
-;;       '(menu-item "View (other window)" ibuffer-visit-buffer-other-window))
-;;     (define-key-after map [menu-bar view visit-buffer-other-frame]
-;;       '(menu-item "View (other frame)" ibuffer-visit-buffer-other-frame))
-;;     (define-key-after map [menu-bar view ibuffer-update]
-;;       '(menu-item "Update" ibuffer-update
-;; 		  :help "Regenerate the list of buffers"))
-;;     (define-key-after map [menu-bar view switch-format]
-;;       '(menu-item "Switch display format" ibuffer-switch-format
-;; 		  :help "Toggle between available values of `ibuffer-formats'"))
-;;     (define-key-after map [menu-bar view dashes]
-;;       '("--"))
-;;     (define-key-after map [menu-bar view sort]
-;;       (cons "Sort" (make-sparse-keymap "Sort")))
-;;     (define-key-after map [menu-bar view sort do-sort-by-major-mode]
-;;       '(menu-item "Sort by major mode" ibuffer-do-sort-by-major-mode
-;; 		  :help "Sort by the alphabetic order of the buffer's major mode"))
-;;     (define-key-after map [menu-bar view sort do-sort-by-size]
-;;       '(menu-item "Sort by buffer size" ibuffer-do-sort-by-size
-;; 		  :help "Sort by the size of the buffer"))
-;;     (define-key-after map [menu-bar view sort do-sort-by-alphabetic]
-;;       '(menu-item "Sort lexicographically" ibuffer-do-sort-by-alphabetic
-;; 		  :help "Sort by the alphabetic order of buffer name"))
-;;     (define-key-after map [menu-bar view sort do-sort-by-recency]
-;;       '(menu-item "Sort by view time" ibuffer-do-sort-by-recency
-;; 		  :help "Sort by the last time the buffer was displayed"))
-;;     (define-key-after map [menu-bar view sort invert-sorting]
-;;       '(menu-item "Reverse sorting order" ibuffer-invert-sorting))
-;;     (define-key-after map [menu-bar view sort toggle-sorting-mode]
-;;       '(menu-item "Switch sorting mode" ibuffer-toggle-sorting-mode
-;; 		  :help "Switch between the various sorting criteria"))
-;;     (define-key-after map [menu-bar view filter]
-;;       (cons "Filter" (make-sparse-keymap "Filter")))
-;;     (define-key-after map [menu-bar view filter filter-disable]
-;;       '(menu-item "Disable all filtering" ibuffer-filter-disable))
-;;     (define-key-after map [menu-bar view filter filter-by-mode]
-;;       '(menu-item "Add filter by major mode..." ibuffer-filter-by-mode
-;; 		  :help "Show only buffers in a major mode"))
-;;     (define-key-after map [menu-bar view filter filter-by-name]
-;;       '(menu-item "Add filter by buffer name..." ibuffer-filter-by-name
-;; 		  :help "Show only buffers whose name matches a regexp"))
-;;     (define-key-after map [menu-bar view filter filter-by-filename]
-;;       '(menu-item "Add filter by filename..." ibuffer-filter-by-filename
-;; 		  :help "Show only buffers whose filename matches a regexp"))
-;;     (define-key-after map [menu-bar view filter filter-by-size-lt]
-;;       '(menu-item "Add filter by size less than..." ibuffer-filter-by-size-lt
-;; 		  :help "Show only buffers of size less than..."))
-;;     (define-key-after map [menu-bar view filter filter-by-size-gt]
-;;       '(menu-item "Add filter by size greater than..." ibuffer-filter-by-size-gt
-;; 		  :help "Show only buffers of size greater than..."))
-;;     (define-key-after map [menu-bar view filter filter-by-content]
-;;       '(menu-item "Add filter by content (regexp)..." ibuffer-filter-by-content
-;; 		  :help "Show only buffers containing a regexp"))
-;;     (define-key-after map [menu-bar view filter filter-by-predicate]
-;;       '(menu-item "Add filter by Lisp predicate..." ibuffer-filter-by-predicate
-;; 		  :help "Show only buffers for which a predicate is true"))
-;;     (define-key-after map [menu-bar view filter pop-filter]
-;;       '(menu-item "Remove top filter" ibuffer-pop-filter))
-;;     (define-key-after map [menu-bar view filter or-filter]
-;;       '(menu-item "OR top two filters" ibuffer-or-filter
-;; 		  :help "Create a new filter which is the logical OR of the top two filters"))
-;;     (define-key-after map [menu-bar view filter negate-filter]
-;;       '(menu-item "Negate top filter" ibuffer-negate-filter))
-;;     (define-key-after map [menu-bar view filter decompose-filter]
-;;       '(menu-item "Decompose top filter" ibuffer-decompose-filter
-;; 		  :help "Break down a complex filter like OR or NOT"))
-;;     (define-key-after map [menu-bar view filter exchange-filters]
-;;       '(menu-item "Swap top two filters" ibuffer-exchange-filters))
-;;     (define-key-after map [menu-bar view filter save-filters]
-;;       '(menu-item "Save current filters permanently..." ibuffer-save-filters
-;; 		  :help "Use a mnemnonic name to store current filter stack"))
-;;     (define-key-after map [menu-bar view filter switch-to-saved-filters]
-;;       '(menu-item "Restore permanently saved filters..." ibuffer-switch-to-saved-filters
-;; 		  :help "Replace current filters with a saved stack"))
-;;     (define-key-after map [menu-bar view filter add-saved-filters]
-;;       '(menu-item "Add to permanently saved filters..." ibuffer-add-saved-filters
-;; 		  :help "Include current filters in an already saved stack"))
-;;     (define-key-after map [menu-bar view filter delete-saved-filters]
-;;       '(menu-item "Delete permanently saved filters..." ibuffer-delete-saved-filters
-;; 		  :help "Remove stack of filters from saved list"))
-;;     (define-key-after map [menu-bar view dashes2]
-;;       '("--"))
-;;     (define-key-after map [menu-bar view diff-with-file]
-;;       '(menu-item "Diff with file" ibuffer-diff-with-file
-;; 		  :help "View the differences between this buffer and its file"))
-;;     (define-key-after map [menu-bar view auto-mode]
-;;       '(menu-item "Toggle Auto Mode" ibuffer-auto-mode
-;; 		  :help "Attempt to automatically update the Ibuffer buffer"))
-;;     (define-key-after map [menu-bar view customize]
-;;       '(menu-item "Customize Ibuffer" (lambda () (interactive)
-;; 					(customize-group 'ibuffer))
-;; 		  :help "Use Custom to customize Ibuffer"))
-;;     (define-key-after map [menu-bar mark]
-;;       (cons "Mark" (make-sparse-keymap "Mark")))
-;;     (define-key-after map [menu-bar mark toggle-marks]
-;;       '(menu-item "Toggle marks" ibuffer-toggle-marks
-;; 		  :help "Unmark marked buffers, and mark unmarked buffers"))
-;;     (define-key-after map [menu-bar mark mark-forward]
-;;       '(menu-item "Mark" ibuffer-mark-forward
-;; 		  :help "Mark the buffer at point"))
-;;     (define-key-after map [menu-bar mark unmark-forward]
-;;       '(menu-item "Unmark" ibuffer-unmark-forward
-;; 		  :help "Unmark the buffer at point"))
-;;     (define-key-after map [menu-bar mark mark-by-mode]
-;;       '(menu-item "Mark by mode..." ibuffer-mark-by-mode
-;; 		  :help "Mark all buffers in a particular major mode"))
-;;     (define-key-after map [menu-bar mark mark-modified-buffers]
-;;       '(menu-item "Mark modified buffers" ibuffer-mark-modified-buffers
-;; 		  :help "Mark all buffers which have been modified"))
-;;     (define-key-after map [menu-bar mark mark-unsaved-buffers]
-;;       '(menu-item "Mark unsaved buffers" ibuffer-mark-unsaved-buffers
-;; 		  :help "Mark all buffers which have a file and are modified"))
-;;     (define-key-after map [menu-bar mark mark-read-only-buffers]
-;;       '(menu-item "Mark read-only buffers" ibuffer-mark-read-only-buffers
-;; 		  :help "Mark all buffers which are read-only"))
-;;     (define-key-after map [menu-bar mark mark-special-buffers]
-;;       '(menu-item "Mark special buffers" ibuffer-mark-special-buffers
-;; 		  :help "Mark all buffers whose name begins with a *"))
-;;     (define-key-after map [menu-bar mark mark-dired-buffers]
-;;       '(menu-item "Mark dired buffers" ibuffer-mark-dired-buffers
-;; 		  :help "Mark buffers in dired-mode"))
-;;     (define-key-after map [menu-bar mark mark-dissociated-buffers]
-;;       '(menu-item "Mark dissociated buffers" ibuffer-mark-dissociated-buffers
-;; 		  :help "Mark buffers with a non-existent associated file"))
-;;     (define-key-after map [menu-bar mark mark-help-buffers]
-;;       '(menu-item "Mark help buffers" ibuffer-mark-help-buffers
-;; 		  :help "Mark buffers in help-mode"))
-;;     (define-key-after map [menu-bar mark mark-old-buffers]
-;;       '(menu-item "Mark old buffers" ibuffer-mark-old-buffers
-;; 		  :help "Mark buffers which have not been viewed recently"))
-;;     (define-key-after map [menu-bar mark unmark-all]
-;;       '(menu-item "Unmark All" ibuffer-unmark-all))
-;;     (define-key-after map [menu-bar mark dashes]
-;;       '("--"))
-;;     (define-key-after map [menu-bar mark mark-by-name-regexp]
-;;       '(menu-item "Mark by buffer name (regexp)..." ibuffer-mark-by-name-regexp
-;; 		  :help "Mark buffers whose name matches a regexp"))
-;;     (define-key-after map [menu-bar mark mark-by-mode-regexp]
-;;       '(menu-item "Mark by major mode (regexp)..." ibuffer-mark-by-mode-regexp
-;; 		  :help "Mark buffers whose major mode name matches a regexp"))
-;;     (define-key-after map [menu-bar mark mark-by-file-name-regexp]
-;;       '(menu-item "Mark by file name (regexp)..." ibuffer-mark-by-file-name-regexp
-;; 		  :help "Mark buffers whose file name matches a regexp"))
-;;     ;; Operate map is added later
-;;     (define-key-after operate-map [do-view]
-;;       '(menu-item "View" ibuffer-do-view))
-;;     (define-key-after operate-map [do-view-other-frame]
-;;       '(menu-item "View (separate frame)" ibuffer-do-view-other-frame))
-;;     (define-key-after operate-map [do-save]
-;;       '(menu-item "Save" ibuffer-do-save))
-;;     (define-key-after operate-map [do-replace-regexp]
-;;       '(menu-item "Replace (regexp)..." ibuffer-do-replace-regexp
-;; 		  :help "Replace text inside marked buffers"))
-;;     (define-key-after operate-map [do-query-replace]
-;;       '(menu-item "Query Replace..." ibuffer-do-query-replace
-;; 		  :help "Replace text in marked buffers, asking each time"))
-;;     (define-key-after operate-map [do-query-replace-regexp]
-;;       '(menu-item "Query Replace (regexp)..." ibuffer-do-query-replace-regexp
-;; 		  :help "Replace text in marked buffers by regexp, asking each time"))
-;;     (define-key-after operate-map [do-print]
-;;       '(menu-item "Print" ibuffer-do-print))
-;;     (define-key-after operate-map [do-toggle-modified]
-;;       '(menu-item "Toggle modification flag" ibuffer-do-toggle-modified))
-;;     (define-key-after operate-map [do-revert]
-;;       '(menu-item "Revert" ibuffer-do-revert
-;; 		  :help "Revert marked buffers to their associated file"))
-;;     (define-key-after operate-map [do-rename-uniquely]
-;;       '(menu-item "Rename Uniquely" ibuffer-do-rename-uniquely
-;; 		  :help "Rename marked buffers to a new, unique name"))
-;;     (define-key-after operate-map [do-delete]
-;;       '(menu-item "Kill" ibuffer-do-delete))
-;;     (define-key-after operate-map [do-occur]
-;;       '(menu-item "List lines matching..." ibuffer-do-occur
-;; 		  :help "View all lines in marked buffers matching a regexp"))
-;;     (define-key-after operate-map [do-shell-command-pipe]
-;;       '(menu-item "Pipe to shell command..." ibuffer-do-shell-command-pipe
-;; 		  :help "For each marked buffer, send its contents to a shell command"))
-;;     (define-key-after operate-map [do-shell-command-pipe-replace]
-;;       '(menu-item "Pipe to shell command (replace)..." ibuffer-do-shell-command-pipe-replace
-;; 		  :help "For each marked buffer, replace its contents with output of shell command"))
-;;     (define-key-after operate-map [do-shell-command-file]
-;;       '(menu-item "Shell command on buffer's file..." ibuffer-do-shell-command-file
-;; 		  :help "For each marked buffer, run a shell command with its file as argument"))
-;;     (define-key-after operate-map [do-eval]
-;;       '(menu-item "Eval..." ibuffer-do-eval
-;; 		  :help "Evaluate a Lisp form in each marked buffer"))
-;;     (define-key-after operate-map [do-view-and-eval]
-;;       '(menu-item "Eval (viewing buffer)..." ibuffer-do-view-and-eval
-;; 		  :help "Evaluate a Lisp form in each marked buffer while viewing it"))
-    (setq ibuffer-mode-map map
-	  ibuffer-mode-operate-map operate-map)))
+    (setq ibuffer-mode-map map))
+  )
 (defvar ibuffer-name-map nil)
 (unless ibuffer-name-map
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map ibuffer-mode-map)
-    (define-key map [(mouse-1)] 'ibuffer-mouse-toggle-mark)
-    (define-key map [(mouse-2)] 'ibuffer-mouse-visit-buffer)
+    (define-key map [button1] 'ibuffer-mouse-toggle-mark)
+    (define-key map [button2] 'ibuffer-mouse-visit-buffer)
     (define-key map [down-mouse-3] 'ibuffer-mouse-popup-menu)
     (setq ibuffer-name-map map)))
 (unless ibuffer-mode-name-map
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map ibuffer-mode-map)
-    (define-key map [(mouse-2)] 'ibuffer-mouse-filter-by-mode)
+    (define-key map [button2] 'ibuffer-mouse-filter-by-mode)
     (define-key map (kbd "RET") 'ibuffer-interactive-filter-by-mode)
     (setq ibuffer-mode-name-map map)))
 ;; quiet the byte-compiler
 (defvar ibuffer-mode-operate-menu nil)
 (defvar ibuffer-mode-mark-menu nil)
-(defvar ibuffer-mode-view-menu nil)
+(defvar ibuffer-mode-immediate-menu nil)
+(defvar ibuffer-mode-sort-menu nil)
+(defvar ibuffer-mode-filter-menu nil)
 (defvar ibuffer-mode-hooks nil)
 FUNCTION is a function of two arguments, which will be the buffers to
+;;; Menu definitions
+(unless ibuffer-mode-sort-menu
+  (easy-menu-define
+    ibuffer-mode-sort-menu ibuffer-mode-map ""
+    '("Sort"
+      ["Toggle sorting mode" ibuffer-toggle-sorting-mode t]
+      ["Reverse sorting order" ibuffer-invert-sorting t]
+      ["Sort by view time" ibuffer-do-sort-by-recency t]
+      ["Sort lexicographically" ibuffer-do-sort-by-alphabetic t]
+      ["Sort by buffer size" ibuffer-do-sort-by-size t]
+      ["Sort by major mode" ibuffer-do-sort-by-major-mode t])))
+(unless ibuffer-mode-immediate-menu
+  (easy-menu-define
+    ibuffer-mode-immediate-menu ibuffer-mode-map ""
+    '("Immediate"
+      ["View this buffer" ibuffer-visit-buffer t]
+      ["View (other window)" ibuffer-visit-buffer-other-window t]
+      ["View (other frame)" ibuffer-visit-buffer-other-frame t]
+      "----"
+      ["Diff with file" ibuffer-diff-with-file t]
+      ["Redisplay" ibuffer-redisplay t]
+      ["Update" ibuffer-update t]
+      ["Switch display format" ibuffer-switch-format t]
+      "----"
+      ["Customize Ibuffer" ibuffer-customize t])))
+(unless ibuffer-mode-mark-menu
+  (easy-menu-define
+    ibuffer-mode-mark-menu ibuffer-mode-map ""
+    '("Mark"
+      ["Toggle marks" ibuffer-toggle-marks t]
+      ["Mark" ibuffer-mark-forward t]
+      ["Unmark" ibuffer-unmark-forward t]
+      ["Mark by mode..." ibuffer-mark-by-mode t]
+      ["Mark modified buffers" ibuffer-mark-modified-buffers t]
+      ["Mark unsaved buffers" ibuffer-mark-unsaved-buffers t]
+      ["Mark read-only buffers" ibuffer-mark-read-only-buffers t]
+      ["Mark special buffers" ibuffer-mark-special-buffers t]
+      ["Mark dired buffers" ibuffer-mark-dired-buffers t]
+      ["Mark dissociated buffers" ibuffer-mark-dissociated-buffers t]
+      ["Mark help buffers" ibuffer-mark-help-buffers t]
+      ["Mark old buffers" ibuffer-mark-old-buffers t]
+      "----"
+      ["Mark by buffer name (regexp)..." ibuffer-mark-by-name-regexp t]
+      ["Mark by major mode (regexp)..." ibuffer-mark-by-mode-regexp t]
+      ["Mark by file name (regexp)..." ibuffer-mark-by-file-name-regexp t]
+      "----"
+      ["Unmark All" ibuffer-unmark-all t])))
+(unless ibuffer-mode-filter-menu
+  (easy-menu-define
+   ibuffer-mode-filter-menu ibuffer-mode-map ""
+   '("Filter"
+     ["Disable all filtering" ibuffer-filter-disable t]
+     "----"
+     ["Add filter by major mode..." ibuffer-filter-by-mode t]
+     ["Add filter by buffer name..." ibuffer-filter-by-name t]
+     ["Add filter by filename..." ibuffer-filter-by-filename t]
+     ["Add filter by size less than..." ibuffer-filter-by-size-lt t]
+     ["Add filter by size greater than..." ibuffer-filter-by-size-gt t]
+     ["Add filter by content (regexp)..." ibuffer-filter-by-content t]
+     ["Add filter by Lisp predicate..." ibuffer-filter-by-predicate t]
+     "----"
+     ["Remove top filter" ibuffer-pop-filter t]
+     ["OR top two filters" ibuffer-or-filter t]
+     ["Negate top filter" ibuffer-negate-filter t]
+     ["Decompose top filter" ibuffer-decompose-filter t]
+     ["Swap top two filters" ibuffer-exchange-filters t]
+     "----"
+     ["Save current filters permanently..." ibuffer-save-filters t]
+     ["Restore permanently saved filters..." ibuffer-switch-to-saved-filters t]
+     ["Add to permanently saved filters..." ibuffer-add-saved-filters t]
+     ["Delete permanently saved filters..." ibuffer-delete-saved-filters t])))
+(defvar ibuffer-operate-menu-data 
+  '("Operate"
+    ["View" ibuffer-do-view t]
+    ["View (separate frame)" ibuffer-do-view-other-frame t]
+    ["Save" ibuffer-do-save t]
+    ["Replace (regexp)..." ibuffer-do-replace-regexp t]
+    ["Query Replace..." ibuffer-do-query-replace t]
+    ["Query Replace (regexp)..." ibuffer-do-query-replace-regexp t]
+    ["Print" ibuffer-do-print t]
+    ["Revert" ibuffer-do-revert t]
+    ["Rename Uniquely" ibuffer-do-rename-uniquely t]
+    ["Kill" ibuffer-do-delete t]
+    ["List lines matching..." ibuffer-do-occur t]
+    ["Shell Command..." ibuffer-do-shell-command t]
+    ["Shell Command (replace)..." ibuffer-do-shell-command-replace t]
+    ["Eval..." ibuffer-do-eval t]
+    ["Eval (viewing buffer)..." ibuffer-do-view-and-eval t]))
+(unless ibuffer-mode-operate-menu
+  (easy-menu-define
+    ibuffer-mode-operate-menu ibuffer-mode-map ""
+    ibuffer-operate-menu-data))
+(defvar ibuffer-popup-menu ibuffer-operate-menu-data)
 ;;; Utility functions
 (defun ibuffer-columnize-and-insert-list (list &optional pad-width)
   "Insert LIST into the current buffer in as many columns as possible.
 	  (incf count))
-	  (line-beginning-position)
-	  (line-end-position))
+	  (ibuffer-line-beginning-position)
+	  (ibuffer-line-end-position))
 	(forward-line (if forwardp 1 -1)))
       (nreverse result))))
 (defsubst ibuffer-current-mark ()
-  (cadr (get-text-property (line-beginning-position)
+  (cadr (get-text-property (ibuffer-line-beginning-position)
 (defun ibuffer-mouse-toggle-mark (event)
   "Display a menu of operations."
   (interactive "e")
   (let ((origline (count-lines (point-min) (point))))
-    (unwind-protect
+    (let ((pnt (ibuffer-event-position event)))
+      (unwind-protect
+	  (progn
+	    (setq buffer-read-only nil)
+	    (ibuffer-save-marks
+	     ;; hm.  we could probably do this in a better fashion
+	     (ibuffer-unmark-all ?\r)
+	     (setq buffer-read-only nil)
+	     (goto-char pnt)
+	     (ibuffer-set-mark ibuffer-marked-char)
+	     (setq buffer-read-only nil)
+	     (save-excursion
+	       (if (featurep 'xemacs)
+		   (popup-menu-and-execute-in-window
+		    ibuffer-popup-menu
+		    (selected-window))
+		 (popup-menu ibuffer-popup-menu)))))
-	  (setq buffer-read-only nil)
-	  (ibuffer-save-marks
-	   ;; hm.  we could probably do this in a better fashion
-	   (ibuffer-unmark-all ?\r)
-	   (setq buffer-read-only nil)
-	   (mouse-set-point event)
-	   (ibuffer-set-mark ibuffer-marked-char)
-	   (setq buffer-read-only nil)
-	   (save-excursion
-	     (popup-menu ibuffer-mode-operate-map))))
-      (progn
-	(setq buffer-read-only t)
-	(goto-line (1+ origline))))))
+	  (setq buffer-read-only t)
+	  (goto-line (1+ origline)))))))
+(defun ibuffer-customize ()
+  "Begin customizing Ibuffer interactively."
+  (interactive)
+  (customize-group 'ibuffer))
 (defun ibuffer-backward-line (&optional arg)
   "Move backwards ARG lines, wrapping around the list if necessary."
   (prog1 (ibuffer-map-on-mark ibuffer-marked-char func)
     (ibuffer-redisplay t)))
-(defun ibuffer-shrink-to-fit (&optional owin)
-  (fit-window-to-buffer nil (when owin (/ (frame-height)
-					  (length (window-list (selected-frame)))))))
 (defun ibuffer-confirm-operation-on (operation names)
   "Display a buffer asking whether to perform OPERATION on NAMES."
   (or ibuffer-expert
   (assert (eq major-mode 'ibuffer-mode))
   (unless arg
     (setq arg 1))
-  (while (and (get-text-property (line-beginning-position)
+  (while (and (get-text-property (ibuffer-line-beginning-position)
 	      (not (eobp)))
     (forward-line 1))
     (while (> arg 0)
       (ibuffer-set-mark mark)
       (forward-line movement)
-      (when (or (get-text-property (line-beginning-position)
+      (when (or (get-text-property (ibuffer-line-beginning-position)
 	(forward-line (- movement))
 (defun ibuffer-set-mark-1 (mark)
-  (let ((beg (line-beginning-position))
-	(end (line-end-position)))
+  (let ((beg (ibuffer-line-beginning-position))
+	(end (ibuffer-line-end-position)))
     (put-text-property beg end 'ibuffer-properties
 		       (list (ibuffer-current-buffer)
   (ibuffer-mark-interactive arg ibuffer-deletion-char -1))
 (defun ibuffer-current-buffer (&optional must-be-live)
-  (let ((buf (car (get-text-property (line-beginning-position)
+  (let ((buf (car (get-text-property (ibuffer-line-beginning-position)
     (when (and must-be-live
 	       (not (buffer-live-p buf)))
 (defun ibuffer-compile-make-eliding-form (strvar elide from-end-p)
-  (let ((ellipsis (if (ibuffer-use-fontification) 
-		      (propertize ibuffer-eliding-string 'face 'bold)
+  (let ((ellipsis (if ibuffer-use-fontification
+		      (ibuffer-propertize ibuffer-eliding-string 'face 'bold)
     (if (or elide ibuffer-elide-long-columns)
 	`(if (> strlen 5)
 		   (nconc (list 'lambda '(buffer mark))
-			  `((let ,(append '(pt)
+			  `((let ,(append ;'(pt) FIXMEFIXMEFIXME
 					  (when str-used
 					  (when global-strlen-used
 			     ('mouse-face 'highlight 'keymap ibuffer-name-map
 	                      'ibuffer-name-column t
- 			      'help-echo "mouse-1: mark this buffer\nmouse-2: select this buffer\nmouse-3: operate on this buffer"))
+ 			      'help-echo "button1: mark, button2: select, button3: operate"))
 (define-ibuffer-column size (:inline t)
 			     ('mouse-face 'highlight
   			      'keymap ibuffer-mode-name-map
-			      'help-echo "mouse-2: filter by this mode"))
+			      'help-echo "button2: filter by mode"))
   (format "%s" mode-name))
 (define-ibuffer-column process ()
       (while (< (point) end)
 	(if (get-text-property (point) 'ibuffer-title-header)
-	    (put-text-property (point) (line-end-position) 'face ibuffer-title-face)
+	    (put-text-property (point) (ibuffer-line-end-position) 'face ibuffer-title-face)
 	  (unless (get-text-property (point) 'ibuffer-title)
 	    (multiple-value-bind (buf mark)
 		(get-text-property (point) 'ibuffer-properties)
 	      (let* ((namebeg (next-single-property-change (point) 'ibuffer-name-column
-							   nil (line-end-position)))
+							   nil (ibuffer-line-end-position)))
 		     (nameend (next-single-property-change namebeg 'ibuffer-name-column
-							   nil (line-end-position))))
+							   nil (ibuffer-line-end-position))))
 		(put-text-property namebeg
 	(forward-line 1))))
   (when verbose (message "Fontifying...done")))
-(defun ibuffer-unfontify-region-function (beg end)
+(defun ibuffer-unfontify-region-function (beg end &optional loudly)
   (let ((inhibit-read-only t))
     (remove-text-properties beg end '(face nil))))
   (let ((buf (ibuffer-current-buffer)))
     (when buf
       (let ((mark (ibuffer-current-mark)))
-	(delete-region (point) (1+ (line-end-position)))
+	(delete-region (point) (1+ (ibuffer-line-end-position)))
 	 buf mark
 current mark symbol, and the beginning and ending line positions."
   (assert (eq major-mode 'ibuffer-mode))
   (let ((curline (count-lines (point-min)
-			      (line-beginning-position)))
+			      (ibuffer-line-beginning-position)))
 	(deleted-lines-count 0)
 	(ibuffer-map-lines-total 0)
         (ibuffer-map-lines-count 0))
                           (funcall function
-                                   (line-beginning-position)
-                                   (1+ (line-end-position))))
+                                   (ibuffer-line-beginning-position)
+                                   (1+ (ibuffer-line-end-position))))
                       ;; Kill the line if the buffer is dead
                ;; A given mapping function should return:
                (cond ((null result)
                       (forward-line 1))
                      ((eq result 'kill)
-                      (delete-region (line-beginning-position)
-                                     (1+ (line-end-position)))
+                      (delete-region (ibuffer-line-beginning-position)
+                                     (1+ (ibuffer-line-end-position)))
 		      (incf deleted-lines-count)
                       (incf ibuffer-map-lines-count))
 	 (let ((str (save-excursion
 		      (forward-line -1)
-		      (buffer-substring (point) (line-end-position)))))
+		      (buffer-substring (point) (ibuffer-line-end-position)))))
 	   (apply #'insert (mapcar
 			    #'(lambda (c)
 				(if (not (or (char-equal c ? )
       (if ibuffer-use-header-line
 	  (setq header-line-format
 		(when ibuffer-filtering-qualifiers
-		  (replace-regexp-in-string "%" "%%"
-					    (concat mode-name result))))
+		  (ibuffer-replace-regexp-in-string "%" "%%"
+						    (concat mode-name result))))
 	  (setq mode-name (concat mode-name result))
 	  (when (boundp 'header-line-format)
 	(orig (count-lines (point-min) (point)))
 	;; Inhibit font-lock caching tricks, since we're modifying the
 	;; entire buffer at once
-	(after-change-functions nil))
+	;; (after-change-functions nil)
+	)
 	  (setq buffer-read-only nil)
 	      (unless (eq major-mode 'ibuffer-mode)
 		(setq need-update t))
-	      (when (ibuffer-use-fontification)
+	      (when ibuffer-use-fontification
 		(require 'font-lock))
 	      (setq ibuffer-delete-window-on-quit other-window-p)
 	      (when shrink
 		(message "Commands: m, u, t, RET, g, k, S, D, Q; q to quit; h for help")))
 	  (select-window owin))))))
 (defun ibuffer-mode ()
   "A major mode for viewing a list of buffers.
 In ibuffer, you can conveniently perform many operations on the
   (setq mode-name "Ibuffer")
   (setq buffer-read-only t)
-  (setq truncate-lines t)
+  (setq truncate-lines ibuffer-truncate-lines)
   ;; This makes things less ugly for Emacs 21 users with a non-nil
   ;; `show-trailing-whitespace'.
   (setq show-trailing-whitespace nil)
-  ;; Dummy font-lock-defaults to make font-lock turn on.  We want this
-  ;; so we know when to enable ibuffer's internal fontification.
-  (set (make-local-variable 'font-lock-defaults)
-       '(nil t nil nil nil
-	     (font-lock-fontify-region-function . ibuffer-fontify-region-function)
-	     (font-lock-unfontify-region-function . ibuffer-unfontify-region-function)))
+  ;; This should be nicer
+  (set (make-local-variable 'font-lock-defaults) nil)
+  (set (make-local-variable 'font-lock-fontify-region-function)
+       'ibuffer-fontify-region-function)
+  (set (make-local-variable 'font-lock-unfontify-region-function)
+       'ibuffer-unfontify-region-function)
   (set (make-local-variable 'revert-buffer-function)
   (set (make-local-variable 'ibuffer-sorting-mode)
   (when (featurep 'ibuf-ext)
     (set (make-local-variable 'ibuffer-tmp-hide-regexps) nil)
     (set (make-local-variable 'ibuffer-tmp-show-regexps) nil))
-  (define-key ibuffer-mode-map [menu-bar edit] 'undefined)
-  (define-key ibuffer-mode-map [menu-bar operate] (cons "Operate" ibuffer-mode-operate-map))
+  (easy-menu-add ibuffer-mode-operate-menu)
+  (easy-menu-add ibuffer-mode-immediate-menu)
+  (easy-menu-add ibuffer-mode-mark-menu)
+  (easy-menu-add ibuffer-mode-sort-menu)
+  (easy-menu-add ibuffer-mode-filter-menu)
   (when ibuffer-default-directory
     (setq default-directory ibuffer-default-directory))
   (run-hooks 'ibuffer-mode-hooks)
   ;; called after mode hooks to allow the user to add filters
-  (ibuffer-update-mode-name))
+  (ibuffer-update-mode-name)
+  (if ibuffer-use-fontification
+      (turn-on-font-lock)))
 (provide 'ibuffer)