]> git.eshelyaron.com Git - emacs.git/commitdiff
(bs--make-header-match-string, bs-show-in-buffer, bs--nth-wrapper): Simplify.
authorJuanma Barranquero <lekktu@gmail.com>
Tue, 16 Oct 2007 10:40:02 +0000 (10:40 +0000)
committerJuanma Barranquero <lekktu@gmail.com>
Tue, 16 Oct 2007 10:40:02 +0000 (10:40 +0000)
(bs-select, bs--insert-one-entry): Simplify.  Use `when'.
(bs-buffer-list): Simplify.  Use `when'.  Use `string-match-p'.
(bs-sort-buffer-interns-are-last): Use `string-match-p'.
(bs-attributes-list, bs-max-window-height, bs-must-always-show-regexp,
bs-maximal-buffer-name-column, bs-minimal-buffer-name-column, bs-configurations,
bs-default-configuration, bs-alternative-configuration,
bs-cycle-configuration-name, bs-string-show-always, bs-string-show-never,
bs-string-current, bs-string-current-marked, bs-string-marked,
bs-string-show-normally, bs-sort-functions, bs-default-sort-name):
Remove * in docstrings.
(bs--redisplay, bs--goto-current-buffer, bs--current-buffer, bs-delete,
bs-apply-sort-faces, bs-next-config-aux): Use `when'.
(bs--window-config-coming-from): Revert 2006-11-09 change.
(bs--restore-window-config): Keep the selected frame.
(bs--track-window-changes, bs--remove-hooks): New functions.
(bs-mode): Use `define-derived-mode'.  Set hook to track window changes.
(bs--create-header): Remove.
(bs--create-header-line): New function, based on `bs--create-header'.
(bs--show-header): Use `bs--create-header-line'.
(bs--show-with-configuration): Revert 2006-11-09 change.
Don't reuse window unless it is visible on the selected frame.
Restore window configuration (possibly in a different frame)
before creating any window.

lisp/ChangeLog
lisp/bs.el

index 17135a37a336cbb073925aa5d59faa9ec254bba5..69919bdec0fa96a0eef8281d6642feca6f520081 100644 (file)
@@ -1,3 +1,31 @@
+2007-10-16  Juanma Barranquero  <lekktu@gmail.com>
+
+       * bs.el (bs--make-header-match-string, bs-show-in-buffer)
+       (bs--nth-wrapper): Simplify.
+       (bs-select, bs--insert-one-entry): Simplify.  Use `when'.
+       (bs-buffer-list): Simplify.  Use `when'.  Use `string-match-p'.
+       (bs-sort-buffer-interns-are-last): Use `string-match-p'.
+       (bs-attributes-list, bs-max-window-height, bs-must-always-show-regexp)
+       (bs-maximal-buffer-name-column, bs-minimal-buffer-name-column)
+       (bs-configurations, bs-default-configuration)
+       (bs-alternative-configuration, bs-cycle-configuration-name)
+       (bs-string-show-always, bs-string-show-never, bs-string-current)
+       (bs-string-current-marked, bs-string-marked, bs-string-show-normally)
+       (bs-sort-functions, bs-default-sort-name): Remove * in docstrings.
+       (bs--redisplay, bs--goto-current-buffer, bs--current-buffer, bs-delete)
+       (bs-apply-sort-faces, bs-next-config-aux): Use `when'.
+       (bs--window-config-coming-from): Revert 2006-11-09 change.
+       (bs--restore-window-config): Keep the selected frame.
+       (bs--track-window-changes, bs--remove-hooks): New functions.
+       (bs-mode): Use `define-derived-mode'.  Set hook to track window changes.
+       (bs--create-header): Remove.
+       (bs--create-header-line): New function, based on `bs--create-header'.
+       (bs--show-header): Use `bs--create-header-line'.
+       (bs--show-with-configuration): Revert 2006-11-09 change.
+       Don't reuse window unless it is visible on the selected frame.
+       Restore window configuration (possibly in a different frame)
+       before creating any window.
+
 2007-10-16  Glenn Morris  <rgm@gnu.org>
 
        * simple.el (blink-matching-open): Don't report false errors with
index 6390bd2dd81271a49189c6a61e450c499d0cbeda..bb2dbae83c0a5153eee22340702ba811b930d320 100644 (file)
     (""       2   2 left  "  ")
     ("File"   12 12 left  bs--get-file-name)
     (""       2   2 left  "  "))
-  "*List specifying the layout of a Buffer Selection Menu buffer.
+  "List specifying the layout of a Buffer Selection Menu buffer.
 Each entry specifies a column and is a list of the form of:
 \(HEADER MINIMUM-LENGTH MAXIMUM-LENGTH ALIGNMENT FUN-OR-STRING)
 
@@ -180,12 +180,7 @@ return a string representing the column's value."
 
 (defun bs--make-header-match-string ()
   "Return a regexp matching the first line of a Buffer Selection Menu buffer."
-  (let ((res "^\\(")
-       (ele bs-attributes-list))
-    (while ele
-      (setq res (concat res (car (car ele)) " *"))
-      (setq ele (cdr ele)))
-    (concat res "$\\)")))
+  (concat "^\\(" (mapconcat #'car bs-attributes-list " *") " *$\\)"))
 
 ;; Font-Lock-Settings
 (defvar bs-mode-font-lock-keywords
@@ -206,7 +201,7 @@ return a string representing the column's value."
   "Default font lock expressions for Buffer Selection Menu.")
 
 (defcustom bs-max-window-height 20
-  "*Maximal window height of Buffer Selection Menu."
+  "Maximal window height of Buffer Selection Menu."
   :group 'bs-appearance
   :type 'integer)
 
@@ -224,7 +219,7 @@ it is reset to nil.  Use `bs-must-always-show-regexp' to specify buffers
 that must always be shown regardless of the configuration.")
 
 (defcustom bs-must-always-show-regexp nil
-  "*Regular expression for specifying buffers to show always.
+  "Regular expression for specifying buffers to show always.
 A buffer whose name matches this regular expression will
 be shown regardless of current configuration of Buffer Selection Menu."
   :group 'bs
@@ -246,7 +241,7 @@ The function gets two arguments - the buffers to compare.
 It must return non-nil if the first buffer should sort before the second.")
 
 (defcustom bs-maximal-buffer-name-column 45
-  "*Maximum column width for buffer names.
+  "Maximum column width for buffer names.
 The column for buffer names has dynamic width.  The width depends on
 maximal and minimal length of names of buffers to show.  The maximal
 width is bounded by `bs-maximal-buffer-name-column'.
@@ -255,7 +250,7 @@ See also `bs-minimal-buffer-name-column'."
   :type 'integer)
 
 (defcustom bs-minimal-buffer-name-column 15
-  "*Minimum column width for buffer names.
+  "Minimum column width for buffer names.
 The column for buffer names has dynamic width.  The width depends on
 maximal and minimal length of names of buffers to show.  The minimal
 width is bounded by `bs-minimal-buffer-name-column'.
@@ -272,7 +267,7 @@ See also `bs-maximal-buffer-name-column'."
     ("files-and-scratch" "^\\*scratch\\*$" nil nil bs-visits-non-file
      bs-sort-buffer-interns-are-last)
     ("all-intern-last" nil nil nil nil bs-sort-buffer-interns-are-last))
-  "*List of all configurations you can use in the Buffer Selection Menu.
+  "List of all configurations you can use in the Buffer Selection Menu.
 A configuration describes which buffers appear in Buffer Selection Menu
 and also the order of buffers.  A configuration is a list with
 six elements.  The first element is a string and describes the configuration.
@@ -284,7 +279,7 @@ By setting these variables you define a configuration."
   :type '(repeat sexp))
 
 (defcustom bs-default-configuration "files"
-  "*Name of default configuration used by the Buffer Selection Menu.
+  "Name of default configuration used by the Buffer Selection Menu.
 \\<bs-mode-map>
 Will be changed using key \\[bs-select-next-configuration].
 Must be a string used in `bs-configurations' for naming a configuration."
@@ -292,7 +287,7 @@ Must be a string used in `bs-configurations' for naming a configuration."
   :type 'string)
 
 (defcustom bs-alternative-configuration "all"
-  "*Name of configuration used when calling `bs-show' with \
+  "Name of configuration used when calling `bs-show' with \
 \\[universal-argument] as prefix key.
 Must be a string used in `bs-configurations' for naming a configuration."
   :group 'bs
@@ -303,7 +298,7 @@ Must be a string used in `bs-configurations' for naming a configuration."
 Must be a string used in `bs-configurations' for naming a configuration.")
 
 (defcustom bs-cycle-configuration-name nil
-  "*Name of configuration used when cycling through the buffer list.
+  "Name of configuration used when cycling through the buffer list.
 A value of nil means to use current configuration `bs-default-configuration'.
 Must be a string used in `bs-configurations' for naming a configuration."
   :group 'bs
@@ -311,32 +306,32 @@ Must be a string used in `bs-configurations' for naming a configuration."
    string))
 
 (defcustom bs-string-show-always "+"
-  "*String added in column 1 indicating a buffer will always be shown."
+  "String added in column 1 indicating a buffer will always be shown."
   :group 'bs-appearance
   :type 'string)
 
 (defcustom bs-string-show-never "-"
-  "*String added in column 1 indicating a buffer will never be shown."
+  "String added in column 1 indicating a buffer will never be shown."
   :group 'bs-appearance
   :type 'string)
 
 (defcustom bs-string-current "."
-  "*String added in column 1 indicating the current buffer."
+  "String added in column 1 indicating the current buffer."
   :group 'bs-appearance
   :type 'string)
 
 (defcustom bs-string-current-marked "#"
-  "*String added in column 1 indicating the current buffer when it is marked."
+  "String added in column 1 indicating the current buffer when it is marked."
   :group 'bs-appearance
   :type 'string)
 
 (defcustom bs-string-marked ">"
-  "*String added in column 1 indicating a marked buffer."
+  "String added in column 1 indicating a marked buffer."
   :group 'bs-appearance
   :type 'string)
 
 (defcustom bs-string-show-normally  " "
-  "*String added in column 1 indicating an unmarked buffer."
+  "String added in column 1 indicating an unmarked buffer."
   :group 'bs-appearance
   :type 'string)
 
@@ -390,7 +385,7 @@ A value of `always' means to show buffer regardless of the configuration.")
     ("by mode"     bs--sort-by-mode     "Mode"   region)
     ("by filename" bs--sort-by-filename "File"   region)
     ("by nothing"  nil                  nil      nil))
-  "*List of all possible sorting aspects for Buffer Selection Menu.
+  "List of all possible sorting aspects for Buffer Selection Menu.
 You can add a new entry with a call to `bs-define-sort-function'.
 Each element is a list of four elements (NAME FUNCTION REGEXP-FOR-SORTING FACE).
 NAME specifies the sort order defined by function FUNCTION.
@@ -425,7 +420,7 @@ The new sort aspect will be inserted into list `bs-sort-functions'."
 This is an element of `bs-sort-functions'.")
 
 (defcustom bs-default-sort-name "by nothing"
-  "*Name of default sort behavior.
+  "Name of default sort behavior.
 Must be \"by nothing\" or a string used in `bs-sort-functions' for
 naming a sort behavior.  Default is \"by nothing\" which means no sorting."
   :group 'bs
@@ -445,7 +440,6 @@ defined by current configuration `bs-current-configuration'.")
 
 (defvar bs--window-config-coming-from nil
   "Window configuration before starting Buffer Selection Menu.")
-(make-variable-frame-local 'bs--window-config-coming-from)
 
 (defvar bs--intern-show-never "^ \\|\\*buffer-selection\\*"
   "Regular expression specifying which buffers never to show.
@@ -529,45 +523,43 @@ a special function.  SORT-DESCRIPTION is an element of `bs-sort-functions'."
   (setq sort-description (or sort-description bs--current-sort-function)
        list (or list (buffer-list)))
   (let ((result nil))
-    (while list
-      (let* ((buffername (buffer-name (car list)))
-            (int-show-never (string-match bs--intern-show-never buffername))
+    (dolist (buf list)
+      (let* ((buffername (buffer-name buf))
+            (int-show-never (string-match-p bs--intern-show-never buffername))
             (ext-show-never (and bs-dont-show-regexp
-                                 (string-match bs-dont-show-regexp
-                                               buffername)))
+                                 (string-match-p bs-dont-show-regexp
+                                                 buffername)))
             (extern-must-show (or (and bs-must-always-show-regexp
-                                       (string-match
+                                       (string-match-p
                                         bs-must-always-show-regexp
                                         buffername))
                                   (and bs-must-show-regexp
-                                       (string-match bs-must-show-regexp
-                                                     buffername))))
+                                       (string-match-p bs-must-show-regexp
+                                                       buffername))))
             (extern-show-never-from-fun (and bs-dont-show-function
                                              (funcall bs-dont-show-function
-                                                      (car list))))
+                                                      buf)))
             (extern-must-show-from-fun (and bs-must-show-function
                                             (funcall bs-must-show-function
-                                                     (car list))))
-            (show-flag (buffer-local-value 'bs-buffer-show-mark (car list))))
-       (if (or (eq show-flag 'always)
-               (and (or bs--show-all (not (eq show-flag 'never)))
-                    (not int-show-never)
-                    (or bs--show-all
-                        extern-must-show
-                        extern-must-show-from-fun
-                        (and (not ext-show-never)
-                             (not extern-show-never-from-fun)))))
-           (setq result (cons (car list)
-                              result)))
-       (setq list (cdr list))))
+                                                     buf)))
+            (show-flag (buffer-local-value 'bs-buffer-show-mark buf)))
+       (when (or (eq show-flag 'always)
+                 (and (or bs--show-all (not (eq show-flag 'never)))
+                      (not int-show-never)
+                      (or bs--show-all
+                          extern-must-show
+                          extern-must-show-from-fun
+                          (and (not ext-show-never)
+                               (not extern-show-never-from-fun)))))
+         (setq result (cons buf result)))))
     (setq result (reverse result))
     ;; The current buffer which was the start point of bs should be an element
     ;; of result list, so that we can leave with space and be back in the
     ;; buffer we started bs-show.
-    (if (and bs--buffer-coming-from
-            (buffer-live-p bs--buffer-coming-from)
-            (not (memq bs--buffer-coming-from result)))
-       (setq result (cons bs--buffer-coming-from result)))
+    (when (and bs--buffer-coming-from
+              (buffer-live-p bs--buffer-coming-from)
+              (not (memq bs--buffer-coming-from result)))
+      (setq result (cons bs--buffer-coming-from result)))
     ;; sorting
     (if (and sort-description
             (nth 1 sort-description))
@@ -587,8 +579,8 @@ If KEEP-LINE-P is non-nil the point will stay on current line.
 SORT-DESCRIPTION is an element of `bs-sort-functions'."
   (let ((line (1+ (count-lines 1 (point)))))
     (bs-show-in-buffer (bs-buffer-list nil sort-description))
-    (if keep-line-p
-       (goto-line line))
+    (when keep-line-p
+      (goto-line line))
     (beginning-of-line)))
 
 (defun bs--goto-current-buffer ()
@@ -602,10 +594,10 @@ actually the line which begins with character in `bs-string-current' or
        point)
     (save-excursion
       (goto-char (point-min))
-      (if (search-forward-regexp regexp nil t)
-         (setq point (- (point) 1))))
-    (if point
-       (goto-char point))))
+      (when (search-forward-regexp regexp nil t)
+       (setq point (1- (point)))))
+    (when point
+      (goto-char point))))
 
 (defun bs--current-config-message ()
   "Return a string describing the current `bs-mode' configuration."
@@ -614,7 +606,23 @@ actually the line which begins with character in `bs-string-current' or
     (format "Show buffer by configuration %S"
            bs-current-configuration)))
 
-(defun bs-mode ()
+(defun bs--track-window-changes (frame)
+  "Track window changes to refresh the buffer list.
+Used from `window-size-change-functions'."
+  (let ((win (get-buffer-window "*buffer-selection*" frame)))
+    (when win
+      (with-selected-window win
+       (bs-refresh)
+       (bs--set-window-height)))))
+
+(defun bs--remove-hooks ()
+  "Remove `bs--track-window-changes' and auxiliary hooks."
+  (remove-hook 'window-size-change-functions 'bs--track-window-changes)
+  ;; Remove itself
+  (remove-hook 'kill-buffer-hook 'bs--remove-hooks t)
+  (remove-hook 'change-major-mode-hook 'bs--remove-hooks t))
+
+(define-derived-mode bs-mode nil "Buffer-Selection-Menu"
   "Major mode for editing a subset of Emacs' buffers.
 \\<bs-mode-map>
 Aside from two header lines each line describes one buffer.
@@ -647,27 +655,27 @@ available Buffer Selection Menu configuration.
 to show always.
 \\[bs-visit-tags-table] -- call `visit-tags-table' on current line's buffer.
 \\[bs-help] -- display this help text."
-  (interactive)
-  (kill-all-local-variables)
-  (use-local-map bs-mode-map)
   (make-local-variable 'font-lock-defaults)
   (make-local-variable 'font-lock-verbose)
   (make-local-variable 'font-lock-global-modes)
   (buffer-disable-undo)
-  (setq major-mode 'bs-mode
-       mode-name "Buffer-Selection-Menu"
-       buffer-read-only t
+  (setq buffer-read-only t
        truncate-lines t
        show-trailing-whitespace nil
        font-lock-global-modes '(not bs-mode)
        font-lock-defaults '(bs-mode-font-lock-keywords t)
        font-lock-verbose nil)
-  (run-mode-hooks 'bs-mode-hook))
+  (add-hook 'window-size-change-functions 'bs--track-window-changes)
+  (add-hook 'kill-buffer-hook 'bs--remove-hooks nil t)
+  (add-hook 'change-major-mode-hook 'bs--remove-hooks nil t))
 
 (defun bs--restore-window-config ()
   "Restore window configuration on the current frame."
   (when bs--window-config-coming-from
-    (set-window-configuration bs--window-config-coming-from)
+    (let ((frame (selected-frame)))
+      (unwind-protect
+          (set-window-configuration bs--window-config-coming-from)
+       (select-frame frame)))
     (setq bs--window-config-coming-from nil)))
 
 (defun bs-kill ()
@@ -705,8 +713,8 @@ Raise an error if not on a buffer line."
   (beginning-of-line)
   (let ((line (+ (- bs-header-lines-length)
                 (count-lines 1 (point)))))
-    (if (< line 0)
-       (error "You are on a header row"))
+    (when (< line 0)
+      (error "You are on a header row"))
     (nth line bs-current-list)))
 
 (defun bs--update-current-line ()
@@ -736,19 +744,18 @@ Leave Buffer Selection Menu."
     (bury-buffer (current-buffer))
     (bs--restore-window-config)
     (switch-to-buffer buffer)
-    (if bs--marked-buffers
-       ;; Some marked buffers for selection
-       (let* ((all (delq buffer bs--marked-buffers))
-              (height (/ (1- (frame-height)) (1+ (length all)))))
-         (delete-other-windows)
-         (switch-to-buffer buffer)
-         (while all
-           (split-window nil height)
-           (other-window 1)
-           (switch-to-buffer (car all))
-           (setq all (cdr all)))
-         ;; goto window we have started bs.
-         (other-window 1)))))
+    (when bs--marked-buffers
+      ;; Some marked buffers for selection
+      (let* ((all (delq buffer bs--marked-buffers))
+            (height (/ (1- (frame-height)) (1+ (length all)))))
+       (delete-other-windows)
+       (switch-to-buffer buffer)
+       (dolist (buf all)
+         (split-window nil height)
+         (other-window 1)
+         (switch-to-buffer buf))
+       ;; goto window we have started bs.
+       (other-window 1)))))
 
 (defun bs-select-other-window ()
   "Select current line's buffer by `switch-to-buffer-other-window'.
@@ -912,11 +919,10 @@ WHAT is a value of nil, `never', or `always'."
     (delete-region (point) (save-excursion
                             (end-of-line)
                             (if (eobp) (point) (1+ (point)))))
-    (if (eobp)
-       (progn
-         (backward-delete-char 1)
-         (beginning-of-line)
-         (recenter -1)))
+    (when (eobp)
+      (backward-delete-char 1)
+      (beginning-of-line)
+      (recenter -1))
     (bs--set-window-height)))
 
 (defun bs-delete-backward ()
@@ -945,14 +951,14 @@ Default is `bs--current-sort-function'."
                              bs--current-sort-function)))
     (save-excursion
       (goto-char (point-min))
-      (if (and (nth 2 sort-description)
-              (search-forward-regexp (nth 2 sort-description) nil t))
-         (let ((inhibit-read-only t))
-           (put-text-property (match-beginning 0)
-                              (match-end 0)
-                              'face
-                              (or (nth 3 sort-description)
-                                  'region)))))))
+      (when (and (nth 2 sort-description)
+                (search-forward-regexp (nth 2 sort-description) nil t))
+       (let ((inhibit-read-only t))
+         (put-text-property (match-beginning 0)
+                            (match-end 0)
+                            'face
+                            (or (nth 3 sort-description)
+                                'region)))))))
 
 (defun bs-toggle-show-all ()
   "Toggle show all buffers / show buffers with current configuration."
@@ -983,10 +989,8 @@ Uses function `vc-toggle-read-only'."
 
 (defun bs--nth-wrapper (count fun &rest args)
   "Call COUNT times function FUN with arguments ARGS."
-  (setq count (or count 1))
-  (while (> count 0)
-    (apply fun args)
-    (setq count (1- count))))
+  (dotimes (i (or count 1))
+    (apply fun args)))
 
 (defun bs-up (arg)
   "Move cursor vertically up ARG lines in Buffer Selection Menu."
@@ -1026,7 +1030,7 @@ A value of nil means BUFFER belongs to a file."
 
 (defun bs-sort-buffer-interns-are-last (b1 b2)
   "Function for sorting internal buffers at the end of all buffers."
-  (string-match "^\\*" (buffer-name b2)))
+  (string-match-p "^\\*" (buffer-name b2)))
 
 ;; ----------------------------------------------------------------------
 ;; Configurations:
@@ -1108,8 +1112,8 @@ Will return the first if START-NAME is at end."
        (length (length list))
        pos)
     (while (and assocs (not pos))
-      (if (string= (car (car assocs)) start-name)
-         (setq pos (- length (length assocs))))
+      (when (string= (car (car assocs)) start-name)
+       (setq pos (- length (length assocs))))
       (setq assocs (cdr assocs)))
     (setq pos (1+ pos))
     (if (eq pos length)
@@ -1151,10 +1155,9 @@ and move point to current buffer."
     (erase-buffer)
     (setq bs--name-entry-length name-entry-length)
     (bs--show-header)
-    (while list
-      (bs--insert-one-entry (car list))
-      (insert "\n")
-      (setq list (cdr list)))
+    (dolist (buffer list)
+      (bs--insert-one-entry buffer)
+      (insert "\n"))
     (delete-backward-char 1)
     (bs--set-window-height)
     (bs--goto-current-buffer)
@@ -1348,27 +1351,21 @@ It goes over all columns described in `bs-attributes-list'
 and evaluates corresponding string.  Inserts string in current buffer;
 normally *buffer-selection*."
   (let ((string "")
-       (columns bs-attributes-list)
        (to-much 0)
         (apply-args (append (list bs--buffer-coming-from bs-current-list))))
     (save-excursion
-      (while columns
-       (set-buffer buffer)
-       (let ((min   (bs--get-value (nth 1 (car columns))))
-             ;;(max   (bs--get-value (nth 2 (car columns)))) refered no more
-             (align (nth 3 (car columns)))
-             (fun   (nth 4 (car columns)))
-             (val   nil)
-             new-string)
-         (setq val (bs--get-value fun apply-args))
-         (setq new-string (bs--format-aux val align (- min to-much)))
+      (set-buffer buffer)
+      (dolist (column bs-attributes-list)
+       (let* ((min (bs--get-value (nth 1 column)))
+              (new-string (bs--format-aux (bs--get-value (nth 4 column) ; fun
+                                                         apply-args)
+                                          (nth 3 column)                ; align
+                                          (- min to-much)))
+              (len (length new-string)))
          (setq string (concat string new-string))
-         (if (> (length new-string) min)
-             (setq to-much (- (length new-string) min)))
-         )                             ; let
-       (setq columns (cdr columns))))
-    (insert string)
-    string))
+         (when (> len min)
+           (setq to-much (- len min))))))
+    (insert string)))
 
 (defun bs--format-aux (string align len)
   "Pad STRING to length LEN with alignment ALIGN.
@@ -1382,28 +1379,26 @@ ALIGN is one of the symbols `left', `middle', or `right'."
 
 (defun bs--show-header ()
   "Insert header for Buffer Selection Menu in current buffer."
-  (dolist (string (bs--create-header))
-    (insert string "\n")))
+  (insert (bs--create-header-line #'identity)
+         "\n"
+         (bs--create-header-line (lambda (title)
+                                   (make-string (length title) ?-)))
+         "\n"))
 
 (defun bs--get-name-length ()
   "Return value of `bs--name-entry-length'."
   bs--name-entry-length)
 
-(defun bs--create-header ()
-  "Return all header lines used in Buffer Selection Menu as a list of strings."
-  (list (mapconcat (lambda (column)
-                    (bs--format-aux (bs--get-value (car column))
-                                    (nth 3 column) ; align
-                                    (bs--get-value (nth 1 column))))
-                  bs-attributes-list
-                  "")
-       (mapconcat (lambda (column)
-                    (let ((length (length (bs--get-value (car column)))))
-                      (bs--format-aux (make-string length ?-)
-                                      (nth 3 column) ; align
-                                      (bs--get-value (nth 1 column)))))
-                  bs-attributes-list
-                  "")))
+(defun bs--create-header-line (col)
+  "Generate a line for the header.
+COL is called for each column in `bs-attributes-list' as a
+function of one argument, the string heading for the column."
+  (mapconcat (lambda (column)
+              (bs--format-aux (funcall col (bs--get-value (car column)))
+                              (nth 3 column) ; align
+                              (bs--get-value (nth 1 column))))
+            bs-attributes-list
+            ""))
 
 (defun bs--show-with-configuration (name &optional arg)
   "Display buffer list of configuration with name NAME.
@@ -1424,14 +1419,14 @@ for buffer selection."
       (setq bs--buffer-coming-from (current-buffer)))
     (let ((liste (bs-buffer-list))
          (active-window (get-window-with-predicate
-                          (lambda (w)
-                            (string= (buffer-name (window-buffer w))
-                                     "*buffer-selection*")))))
+                         (lambda (w)
+                           (string= (buffer-name (window-buffer w))
+                                    "*buffer-selection*"))
+                         nil (selected-frame))))
       (if active-window
          (select-window active-window)
-        (modify-frame-parameters nil
-                                 (list (cons 'bs--window-config-coming-from
-                                             (current-window-configuration))))
+       (bs--restore-window-config)
+       (setq bs--window-config-coming-from (current-window-configuration))
        (when (> (window-height (selected-window)) 7)
           (split-window-vertically)
           (other-window 1)))