├── .gitignore ├── ibuffer-git.el └── screenshot.html /.gitignore: -------------------------------------------------------------------------------- 1 | *.elc 2 | -------------------------------------------------------------------------------- /ibuffer-git.el: -------------------------------------------------------------------------------- 1 | ;;; ibuffer-git.el --- show git status in ibuffer column 2 | 3 | ;; Copyright (C) 2010 Jonathan Rockway 4 | 5 | ;; Author: Jonathan Rockway 6 | ;; Keywords: convenience 7 | 8 | ;; This program is free software; you can redistribute it and/or modify 9 | ;; it under the terms of the GNU General Public License as published by 10 | ;; the Free Software Foundation, either version 3 of the License, or 11 | ;; (at your option) any later version. 12 | 13 | ;; This program is distributed in the hope that it will be useful, 14 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ;; GNU General Public License for more details. 17 | 18 | ;; You should have received a copy of the GNU General Public License 19 | ;; along with this program. If not, see . 20 | 21 | ;;; Commentary: 22 | 23 | ;; This package adds git integration to Ibuffer. Two columns are 24 | ;; defined, git-status and git-status-mini. 25 | ;; 26 | ;; To actually make these columns show up, you need to customize 27 | ;; `ibuffer-formats'. The symbol `git-status-mini' can be inserted 28 | ;; where you want it, and `git-status' should be inserted with 29 | ;; something as something like `(git-status 8 8 :left)', where 8 is 30 | ;; the number you picked for `ibuffer-git-column-length'. 31 | 32 | ;;; Code: 33 | 34 | (require 'ibuffer) 35 | (require 'cl) 36 | 37 | (defgroup ibuffer-git nil 38 | "Git integration for Ibuffer" 39 | :group 'ibuffer) 40 | 41 | (defun* ibuffer-git-check-status (filename) 42 | "Return a cons cell representing the number of lines added to and removed from FILENAME since the last git commit. Return NIL if the file is not under git's control (or there is some other error), and `(0 . 0)' if there are no changes. 43 | 44 | FILENAME must be a filename." 45 | (condition-case e 46 | (let* ((default-directory (file-name-directory filename)) 47 | (res (car (process-lines "git" "diff" "--numstat" 48 | (file-name-nondirectory filename))))) 49 | (cond ((not res) (cons 0 0)) 50 | ((string-match "^\\([0-9]+\\)\t\\([0-9]+\\)\t" res) 51 | (cons (read (match-string 1 res)) (read (match-string 2 res)))) 52 | (t nil))) 53 | (error nil))) 54 | 55 | (defface ibuffer-git-add-face '((t (:inherit (diff-added)))) 56 | "Face to show +s in" 57 | :group 'ibuffer-git) 58 | 59 | (defface ibuffer-git-del-face '((t (:inherit (diff-removed)))) 60 | "Face to show -s in" 61 | :group 'ibuffer-git) 62 | 63 | (defcustom ibuffer-git-column-length 8 64 | "How big your non-mini git status column in Ibuffer will be." 65 | :group 'ibuffer-git 66 | :type 'integer) 67 | 68 | (defun ibuffer-git-format-result (res) 69 | "Format the results of `ibuffer-git-check-status' for display in the ibuffer. 70 | 71 | Argument RES is a cons cell in the format `(ADD . DEL)'." 72 | (if (not res) "" 73 | (destructuring-bind (add . del) res 74 | (cond ((and (= 0 add) (= 0 del)) "") 75 | (t (let* ((add-ratio (/ (float add) (+ add del))) 76 | (plus (ceiling (* add-ratio ibuffer-git-column-length))) 77 | (minus (- ibuffer-git-column-length plus))) 78 | (concat 79 | (propertize (concat (loop for i from 1 to (min add plus) collect ?+)) 80 | 'face 'ibuffer-git-add-face) 81 | (propertize (concat (loop for i from 1 to (min del minus) collect ?-)) 82 | 'face 'ibuffer-git-del-face)))))))) 83 | 84 | (defvar ibuffer-git-status-keymap (make-sparse-keymap) 85 | "Keymap for clicking on the diffs") 86 | 87 | (define-key ibuffer-git-status-keymap (kbd "") #'ibuffer-git-visit-diff) 88 | 89 | (defun ibuffer-git-visit-diff (event) 90 | "Show the detailed diff for the ibuffer entry at the point. 91 | Argument EVENT is the mouse event that triggered us." 92 | (interactive "e") 93 | (with-current-buffer 94 | (progn (mouse-set-point event) 95 | (ibuffer-current-buffer t)) 96 | (vc-diff nil t))) 97 | 98 | (define-ibuffer-column git-status 99 | (:name "Git" 100 | :inline t 101 | :props ('mouse-face 'highlight 102 | 'keymap ibuffer-git-status-keymap 103 | 'help-echo "mouse-2: see detailed diff")) 104 | (ibuffer-git-format-result 105 | (ignore-errors (when (buffer-file-name) 106 | (ibuffer-git-check-status (buffer-file-name)))))) 107 | 108 | 109 | (define-ibuffer-column git-status-mini (:name "G" :inline t) 110 | (destructuring-bind (a . d) 111 | (or (ignore-errors (when (buffer-file-name) 112 | (ibuffer-git-check-status (buffer-file-name)))) 113 | (cons 0 0)) 114 | (cond ((= 0 (+ a d)) " ") 115 | ((< a d) (propertize "-" 'face 'ibuffer-git-del-face)) 116 | ((>= a d) (propertize "+" 'face 'ibuffer-git-add-face))))) 117 | 118 | (provide 'ibuffer-git) 119 | ;;; ibuffer-git.el ends here 120 | -------------------------------------------------------------------------------- /screenshot.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | *Ibuffer* 6 | 66 | 67 | 68 |
 69 |  MRG Name                    Size Mode             Project          Git      Filename/Process
 70 |  --- ----                    ---- ----             -------          ---      ----------------
 71 | [ Default ]
 72 |      example.html           17889 HTML                                       ~/example.html
 73 |  * + ibuffer-git.el          3691 Emacs-Lisp       ibuffer-git      +++++++- ~/projects/ibuffer-git/ibuffer-git.el
 74 |  *   *Messages*              3911 Fundamental
 75 |  *   *Customize Grou...      1179 Custom
 76 |   %  ibuffer.el.gz         100600 Emacs-Lisp                                 /usr/share/emacs/23.1/lisp/ibuffer.el.gz
 77 |   %  ibuf-macs.el.gz        10652 Emacs-Lisp                                 /usr/share/emacs/23.1/lisp/ibuf-macs.el.gz
 78 |   %  *info*                300342 Info
 79 |    + WithIndex.pm             464 CPerl            ai               +-       ~/projects/ai/lib/Ai/Site/WithIndex.pm
 80 |  *   *ielm*                  3212 IELM                                       (ielm run)
 81 |   %  *Help*                 30884 Help
 82 |   %  *Completions*            176 Completion List
 83 |      Blog/Article.pm          272 CPerl            ai                        ~/projects/ai/lib/Ai/Page/Blog/Article.pm
 84 |      ai/README                163 Fundamental      ai                        ~/projects/ai/README
 85 |      Blog/Index.pm            291 CPerl            ai                        ~/projects/ai/lib/Ai/Page/Blog/Index.pm
 86 |      Page/Article.pm          430 CPerl            ai                        ~/projects/ai/lib/Ai/Page/Article.pm
 87 |      Page/WithSite.pm         221 CPerl            ai                        ~/projects/ai/lib/Ai/Page/WithSite.pm
 88 |      Page/Index.pm            145 CPerl            ai                        ~/projects/ai/lib/Ai/Page/Index.pm
 89 |      Page/Blog.pm              73 CPerl            ai                        ~/projects/ai/lib/Ai/Page/Blog.pm
 90 |      Mapper/Blog.pm          1060 CPerl            ai                        ~/projects/ai/lib/Ai/Mapper/Blog.pm
 91 |      Set.pm                   489 CPerl            ai                        ~/projects/ai/lib/Ai/Role/WithDependencies/Set.pm
 92 |      Role/WithSite.pm         181 CPerl            ai                        ~/projects/ai/lib/Ai/Role/WithSite.pm
 93 |      WithDependencie...        96 CPerl            ai                        ~/projects/ai/lib/Ai/Role/WithDependencies.pm
 94 |      Versioned.pm             859 CPerl            ai                        ~/projects/ai/lib/Ai/Article/Versioned.pm
 95 |      Markdown.pm              193 CPerl            ai                        ~/projects/ai/lib/Ai/Article/Markdown.pm
 96 |      Article/Simple.pm        170 CPerl            ai                        ~/projects/ai/lib/Ai/Article/Simple.pm
 97 |      Resolved.pm              353 CPerl            ai                        ~/projects/ai/lib/Ai/Link/Resolved.pm
 98 |      Link/Page.pm             440 CPerl            ai                        ~/projects/ai/lib/Ai/Link/Page.pm
 99 |      Unresolved.pm            189 CPerl            ai                        ~/projects/ai/lib/Ai/Link/Unresolved.pm
100 |      Site/Blog.pm             737 CPerl            ai                        ~/projects/ai/lib/Ai/Site/Blog.pm
101 |      Site/Simple.pm           913 CPerl            ai                        ~/projects/ai/lib/Ai/Site/Simple.pm
102 |      Image/File.pm            379 CPerl            ai                        ~/projects/ai/lib/Ai/Dependency/Image/File.pm
103 |      Image.pm                 372 CPerl            ai                        ~/projects/ai/lib/Ai/Dependency/Image.pm
104 |      Dependency/File.pm       271 CPerl            ai                        ~/projects/ai/lib/Ai/Dependency/File.pm
105 |      Dependency.pm            103 CPerl            ai                        ~/projects/ai/lib/Ai/Dependency.pm
106 |      Ai/Article.pm            636 CPerl            ai                        ~/projects/ai/lib/Ai/Article.pm
107 |      Link.pm                  112 CPerl            ai                        ~/projects/ai/lib/Ai/Link.pm
108 |      Ai/Page.pm               227 CPerl            ai                        ~/projects/ai/lib/Ai/Page.pm
109 |      Linkable.pm               47 CPerl            ai                        ~/projects/ai/lib/Ai/Linkable.pm
110 |      Types.pm                 943 CPerl            ai                        ~/projects/ai/lib/Ai/Types.pm
111 |      Mapper.pm                105 CPerl            ai                        ~/projects/ai/lib/Ai/Mapper.pm
112 |      Resolver.pm              799 CPerl            ai                        ~/projects/ai/lib/Ai/Resolver.pm
113 |      Site.pm                  144 CPerl            ai                        ~/projects/ai/lib/Ai/Site.pm
114 |      blog-article.t          1213 CPerl            ai                        ~/projects/ai/t/blog-article.t
115 |    + small-blog.t            1714 CPerl            ai               +++++++  ~/projects/ai/t/small-blog.t
116 |      Makefile.PL               91 CPerl            ai                        ~/projects/ai/Makefile.PL
117 |      eproject.el            24289 Emacs-Lisp       eproject                  ~/elisp/eproject/eproject.el
118 |      eproject-extras.el     11757 Emacs-Lisp       eproject                  ~/elisp/eproject/eproject-extras.el
119 |    + test/README               42 Fundamental      test             ++++-    ~/test/README
120 |  *%  *Article*                162 Article
121 |  *%  *Group*                  462 Group
122 |      test.hs                    0 Haskell                                    ~/test.hs
123 |  *   *haskell*              38281 Inf-Haskell                                (haskell run) ~/projects/super-mario-bros/
124 |      mario.hs                1283 Haskell          super-mario-bros          ~/projects/super-mario-bros/mario.hs
125 |      *scratch*                  0 Lisp Interaction
126 |      pmerge.hs               2954 Haskell          pmerge                    ~/projects/pmerge/pmerge.hs
127 |      README.mkdn              607 Fundamental      super-mario-bros          ~/projects/super-mario-bros/README.mkdn
128 |      super-mario-bro...       398 Fundamental                                ~/projects/super-mario-bros/super-mario-bros.cabal
129 |      pmerge.cabal             350 Fundamental      pmerge                    ~/projects/pmerge/pmerge.cabal
130 |  *   *eshell*                  34 EShell                                     ~/
131 |   %  *w3m*                    344 w3m                                        ~/.w3m/Blue Cross Blue Shield of Illinois - Login - Blue Access for Members
132 |      .newsrc-dribble       240507 Fundamental                                ~/.gnus.dribble/.newsrc-dribble
133 |   %  *Quail Completi...         0 Fundamental
134 |  *   *Shell Command ...        91 Fundamental
135 |  *%  *magit-process*           36 Fundamental
136 |  *   #moose                116734 rcirc
137 |  *   &bitlbee               24554 rcirc
138 |  *   angelixd               23848 rcirc
139 |  *   #emacs                456112 rcirc
140 |  *   nothingmuch-fbg         1586 rcirc
141 |  *   #xmonad                81024 rcirc
142 |  *   #dbix-class           202836 rcirc
143 |  *   jrockway                3878 rcirc
144 |  *   #perl                 189591 rcirc
145 |  *   mst                      610 rcirc
146 |  *   #haskell<2>           459946 rcirc
147 |  *   #haskell                  77 rcirc
148 |  *   #perl6                240730 rcirc
149 |  *   *localhost<1>*          1020 rcirc                                      (localhost<1> open)
150 |  *   *localhost<2>*           589 rcirc                                      (localhost<2> open)
151 |  *   *localhost*              934 rcirc                                      (localhost open)
152 |  *   *localhost<3>*           381 rcirc                                      (localhost<3> open)
153 |  *   #catalyst             178924 rcirc
154 |  *   #catalyst-dev          30475 rcirc
155 |  *   #tt                    10501 rcirc
156 |  *   #angerwhale              989 rcirc
157 |  *   #chicago.pm              592 rcirc
158 |  *   #killtrac                100 rcirc
159 |  *   #reaction               5134 rcirc
160 |  *   #yapc                  57853 rcirc
161 |  *   #par                     342 rcirc
162 |  *   #toolchain             35393 rcirc
163 |  *   #poe                   45052 rcirc
164 |  *   #moose-dev             18799 rcirc
165 |  *   #qa                      131 rcirc
166 |  *   #p5p                   81713 rcirc
167 |  *   #http-engine            5743 rcirc
168 |  *   #kiokudb               18891 rcirc
169 |  *   #devel-repl              204 rcirc
170 |  *   #svk                     828 rcirc
171 |  *   #jifty                  4193 rcirc
172 |  *   #jemplate                138 rcirc
173 |  *   #git                  441667 rcirc
174 |  *   #yapc.asia              4035 rcirc
175 |  *   #yapc.asia-ja          10736 rcirc
176 |  *   #plagger                1975 rcirc
177 |  *   #kwiki                   777 rcirc
178 |  *   #perl<2>              457054 rcirc
179 |  *   #lisp                 353863 rcirc
180 |  *   #yi                     8326 rcirc
181 |  *   #rcirc                 31212 rcirc
182 | 
183 |      111 buffers          4429634                                            111 files, 6 processes
184 | 185 | 186 | --------------------------------------------------------------------------------