From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Yuri Khan Newsgroups: gmane.emacs.help Subject: tabbar: Grouping buffers by windows Date: Thu, 19 Sep 2013 22:06:59 +0700 Message-ID: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Trace: ger.gmane.org 1379603258 15505 80.91.229.3 (19 Sep 2013 15:07:38 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 19 Sep 2013 15:07:38 +0000 (UTC) To: "help-gnu-emacs@gnu.org" Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Thu Sep 19 17:07:40 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 1VMfpT-0000Ds-HX for geh-help-gnu-emacs@m.gmane.org; Thu, 19 Sep 2013 17:07:39 +0200 Original-Received: from localhost ([::1]:51665 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VMfpT-000295-1m for geh-help-gnu-emacs@m.gmane.org; Thu, 19 Sep 2013 11:07:39 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:55472) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VMfpC-00028h-7f for help-gnu-emacs@gnu.org; Thu, 19 Sep 2013 11:07:28 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VMfp6-0002tC-6e for help-gnu-emacs@gnu.org; Thu, 19 Sep 2013 11:07:22 -0400 Original-Received: from mail-lb0-f175.google.com ([209.85.217.175]:58571) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VMfp5-0002sE-Rn for help-gnu-emacs@gnu.org; Thu, 19 Sep 2013 11:07:16 -0400 Original-Received: by mail-lb0-f175.google.com with SMTP id y6so7818576lbh.6 for ; Thu, 19 Sep 2013 08:06:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:date:message-id:subject:from:to:content-type :content-transfer-encoding; bh=GIdnjjavMz83Kmm77cEm7y6I4o7tvSBA8yhbuIZBbWo=; b=F5xx3/+MS+86YYwrEyBEAaMU9WoYAotkfs7Jzes6J0fa0vI6LLA/uZJWsUuzDpeGER T8/FDN7HMTCaADwWUFZG+0nRh9D5P6NBBfh9THDAGkft2DgyPKYDHlP3OtKHb9PYXb6S QZJAPmi33cvoumzM5cda2IW9hcwwf3dF5ehudc9uzEp4sIz7ix93NbVt+0y3SBQk7ITG sr5t1i/0UN2c4iqMZJvMixDTtTSRQuJOA7rm63CsYzFNrPf4gPNxSLbg8Pe8BU8E4W0H mMwjHmmeAT7YvGI/18P9sp/s4p8NprfMZ/sguH2Bk5gjf1ujMArp2r9fAss7PJRqQuSZ YxEg== X-Received: by 10.152.37.103 with SMTP id x7mr1670818laj.28.1379603219247; Thu, 19 Sep 2013 08:06:59 -0700 (PDT) Original-Received: by 10.114.185.101 with HTTP; Thu, 19 Sep 2013 08:06:59 -0700 (PDT) X-Google-Sender-Auth: RESB8ESWPVbm9LcIJ2DvHOlaWJ0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.85.217.175 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:93455 Archived-At: Hello All, I am using tabbar-mode to visualize my buffers. Additionally, I map M-S- and M-S- to tabbar-backward-tab and tabbar-forward-tab, respectively. =3D=3D=3D (global-set-key (kbd "M-S-") 'tabbar-forward-tab) (global-set-key (kbd "M-S-") 'tabbar-backward-tab) (tabbar-mode 1) (tabbar-mwheel-mode 0) =3D=3D=3D In the default configuration, every window displays every tab. This poses three problems: * If the buffer I want is more than three tabs away from where I am, I reach for the mouse, which is annoying. * When the tabbar grows beyond the screen width, I cannot see all tabs. I cannot choose which direction to go, and I cannot click because the tab I want is offscreen and scrolling the tabbar is cumbersome. * I often split my frame into two windows, and I often have two or three frames dedicated to different tasks. (For example, I might have a separate frame where I do my .emacs.d customizations, a separate frame for the program I=E2=80=99m writing (with one frame for a .h file and another for .cpp), and a third frame for the library I=E2=80=99m using.) I usually don=E2=80=99t want to mix buffers =E2=80=94 in my mind, in most cas= es, each buffer logically belongs to a single window in a single frame; a buffer should show up in a different window only if I explicitly ask for it. Therefore, I want tabbar to show in each window only those tabs that =E2=80=9Cbelong=E2=80=9D to that window. After some trying and tweaking, I decided on the following heuristics for the =E2=80=9Cbelong=E2=80=9D relationship: * Each buffer remembers and maintains the last window where it was displaye= d. * Each buffer also maintains a list of windows it is =E2=80=9Cpinned=E2=80= =9D to. (Pinning and unpinning are explicit user commands.) * Each window=E2=80=99s tabbar shows tabs for the buffer that is currently displayed in that window, all buffers pinned to that window, and all buffers that were last displayed in that window. I have implemented this logic and it seems to work for me. I=E2=80=99d be g= lad if somebody much more familiar with Elisp reviewed my code and gave comments if I am doing something wrong or suboptimal. Here=E2=80=99s the code from my init.el: =3D=3D=3D (defvar yk-buffer-last-window nil "Window the buffer was last displayed in"= ) (make-variable-buffer-local 'yk-buffer-last-window) (defun yk-tabbar-window-configuration-change () (setq yk-buffer-last-window (selected-window))) (add-hook 'window-configuration-change-hook 'yk-tabbar-window-configuration-change) (defadvice select-window (after yk-tabbar-select-window (window &optional norecord)) (with-current-buffer (window-buffer window) (setq yk-buffer-last-window window))) (ad-activate 'select-window) (defvar yk-buffer-pin-window-list nil "Windows the buffer is pinned to") (make-variable-buffer-local 'yk-buffer-pin-window-list) (defun yk-tabbar-pin-buffer () "Pin the current buffer to the selected window." (interactive) (add-to-list 'yk-buffer-pin-window-list (selected-window) nil 'eq)) (defun yk-tabbar-unpin-buffer () "Unpin the current buffer from the selected window." (interactive) (delq (selected-window) yk-buffer-pin-window-list)) ;;; The buffer=E2=80=99s list of groups is, in this order: ;;; 1. The currently selected window, if it is displaying this buffer. ;;; 2. All other windows (if any) that are displaying this buffer. ;;; 3. The windows that this buffer is pinned to (if any). ;;; 4. The window that this buffer was last displayed in (if any). ;;; 5. The default group (always). (defun yk-tabbar-buffer-groups () (let* ((window (selected-window)) (buffer (current-buffer)) (windows (get-buffer-window-list buffer nil t))) (append (mapcar 'prin1-to-string (append (and (eq (window-buffer window) buffer) `(,window)) = ; 1 (remq window windows) = ; 2 yk-buffer-pin-window-list = ; 3 (and yk-buffer-last-window `(,yk-buffer-last-window)))= ) ; 4 '("default")))) = ; 5 (setq tabbar-buffer-groups-function 'yk-tabbar-buffer-groups) =3D=3D=3D