Compare commits

...

10 commits

Author SHA1 Message Date
mANIApHOBIC
a5f6f9e84e Checkpoint commit on hp002 2015-06-13 07:23:18 -07:00
mANIApHOBIC
68002c58d9 Checkpoint commit on hp002 2015-06-13 07:18:57 -07:00
mANIApHOBIC
54431651e8 I removed scala.el 2014-11-26 20:10:59 -08:00
mANIApHOBIC
5c0b839107 I renamed org-mode.el 2014-11-26 20:10:36 -08:00
mANIApHOBIC
7e62097955 I updated .gitignore 2014-10-14 18:51:00 -07:00
mANIApHOBIC
03a8b2b51d Initial commit of several lisp.d files. 2014-10-14 18:50:59 -07:00
mANIApHOBIC
d6fd93de72 Checkpoint commit on mac002 2014-10-14 18:50:59 -07:00
Me
8af85e909f I added magit mode code and updated updated the org-agenda-files
variable.
2014-02-09 21:52:09 -08:00
mANIApHOBIC
ad0627eaba I added YAML mode. 2013-11-29 12:11:58 -08:00
mANIApHOBIC
525c67bf52 changes from mac002.lan on Sun Oct 20 08:31:40 PDT 2013 2013-10-20 08:33:12 -07:00
88 changed files with 41955 additions and 26 deletions

4
.gitignore vendored
View file

@ -1,3 +1,5 @@
*~
auto-save-list
elpa
eshell
jabber-avatar-cache
session.*

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,676 @@
(1
(ace-window .
[(0 9 0)
((avy
(0 2 0)))
"Quickly switch windows." single
((:url . "https://github.com/abo-abo/ace-window")
(:keywords "window" "location"))])
(ack .
[(1 3)
nil "Interface to ack-like source code search tools" tar
((:keywords "tools" "processes" "convenience")
(:url . "https://github.com/leoliu/ack-el"))])
(ada-mode .
[(5 1 8)
((wisi
(1 1 1))
(cl-lib
(0 4))
(emacs
(24 2)))
"major-mode for editing Ada sources" tar
((:keywords "languages" "ada")
(:url . "http://stephe-leake.org/emacs/ada-mode/emacs-ada-mode.html"))])
(ada-ref-man .
[(2012 0)
nil "Ada Reference Manual 2012" tar
((:keywords "languages" "ada")
(:url . "http://stephe-leake.org/ada/arm.html"))])
(adaptive-wrap .
[(0 5)
nil "Smart line-wrapping with wrap-prefix" single
((:url . "http://elpa.gnu.org/packages/adaptive-wrap.html")
(:keywords))])
(adjust-parens .
[(3 0)
nil "Indent and dedent Lisp code, automatically adjust close parens" tar
((:url . "http://elpa.gnu.org/packages/adjust-parens.html"))])
(aggressive-indent .
[(1 0 2)
((emacs
(24 1))
(names
(20150125 9))
(cl-lib
(0 5)))
"Minor mode to aggressively keep your code always indented" single
((:url . "http://github.com/Malabarba/aggressive-indent-mode")
(:keywords "indent" "lisp" "maint" "tools"))])
(ahungry-theme .
[(1 0 6)
((emacs
(24)))
"Ahungry color theme for Emacs. Make sure to (load-theme 'ahungry)." tar
((:keywords "ahungry" "palette" "color" "theme" "emacs" "color-theme" "deftheme")
(:url . "https://github.com/ahungry/color-theme-ahungry"))])
(all .
[(1 0)
nil "Edit all lines matching a given regexp" single
((:url . "http://elpa.gnu.org/packages/all.html")
(:keywords "matching"))])
(ascii-art-to-unicode .
[(1 9)
nil "a small artist adjunct" single
((:url . "http://www.gnuvola.org/software/aa2u/")
(:keywords "ascii" "unicode" "box-drawing"))])
(auctex .
[(11 88 6)
nil "Integrated environment for *TeX*" tar
((:url . "http://www.gnu.org/software/auctex/"))])
(aumix-mode .
[(7)
nil "run the aumix program in a buffer" single
((:url . "http://user42.tuxfamily.org/aumix-mode/index.html")
(:keywords "multimedia" "mixer" "aumix"))])
(auto-overlays .
[(0 10 9)
nil "Automatic regexp-delimited overlays" tar
((:keywords "extensions")
(:url . "http://www.dr-qubit.org/emacs.php"))])
(avy .
[(0 2 1)
((emacs
(24 1))
(cl-lib
(0 5)))
"set-based completion" tar
((:keywords "point" "location")
(:url . "https://github.com/abo-abo/avy"))])
(bug-hunter .
[(0 2)
((seq
(1 3))
(cl-lib
(0 5)))
"Hunt down errors in elisp files" single
((:url . "http://github.com/Malabarba/elisp-bug-hunter")
(:keywords "lisp"))])
(caps-lock .
[(1 0)
nil "Caps-lock as a minor mode" single
((:url . "http://elpa.gnu.org/packages/caps-lock.html")
(:keywords))])
(chess .
[(2 0 4)
((cl-lib
(0 5)))
"Play chess in GNU Emacs" tar
((:keywords "games")
(:url . "http://elpa.gnu.org/packages/chess.html"))])
(cl-generic .
[(0 2)
nil "Forward cl-generic compatibility for Emacs<25" single
((:url . "http://elpa.gnu.org/packages/cl-generic.html")
(:keywords))])
(cl-lib .
[(0 5)
nil "Properly prefixed CL functions and macros" single
((:url . "http://elpa.gnu.org/packages/cl-lib.html")
(:keywords))])
(coffee-mode .
[(0 4 1 1)
nil "Major mode for CoffeeScript files" single
((:url . "http://github.com/defunkt/coffee-mode")
(:keywords "coffeescript" "major" "mode"))])
(company .
[(0 8 12)
((emacs
(24 1))
(cl-lib
(0 5)))
"Modular text completion framework" tar
((:keywords "abbrev" "convenience" "matching")
(:url . "http://company-mode.github.io/"))])
(company-statistics .
[(0 1 1)
((emacs
(24 3))
(company
(0 8 5)))
"Sort candidates using completion history" tar
((:keywords "abbrev" "convenience" "matching")
(:url . "https://github.com/company-mode/company-statistics"))])
(context-coloring .
[(6 3 0)
((emacs
(24))
(js2-mode
(20150126)))
"Highlight by scope" single
((:url . "https://github.com/jacksonrayhamilton/context-coloring")
(:keywords "convenience" "faces" "tools"))])
(crisp .
[(1 3 4)
nil "CRiSP/Brief Emacs emulator" single
((:url . "http://elpa.gnu.org/packages/crisp.html")
(:keywords "emulations" "brief" "crisp"))])
(csv-mode .
[(1 4)
nil "Major mode for editing comma/char separated values" single
((:url . "http://centaur.maths.qmul.ac.uk/Emacs/")
(:keywords "convenience"))])
(darkroom .
[(0 1)
((cl-lib
(0 5)))
"Remove visual distractions and focus on writing" single
((:url . "http://elpa.gnu.org/packages/darkroom.html")
(:keywords "convenience" "emulations"))])
(dbus-codegen .
[(0 1)
((cl-lib
(0 5)))
"Lisp code generation for D-Bus." single
((:url . "http://elpa.gnu.org/packages/dbus-codegen.html")
(:keywords "comm" "dbus" "convenience"))])
(debbugs .
[(0 7)
nil "SOAP library to access debbugs servers" tar
((:keywords "comm" "hypermedia")
(:url . "http://elpa.gnu.org/packages/debbugs.html"))])
(dict-tree .
[(0 12 8)
((trie
(0 2 5))
(tNFA
(0 1 1))
(heap
(0 3)))
"Dictionary data structure" single
((:url . "http://www.dr-qubit.org/emacs.php")
(:keywords "extensions" "matching" "data structures trie" "tree" "dictionary" "completion" "regexp"))])
(diff-hl .
[(1 7 0)
((cl-lib
(0 2)))
"Highlight uncommitted changes" tar
((:keywords "vc" "diff")
(:url . "https://github.com/dgutov/diff-hl"))])
(dismal .
[(1 5)
((cl-lib
(0)))
"Dis Mode Ain't Lotus: Spreadsheet program Emacs" tar
((:url . "http://elpa.gnu.org/packages/dismal.html"))])
(djvu .
[(0 5)
nil "Edit and view Djvu files via djvused" single
((:url . "http://elpa.gnu.org/packages/djvu.html")
(:keywords "files" "wp"))])
(docbook .
[(0 1)
nil "Info-like viewer for DocBook" single
((:url . "http://elpa.gnu.org/packages/docbook.html")
(:keywords "docs" "help"))])
(easy-kill .
[(0 9 3)
((emacs
(24))
(cl-lib
(0 5)))
"kill & mark things easily" tar
((:keywords "killing" "convenience")
(:url . "https://github.com/leoliu/easy-kill"))])
(ediprolog .
[(1 0)
nil "Emacs Does Interactive Prolog" single
((:url . "http://elpa.gnu.org/packages/ediprolog.html")
(:keywords "languages" "processes"))])
(eldoc-eval .
[(0 1)
nil "Enable eldoc support when minibuffer is in use." single
((:url . "http://elpa.gnu.org/packages/eldoc-eval.html")
(:keywords))])
(electric-spacing .
[(5 0)
nil "Insert operators with surrounding spaces smartly" single
((:url . "http://elpa.gnu.org/packages/electric-spacing.html")
(:keywords))])
(enwc .
[(1 0)
nil "The Emacs Network Client" tar
((:keywords "enwc" "network" "wicd" "manager" "nm")
(:url . "http://elpa.gnu.org/packages/enwc.html"))])
(epoch-view .
[(0 0 1)
nil "Minor mode to visualize epoch timestamps" single
((:url . "http://elpa.gnu.org/packages/epoch-view.html")
(:keywords "data" "timestamp" "epoch" "unix"))])
(ergoemacs-mode .
[(5 14 7 3)
((emacs
(24 1))
(undo-tree
(0 6 5)))
"Emacs mode based on common modern interface and ergonomics." tar
((:keywords "convenience")
(:url . "https://github.com/ergoemacs/ergoemacs-mode"))])
(f90-interface-browser .
[(1 1)
nil "Parse and browse f90 interfaces" single
((:url . "http://github.com/wence-/f90-iface/")
(:keywords))])
(flylisp .
[(0 2)
((emacs
(24 1))
(cl-lib
(0 4)))
"Color unbalanced parentheses and parentheses inconsistent with indentation" single
((:url . "http://elpa.gnu.org/packages/flylisp.html")
(:keywords))])
(ggtags .
[(0 8 10)
((emacs
(24))
(cl-lib
(0 5)))
"emacs frontend to GNU Global source code tagging system" single
((:url . "https://github.com/leoliu/ggtags")
(:keywords "tools" "convenience"))])
(gnorb .
[(1 1 1)
((cl-lib
(0 5)))
"Glue code between Gnus, Org, and BBDB" tar
((:keywords "mail" "org" "gnus" "bbdb" "todo" "task")
(:url . "https://github.com/girzel/gnorb"))])
(gnugo .
[(3 0 0)
((ascii-art-to-unicode
(1 5))
(xpm
(1 0 1))
(cl-lib
(0 5)))
"play GNU Go in a buffer" tar
((:keywords "games" "processes")
(:url . "http://www.gnuvola.org/software/gnugo/"))])
(heap .
[(0 3)
nil "Heap (a.k.a. priority queue) data structure" single
((:url . "http://www.dr-qubit.org/emacs.php")
(:keywords "extensions" "data structures" "heap" "priority queue"))])
(hydra .
[(0 13 2)
((cl-lib
(0 5)))
"Make bindings that stick around." tar
((:keywords "bindings")
(:url . "https://github.com/abo-abo/hydra"))])
(ioccur .
[(2 4)
nil "Incremental occur" single
((:url . "http://elpa.gnu.org/packages/ioccur.html")
(:keywords))])
(iterators .
[(0 1)
((emacs
(25)))
"Functions for working with iterators" single
((:url . "http://elpa.gnu.org/packages/iterators.html")
(:keywords "extensions" "elisp"))])
(javaimp .
[(0 5)
nil "Add and reorder Java import statements in Maven projects" single
((:url . "http://elpa.gnu.org/packages/javaimp.html")
(:keywords "java" "maven" "programming"))])
(jgraph-mode .
[(1 1)
((cl-lib
(0 5)))
"Major mode for Jgraph files" single
((:url . "http://elpa.gnu.org/packages/jgraph-mode.html")
(:keywords "tex" "wp"))])
(js2-mode .
[(20150202)
((emacs
(24 1))
(cl-lib
(0 5)))
"Improved JavaScript editing mode" tar
((:keywords "languages" "javascript")
(:url . "https://github.com/mooz/js2-mode/"))])
(jumpc .
[(3 0)
nil "jump to previous insertion points" single
((:url . "http://elpa.gnu.org/packages/jumpc.html")
(:keywords))])
(let-alist .
[(1 0 4)
nil "Easily let-bind values of an assoc-list by their names" single
((:url . "http://elpa.gnu.org/packages/let-alist.html")
(:keywords "extensions" "lisp"))])
(lex .
[(1 1)
nil "Lexical analyser construction" tar
((:url . "http://elpa.gnu.org/packages/lex.html"))])
(lmc .
[(1 3)
nil "Little Man Computer in Elisp" single
((:url . "http://elpa.gnu.org/packages/lmc.html")
(:keywords))])
(load-dir .
[(0 0 3)
nil "Load all Emacs Lisp files in a given directory" single
((:url . "http://elpa.gnu.org/packages/load-dir.html")
(:keywords "lisp" "files" "convenience"))])
(load-relative .
[(1 2)
nil "relative file load (within a multi-file Emacs package)" single
((:url . "http://github.com/rocky/emacs-load-relative")
(:keywords "internal"))])
(loc-changes .
[(1 2)
nil "keep track of positions even after buffer changes" single
((:url . "http://github.com/rocky/emacs-loc-changes")
(:keywords))])
(markchars .
[(0 2 0)
nil "Mark chars fitting certain characteristics" single
((:url . "http://elpa.gnu.org/packages/markchars.html")
(:keywords))])
(memory-usage .
[(0 2)
nil "Analyze the memory usage of Emacs in various ways" single
((:url . "http://elpa.gnu.org/packages/memory-usage.html")
(:keywords "maint"))])
(metar .
[(0 1)
((cl-lib
(0 5)))
"Retrieve and decode METAR weather information" single
((:url . "http://elpa.gnu.org/packages/metar.html")
(:keywords "comm"))])
(minibuffer-line .
[(0 1)
nil "Display status info in the minibuffer window" single
((:url . "http://elpa.gnu.org/packages/minibuffer-line.html")
(:keywords))])
(minimap .
[(1 2)
nil "Sidebar showing a \"mini-map\" of a buffer" single
((:url . "http://elpa.gnu.org/packages/minimap.html")
(:keywords))])
(muse .
[(3 20)
nil "Authoring and publishing tool for Emacs" tar
((:keywords "hypermedia")
(:url . "http://mwolson.org/projects/EmacsMuse.html"))])
(names .
[(20150115 1)
((emacs
(24 1))
(cl-lib
(0 5)))
"Namespaces for emacs-lisp. Avoid name clobbering without hiding symbols." tar
((:keywords "extensions" "lisp")
(:url . "http://github.com/Bruce-Connor/names"))])
(nhexl-mode .
[(0 1)
nil "Minor mode to edit files via hex-dump format" single
((:url . "http://elpa.gnu.org/packages/nhexl-mode.html")
(:keywords "data"))])
(nlinum .
[(1 6)
nil "Show line numbers in the margin" single
((:url . "http://elpa.gnu.org/packages/nlinum.html")
(:keywords "convenience"))])
(notes-mode .
[(1 30)
nil "Indexing system for on-line note-taking" tar
((:url . "http://elpa.gnu.org/packages/notes-mode.html"))])
(num3-mode .
[(1 2)
nil "highlight groups of digits in long numbers" single
((:url . "http://elpa.gnu.org/packages/num3-mode.html")
(:keywords "faces" "minor-mode"))])
(oauth2 .
[(0 10)
nil "OAuth 2.0 Authorization Protocol" single
((:url . "http://elpa.gnu.org/packages/oauth2.html")
(:keywords "comm"))])
(omn-mode .
[(1 0)
nil "Support for OWL Manchester Notation" single
((:url . "http://elpa.gnu.org/packages/omn-mode.html")
(:keywords))])
(org .
[(20150608)
nil "Outline-based notes management and organizer" tar nil])
(osc .
[(0 1)
nil "Open Sound Control protocol library" single
((:url . "http://elpa.gnu.org/packages/osc.html")
(:keywords "comm" "processes" "multimedia"))])
(pabbrev .
[(4 2)
nil "Predictive abbreviation expansion" single
((:url . "http://elpa.gnu.org/packages/pabbrev.html")
(:keywords))])
(pinentry .
[(0 1)
nil "GnuPG Pinentry server implementation" single
((:url . "http://elpa.gnu.org/packages/pinentry.html")
(:keywords "gnupg"))])
(poker .
[(0 1)
nil "Texas hold'em poker" single
((:url . "http://elpa.gnu.org/packages/poker.html")
(:keywords "games"))])
(quarter-plane .
[(0 1)
nil "Minor mode for quarter-plane style editing" single
((:url . "http://elpa.gnu.org/packages/quarter-plane.html")
(:keywords "convenience" "wp"))])
(queue .
[(0 1 1)
nil "Queue data structure" single
((:url . "http://www.dr-qubit.org/emacs.php")
(:keywords "extensions" "data structures" "queue"))])
(rainbow-mode .
[(0 11)
nil "Colorize color names in buffers" single
((:url . "http://elpa.gnu.org/packages/rainbow-mode.html")
(:keywords "faces"))])
(register-list .
[(0 1)
nil "Interactively list/edit registers" single
((:url . "http://elpa.gnu.org/packages/register-list.html")
(:keywords "register"))])
(rudel .
[(0 3)
nil "A collaborative editing framework for Emacs" tar
((:keywords "rudel" "collaboration")
(:url . "http://rudel.sourceforge.net/"))])
(scroll-restore .
[(1 0)
nil "restore original position after scrolling" single
((:url . "http://elpa.gnu.org/packages/scroll-restore.html")
(:keywords "scrolling"))])
(seq .
[(1 7)
nil "Sequence manipulation functions" single
((:url . "http://elpa.gnu.org/packages/seq.html")
(:keywords "sequences"))])
(shen-mode .
[(0 1)
nil "A major mode for editing shen source code" tar
((:keywords "languages" "shen")
(:url . "http://elpa.gnu.org/packages/shen-mode.html"))])
(sisu-mode .
[(3 0 3)
nil "Major mode for SiSU markup text" single
((:url . "http://elpa.gnu.org/packages/sisu-mode.html")
(:keywords "text" "processes" "tools"))])
(sml-mode .
[(6 7)
nil "Major mode for editing (Standard) ML" single
((:url . "http://elpa.gnu.org/packages/sml-mode.html")
(:keywords "sml"))])
(sokoban .
[(1 4)
nil "Implementation of Sokoban for Emacs." tar
((:keywords "games")
(:url . "http://elpa.gnu.org/packages/sokoban.html"))])
(sotlisp .
[(1 1)
((emacs
(24 1)))
"Write lisp at the speed of thought." single
((:url . "https://github.com/Malabarba/speed-of-thought-lisp")
(:keywords "convenience" "lisp"))])
(spinner .
[(1 3 1)
nil "Add spinners and progress-bars to the mode-line for ongoing operations" single
((:url . "https://github.com/Malabarba/spinner.el")
(:keywords "processes" "mode-line"))])
(svg .
[(0 1)
((emacs
(25)))
"svg image creation functions" single
((:url . "http://elpa.gnu.org/packages/svg.html")
(:keywords "image"))])
(svg-clock .
[(0 5)
((svg
(0 1))
(emacs
(25 0)))
"Analog clock using Scalable Vector Graphics" single
((:url . "http://elpa.gnu.org/packages/svg-clock.html")
(:keywords "demo" "svg" "clock"))])
(swiper .
[(0 4 1)
((emacs
(24 1)))
"Isearch with an overview. Oh, man!" tar
((:keywords "matching")
(:url . "https://github.com/abo-abo/swiper"))])
(tNFA .
[(0 1 1)
((queue
(0 1)))
"Tagged non-deterministic finite-state automata" single
((:url . "http://www.dr-qubit.org/emacs.php")
(:keywords "extensions" "matching" "data structures tnfa" "nfa" "dfa" "finite state automata" "automata" "regexp"))])
(temp-buffer-browse .
[(1 4)
nil "temp buffer browse mode" single
((:url . "http://elpa.gnu.org/packages/temp-buffer-browse.html")
(:keywords "convenience"))])
(test-simple .
[(1 1)
((cl-lib
(0)))
"Simple Unit Test Framework for Emacs Lisp" single
((:url . "http://github.com/rocky/emacs-test-simple")
(:keywords "unit-test"))])
(timerfunctions .
[(1 4 2)
((cl-lib
(0 5)))
"Enhanced versions of some timer.el functions" single
((:url . "http://elpa.gnu.org/packages/timerfunctions.html")
(:keywords))])
(tiny .
[(0 1)
nil "Quickly generate linear ranges in Emacs" tar
((:keywords "convenience")
(:url . "https://github.com/abo-abo/tiny"))])
(trie .
[(0 2 6)
((tNFA
(0 1 1))
(heap
(0 3)))
"Trie data structure" single
((:url . "http://www.dr-qubit.org/emacs.php")
(:keywords "extensions" "matching" "data structures trie" "ternary search tree" "tree" "completion" "regexp"))])
(undo-tree .
[(0 6 5)
nil "Treat undo history as a tree" single
((:url . "http://www.dr-qubit.org/emacs.php")
(:keywords "convenience" "files" "undo" "redo" "history" "tree"))])
(uni-confusables .
[(0 1)
nil "Unicode confusables table" tar
((:url . "http://elpa.gnu.org/packages/uni-confusables.html"))])
(vlf .
[(1 7)
nil "View Large Files" tar
((:keywords "large files" "utilities")
(:url . "https://github.com/m00natic/vlfi"))])
(w3 .
[(4 0 49)
nil "Fully customizable, largely undocumented web browser for Emacs" tar
((:keywords "faces" "help" "comm" "news" "mail" "processes" "mouse" "hypermedia")
(:url . "http://elpa.gnu.org/packages/w3.html"))])
(wcheck-mode .
[(2014 6 21)
nil "General interface for text checkers" single
((:url . "https://github.com/tlikonen/wcheck-mode")
(:keywords "text" "spell" "check" "languages" "ispell"))])
(web-server .
[(0 1 1)
((emacs
(24 3)))
"Emacs Web Server" tar
((:keywords "http" "server" "network")
(:url . "https://github.com/eschulte/emacs-web-server"))])
(websocket .
[(1 4)
nil "Emacs WebSocket client and server" tar
((:keywords "communication" "websocket" "server")
(:url . "http://elpa.gnu.org/packages/websocket.html"))])
(windresize .
[(0 1)
nil "Resize windows interactively" single
((:url . "http://elpa.gnu.org/packages/windresize.html")
(:keywords "window"))])
(wisi .
[(1 1 1)
((cl-lib
(0 4))
(emacs
(24 2)))
"Utilities for implementing an indentation/navigation engine using a generalized LALR parser" tar
((:keywords "parser" "indentation" "navigation")
(:url . "http://stephe-leake.org/emacs/ada-mode/emacs-ada-mode.html"))])
(wpuzzle .
[(1 1)
nil "find as many word in a given time" single
((:url . "http://elpa.gnu.org/packages/wpuzzle.html")
(:keywords))])
(xclip .
[(1 3)
nil "use xclip to copy&paste" single
((:url . "http://elpa.gnu.org/packages/xclip.html")
(:keywords "convenience" "tools"))])
(xpm .
[(1 0 3)
nil "edit XPM images" tar
((:keywords "multimedia" "xpm")
(:url . "http://www.gnuvola.org/software/xpm/"))])
(yasnippet .
[(0 8 0)
nil "Yet another snippet extension for Emacs." tar
((:keywords "convenience" "emulation")
(:url . "http://github.com/capitaomorte/yasnippet"))])
(ztree .
[(1 0 1)
nil "Text mode directory tree" tar
((:keywords "files" "tools")
(:url . "https://github.com/fourier/ztree"))]))

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,64 @@
;;; csv-mode-autoloads.el --- automatically extracted autoloads
;;
;;; Code:
;;;### (autoloads (csv-mode) "csv-mode" "csv-mode.el" (21607 50369
;;;;;; 931412 957000))
;;; Generated autoloads from csv-mode.el
(autoload 'csv-mode "csv-mode" "\
Major mode for editing files of comma-separated value type.
CSV mode is derived from `text-mode', and runs `text-mode-hook' before
running `csv-mode-hook'. It turns `auto-fill-mode' off by default.
CSV mode can be customized by user options in the CSV customization
group. The separators are specified by the value of `csv-separators'.
CSV mode commands ignore blank lines and comment lines beginning with
the value of `csv-comment-start', which delimit \"paragraphs\".
\"Sexp\" is re-interpreted to mean \"field\", so that `forward-sexp'
\(\\[forward-sexp]), `kill-sexp' (\\[kill-sexp]), etc. all apply to fields.
Standard comment commands apply, such as `comment-dwim' (\\[comment-dwim]).
If `font-lock-mode' is enabled then separators, quoted values and
comment lines are highlighted using respectively `csv-separator-face',
`font-lock-string-face' and `font-lock-comment-face'.
The user interface (UI) for CSV mode commands is similar to that of
the standard commands `sort-fields' and `sort-numeric-fields', except
that if there is no prefix argument then the UI prompts for the field
index or indices. In `transient-mark-mode' only: if the region is not
set then the UI attempts to set it to include all consecutive CSV
records around point, and prompts for confirmation; if there is no
prefix argument then the UI prompts for it, offering as a default the
index of the field containing point if the region was not set
explicitly. The region set automatically is delimited by blank lines
and comment lines, and the number of header lines at the beginning of
the region given by the value of `csv-header-lines' are skipped.
Sort order is controlled by `csv-descending'.
CSV mode provides the following specific keyboard key bindings:
\\{csv-mode-map}
\(fn)" t nil)
(add-to-list 'auto-mode-alist '("\\.[Cc][Ss][Vv]\\'" . csv-mode))
;;;***
;;;### (autoloads nil nil ("csv-mode-pkg.el") (21607 50370 13415
;;;;;; 845000))
;;;***
(provide 'csv-mode-autoloads)
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; coding: utf-8
;; End:
;;; csv-mode-autoloads.el ends here

View file

@ -0,0 +1 @@
(define-package "csv-mode" "1.2" "Major mode for editing comma/char separated values" (quote nil))

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

56
elpa/csv-mode-readme.txt Normal file
View file

@ -0,0 +1,56 @@
This package implements CSV mode, a major mode for editing records
in a generalized CSV (character-separated values) format. It binds
finds with prefix ".csv" to `csv-mode' in `auto-mode-alist'.
In CSV mode, the following commands are available:
- C-c C-s (`csv-sort-fields') and C-c C-n (`csv-sort-numeric-fields')
respectively sort lexicographically and numerically on a
specified field or column.
- C-c C-r (`csv-reverse-region') reverses the order. (These
commands are based closely on, and use, code in `sort.el'.)
- C-c C-k (`csv-kill-fields') and C-c C-y (`csv-yank-fields') kill
and yank fields or columns, although they do not use the normal
kill ring. C-c C-k can kill more than one field at once, but
multiple killed fields can be yanked only as a fixed group
equivalent to a single field.
- C-c C-a (`csv-align-fields') aligns fields into columns
- C-c C-u (`csv-unalign-fields') undoes such alignment; separators
can be hidden within aligned records.
- C-c C-t (`csv-transpose') interchanges rows and columns. For
details, see the documentation for the individual commands.
CSV mode can recognize fields separated by any of several single
characters, specified by the value of the customizable user option
`csv-separators'. CSV data fields can be delimited by quote
characters (and must if they contain separator characters). This
implementation supports quoted fields, where the quote characters
allowed are specified by the value of the customizable user option
`csv-field-quotes'. By default, the only separator is a comma and
the only field quote is a double quote. These user options can be
changed ONLY by customizing them, e.g. via M-x customize-variable.
CSV mode commands ignore blank lines and comment lines beginning
with the value of the buffer local variable `csv-comment-start',
which by default is #. The user interface is similar to that of
the standard commands `sort-fields' and `sort-numeric-fields', but
see the major mode documentation below.
The global minor mode `csv-field-index-mode' provides display of
the current field index in the mode line, cf. `line-number-mode'
and `column-number-mode'. It is on by default.
Installation:
Put this file somewhere that Emacs can find it (i.e. in one of the
directories in your `load-path' such as `site-lisp'), optionally
byte-compile it (recommended), and put this in your .emacs file:
(add-to-list 'auto-mode-alist '("\\.[Cc][Ss][Vv]\\'" . csv-mode))
(autoload 'csv-mode "csv-mode"
"Major mode for editing comma-separated value files." t)

View file

@ -0,0 +1,18 @@
;;; dash-autoloads.el --- automatically extracted autoloads
;;
;;; Code:
;;;### (autoloads nil nil ("dash-pkg.el" "dash.el") (21856 52890
;;;;;; 744648 259000))
;;;***
(provide 'dash-autoloads)
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; coding: utf-8
;; End:
;;; dash-autoloads.el ends here

View file

@ -0,0 +1 @@
(define-package "dash" "20150513.1027" "A modern list library for Emacs" (quote nil))

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -0,0 +1,18 @@
;;; epl-autoloads.el --- automatically extracted autoloads
;;
;;; Code:
;;;### (autoloads nil nil ("epl-pkg.el" "epl.el") (21856 52888 997407
;;;;;; 496000))
;;;***
(provide 'epl-autoloads)
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; coding: utf-8
;; End:
;;; epl-autoloads.el ends here

View file

@ -0,0 +1 @@
(define-package "epl" "20150517.433" "Emacs Package Library" (quote ((cl-lib "0.3"))))

Binary file not shown.

View file

@ -0,0 +1,695 @@
;;; epl.el --- Emacs Package Library -*- lexical-binding: t; -*-
;; Copyright (C) 2013-2015 Sebastian Wiesner
;; Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2015 Free Software
;; Author: Sebastian Wiesner <swiesner@lunaryorn.com>
;; Maintainer: Johan Andersson <johan.rejeep@gmail.com>
;; Sebastian Wiesner <swiesner@lunaryorn.com>
;; Version: 0.9-cvs
;; Package-Version: 20150517.433
;; Package-Requires: ((cl-lib "0.3"))
;; Keywords: convenience
;; URL: http://github.com/cask/epl
;; This file is NOT part of GNU Emacs.
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; A package management library for Emacs, based on package.el.
;; The purpose of this library is to wrap all the quirks and hassle of
;; package.el into a sane API.
;; The following functions comprise the public interface of this library:
;;; Package directory selection
;; `epl-package-dir' gets the directory of packages.
;; `epl-default-package-dir' gets the default package directory.
;; `epl-change-package-dir' changes the directory of packages.
;;; Package system management
;; `epl-initialize' initializes the package system and activates all
;; packages.
;; `epl-reset' resets the package system.
;; `epl-refresh' refreshes all package archives.
;; `epl-add-archive' adds a new package archive.
;;; Package objects
;; Struct `epl-requirement' describes a requirement of a package with `name' and
;; `version' slots.
;; `epl-requirement-version-string' gets a requirement version as string.
;; Struct `epl-package' describes an installed or installable package with a
;; `name' and some internal `description'.
;; `epl-package-version' gets the version of a package.
;; `epl-package-version-string' gets the version of a package as string.
;; `epl-package-summary' gets the summary of a package.
;; `epl-package-requirements' gets the requirements of a package.
;; `epl-package-directory' gets the installation directory of a package.
;; `epl-package-from-buffer' creates a package object for the package contained
;; in the current buffer.
;; `epl-package-from-file' creates a package object for a package file, either
;; plain lisp or tarball.
;; `epl-package-from-descriptor-file' creates a package object for a package
;; description (i.e. *-pkg.el) file.
;;; Package database access
;; `epl-package-installed-p' determines whether a package is installed, either
;; built-in or explicitly installed.
;; `epl-package-outdated-p' determines whether a package is outdated, that is,
;; whether a package with a higher version number is available.
;; `epl-built-in-packages', `epl-installed-packages', `epl-outdated-packages'
;; and `epl-available-packages' get all packages built-in, installed, outdated,
;; or available for installation respectively.
;; `epl-find-built-in-package', `epl-find-installed-packages' and
;; `epl-find-available-packages' find built-in, installed and available packages
;; by name.
;; `epl-find-upgrades' finds all upgradable packages.
;; `epl-built-in-p' return true if package is built-in to Emacs.
;;; Package operations
;; `epl-install-file' installs a package file.
;; `epl-package-install' installs a package.
;; `epl-package-delete' deletes a package.
;; `epl-upgrade' upgrades packages.
;;; Code:
(require 'cl-lib)
(require 'package)
(unless (fboundp #'define-error)
;; `define-error' for 24.3 and earlier, copied from subr.el
(defun define-error (name message &optional parent)
"Define NAME as a new error signal.
MESSAGE is a string that will be output to the echo area if such an error
is signaled without being caught by a `condition-case'.
PARENT is either a signal or a list of signals from which it inherits.
Defaults to `error'."
(unless parent (setq parent 'error))
(let ((conditions
(if (consp parent)
(apply #'append
(mapcar (lambda (parent)
(cons parent
(or (get parent 'error-conditions)
(error "Unknown signal `%s'" parent))))
parent))
(cons parent (get parent 'error-conditions)))))
(put name 'error-conditions
(delete-dups (copy-sequence (cons name conditions))))
(when message (put name 'error-message message)))))
(defsubst epl--package-desc-p (package)
"Whether PACKAGE is a `package-desc' object.
Like `package-desc-p', but return nil, if `package-desc-p' is not
defined as function."
(and (fboundp 'package-desc-p) (package-desc-p package)))
;;; EPL errors
(define-error 'epl-error "EPL error")
(define-error 'epl-invalid-package "Invalid EPL package" 'epl-error)
(define-error 'epl-invalid-package-file "Invalid EPL package file"
'epl-invalid-package)
;;; Package directory
(defun epl-package-dir ()
"Get the directory of packages."
package-user-dir)
(defun epl-default-package-dir ()
"Get the default directory of packages."
(eval (car (get 'package-user-dir 'standard-value))))
(defun epl-change-package-dir (directory)
"Change the directory of packages to DIRECTORY."
(setq package-user-dir directory)
(epl-initialize))
;;; Package system management
(defvar epl--load-path-before-initialize nil
"Remember the load path for `epl-reset'.")
(defun epl-initialize (&optional no-activate)
"Load Emacs Lisp packages and activate them.
With NO-ACTIVATE non-nil, do not activate packages."
(setq epl--load-path-before-initialize load-path)
(package-initialize no-activate))
(defalias 'epl-refresh 'package-refresh-contents)
(defun epl-add-archive (name url)
"Add a package archive with NAME and URL."
(add-to-list 'package-archives (cons name url)))
(defun epl-reset ()
"Reset the package system.
Clear the list of installed and available packages, the list of
package archives and reset the package directory."
(setq package-alist nil
package-archives nil
package-archive-contents nil
load-path epl--load-path-before-initialize)
(when (boundp 'package-obsolete-alist) ; Legacy package.el
(setq package-obsolete-alist nil))
(epl-change-package-dir (epl-default-package-dir)))
;;; Package structures
(cl-defstruct (epl-requirement
(:constructor epl-requirement-create))
"Structure describing a requirement.
Slots:
`name' The name of the required package, as symbol.
`version' The version of the required package, as version list."
name
version)
(defun epl-requirement-version-string (requirement)
"The version of a REQUIREMENT, as string."
(package-version-join (epl-requirement-version requirement)))
(cl-defstruct (epl-package (:constructor epl-package-create))
"Structure representing a package.
Slots:
`name' The package name, as symbol.
`description' The package description.
The format package description varies between package.el
variants. For `package-desc' variants, it is simply the
corresponding `package-desc' object. For legacy variants, it is
a vector `[VERSION REQS DOCSTRING]'.
Do not access `description' directly, but instead use the
`epl-package' accessors."
name
description)
(defmacro epl-package-as-description (var &rest body)
"Cast VAR to a package description in BODY.
VAR is a symbol, bound to an `epl-package' object. This macro
casts this object to the `description' object, and binds the
description to VAR in BODY."
(declare (indent 1))
(unless (symbolp var)
(signal 'wrong-type-argument (list #'symbolp var)))
`(if (epl-package-p ,var)
(let ((,var (epl-package-description ,var)))
,@body)
(signal 'wrong-type-argument (list #'epl-package-p ,var))))
(defsubst epl-package--package-desc-p (package)
"Whether the description of PACKAGE is a `package-desc'."
(epl--package-desc-p (epl-package-description package)))
(defun epl-package-version (package)
"Get the version of PACKAGE, as version list."
(epl-package-as-description package
(cond
((fboundp 'package-desc-version) (package-desc-version package))
;; Legacy
((fboundp 'package-desc-vers)
(let ((version (package-desc-vers package)))
(if (listp version) version (version-to-list version))))
(:else (error "Cannot get version from %S" package)))))
(defun epl-package-version-string (package)
"Get the version from a PACKAGE, as string."
(package-version-join (epl-package-version package)))
(defun epl-package-summary (package)
"Get the summary of PACKAGE, as string."
(epl-package-as-description package
(cond
((fboundp 'package-desc-summary) (package-desc-summary package))
((fboundp 'package-desc-doc) (package-desc-doc package)) ; Legacy
(:else (error "Cannot get summary from %S" package)))))
(defsubst epl-requirement--from-req (req)
"Create a `epl-requirement' from a `package-desc' REQ."
(let ((version (cadr req)))
(epl-requirement-create :name (car req)
:version (if (listp version) version
(version-to-list version)))))
(defun epl-package-requirements (package)
"Get the requirements of PACKAGE.
The requirements are a list of `epl-requirement' objects."
(epl-package-as-description package
(mapcar #'epl-requirement--from-req (package-desc-reqs package))))
(defun epl-package-directory (package)
"Get the directory PACKAGE is installed to.
Return the absolute path of the installation directory of
PACKAGE, or nil, if PACKAGE is not installed."
(cond
((fboundp 'package-desc-dir)
(package-desc-dir (epl-package-description package)))
((fboundp 'package--dir)
(package--dir (symbol-name (epl-package-name package))
(epl-package-version-string package)))
(:else (error "Cannot get package directory from %S" package))))
(defun epl-package-->= (pkg1 pkg2)
"Determine whether PKG1 is before PKG2 by version."
(not (version-list-< (epl-package-version pkg1)
(epl-package-version pkg2))))
(defun epl-package--from-package-desc (package-desc)
"Create an `epl-package' from a PACKAGE-DESC.
PACKAGE-DESC is a `package-desc' object, from recent package.el
variants."
(if (and (fboundp 'package-desc-name)
(epl--package-desc-p package-desc))
(epl-package-create :name (package-desc-name package-desc)
:description package-desc)
(signal 'wrong-type-argument (list 'epl--package-desc-p package-desc))))
(defun epl-package--parse-info (info)
"Parse a package.el INFO."
(if (epl--package-desc-p info)
(epl-package--from-package-desc info)
;; For legacy package.el, info is a vector [NAME REQUIRES DESCRIPTION
;; VERSION COMMENTARY]. We need to re-shape this vector into the
;; `package-alist' format [VERSION REQUIRES DESCRIPTION] to attach it to the
;; new `epl-package'.
(let ((name (intern (aref info 0)))
(info (vector (aref info 3) (aref info 1) (aref info 2))))
(epl-package-create :name name :description info))))
(defun epl-package-from-buffer (&optional buffer)
"Create an `epl-package' object from BUFFER.
BUFFER defaults to the current buffer.
Signal `epl-invalid-package' if the buffer does not contain a
valid package file."
(let ((info (with-current-buffer (or buffer (current-buffer))
(condition-case err
(package-buffer-info)
(error (signal 'epl-invalid-package (cdr err)))))))
(epl-package--parse-info info)))
(defun epl-package-from-lisp-file (file-name)
"Parse the package headers the file at FILE-NAME.
Return an `epl-package' object with the header metadata."
(with-temp-buffer
(insert-file-contents file-name)
(condition-case err
(epl-package-from-buffer (current-buffer))
;; Attach file names to invalid package errors
(epl-invalid-package
(signal 'epl-invalid-package-file (cons file-name (cdr err))))
;; Forward other errors
(error (signal (car err) (cdr err))))))
(defun epl-package-from-tar-file (file-name)
"Parse the package tarball at FILE-NAME.
Return a `epl-package' object with the meta data of the tarball
package in FILE-NAME."
(condition-case nil
;; In legacy package.el, `package-tar-file-info' takes the name of the tar
;; file to parse as argument. In modern package.el, it has no arguments
;; and works on the current buffer. Hence, we just try to call the legacy
;; version, and if that fails because of a mismatch between formal and
;; actual arguments, we use the modern approach. To avoid spurious
;; signature warnings by the byte compiler, we suppress warnings when
;; calling the function.
(epl-package--parse-info (with-no-warnings
(package-tar-file-info file-name)))
(wrong-number-of-arguments
(with-temp-buffer
(insert-file-contents-literally file-name)
;; Switch to `tar-mode' to enable extraction of the file. Modern
;; `package-tar-file-info' relies on `tar-mode', and signals an error if
;; called in a buffer with a different mode.
(tar-mode)
(epl-package--parse-info (with-no-warnings
(package-tar-file-info)))))))
(defun epl-package-from-file (file-name)
"Parse the package at FILE-NAME.
Return an `epl-package' object with the meta data of the package
at FILE-NAME."
(if (string-match-p (rx ".tar" string-end) file-name)
(epl-package-from-tar-file file-name)
(epl-package-from-lisp-file file-name)))
(defun epl-package--parse-descriptor-requirement (requirement)
"Parse a REQUIREMENT in a package descriptor."
;; This function is only called on legacy package.el. On package-desc
;; package.el, we just let package.el do the work.
(cl-destructuring-bind (name version-string) requirement
(list name (version-to-list version-string))))
(defun epl-package-from-descriptor-file (descriptor-file)
"Load a `epl-package' from a package DESCRIPTOR-FILE.
A package descriptor is a file defining a new package. Its name
typically ends with -pkg.el."
(with-temp-buffer
(insert-file-contents descriptor-file)
(goto-char (point-min))
(let ((sexp (read (current-buffer))))
(unless (eq (car sexp) 'define-package)
(error "%S is no valid package descriptor" descriptor-file))
(if (and (fboundp 'package-desc-from-define)
(fboundp 'package-desc-name))
;; In Emacs snapshot, we can conveniently call a function to parse the
;; descriptor
(let ((desc (apply #'package-desc-from-define (cdr sexp))))
(epl-package-create :name (package-desc-name desc)
:description desc))
;; In legacy package.el, we must manually deconstruct the descriptor,
;; because the load function has eval's the descriptor and has a lot of
;; global side-effects.
(cl-destructuring-bind
(name version-string summary requirements) (cdr sexp)
(epl-package-create
:name (intern name)
:description
(vector (version-to-list version-string)
(mapcar #'epl-package--parse-descriptor-requirement
;; Strip the leading `quote' from the package list
(cadr requirements))
summary)))))))
;;; Package database access
(defun epl-package-installed-p (package)
"Determine whether a PACKAGE is installed.
PACKAGE is either a package name as symbol, or a package object."
(let ((name (if (epl-package-p package)
(epl-package-name package)
package))
(version (when (epl-package-p package)
(epl-package-version package))))
(package-installed-p name version)))
(defun epl--parse-built-in-entry (entry)
"Parse an ENTRY from the list of built-in packages.
Return the corresponding `epl-package' object."
(if (fboundp 'package--from-builtin)
;; In package-desc package.el, convert the built-in package to a
;; `package-desc' and convert that to an `epl-package'
(epl-package--from-package-desc (package--from-builtin entry))
(epl-package-create :name (car entry) :description (cdr entry))))
(defun epl-built-in-packages ()
"Get all built-in packages.
Return a list of `epl-package' objects."
;; This looks mighty strange, but it's the only way to force package.el to
;; build the list of built-in packages. Without this, `package--builtins'
;; might be empty.
(package-built-in-p 'foo)
(mapcar #'epl--parse-built-in-entry package--builtins))
(defun epl-find-built-in-package (name)
"Find a built-in package with NAME.
NAME is a package name, as symbol.
Return the built-in package as `epl-package' object, or nil if
there is no built-in package with NAME."
(when (package-built-in-p name)
;; We must call `package-built-in-p' *before* inspecting
;; `package--builtins', because otherwise `package--builtins' might be
;; empty.
(epl--parse-built-in-entry (assq name package--builtins))))
(defun epl-package-outdated-p (package)
"Determine whether a PACKAGE is outdated.
A package is outdated, if there is an available package with a
higher version.
PACKAGE is either a package name as symbol, or a package object.
In the former case, test the installed or built-in package with
the highest version number, in the later case, test the package
object itself.
Return t, if the package is outdated, or nil otherwise."
(let* ((package (if (epl-package-p package)
package
(or (car (epl-find-installed-packages package))
(epl-find-built-in-package package))))
(available (car (epl-find-available-packages
(epl-package-name package)))))
(and package available (version-list-< (epl-package-version package)
(epl-package-version available)))))
(defun epl--parse-package-list-entry (entry)
"Parse a list of packages from ENTRY.
ENTRY is a single entry in a package list, e.g. `package-alist',
`package-archive-contents', etc. Typically it is a cons cell,
but the exact format varies between package.el versions. This
function tries to parse all known variants.
Return a list of `epl-package' objects parsed from ENTRY."
(let ((descriptions (cdr entry)))
(cond
((listp descriptions)
(sort (mapcar #'epl-package--from-package-desc descriptions)
#'epl-package-->=))
;; Legacy package.el has just a single package in an entry, which is a
;; standard description vector
((vectorp descriptions)
(list (epl-package-create :name (car entry)
:description descriptions)))
(:else (error "Cannot parse entry %S" entry)))))
(defun epl-installed-packages ()
"Get all installed packages.
Return a list of package objects."
(apply #'append (mapcar #'epl--parse-package-list-entry package-alist)))
(defsubst epl--filter-outdated-packages (packages)
"Filter outdated packages from PACKAGES."
(let (res)
(dolist (package packages)
(when (epl-package-outdated-p package)
(push package res)))
(nreverse res)))
(defun epl-outdated-packages ()
"Get all outdated packages, as in `epl-package-outdated-p'.
Return a list of package objects."
(epl--filter-outdated-packages (epl-installed-packages)))
(defsubst epl--find-package-in-list (name list)
"Find a package by NAME in a package LIST.
Return a list of corresponding `epl-package' objects."
(let ((entry (assq name list)))
(when entry
(epl--parse-package-list-entry entry))))
(defun epl-find-installed-package (name)
"Find the latest installed package by NAME.
NAME is a package name, as symbol.
Return the installed package with the highest version number as
`epl-package' object, or nil, if no package with NAME is
installed."
(car (epl-find-installed-packages name)))
(make-obsolete 'epl-find-installed-package 'epl-find-installed-packages "0.7")
(defun epl-find-installed-packages (name)
"Find all installed packages by NAME.
NAME is a package name, as symbol.
Return a list of all installed packages with NAME, sorted by
version number in descending order. Return nil, if there are no
packages with NAME."
(epl--find-package-in-list name package-alist))
(defun epl-available-packages ()
"Get all packages available for installation.
Return a list of package objects."
(apply #'append (mapcar #'epl--parse-package-list-entry
package-archive-contents)))
(defun epl-find-available-packages (name)
"Find available packages for NAME.
NAME is a package name, as symbol.
Return a list of available packages for NAME, sorted by version
number in descending order. Return nil, if there are no packages
for NAME."
(epl--find-package-in-list name package-archive-contents))
(cl-defstruct (epl-upgrade
(:constructor epl-upgrade-create))
"Structure describing an upgradable package.
Slots:
`installed' The installed package
`available' The package available for installation."
installed
available)
(defun epl-find-upgrades (&optional packages)
"Find all upgradable PACKAGES.
PACKAGES is a list of package objects to upgrade, defaulting to
all installed packages.
Return a list of `epl-upgrade' objects describing all upgradable
packages."
(let ((packages (or packages (epl-installed-packages)))
upgrades)
(dolist (pkg packages)
(let* ((version (epl-package-version pkg))
(name (epl-package-name pkg))
;; Find the latest available package for NAME
(available-pkg (car (epl-find-available-packages name)))
(available-version (when available-pkg
(epl-package-version available-pkg))))
(when (and available-version (version-list-< version available-version))
(push (epl-upgrade-create :installed pkg
:available available-pkg)
upgrades))))
(nreverse upgrades)))
(defalias 'epl-built-in-p 'package-built-in-p)
;;; Package operations
(defalias 'epl-install-file 'package-install-file)
(defun epl-package-install (package &optional force)
"Install a PACKAGE.
PACKAGE is a `epl-package' object. If FORCE is given and
non-nil, install PACKAGE, even if it is already installed."
(when (or force (not (epl-package-installed-p package)))
(if (epl-package--package-desc-p package)
(package-install (epl-package-description package))
;; The legacy API installs by name. We have no control over versioning,
;; etc.
(package-install (epl-package-name package)))))
(defun epl-package-delete (package)
"Delete a PACKAGE.
PACKAGE is a `epl-package' object to delete."
;; package-delete allows for packages being trashed instead of fully deleted.
;; Let's prevent his silly behavior
(let ((delete-by-moving-to-trash nil))
;; The byte compiler will warn us that we are calling `package-delete' with
;; the wrong number of arguments, since it can't infer that we guarantee to
;; always call the correct version. Thus we suppress all warnings when
;; calling `package-delete'. I wish there was a more granular way to
;; disable just that specific warning, but it is what it is.
(if (epl-package--package-desc-p package)
(with-no-warnings
(package-delete (epl-package-description package)))
;; The legacy API deletes by name (as string!) and version instead by
;; descriptor. Hence `package-delete' takes two arguments. For some
;; insane reason, the arguments are strings here!
(let ((name (symbol-name (epl-package-name package)))
(version (epl-package-version-string package)))
(with-no-warnings
(package-delete name version))
;; Legacy package.el does not remove the deleted package
;; from the `package-alist', so we do it manually here.
(let ((pkg (assq (epl-package-name package) package-alist)))
(when pkg
(setq package-alist (delq pkg package-alist))))))))
(defun epl-upgrade (&optional packages preserve-obsolete)
"Upgrade PACKAGES.
PACKAGES is a list of package objects to upgrade, defaulting to
all installed packages.
The old versions of the updated packages are deleted, unless
PRESERVE-OBSOLETE is non-nil.
Return a list of all performed upgrades, as a list of
`epl-upgrade' objects."
(let ((upgrades (epl-find-upgrades packages)))
(dolist (upgrade upgrades)
(epl-package-install (epl-upgrade-available upgrade) 'force)
(unless preserve-obsolete
(epl-package-delete (epl-upgrade-installed upgrade))))
upgrades))
(provide 'epl)
;;; epl.el ends here

Binary file not shown.

View file

@ -0,0 +1,18 @@
This is the file .../info/dir, which contains the
topmost node of the Info hierarchy, called (dir)Top.
The first time you invoke Info you start off looking at this node.

File: dir, Node: Top This is the top of the INFO tree
This (the Directory node) gives a menu of major topics.
Typing "q" exits, "?" lists all Info commands, "d" returns here,
"h" gives a primer for first-timers,
"mEmacs<Return>" visits the Emacs manual, etc.
In Emacs, you can click mouse button 2 on a menu item or cross reference
to select it.
* Menu:
Emacs
* Flycheck: (flycheck). Modern on-the-fly syntax checking

View file

@ -0,0 +1,484 @@
This is fdl-1.3.info, produced by makeinfo version 5.2 from
fdl-1.3.texi.
Version 1.3, 3 November 2008
Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
<http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
0. PREAMBLE
The purpose of this License is to make a manual, textbook, or other
functional and useful document "free" in the sense of freedom: to
assure everyone the effective freedom to copy and redistribute it,
with or without modifying it, either commercially or
noncommercially. Secondarily, this License preserves for the
author and publisher a way to get credit for their work, while not
being considered responsible for modifications made by others.
This License is a kind of "copyleft", which means that derivative
works of the document must themselves be free in the same sense.
It complements the GNU General Public License, which is a copyleft
license designed for free software.
We have designed this License in order to use it for manuals for
free software, because free software needs free documentation: a
free program should come with manuals providing the same freedoms
that the software does. But this License is not limited to
software manuals; it can be used for any textual work, regardless
of subject matter or whether it is published as a printed book. We
recommend this License principally for works whose purpose is
instruction or reference.
1. APPLICABILITY AND DEFINITIONS
This License applies to any manual or other work, in any medium,
that contains a notice placed by the copyright holder saying it can
be distributed under the terms of this License. Such a notice
grants a world-wide, royalty-free license, unlimited in duration,
to use that work under the conditions stated herein. The
"Document", below, refers to any such manual or work. Any member
of the public is a licensee, and is addressed as "you". You accept
the license if you copy, modify or distribute the work in a way
requiring permission under copyright law.
A "Modified Version" of the Document means any work containing the
Document or a portion of it, either copied verbatim, or with
modifications and/or translated into another language.
A "Secondary Section" is a named appendix or a front-matter section
of the Document that deals exclusively with the relationship of the
publishers or authors of the Document to the Document's overall
subject (or to related matters) and contains nothing that could
fall directly within that overall subject. (Thus, if the Document
is in part a textbook of mathematics, a Secondary Section may not
explain any mathematics.) The relationship could be a matter of
historical connection with the subject or with related matters, or
of legal, commercial, philosophical, ethical or political position
regarding them.
The "Invariant Sections" are certain Secondary Sections whose
titles are designated, as being those of Invariant Sections, in the
notice that says that the Document is released under this License.
If a section does not fit the above definition of Secondary then it
is not allowed to be designated as Invariant. The Document may
contain zero Invariant Sections. If the Document does not identify
any Invariant Sections then there are none.
The "Cover Texts" are certain short passages of text that are
listed, as Front-Cover Texts or Back-Cover Texts, in the notice
that says that the Document is released under this License. A
Front-Cover Text may be at most 5 words, and a Back-Cover Text may
be at most 25 words.
A "Transparent" copy of the Document means a machine-readable copy,
represented in a format whose specification is available to the
general public, that is suitable for revising the document
straightforwardly with generic text editors or (for images composed
of pixels) generic paint programs or (for drawings) some widely
available drawing editor, and that is suitable for input to text
formatters or for automatic translation to a variety of formats
suitable for input to text formatters. A copy made in an otherwise
Transparent file format whose markup, or absence of markup, has
been arranged to thwart or discourage subsequent modification by
readers is not Transparent. An image format is not Transparent if
used for any substantial amount of text. A copy that is not
"Transparent" is called "Opaque".
Examples of suitable formats for Transparent copies include plain
ASCII without markup, Texinfo input format, LaTeX input format,
SGML or XML using a publicly available DTD, and standard-conforming
simple HTML, PostScript or PDF designed for human modification.
Examples of transparent image formats include PNG, XCF and JPG.
Opaque formats include proprietary formats that can be read and
edited only by proprietary word processors, SGML or XML for which
the DTD and/or processing tools are not generally available, and
the machine-generated HTML, PostScript or PDF produced by some word
processors for output purposes only.
The "Title Page" means, for a printed book, the title page itself,
plus such following pages as are needed to hold, legibly, the
material this License requires to appear in the title page. For
works in formats which do not have any title page as such, "Title
Page" means the text near the most prominent appearance of the
work's title, preceding the beginning of the body of the text.
The "publisher" means any person or entity that distributes copies
of the Document to the public.
A section "Entitled XYZ" means a named subunit of the Document
whose title either is precisely XYZ or contains XYZ in parentheses
following text that translates XYZ in another language. (Here XYZ
stands for a specific section name mentioned below, such as
"Acknowledgements", "Dedications", "Endorsements", or "History".)
To "Preserve the Title" of such a section when you modify the
Document means that it remains a section "Entitled XYZ" according
to this definition.
The Document may include Warranty Disclaimers next to the notice
which states that this License applies to the Document. These
Warranty Disclaimers are considered to be included by reference in
this License, but only as regards disclaiming warranties: any other
implication that these Warranty Disclaimers may have is void and
has no effect on the meaning of this License.
2. VERBATIM COPYING
You may copy and distribute the Document in any medium, either
commercially or noncommercially, provided that this License, the
copyright notices, and the license notice saying this License
applies to the Document are reproduced in all copies, and that you
add no other conditions whatsoever to those of this License. You
may not use technical measures to obstruct or control the reading
or further copying of the copies you make or distribute. However,
you may accept compensation in exchange for copies. If you
distribute a large enough number of copies you must also follow the
conditions in section 3.
You may also lend copies, under the same conditions stated above,
and you may publicly display copies.
3. COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly
have printed covers) of the Document, numbering more than 100, and
the Document's license notice requires Cover Texts, you must
enclose the copies in covers that carry, clearly and legibly, all
these Cover Texts: Front-Cover Texts on the front cover, and
Back-Cover Texts on the back cover. Both covers must also clearly
and legibly identify you as the publisher of these copies. The
front cover must present the full title with all words of the title
equally prominent and visible. You may add other material on the
covers in addition. Copying with changes limited to the covers, as
long as they preserve the title of the Document and satisfy these
conditions, can be treated as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit
legibly, you should put the first ones listed (as many as fit
reasonably) on the actual cover, and continue the rest onto
adjacent pages.
If you publish or distribute Opaque copies of the Document
numbering more than 100, you must either include a machine-readable
Transparent copy along with each Opaque copy, or state in or with
each Opaque copy a computer-network location from which the general
network-using public has access to download using public-standard
network protocols a complete Transparent copy of the Document, free
of added material. If you use the latter option, you must take
reasonably prudent steps, when you begin distribution of Opaque
copies in quantity, to ensure that this Transparent copy will
remain thus accessible at the stated location until at least one
year after the last time you distribute an Opaque copy (directly or
through your agents or retailers) of that edition to the public.
It is requested, but not required, that you contact the authors of
the Document well before redistributing any large number of copies,
to give them a chance to provide you with an updated version of the
Document.
4. MODIFICATIONS
You may copy and distribute a Modified Version of the Document
under the conditions of sections 2 and 3 above, provided that you
release the Modified Version under precisely this License, with the
Modified Version filling the role of the Document, thus licensing
distribution and modification of the Modified Version to whoever
possesses a copy of it. In addition, you must do these things in
the Modified Version:
A. Use in the Title Page (and on the covers, if any) a title
distinct from that of the Document, and from those of previous
versions (which should, if there were any, be listed in the
History section of the Document). You may use the same title
as a previous version if the original publisher of that
version gives permission.
B. List on the Title Page, as authors, one or more persons or
entities responsible for authorship of the modifications in
the Modified Version, together with at least five of the
principal authors of the Document (all of its principal
authors, if it has fewer than five), unless they release you
from this requirement.
C. State on the Title page the name of the publisher of the
Modified Version, as the publisher.
D. Preserve all the copyright notices of the Document.
E. Add an appropriate copyright notice for your modifications
adjacent to the other copyright notices.
F. Include, immediately after the copyright notices, a license
notice giving the public permission to use the Modified
Version under the terms of this License, in the form shown in
the Addendum below.
G. Preserve in that license notice the full lists of Invariant
Sections and required Cover Texts given in the Document's
license notice.
H. Include an unaltered copy of this License.
I. Preserve the section Entitled "History", Preserve its Title,
and add to it an item stating at least the title, year, new
authors, and publisher of the Modified Version as given on the
Title Page. If there is no section Entitled "History" in the
Document, create one stating the title, year, authors, and
publisher of the Document as given on its Title Page, then add
an item describing the Modified Version as stated in the
previous sentence.
J. Preserve the network location, if any, given in the Document
for public access to a Transparent copy of the Document, and
likewise the network locations given in the Document for
previous versions it was based on. These may be placed in the
"History" section. You may omit a network location for a work
that was published at least four years before the Document
itself, or if the original publisher of the version it refers
to gives permission.
K. For any section Entitled "Acknowledgements" or "Dedications",
Preserve the Title of the section, and preserve in the section
all the substance and tone of each of the contributor
acknowledgements and/or dedications given therein.
L. Preserve all the Invariant Sections of the Document, unaltered
in their text and in their titles. Section numbers or the
equivalent are not considered part of the section titles.
M. Delete any section Entitled "Endorsements". Such a section
may not be included in the Modified Version.
N. Do not retitle any existing section to be Entitled
"Endorsements" or to conflict in title with any Invariant
Section.
O. Preserve any Warranty Disclaimers.
If the Modified Version includes new front-matter sections or
appendices that qualify as Secondary Sections and contain no
material copied from the Document, you may at your option designate
some or all of these sections as invariant. To do this, add their
titles to the list of Invariant Sections in the Modified Version's
license notice. These titles must be distinct from any other
section titles.
You may add a section Entitled "Endorsements", provided it contains
nothing but endorsements of your Modified Version by various
parties--for example, statements of peer review or that the text
has been approved by an organization as the authoritative
definition of a standard.
You may add a passage of up to five words as a Front-Cover Text,
and a passage of up to 25 words as a Back-Cover Text, to the end of
the list of Cover Texts in the Modified Version. Only one passage
of Front-Cover Text and one of Back-Cover Text may be added by (or
through arrangements made by) any one entity. If the Document
already includes a cover text for the same cover, previously added
by you or by arrangement made by the same entity you are acting on
behalf of, you may not add another; but you may replace the old
one, on explicit permission from the previous publisher that added
the old one.
The author(s) and publisher(s) of the Document do not by this
License give permission to use their names for publicity for or to
assert or imply endorsement of any Modified Version.
5. COMBINING DOCUMENTS
You may combine the Document with other documents released under
this License, under the terms defined in section 4 above for
modified versions, provided that you include in the combination all
of the Invariant Sections of all of the original documents,
unmodified, and list them all as Invariant Sections of your
combined work in its license notice, and that you preserve all
their Warranty Disclaimers.
The combined work need only contain one copy of this License, and
multiple identical Invariant Sections may be replaced with a single
copy. If there are multiple Invariant Sections with the same name
but different contents, make the title of each such section unique
by adding at the end of it, in parentheses, the name of the
original author or publisher of that section if known, or else a
unique number. Make the same adjustment to the section titles in
the list of Invariant Sections in the license notice of the
combined work.
In the combination, you must combine any sections Entitled
"History" in the various original documents, forming one section
Entitled "History"; likewise combine any sections Entitled
"Acknowledgements", and any sections Entitled "Dedications". You
must delete all sections Entitled "Endorsements."
6. COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other
documents released under this License, and replace the individual
copies of this License in the various documents with a single copy
that is included in the collection, provided that you follow the
rules of this License for verbatim copying of each of the documents
in all other respects.
You may extract a single document from such a collection, and
distribute it individually under this License, provided you insert
a copy of this License into the extracted document, and follow this
License in all other respects regarding verbatim copying of that
document.
7. AGGREGATION WITH INDEPENDENT WORKS
A compilation of the Document or its derivatives with other
separate and independent documents or works, in or on a volume of a
storage or distribution medium, is called an "aggregate" if the
copyright resulting from the compilation is not used to limit the
legal rights of the compilation's users beyond what the individual
works permit. When the Document is included in an aggregate, this
License does not apply to the other works in the aggregate which
are not themselves derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these
copies of the Document, then if the Document is less than one half
of the entire aggregate, the Document's Cover Texts may be placed
on covers that bracket the Document within the aggregate, or the
electronic equivalent of covers if the Document is in electronic
form. Otherwise they must appear on printed covers that bracket
the whole aggregate.
8. TRANSLATION
Translation is considered a kind of modification, so you may
distribute translations of the Document under the terms of section
4. Replacing Invariant Sections with translations requires special
permission from their copyright holders, but you may include
translations of some or all Invariant Sections in addition to the
original versions of these Invariant Sections. You may include a
translation of this License, and all the license notices in the
Document, and any Warranty Disclaimers, provided that you also
include the original English version of this License and the
original versions of those notices and disclaimers. In case of a
disagreement between the translation and the original version of
this License or a notice or disclaimer, the original version will
prevail.
If a section in the Document is Entitled "Acknowledgements",
"Dedications", or "History", the requirement (section 4) to
Preserve its Title (section 1) will typically require changing the
actual title.
9. TERMINATION
You may not copy, modify, sublicense, or distribute the Document
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense, or distribute it is void,
and will automatically terminate your rights under this License.
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the
copyright holder fails to notify you of the violation by some
reasonable means prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from
that copyright holder, and you cure the violation prior to 30 days
after your receipt of the notice.
Termination of your rights under this section does not terminate
the licenses of parties who have received copies or rights from you
under this License. If your rights have been terminated and not
permanently reinstated, receipt of a copy of some or all of the
same material does not give you any rights to use it.
10. FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised versions of
the GNU Free Documentation License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns. See
<http://www.gnu.org/copyleft/>.
Each version of the License is given a distinguishing version
number. If the Document specifies that a particular numbered
version of this License "or any later version" applies to it, you
have the option of following the terms and conditions either of
that specified version or of any later version that has been
published (not as a draft) by the Free Software Foundation. If the
Document does not specify a version number of this License, you may
choose any version ever published (not as a draft) by the Free
Software Foundation. If the Document specifies that a proxy can
decide which future versions of this License can be used, that
proxy's public statement of acceptance of a version permanently
authorizes you to choose that version for the Document.
11. RELICENSING
"Massive Multiauthor Collaboration Site" (or "MMC Site") means any
World Wide Web server that publishes copyrightable works and also
provides prominent facilities for anybody to edit those works. A
public wiki that anybody can edit is an example of such a server.
A "Massive Multiauthor Collaboration" (or "MMC") contained in the
site means any set of copyrightable works thus published on the MMC
site.
"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
license published by Creative Commons Corporation, a not-for-profit
corporation with a principal place of business in San Francisco,
California, as well as future copyleft versions of that license
published by that same organization.
"Incorporate" means to publish or republish a Document, in whole or
in part, as part of another Document.
An MMC is "eligible for relicensing" if it is licensed under this
License, and if all works that were first published under this
License somewhere other than this MMC, and subsequently
incorporated in whole or in part into the MMC, (1) had no cover
texts or invariant sections, and (2) were thus incorporated prior
to November 1, 2008.
The operator of an MMC Site may republish an MMC contained in the
site under CC-BY-SA on the same site at any time before August 1,
2009, provided the MMC is eligible for relicensing.
ADDENDUM: How to use this License for your documents
====================================================
To use this License in a document you have written, include a copy of
the License in the document and put the following copyright and license
notices just after the title page:
Copyright (C) YEAR YOUR NAME.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
Texts. A copy of the license is included in the section entitled ``GNU
Free Documentation License''.
If you have Invariant Sections, Front-Cover Texts and Back-Cover
Texts, replace the "with...Texts." line with this:
with the Invariant Sections being LIST THEIR TITLES, with
the Front-Cover Texts being LIST, and with the Back-Cover Texts
being LIST.
If you have Invariant Sections without Cover Texts, or some other
combination of the three, merge those two alternatives to suit the
situation.
If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of free
software license, such as the GNU General Public License, to permit
their use in free software.

Tag Table:

End Tag Table

View file

@ -0,0 +1,227 @@
;;; flycheck-autoloads.el --- automatically extracted autoloads
;;
;;; Code:
;;;### (autoloads (flycheck-def-option-var flycheck-def-config-file-var
;;;;;; flycheck-define-command-checker flycheck-define-error-level
;;;;;; global-flycheck-mode flycheck-mode flycheck-info) "flycheck"
;;;;;; "flycheck.el" (21856 52893 118962 269000))
;;; Generated autoloads from flycheck.el
(autoload 'flycheck-info "flycheck" "\
Open the Flycheck manual.
\(fn)" t nil)
(autoload 'flycheck-mode "flycheck" "\
Minor mode for on-the-fly syntax checking.
When called interactively, toggle `flycheck-mode'. With prefix
ARG, enable `flycheck-mode' if ARG is positive, otherwise disable
it.
When called from Lisp, enable `flycheck-mode' if ARG is omitted,
nil or positive. If ARG is `toggle', toggle `flycheck-mode'.
Otherwise behave as if called interactively.
In `flycheck-mode' the buffer is automatically syntax-checked
using the first suitable syntax checker from `flycheck-checkers'.
Use `flycheck-select-checker' to select a checker for the current
buffer manually.
\\{flycheck-mode-map}
\(fn &optional ARG)" t nil)
(defvar global-flycheck-mode nil "\
Non-nil if Global-Flycheck mode is enabled.
See the command `global-flycheck-mode' for a description of this minor mode.
Setting this variable directly does not take effect;
either customize it (see the info node `Easy Customization')
or call the function `global-flycheck-mode'.")
(custom-autoload 'global-flycheck-mode "flycheck" nil)
(autoload 'global-flycheck-mode "flycheck" "\
Toggle Flycheck mode in all buffers.
With prefix ARG, enable Global-Flycheck mode if ARG is positive;
otherwise, disable it. If called from Lisp, enable the mode if
ARG is omitted or nil.
Flycheck mode is enabled in all buffers where
`flycheck-mode-on-safe' would do it.
See `flycheck-mode' for more information on Flycheck mode.
\(fn &optional ARG)" t nil)
(autoload 'flycheck-define-error-level "flycheck" "\
Define a new error LEVEL with PROPERTIES.
The following PROPERTIES constitute an error level:
`:severity SEVERITY'
A number denoting the severity of this level. The higher
the number, the more severe is this level compared to other
levels. Defaults to 0.
The severity is used by `flycheck-error-level-<' to
determine the ordering of errors according to their levels.
`:overlay-category CATEGORY'
A symbol denoting the overlay category to use for error
highlight overlays for this level. See Info
node `(elisp)Overlay Properties' for more information about
overlay categories.
A category for an error level overlay should at least define
the `face' property, for error highlighting. Other useful
properties for error level categories are `priority' to
influence the stacking of multiple error level overlays, and
`help-echo' to define a default error messages for errors
without messages.
`:fringe-bitmap BITMAP'
A fringe bitmap symbol denoting the bitmap to use for fringe
indicators for this level. See Info node `(elisp)Fringe
Bitmaps' for more information about fringe bitmaps,
including a list of built-in fringe bitmaps.
`:fringe-face FACE'
A face symbol denoting the face to use for fringe indicators
for this level.
`:error-list-face FACE'
A face symbol denoting the face to use for messages of this
level in the error list. See `flycheck-list-errors'.
\(fn LEVEL &rest PROPERTIES)" nil nil)
(put 'flycheck-define-error-level 'lisp-indent-function '1)
(autoload 'flycheck-define-command-checker "flycheck" "\
Define SYMBOL as syntax checker which runs a command.
Define SYMBOL as generic syntax checker via
`flycheck-define-generic-checker', which uses an external command
to check the buffer. SYMBOL and DOCSTRING are the same as for
`flycheck-define-generic-checker'.
In addition to the properties understood by
`flycheck-define-generic-checker', the following PROPERTIES
constitute a command syntax checker. Unless otherwise noted, all
properties are mandatory. Note that the default `:error-filter'
of command checkers is `flycheck-sanitize-errors'.
`:command COMMAND'
The command to run for syntax checking.
COMMAND is a list of the form `(EXECUTABLE [ARG ...])'.
EXECUTABLE is a string with the executable of this syntax
checker. It can be overridden with the variable
`flycheck-SYMBOL-executable'. Note that this variable is
NOT implicitly defined by this function. Use
`flycheck-def-executable-var' to define this variable.
Each ARG is an argument to the executable, either as string,
or as special symbol or form for
`flycheck-substitute-argument', which see.
`:error-patterns PATTERNS'
A list of patterns to parse the output of the `:command'.
Each ITEM in PATTERNS is a list `(LEVEL SEXP ...)', where
LEVEL is a Flycheck error level (see
`flycheck-define-error-level'), followed by one or more RX
`SEXP's which parse an error of that level and extract line,
column, file name and the message.
See `rx' for general information about RX, and
`flycheck-rx-to-string' for some special RX forms provided
by Flycheck.
All patterns are applied in the order of declaration to the
whole output of the syntax checker. Output already matched
by a pattern will not be matched by subsequent patterns. In
other words, the first pattern wins.
This property is optional. If omitted, however, an
`:error-parser' is mandatory.
`:error-parser FUNCTION'
A function to parse errors with.
The function shall accept three arguments OUTPUT CHECKER
BUFFER. OUTPUT is the syntax checker output as string,
CHECKER the syntax checker that was used, and BUFFER a
buffer object representing the checked buffer. The function
must return a list of `flycheck-error' objects parsed from
OUTPUT.
This property is optional. If omitted, it defaults to
`flycheck-parse-with-patterns'. In this case,
`:error-patterns' is mandatory.
Note that you may not give `:start', `:interrupt', and
`:print-doc' for a command checker. You can give a custom
`:verify' function, but you should take care to call
`flycheck-verify-command-checker' in a custom `:verify'
function.
\(fn SYMBOL DOCSTRING &rest PROPERTIES)" nil nil)
(put 'flycheck-define-command-checker 'lisp-indent-function '1)
(put 'flycheck-define-command-checker 'doc-string-elt '2)
(autoload 'flycheck-def-config-file-var "flycheck" "\
Define SYMBOL as config file variable for CHECKER, with default FILE-NAME.
SYMBOL is declared as customizable variable using `defcustom', to
provide a configuration file for the given syntax CHECKER.
CUSTOM-ARGS are forwarded to `defcustom'.
FILE-NAME is the initial value of the new variable. If omitted,
the default value is nil.
Use this together with the `config-file' form in the `:command'
argument to `flycheck-define-checker'.
\(fn SYMBOL CHECKER &optional FILE-NAME &rest CUSTOM-ARGS)" nil t)
(put 'flycheck-def-config-file-var 'lisp-indent-function '3)
(autoload 'flycheck-def-option-var "flycheck" "\
Define SYMBOL as option variable with INIT-VALUE for CHECKER.
SYMBOL is declared as customizable variable using `defcustom', to
provide an option for the given syntax CHECKER. INIT-VALUE is
the initial value of the variable, and DOCSTRING is its
docstring. CUSTOM-ARGS are forwarded to `defcustom'.
Use this together with the `option', `option-list' and
`option-flag' forms in the `:command' argument to
`flycheck-define-checker'.
\(fn SYMBOL INIT-VALUE CHECKER DOCSTRING &rest CUSTOM-ARGS)" nil t)
(put 'flycheck-def-option-var 'lisp-indent-function '3)
(put 'flycheck-def-option-var 'doc-string-elt '4)
;;;***
;;;### (autoloads nil nil ("flycheck-ert.el" "flycheck-pkg.el") (21856
;;;;;; 52893 178287 551000))
;;;***
(provide 'flycheck-autoloads)
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; coding: utf-8
;; End:
;;; flycheck-autoloads.el ends here

View file

@ -0,0 +1,469 @@
;;; flycheck-ert.el --- Flycheck: ERT extensions -*- lexical-binding: t; -*-
;; Copyright (C) 2013-2015 Sebastian Wiesner <swiesner@lunaryorn.com>
;; Author: Sebastian Wiesner <swiesner@lunaryorn.com>
;; URL: https://github.com/flycheck/flycheck
;; This file is not part of GNU Emacs.
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; Unit testing library for Flycheck, the modern on-the-fly syntax checking
;; extension for GNU Emacs.
;; Provide various utility functions and unit test helpers to test Flycheck and
;; Flycheck extensions.
;;; Code:
(require 'flycheck)
(require 'ert)
(require 'macroexp) ; For macro utilities
;;; Compatibility
(eval-and-compile
;; Provide `ert-skip' and friends for Emacs 24.3
(defconst flycheck-ert-ert-can-skip (fboundp 'ert-skip)
"Whether ERT supports test skipping.")
(unless flycheck-ert-ert-can-skip
;; Fake skipping
(put 'flycheck-ert-skipped 'error-message "Test skipped")
(put 'flycheck-ert-skipped 'error-conditions '(error))
(defun ert-skip (data)
(signal 'flycheck-ert-skipped data))
(defmacro skip-unless (form)
`(unless (ignore-errors ,form)
(signal 'flycheck-ert-skipped ',form)))
(defun ert-test-skipped-p (result)
(and (ert-test-failed-p result)
(eq (car (ert-test-failed-condition result))
'flycheck-ert-skipped)))))
;;; Internal variables
(defvar flycheck-ert--resource-directory nil
"The directory to get resources from in this test suite.")
;;; Resource management macros
(defmacro flycheck-ert-with-temp-buffer (&rest body)
"Eval BODY within a temporary buffer.
Like `with-temp-buffer', but resets the modification state of the
temporary buffer to make sure that it is properly killed even if
it has a backing file and is modified."
(declare (indent 0))
`(with-temp-buffer
(unwind-protect
,(macroexp-progn body)
;; Reset modification state of the buffer, and unlink it from its backing
;; file, if any, because Emacs refuses to kill modified buffers with
;; backing files, even if they are temporary.
(set-buffer-modified-p nil)
(set-visited-file-name nil 'no-query))))
(defmacro flycheck-ert-with-file-buffer (file-name &rest body)
"Create a buffer from FILE-NAME and eval BODY.
BODY is evaluated with `current-buffer' being a buffer with the
contents FILE-NAME."
(declare (indent 1))
`(let ((file-name ,file-name))
(unless (file-exists-p file-name)
(error "%s does not exist" file-name))
(flycheck-ert-with-temp-buffer
(insert-file-contents file-name 'visit)
(set-visited-file-name file-name 'no-query)
(cd (file-name-directory file-name))
;; Mark the buffer as not modified, because we just loaded the file up to
;; now.
(set-buffer-modified-p nil)
,@body)))
(defmacro flycheck-ert-with-help-buffer (&rest body)
"Execute BODY and kill the help buffer afterwards.
Use this macro to test functions that create a Help buffer."
(declare (indent 0))
`(unwind-protect
,(macroexp-progn body)
(when (buffer-live-p (get-buffer (help-buffer)))
(kill-buffer (help-buffer)))))
(defmacro flycheck-ert-with-global-mode (&rest body)
"Execute BODY with Global Flycheck Mode enabled.
After BODY, restore the old state of Global Flycheck Mode."
(declare (indent 0))
`(let ((old-state global-flycheck-mode))
(unwind-protect
(progn
(global-flycheck-mode 1)
,@body)
(global-flycheck-mode (if old-state 1 -1)))))
(defmacro flycheck-ert-with-env (env &rest body)
"Add ENV to `process-environment' in BODY.
Execute BODY with a `process-environment' with contains all
variables from ENV added.
ENV is an alist, where each cons cell `(VAR . VALUE)' is a
environment variable VAR to be added to `process-environment'
with VALUE."
(declare (indent 1))
`(let ((process-environment (copy-sequence process-environment)))
(pcase-dolist (`(,var . ,value) ,env)
(setenv var value))
,@body))
;;; Test resources
(defun flycheck-ert-resource-filename (resource-file)
"Determine the absolute file name of a RESOURCE-FILE.
Relative file names are expanded against
`flycheck-ert-resources-directory'."
(expand-file-name resource-file flycheck-ert--resource-directory))
(defmacro flycheck-ert-with-resource-buffer (resource-file &rest body)
"Create a temp buffer from a RESOURCE-FILE and execute BODY.
The absolute file name of RESOURCE-FILE is determined with
`flycheck-ert-resource-filename'."
(declare (indent 1))
`(flycheck-ert-with-file-buffer
(flycheck-ert-resource-filename ,resource-file)
,@body))
(defun flycheck-ert-locate-config-file (filename _checker)
"Find a configuration FILENAME within unit tests.
_CHECKER is ignored."
(let* ((directory (flycheck-ert-resource-filename "config-files"))
(filepath (expand-file-name filename directory)))
(when (file-exists-p filepath)
filepath)))
;;; Test suite initialization
(defun flycheck-ert-initialize (resource-dir)
"Initialize a test suite with RESOURCE-DIR.
RESOURCE-DIR is the directory, `flycheck-ert-resource-filename'
should use to lookup resource files."
(when flycheck-ert--resource-directory
(error "Test suite already initialized"))
(let ((tests (ert-select-tests t t)))
;; Select all tests
(unless tests
(error "No tests defined. Call `flycheck-ert-initialize' after defining all tests!"))
(setq flycheck-ert--resource-directory resource-dir)
;; Emacs 24.3 don't support skipped tests, so we add poor man's test
;; skipping: We mark skipped tests as expected failures by adjusting the
;; expected result of all test cases. Not particularly pretty, but works :)
(unless flycheck-ert-ert-can-skip
(dolist (test tests)
(let ((result (ert-test-expected-result-type test)))
(setf (ert-test-expected-result-type test)
`(or ,result (satisfies ert-test-skipped-p))))))))
;;; Environment and version information
(defconst flycheck-ert-user-error-type
(if (version< emacs-version "24.2")
'error
'user-error)
"The `user-error' type used by Flycheck.")
(defun flycheck-ert-travis-ci-p ()
"Determine whether we are running on Travis CI."
(string= (getenv "TRAVIS") "true"))
(defun flycheck-ert-check-gpg ()
"Check whether GPG is available."
(or (epg-check-configuration (epg-configuration)) t))
(defun flycheck-ert-extract-version-command (re executable &rest args)
"Use RE to extract the version from EXECUTABLE with ARGS.
Run EXECUTABLE with ARGS, catch the output, and apply RE to find
the version number. Return the text captured by the first group
in RE, or nil, if EXECUTABLE is missing, or if RE failed to
match."
(-when-let (executable (executable-find executable))
(with-temp-buffer
(apply #'call-process executable nil t nil args)
(goto-char (point-min))
(when (re-search-forward re nil 'no-error)
(match-string 1)))))
;;; Test case definitions
(defmacro flycheck-ert-def-checker-test (checker language name
&rest keys-and-body)
"Define a test case for a syntax CHECKER for LANGUAGE.
CHECKER is a symbol or a list of symbols denoting syntax checkers
being tested by the test. The test case is skipped, if any of
these checkers cannot be used. LANGUAGE is a symbol or a list of
symbols denoting the programming languages supported by the
syntax checkers. This is currently only used for tagging the
test appropriately.
NAME is a symbol denoting the local name of the test. The test
itself is ultimately named
`flycheck-define-checker/CHECKER/NAME'. If CHECKER is a list,
the first checker in the list is used for naming the test.
Optionally, the keyword arguments `:tags' and `:expected-result'
may be given. They have the same meaning as in `ert-deftest.',
and are added to the tags and result expectations set up by this
macro.
The remaining forms denote the body of the test case, including
assertions and setup code."
(declare (indent 3))
(unless checker
(error "No syntax checkers specified."))
(unless language
(error "No languages specified"))
(let* ((checkers (if (symbolp checker) (list checker) checker))
(checker (car checkers))
(languages (if (symbolp language) (list language) language))
(language-tags (mapcar (lambda (l) (intern (format "language-%s" l)))
languages))
(checker-tags (mapcar (lambda (c) (intern (format "checker-%s" c)))
checkers))
(local-name (or name 'default))
(full-name (intern (format "flycheck-define-checker/%s/%s"
checker local-name)))
(keys-and-body (ert--parse-keys-and-body keys-and-body))
(body (cadr keys-and-body))
(keys (car keys-and-body))
(default-tags '(syntax-checker external-tool)))
`(ert-deftest ,full-name ()
:expected-result
(list 'or
'(satisfies flycheck-ert-syntax-check-timed-out-p)
,(or (plist-get keys :expected-result) :passed))
:tags (append ',(append default-tags language-tags checker-tags)
,(plist-get keys :tags))
,@(mapcar (lambda (c) `(skip-unless
;; Ignore non-command checkers
(or (not (get ',c 'flycheck-command))
(executable-find (flycheck-checker-executable ',c)))))
checkers)
,@body)))
;;; Test case results
(defun flycheck-ert-syntax-check-timed-out-p (result)
"Whether RESULT denotes a timed-out test.
RESULT is an ERT test result object."
(and (ert-test-failed-p result)
(eq (car (ert-test-failed-condition result))
'flycheck-ert-syntax-check-timed-out)))
;;; Syntax checking in tests
(defvar-local flycheck-ert-syntax-checker-finished nil
"Non-nil if the current checker has finished.")
(add-hook 'flycheck-after-syntax-check-hook
(lambda () (setq flycheck-ert-syntax-checker-finished t)))
(defconst flycheck-ert-checker-wait-time 10
"Time to wait until a checker is finished in seconds.
After this time has elapsed, the checker is considered to have
failed, and the test aborted with failure.")
(put 'flycheck-ert-syntax-check-timed-out 'error-message
"Syntax check timed out.")
(put 'flycheck-ert-syntax-check-timed-out 'error-conditions '(error))
(defun flycheck-ert-wait-for-syntax-checker ()
"Wait until the syntax check in the current buffer is finished."
(let ((starttime (float-time)))
(while (and (not flycheck-ert-syntax-checker-finished)
(< (- (float-time) starttime) flycheck-ert-checker-wait-time))
(sleep-for 1))
(unless (< (- (float-time) starttime) flycheck-ert-checker-wait-time)
(flycheck-stop)
(signal 'flycheck-ert-syntax-check-timed-out nil)))
(setq flycheck-ert-syntax-checker-finished nil))
(defun flycheck-ert-buffer-sync ()
"Like `flycheck-buffer', but synchronously."
(setq flycheck-ert-syntax-checker-finished nil)
(should (not (flycheck-running-p)))
(flycheck-mode) ; This will only start a deferred check,
(flycheck-buffer) ; so we need an explicit manual check
;; After starting the check, the checker should either be running now, or
;; already be finished (if it was fast).
(should (or flycheck-current-syntax-check
flycheck-ert-syntax-checker-finished))
;; Also there should be no deferred check pending anymore
(should-not (flycheck-deferred-check-p))
(flycheck-ert-wait-for-syntax-checker))
(defun flycheck-ert-ensure-clear ()
"Clear the current buffer.
Raise an assertion error if the buffer is not clear afterwards."
(flycheck-clear)
(should (not flycheck-current-errors))
(should (not (-any? (lambda (ov) (overlay-get ov 'flycheck-overlay))
(overlays-in (point-min) (point-max))))))
;;; Test assertions
(defun flycheck-ert-should-overlay (error)
"Test that ERROR has a proper overlay in the current buffer.
ERROR is a Flycheck error object."
(let* ((overlay (-first (lambda (ov) (equal (overlay-get ov 'flycheck-error)
error))
(flycheck-overlays-in 0 (+ 1 (buffer-size)))))
(region (flycheck-error-region-for-mode error 'symbols))
(message (flycheck-error-message error))
(level (flycheck-error-level error))
(category (flycheck-error-level-overlay-category level))
(face (get category 'face))
(fringe-bitmap (flycheck-error-level-fringe-bitmap level))
(fringe-face (flycheck-error-level-fringe-face level))
(fringe-icon (list 'left-fringe fringe-bitmap fringe-face)))
(should overlay)
(should (overlay-get overlay 'flycheck-overlay))
(should (= (overlay-start overlay) (car region)))
(should (= (overlay-end overlay) (cdr region)))
(should (eq (overlay-get overlay 'face) face))
(should (equal (get-char-property 0 'display
(overlay-get overlay 'before-string))
fringe-icon))
(should (eq (overlay-get overlay 'category) category))
(should (equal (overlay-get overlay 'flycheck-error) error))
(should (string= (overlay-get overlay 'help-echo) message))))
(defun flycheck-ert-should-errors (&rest errors)
"Test that the current buffers has ERRORS.
ERRORS is a list of errors expected to be present in the current
buffer. Each error is given as a list of arguments to
`flycheck-error-new-at'.
If ERRORS are omitted, test that there are no errors at all in
the current buffer.
With ERRORS, test that each error in ERRORS is present in the
current buffer, and that the number of errors in the current
buffer is equal to the number of given ERRORS. In other words,
check that the buffer has all ERRORS, and no other errors."
(let ((expected (mapcar (apply-partially #'apply #'flycheck-error-new-at)
errors)))
(should (equal expected flycheck-current-errors))
(mapc #'flycheck-ert-should-overlay expected))
(should (= (length errors)
(length (flycheck-overlays-in (point-min) (point-max))))))
(defun flycheck-ert-should-syntax-check (resource-file modes &rest errors)
"Test a syntax check in RESOURCE-FILE with MODES.
RESOURCE-FILE is the file to check. MODES is a single major mode
symbol or a list thereof, specifying the major modes to syntax
check with. If more than one major mode is specified, the test
is run for each mode separately, so if you give three major
modes, the entire test will run three times. ERRORS is the list
of expected errors, as in `flycheck-ert-should-errors'. If
omitted, the syntax check must not emit any errors. The errors
are cleared after each test.
The syntax checker is selected via standard syntax checker
selection. To test a specific checker, you need to set
`flycheck-checker' or `flycheck-disabled-checkers' accordingly
before using this predicate, depending on whether you want to use
manual or automatic checker selection.
During the syntax check, configuration files of syntax checkers
are also searched in the `config-files' sub-directory of the
resource directory."
(when (symbolp modes)
(setq modes (list modes)))
(dolist (mode modes)
(unless (fboundp mode)
(ert-skip (format "%S missing" mode)))
(flycheck-ert-with-resource-buffer resource-file
(funcall mode)
;; Configure config file locating for unit tests
(dolist (fn '(flycheck-locate-config-file-absolute-path
flycheck-ert-locate-config-file))
(add-hook 'flycheck-locate-config-file-functions fn 'append 'local))
(let ((process-hook-called 0))
(add-hook 'flycheck-process-error-functions
(lambda (_err)
(setq process-hook-called (1+ process-hook-called))
nil)
nil :local)
(flycheck-ert-buffer-sync)
(apply #'flycheck-ert-should-errors errors)
(should (= process-hook-called (length errors))))
(flycheck-ert-ensure-clear))))
(defun flycheck-ert-at-nth-error (n)
"Determine whether point is at the N'th Flycheck error.
Return non-nil if the point is at the N'th Flycheck error in the
current buffer. Otherwise return nil."
(let* ((error (nth (1- n) flycheck-current-errors))
(mode flycheck-highlighting-mode)
(region (flycheck-error-region-for-mode error mode)))
(and (member error (flycheck-overlay-errors-at (point)))
(= (point) (car region)))))
(defun flycheck-ert-explain--at-nth-error (n)
(let ((errors (flycheck-overlay-errors-at (point))))
(if (null errors)
(format "Expected to be at error %s, but no error at point %s"
n (point))
(let ((pos (cl-position (car errors) flycheck-current-errors)))
(format "Expected to be at error %s, but point %s is at error %s"
n (point) (1+ pos))))))
(put 'flycheck-ert-at-nth-error 'ert-explainer
'flycheck-ert-explain--at-nth-error)
(provide 'flycheck-ert)
;;; flycheck-ert.el ends here

Binary file not shown.

View file

@ -0,0 +1,11 @@
(define-package "flycheck" "20150523.131" "Modern on-the-fly syntax checking"
'((dash "2.4.0")
(pkg-info "0.4")
(let-alist "1.0.1")
(cl-lib "0.3")
(emacs "24.1"))
:url "https://www.flycheck.org" :keywords
'("convenience" "languages" "tools"))
;; Local Variables:
;; no-byte-compile: t
;; End:

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

8
elpa/flycheck-readme.txt Normal file
View file

@ -0,0 +1,8 @@
Modern on-the-fly syntax checking for GNU Emacs.
Provide `flycheck-mode' which enables on-the-fly syntax checking for a large
number of different modes and languages (see `flycheck-checkers' for a
complete list).
Support for new modes and languages can be added by defining a new syntax
checker (see `flycheck-define-checker').

View file

@ -0,0 +1,37 @@
;;; git-commit-mode-autoloads.el --- automatically extracted autoloads
;;
;;; Code:
;;;### (autoloads (git-commit-mode) "git-commit-mode" "git-commit-mode.el"
;;;;;; (21607 37947 797870 334000))
;;; Generated autoloads from git-commit-mode.el
(autoload 'git-commit-mode "git-commit-mode" "\
Major mode for editing git commit messages.
This mode helps with editing git commit messages both by
providing commands to do common tasks, and by highlighting the
basic structure of and errors in git commit messages.
\(fn)" t nil)
(add-to-list 'auto-mode-alist '("/MERGE_MSG\\'" . git-commit-mode))
(add-to-list 'auto-mode-alist '("/\\(?:COMMIT\\|NOTES\\|TAG\\|PULLREQ\\)_EDITMSG\\'" . git-commit-mode))
;;;***
;;;### (autoloads nil nil ("git-commit-mode-pkg.el") (21607 37947
;;;;;; 903089 998000))
;;;***
(provide 'git-commit-mode-autoloads)
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; coding: utf-8
;; End:
;;; git-commit-mode-autoloads.el ends here

View file

@ -0,0 +1 @@
(define-package "git-commit-mode" "20141014.1634" "Major mode for editing git commit messages" (quote nil))

View file

@ -0,0 +1,668 @@
;;; git-commit-mode.el --- Major mode for editing git commit messages -*- lexical-binding: t; -*-
;; Version: 20141014.1634
;; Copyright (c) 2010-2012 Florian Ragwitz
;; Copyright (c) 2012-2013 Sebastian Wiesner
;; Copyright (C) 2010-2014 The Magit Project Developers
;; Authors: Jonas Bernoulli <jonas@bernoul.li>
;; Sebastian Wiesner <lunaryorn@gmail.com>
;; Florian Ragwitz <rafl@debian.org>
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
;; Homepage: https://github.com/magit/git-modes
;; Keywords: convenience vc git
;; This file is not part of GNU Emacs.
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this file. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; A major mode for editing Git commit messages.
;;;; Formatting
;; Highlight the formatting of git commit messages and indicate errors according
;; to the guidelines for commit messages (see
;; http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
;;
;; Highlight the first line (aka "summary") specially if it exceeds 50
;; characters (configurable using `git-commit-summary-max-length').
;;
;; Enable `auto-fill-mode' and set the `fill-column' to 72 according to the
;; aforementioned guidelines (configurable using `git-commit-fill-column').
;;;; Headers
;; Provide commands to insert standard headers into commit messages.
;;
;; - C-c C-s inserts Signed-off-by (`git-commit-signoff').
;; - C-C C-a inserts Acked-by (`git-commit-ack').
;; - C-c C-t inserts Tested-by (`git-commit-test').
;; - C-c C-r inserts Reviewed-by (`git-commit-review').
;; - C-c C-o inserts Cc (`git-commit-cc').
;; - C-c C-p inserts Reported-by (`git-commit-reported').
;;;; Committing
;; C-c C-c finishes a commit.
;;
;; Check a buffer for stylistic errors before committing, and ask for
;; confirmation before committing with style errors.
;;; Code:
(require 'log-edit)
(require 'ring)
(require 'server)
;;; Options
;;;; Variables
(defgroup git-commit nil
"Edit Git commit messages."
:prefix "git-commit-"
:group 'tools)
(defcustom git-commit-confirm-commit nil
"Whether to ask for confirmation before committing.
If t, ask for confirmation before creating a commit with style
errors, unless the commit is forced. If nil, never ask for
confirmation before committing."
:group 'git-commit
:type '(choice (const :tag "On style errors" t)
(const :tag "Never" nil)))
(defcustom git-commit-mode-hook '(turn-on-auto-fill)
"Hook run when entering Git Commit mode."
:options '(turn-on-auto-fill flyspell-mode git-commit-save-message)
:type 'hook
:group 'git-commit)
(defcustom git-commit-kill-buffer-hook '(git-commit-save-message)
"Hook run when killing a Git Commit mode buffer.
This hook is run by both `git-commit-commit'
and `git-commit-abort'."
:options '(git-commit-save-message)
:type 'hook
:group 'git-commit)
(defcustom git-commit-summary-max-length 50
"Fontify characters beyond this column in summary lines as errors."
:group 'git-commit
:type 'number)
(defcustom git-commit-fill-column 72
"Automatically wrap commit message lines beyond this column."
:group 'git-commit
:type 'number)
(defcustom git-commit-known-pseudo-headers
'("Signed-off-by" "Acked-by" "Cc"
"Suggested-by" "Reported-by" "Tested-by" "Reviewed-by")
"A list of git pseudo headers to be highlighted."
:group 'git-commit
:type '(repeat string))
;;;; Faces
(defgroup git-commit-faces nil
"Faces for highlighting Git commit messages."
:prefix "git-commit-"
:group 'git-commit
:group 'faces)
(defface git-commit-summary-face
'((t :inherit font-lock-type-face))
"Face used to highlight the summary in git commit messages"
:group 'git-commit-faces)
(defface git-commit-overlong-summary-face
'((t :inherit font-lock-warning-face))
"Face used to highlight overlong parts of git commit message summaries"
:group 'git-commit-faces)
(defface git-commit-nonempty-second-line-face
'((t :inherit font-lock-warning-face))
"Face used to highlight text on the second line of git commit messages"
:group 'git-commit-faces)
(defface git-commit-note-face
'((t :inherit font-lock-string-face))
"Face used to highlight notes in git commit messages"
:group 'git-commit-faces)
(defface git-commit-pseudo-header-face
'((t :inherit font-lock-string-face))
"Font used to hightlight pseudo headers in git commit messages"
:group 'git-commit-faces)
(defface git-commit-known-pseudo-header-face
'((t :inherit font-lock-keyword-face))
"Face used to hightlight common pseudo headers in git commit messages"
:group 'git-commit-faces)
(defface git-commit-branch-face
'((t :inherit font-lock-variable-name-face))
"Face used to highlight the branch name in comments in git commit messages"
:group 'git-commit-faces)
(defface git-commit-no-branch-face
'((t :inherit git-commit-branch-face))
"Face used when a commit is going to be made outside of any branches"
:group 'git-commit-faces)
(defface git-commit-comment-heading-face
'((t :inherit git-commit-known-pseudo-header-face))
"Face used to highlight section headings in the default
comments in git commit messages"
:group 'git-commit-faces)
(defface git-commit-comment-file-face
'((t :inherit git-commit-pseudo-header-face))
"Face used to highlight file names in the default comments in
git commit messages"
:group 'git-commit-faces)
(defface git-commit-comment-action-face
'((t :inherit git-commit-branch-face))
"Face used to highlight what has happened to files in the
default comments in git commit messages"
:group 'git-commit-faces)
;;; Keymap
(defvar git-commit-mode-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd "C-c C-c") 'git-commit-commit)
(define-key map (kbd "C-c C-k") 'git-commit-abort)
(define-key map (kbd "C-c C-s") 'git-commit-signoff)
(define-key map (kbd "C-c C-a") 'git-commit-ack)
(define-key map (kbd "C-c C-t") 'git-commit-test)
(define-key map (kbd "C-c C-r") 'git-commit-review)
(define-key map (kbd "C-c C-o") 'git-commit-cc)
(define-key map (kbd "C-c C-p") 'git-commit-reported)
(define-key map (kbd "C-c C-i") 'git-commit-suggested)
(define-key map (kbd "C-c M-s") 'git-commit-save-message)
(define-key map (kbd "M-p") 'git-commit-prev-message)
(define-key map (kbd "M-n") 'git-commit-next-message)
(define-key map [remap server-edit] 'git-commit-commit)
(define-key map [remap kill-buffer] 'git-commit-abort)
(define-key map [remap ido-kill-buffer] 'git-commit-abort)
(define-key map [remap iswitchb-kill-buffer] 'git-commit-abort)
;; Old bindings to avoid confusion
(define-key map (kbd "C-c C-x s") 'git-commit-signoff)
(define-key map (kbd "C-c C-x a") 'git-commit-ack)
(define-key map (kbd "C-c C-x t") 'git-commit-test)
(define-key map (kbd "C-c C-x r") 'git-commit-review)
(define-key map (kbd "C-c C-x o") 'git-commit-cc)
(define-key map (kbd "C-c C-x p") 'git-commit-reported)
map)
"Key map used by `git-commit-mode'.")
;;; Menu
(require 'easymenu)
(easy-menu-define git-commit-mode-menu git-commit-mode-map
"Git Commit Mode Menu"
'("Commit"
["Previous" git-commit-prev-message t]
["Next" git-commit-next-message t]
"-"
["Ack" git-commit-ack :active t
:help "Insert an 'Acked-by' header"]
["Sign-Off" git-commit-signoff :active t
:help "Insert a 'Signed-off-by' header"]
["Tested-by" git-commit-test :active t
:help "Insert a 'Tested-by' header"]
["Reviewed-by" git-commit-review :active t
:help "Insert a 'Reviewed-by' header"]
["CC" git-commit-cc t
:help "Insert a 'Cc' header"]
["Reported" git-commit-reported :active t
:help "Insert a 'Reported-by' header"]
["Suggested" git-commit-suggested t
:help "Insert a 'Suggested-by' header"]
"-"
["Save" git-commit-save-message t]
["Cancel" git-commit-abort t]
["Commit" git-commit-commit t]))
;;; Committing
(defvar git-commit-commit-hook nil
"Hook run by `git-commit-commit' unless clients exist.
Only use this if you know what you are doing.")
(defvar git-commit-previous-winconf nil)
(defmacro git-commit-restore-previous-winconf (&rest body)
"Run BODY and then restore `git-commit-previous-winconf'.
When `git-commit-previous-winconf' is nil or was created from
another frame do nothing."
(declare (indent 0))
(let ((winconf (make-symbol "winconf"))
(frame (make-symbol "frame")))
`(let ((,winconf git-commit-previous-winconf)
(,frame (selected-frame)))
,@body
(when (and ,winconf
(equal ,frame (window-configuration-frame ,winconf)))
(set-window-configuration ,winconf)
(setq git-commit-previous-winconf nil)))))
(defun git-commit-commit (&optional force)
"Finish editing the commit message and commit.
Check for stylistic errors in the current commit, and ask the
user for confirmation depending on `git-commit-confirm-commit'.
If FORCE is non-nil or if a raw prefix arg is given, commit
immediately without asking.
Return t, if the commit was successful, or nil otherwise."
(interactive "P")
(if (and git-commit-confirm-commit
(git-commit-has-style-errors-p)
(not force)
(not (y-or-n-p "Commit despite stylistic errors?")))
(message "Commit canceled due to stylistic errors.")
(save-buffer)
(run-hooks 'git-commit-kill-buffer-hook)
(remove-hook 'kill-buffer-query-functions
'git-commit-kill-buffer-noop t)
(git-commit-restore-previous-winconf
(if (git-commit-buffer-clients)
(server-edit)
(run-hook-with-args 'git-commit-commit-hook)
(kill-buffer)))))
(defun git-commit-abort ()
"Abort the commit.
The commit message is saved to the kill ring."
(interactive)
(when (< emacs-major-version 24)
;; Emacsclient doesn't exit with non-zero when -error is used.
;; Instead cause Git to error out by feeding it an empty file.
(erase-buffer))
(save-buffer)
(run-hooks 'git-commit-kill-buffer-hook)
(remove-hook 'kill-buffer-hook 'server-kill-buffer t)
(remove-hook 'kill-buffer-query-functions 'git-commit-kill-buffer-noop t)
(git-commit-restore-previous-winconf
(let ((buffer (current-buffer))
(clients (git-commit-buffer-clients)))
(if clients
(progn
(dolist (client clients)
(ignore-errors
(server-send-string client "-error Commit aborted by user"))
(delete-process client))
(when (buffer-live-p buffer)
(kill-buffer buffer)))
(kill-buffer))))
(accept-process-output nil 0.1)
(message (concat "Commit aborted."
(when (memq 'git-commit-save-message
git-commit-kill-buffer-hook)
" Message saved to `log-edit-comment-ring'."))))
(defun git-commit-buffer-clients ()
(and (fboundp 'server-edit)
(boundp 'server-buffer-clients)
server-buffer-clients))
;;; History
(defun git-commit-save-message ()
"Save current message to `log-edit-comment-ring'."
(interactive)
(let ((message (buffer-substring
(point-min)
(git-commit-find-pseudo-header-position))))
(when (and (string-match "^\\s-*\\sw" message)
(or (ring-empty-p log-edit-comment-ring)
(not (ring-member log-edit-comment-ring message))))
;; if index is nil, we end up cycling back to message we just saved!
(unless log-edit-comment-ring-index
(setq log-edit-comment-ring-index 0))
(ring-insert log-edit-comment-ring message))))
(defun git-commit-prev-message (arg)
"Cycle backward through message history, after saving current message.
With a numeric prefix ARG, go back ARG comments."
(interactive "*p")
(when (and (git-commit-save-message) (> arg 0))
(setq log-edit-comment-ring-index
(log-edit-new-comment-index
arg (ring-length log-edit-comment-ring))))
(save-restriction
(narrow-to-region (point-min) (git-commit-find-pseudo-header-position))
(log-edit-previous-comment arg)))
(defun git-commit-next-message (arg)
"Cycle forward through message history, after saving current message.
With a numeric prefix ARG, go forward ARG comments."
(interactive "*p")
(git-commit-prev-message (- arg)))
;;; Headers
(defun git-commit-find-pseudo-header-position ()
"Find the position at which commit pseudo headers should be inserted.
Those headers usually live at the end of a commit message, but
before any trailing comments git or the user might have
inserted."
(save-excursion
(goto-char (point-max))
(if (re-search-backward "^[^#\n]" nil t)
;; we found last non-empty non-comment line, headers go after
(forward-line 1)
;; there's only blanks & comments, headers go before comments
(goto-char (point-min))
(and (re-search-forward "^#" nil t) (forward-line 0)))
(skip-chars-forward "\n")
(point)))
(defun git-commit-determine-pre-for-pseudo-header ()
"Find the characters to insert before the pseudo header.
Returns either zero, one or two newlines after computation.
`point' either points to an empty line (with a non-empty previous
line) or the end of a non-empty line."
(let ((pre "")
(prev-line nil))
(if (not (eq (point) (point-at-bol)))
(progn
(setq pre (concat pre "\n"))
(setq prev-line (thing-at-point 'line)))
;; else: (point) is at an empty line
(when (not (eq (point) (point-min)))
(setq prev-line
(save-excursion
(forward-line -1)
(thing-at-point 'line)))))
;; we have prev-line now; if it doesn't match any known pseudo
;; header, add a newline
(when prev-line
(if (not (delq nil (mapcar (lambda (pseudo-header)
(string-match pseudo-header prev-line))
git-commit-known-pseudo-headers)))
(setq pre (concat pre "\n"))))
pre))
(defun git-commit-insert-header (type name email)
"Insert a header into the commit message.
The inserted header has the format 'TYPE: NAME <EMAIL>'.
The header is inserted at the position returned by
`git-commit-find-pseudo-header-position'. When this position
isn't after an existing header or a newline, an extra newline is
inserted before the header."
(let ((header-at (git-commit-find-pseudo-header-position)))
(save-excursion
(goto-char header-at)
(let ((pre (git-commit-determine-pre-for-pseudo-header)))
(insert (format "%s%s: %s <%s>\n" pre type name email))))))
(defun git-commit-insert-header-as-self (type)
"Insert a header with the name and email of the current user.
The inserted header has the format 'TYPE: NAME <EMAIL>'.
Also see `git-commit-insert-header'."
(git-commit-insert-header
type
(or (getenv "GIT_AUTHOR_NAME")
(getenv "GIT_COMMITTER_NAME")
(ignore-errors (car (process-lines "git" "config" "user.name")))
user-full-name)
(or (getenv "GIT_AUTHOR_EMAIL")
(getenv "GIT_COMMITTER_EMAIL")
(getenv "EMAIL")
(ignore-errors (car (process-lines "git" "config" "user.email")))
user-mail-address)))
(defmacro git-define-git-commit-self (action header)
"Create function git-commit-ACTION.
ACTION will be part of the function name.
HEADER is the actual header to be inserted into the comment."
(let ((func-name (intern (concat "git-commit-" action))))
`(defun ,func-name ()
,(format "Insert a '%s' header at the end of the commit message.
The author name and email address used for the header are
retrieved automatically with the same mechanism git uses."
header)
(interactive)
(git-commit-insert-header-as-self ,header))))
(git-define-git-commit-self "ack" "Acked-by")
(git-define-git-commit-self "review" "Reviewed-by")
(git-define-git-commit-self "signoff" "Signed-off-by")
(git-define-git-commit-self "test" "Tested-by")
(defmacro git-define-git-commit (action header)
"Create interactive function git-commit-ACTION.
ACTION will be part of the function name.
HEADER is the actual header to be inserted into the comment."
(let ((func-name (intern (concat "git-commit-" action))))
`(defun ,func-name (name email)
,(format "Insert a '%s' header at the end of the commit message.
The value of the header is determined by NAME and EMAIL.
When called interactively, both NAME and EMAIL are read from the
minibuffer."
header)
(interactive
(list (read-string "Name: ")
(read-string "Email: ")))
(git-commit-insert-header ,header name email))))
(git-define-git-commit "cc" "Cc")
(git-define-git-commit "reported" "Reported-by")
(git-define-git-commit "suggested" "Suggested-by")
(defconst git-commit-comment-headings-alist
'(("Not currently on any branch." . git-commit-no-branch-face)
("Changes to be committed:" . git-commit-comment-heading-face)
("Untracked files:" . git-commit-comment-heading-face)
("Changed but not updated:" . git-commit-comment-heading-face)
("Changes not staged for commit:" . git-commit-comment-heading-face)
("Unmerged paths:" . git-commit-comment-heading-face))
"Headings in message comments.
The `car' of each cell is the heading text, the `cdr' the face to
use for fontification.")
(defun git-commit-summary-regexp ()
(concat
;; Skip empty lines or comments before the summary
"\\`\\(?:^\\(?:\\s-*\\|\\s<.*\\)\n\\)*"
;; The summary line
(format "\\(.\\{0,%d\\}\\)\\(.*\\)" git-commit-summary-max-length)
;; Non-empty non-comment second line
;;
;; For instant highlighting of non-empty second lines in font-lock,
;; the last capturing group must capture the empty string ("") in
;; "summary line\n".
;; That's why the simpler regex "\\(?:\n\\([^\n#].*\\)\\)?",
;; which captures 'nil', can't be used.
"\\(?:\n\\#\\|\n\\(.*\\)\\)?"))
(defun git-commit-has-style-errors-p ()
"Check whether the current buffer has style errors.
Return t, if the current buffer has style errors, or nil
otherwise."
(save-excursion
(goto-char (point-min))
(when (re-search-forward (git-commit-summary-regexp) nil t)
(or (string-match-p ".+" (or (match-string 2) ""))
(string-match-p "^.+$" (or (match-string 3) ""))))))
;;; Font-Lock
(defun git-commit-mode-summary-font-lock-keywords (&optional errors)
"Create font lock keywords to fontify the Git summary.
If ERRORS is non-nil create keywords that highlight errors in the
summary line, not the summary line itself."
(if errors
`(,(git-commit-summary-regexp)
(2 'git-commit-overlong-summary-face t t)
(3 'git-commit-nonempty-second-line-face t t))
`(,(git-commit-summary-regexp)
(1 'git-commit-summary-face t))))
(defun git-commit-mode-heading-keywords ()
"Create font lock keywords to fontify comment headings.
Known comment headings are provided by `git-commit-comment-headings'."
(mapcar (lambda (cell) `(,(format "^\\s<\\s-+\\(%s\\)$"
(regexp-quote (car cell)))
(1 ',(cdr cell) t)))
git-commit-comment-headings-alist))
(defun git-commit-mode-font-lock-keywords ()
(append
`(("^\\s<.*$" . 'font-lock-comment-face)
("^\\s<\\s-On branch \\(.*\\)$" (1 'git-commit-branch-face t))
("^\\s<\t\\(?:\\([^:\n]+\\):\\s-+\\)?\\(.*\\)$"
(1 'git-commit-comment-action-face t t)
(2 'git-commit-comment-file-face t))
(,(concat "^\\("
(regexp-opt git-commit-known-pseudo-headers)
":\\)\\(\s.*\\)$")
(1 'git-commit-known-pseudo-header-face)
(2 'git-commit-pseudo-header-face))
("^\\<\\S-+:\\s-.*$" . 'git-commit-pseudo-header-face)
(eval . (git-commit-mode-summary-font-lock-keywords))
("\\[[^\n]+?\\]" (0 'git-commit-note-face t)) ; Notes override summary line
;; Warnings from overlong lines and nonempty second line override
;; everything
(eval . (git-commit-mode-summary-font-lock-keywords t)))
(git-commit-mode-heading-keywords)))
(defun git-commit-font-lock-diff ()
"Add font lock on diff."
(save-excursion
(goto-char (point-min))
(when (re-search-forward "^diff --git" nil t)
(let ((beg (match-beginning 0)))
(let* ((buffer (current-buffer))
(font-lock-verbose nil)
(font-lock-support-mode nil)
(text (with-temp-buffer
(insert
(with-current-buffer buffer
(buffer-substring-no-properties beg (point-max))))
(diff-mode)
(font-lock-fontify-buffer)
(let ((pos (point-min))
next)
(while (setq next (next-single-property-change pos 'face))
(put-text-property pos next 'font-lock-face
(get-text-property pos 'face))
(setq pos next)))
(buffer-string))))
(delete-region beg (point-max))
(insert text))))))
;;; Mode
(defvar git-commit-mode-syntax-table
(let ((table (make-syntax-table text-mode-syntax-table)))
(modify-syntax-entry ?# "<" table)
(modify-syntax-entry ?\n ">" table)
(modify-syntax-entry ?\r ">" table)
table)
"Syntax table used by `git-commit-mode'.")
;;;###autoload
(define-derived-mode git-commit-mode text-mode "Git Commit"
"Major mode for editing git commit messages.
This mode helps with editing git commit messages both by
providing commands to do common tasks, and by highlighting the
basic structure of and errors in git commit messages."
;; Font locking
(setq font-lock-defaults (list (git-commit-mode-font-lock-keywords) t))
(set (make-local-variable 'font-lock-multiline) t)
(git-commit-font-lock-diff)
;; Filling according to the guidelines
(setq fill-column git-commit-fill-column)
;; Recognize changelog-style paragraphs
(set (make-local-variable 'paragraph-start)
(concat paragraph-start "\\|*\\|("))
;; Treat lines starting with a hash/pound as comments
(set (make-local-variable 'comment-start) "#")
(set (make-local-variable 'comment-start-skip)
(concat "^" (regexp-quote comment-start) "+"
"\\s-*"))
(set (make-local-variable 'comment-use-syntax) nil)
;; Do not remember point location in commit messages
(when (boundp 'save-place)
(setq save-place nil))
;; If the commit summary is empty, insert a newline after point
(when (string= "" (buffer-substring-no-properties
(line-beginning-position)
(line-end-position)))
(open-line 1))
;; That's what happens when every little detail is commented
(make-local-variable 'log-edit-comment-ring-index)
;; Make sure `git-commit-abort' cannot be by-passed
(add-hook 'kill-buffer-query-functions
'git-commit-kill-buffer-noop nil t)
;; Make the wrong usage info from `server-execute' go way
(run-with-timer 0.01 nil (lambda (m) (message "%s" m))
(substitute-command-keys
(concat "Type \\[git-commit-commit] "
(let ((n (buffer-file-name)))
(cond ((equal n "TAG_EDITMSG") "to tag")
((or (equal n "NOTES_EDITMSG")
(equal n "PULLREQ_EDITMSG"))
"when done")
(t "to commit")))
" (\\[git-commit-abort] to abort)."))))
(defun git-commit-kill-buffer-noop ()
(message
(substitute-command-keys
"Don't kill this buffer. Instead abort using \\[git-commit-abort]."))
nil)
(defun git-commit-mode-flyspell-verify ()
(not (nth 4 (syntax-ppss)))) ; not inside a comment
(eval-after-load 'flyspell
'(put 'git-commit-mode 'flyspell-mode-predicate
'git-commit-mode-flyspell-verify))
;;;###autoload
(add-to-list 'auto-mode-alist '("/MERGE_MSG\\'" . git-commit-mode))
;;;###autoload
(add-to-list 'auto-mode-alist
'("/\\(?:COMMIT\\|NOTES\\|TAG\\|PULLREQ\\)_EDITMSG\\'"
. git-commit-mode))
(defun git-commit-auto-mode-enable ()
(message "git-commit-auto-mode-enable is obsolete and doesn't do anything"))
(make-obsolete 'git-commit-auto-mode-enable "This mode is a noop now" "")
(provide 'git-commit-mode)
;; Local Variables:
;; indent-tabs-mode: nil
;; End:
;;; git-commit-mode.el ends here

Binary file not shown.

View file

@ -0,0 +1,36 @@
;;; git-rebase-mode-autoloads.el --- automatically extracted autoloads
;;
;;; Code:
;;;### (autoloads (git-rebase-mode) "git-rebase-mode" "git-rebase-mode.el"
;;;;;; (21607 37946 917866 10000))
;;; Generated autoloads from git-rebase-mode.el
(autoload 'git-rebase-mode "git-rebase-mode" "\
Major mode for editing of a Git rebase file.
Rebase files are generated when you run 'git rebase -i' or run
`magit-interactive-rebase'. They describe how Git should perform
the rebase. See the documentation for git-rebase (e.g., by
running 'man git-rebase' at the command line) for details.
\(fn)" t nil)
(add-to-list 'auto-mode-alist '("/git-rebase-todo\\'" . git-rebase-mode))
;;;***
;;;### (autoloads nil nil ("git-rebase-mode-pkg.el") (21607 37947
;;;;;; 63042 677000))
;;;***
(provide 'git-rebase-mode-autoloads)
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; coding: utf-8
;; End:
;;; git-rebase-mode-autoloads.el ends here

View file

@ -0,0 +1 @@
(define-package "git-rebase-mode" "20140928.1547" "Major mode for editing git rebase files" (quote nil))

View file

@ -0,0 +1,394 @@
;;; git-rebase-mode.el --- Major mode for editing git rebase files
;; Version: 20140928.1547
;; Copyright (C) 2010-2014 The Magit Project Developers
;; Author: Phil Jackson <phil@shellarchive.co.uk>
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
;; Homepage: https://github.com/magit/git-modes
;; Keywords: convenience vc git
;; This file is not part of GNU Emacs.
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this file. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; Allows the editing of a git rebase file (which you might get when
;; using 'git rebase -i' or hitting 'E' in Magit). Assumes editing is
;; happening in a server.
;;; Code:
(require 'easymenu)
(require 'server)
(require 'thingatpt)
;;; Options
;;;; Variables
(defgroup git-rebase nil
"Edit Git rebase sequences."
:group 'tools)
(defcustom git-rebase-auto-advance nil
"If non-nil, moves point forward a line after running an action."
:group 'git-rebase
:type 'boolean)
(defcustom git-rebase-remove-instructions nil
"Whether to remove the instructions from the rebase buffer.
Because you have seen them before and can still remember."
:group 'git-rebase
:type 'boolean)
;;;; Faces
(defgroup git-rebase-faces nil
"Faces used by Git-Rebase mode."
:group 'faces
:group 'git-rebase)
(defface git-rebase-hash
'((((class color) (background light))
:foreground "firebrick")
(((class color) (background dark))
:foreground "tomato"))
"Face for commit hashes."
:group 'git-rebase-faces)
(defface git-rebase-description nil
"Face for commit descriptions."
:group 'git-rebase-faces)
(defface git-rebase-killed-action
'((((class color))
:inherit font-lock-comment-face
:strike-through t))
"Face for commented action and exec lines."
:group 'git-rebase-faces)
(define-obsolete-face-alias 'git-rebase-description-face
'git-rebase-description "1.0.0")
(define-obsolete-face-alias 'git-rebase-killed-action-face
'git-rebase-killed-action "1.0.0")
;;; Regexps
(defconst git-rebase-action-line-re
(concat "^#?"
"\\([efprs]\\|pick\\|reword\\|edit\\|squash\\|fixup\\) "
"\\([a-z0-9]\\{4,40\\}\\) "
"\\(.*\\)")
"Regexp matching action lines in rebase buffers.")
(defconst git-rebase-exec-line-re
"^#?\\(x\\|exec\\)[[:space:]]\\(.*\\)"
"Regexp matching exec lines in rebase buffer.")
(defconst git-rebase-dead-line-re
(format "^#\\(?:%s\\|%s\\)"
(substring git-rebase-action-line-re 1)
(substring git-rebase-exec-line-re 1))
"Regexp matching commented action and exex lines in rebase buffers.")
;;; Keymaps
(defvar git-rebase-mode-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map special-mode-map)
(define-key map (kbd "q") 'git-rebase-server-edit)
(define-key map (kbd "C-c C-c") 'git-rebase-server-edit)
(define-key map (kbd "a") 'git-rebase-abort)
(define-key map (kbd "C-c C-k") 'git-rebase-abort)
(define-key map [remap undo] 'git-rebase-undo)
(define-key map (kbd "RET") 'git-rebase-show-commit)
(define-key map (kbd "x") 'git-rebase-exec)
(define-key map (kbd "c") 'git-rebase-pick)
(define-key map (kbd "r") 'git-rebase-reword)
(define-key map (kbd "e") 'git-rebase-edit)
(define-key map (kbd "s") 'git-rebase-squash)
(define-key map (kbd "f") 'git-rebase-fixup)
(define-key map (kbd "y") 'git-rebase-insert)
(define-key map (kbd "k") 'git-rebase-kill-line)
(define-key map (kbd "C-k") 'git-rebase-kill-line)
(define-key map (kbd "p") 'git-rebase-backward-line)
(define-key map (kbd "n") 'forward-line)
(define-key map (kbd "M-p") 'git-rebase-move-line-up)
(define-key map (kbd "M-n") 'git-rebase-move-line-down)
(define-key map (kbd "M-<up>") 'git-rebase-move-line-up)
(define-key map (kbd "M-<down>") 'git-rebase-move-line-down)
map)
"Keymap for Git-Rebase mode.")
(easy-menu-define git-rebase-mode-menu git-rebase-mode-map
"Git-Rebase mode menu"
'("Rebase"
["Pick" git-rebase-pick t]
["Reword" git-rebase-reword t]
["Edit" git-rebase-edit t]
["Squash" git-rebase-squash t]
["Fixup" git-rebase-fixup t]
["Kill" git-rebase-kill-line t]
["Move Down" git-rebase-move-line-down t]
["Move Up" git-rebase-move-line-up t]
["Execute" git-rebase-exec t]
"---"
["Abort" git-rebase-abort t]
["Done" git-rebase-server-edit t]))
;;; Utilities
(defun git-rebase-edit-line (change-to)
(when (git-rebase-looking-at-action)
(let ((buffer-read-only nil)
(start (point)))
(goto-char (point-at-bol))
(delete-region (point) (progn (forward-word 1) (point)))
(insert change-to)
(goto-char start)
(when git-rebase-auto-advance
(forward-line)))))
(defmacro git-rebase-define-action (sym)
(declare (indent defun))
(let ((fn (intern (format "git-rebase-%s" sym))))
`(progn
(defun ,fn ()
(interactive)
(git-rebase-edit-line ,(symbol-name sym)))
(put ',fn 'definition-name ',sym))))
(defun git-rebase-looking-at-action ()
"Return non-nil if looking at an action line."
(save-excursion
(goto-char (point-at-bol))
(looking-at git-rebase-action-line-re)))
(defun git-rebase-looking-at-action-or-exec ()
"Return non-nil if looking at an action line or exec line."
(save-excursion
(goto-char (point-at-bol))
(or (looking-at git-rebase-action-line-re)
(looking-at git-rebase-exec-line-re))))
(defun git-rebase-looking-at-exec ()
"Return non-nil if cursor is on an exec line."
(string-match git-rebase-exec-line-re (thing-at-point 'line)))
(defun git-rebase-looking-at-killed-exec ()
"Return non-nil if looking at an exec line that has been commented out."
(let ((line (thing-at-point 'line)))
(and (eq (aref line 0) ?#)
(string-match git-rebase-exec-line-re line))))
;;; Commands
(git-rebase-define-action pick)
(git-rebase-define-action reword)
(git-rebase-define-action edit)
(git-rebase-define-action squash)
(git-rebase-define-action fixup)
(defun git-rebase-move-line-up ()
"Move the current action line up."
(interactive)
(when (git-rebase-looking-at-action-or-exec)
(let ((buffer-read-only nil)
(col (current-column)))
(goto-char (point-at-bol))
(unless (bobp)
(transpose-lines 1)
(forward-line -2))
(move-to-column col))))
(defun git-rebase-move-line-down ()
"Assuming the next line is also an action line, move the current line down."
(interactive)
;; if we're on an action and the next line is also an action
(when (and (git-rebase-looking-at-action-or-exec)
(save-excursion
(forward-line)
(git-rebase-looking-at-action-or-exec)))
(let ((buffer-read-only nil)
(col (current-column)))
(forward-line 1)
(transpose-lines 1)
(forward-line -1)
(move-to-column col))))
(defun git-rebase-server-edit ()
"Save the action buffer and end the session."
(interactive)
(save-buffer)
(server-edit))
(defun git-rebase-abort ()
"Abort this rebase.
This is dune by emptying the buffer, saving and closing server
connection."
(interactive)
(when (or (not (buffer-modified-p))
(y-or-n-p "Abort this rebase? "))
(let ((buffer-read-only nil))
(erase-buffer)
(save-buffer)
(server-edit))))
(defun git-rebase-kill-line ()
"Kill the current action line."
(interactive)
(when (and (not (eq (char-after (point-at-bol)) ?#))
(git-rebase-looking-at-action-or-exec))
(beginning-of-line)
(let ((inhibit-read-only t))
(insert "#"))
(forward-line)))
(defun git-rebase-insert (rev)
"Read an arbitrary commit and insert it below current line."
(interactive
(list (if (fboundp 'magit-read-branch-or-commit)
(magit-read-branch-or-commit "Insert revision")
(read-string "Insert revision: "))))
(forward-line)
(let ((summary (if (fboundp 'magit-rev-format)
(magit-rev-format "%h %s" rev)
(process-lines "git" "show" "-s" "--format=%h %s" rev))))
(if summary
(let ((inhibit-read-only t))
(insert "pick " summary ?\n))
(user-error "Unknown revision"))))
(defun git-rebase-exec (edit)
"Prompt the user for a shell command to be executed, and
add it to the todo list.
If the cursor is on a commented-out exec line, uncomment the
current line instead of prompting.
When the prefix argument EDIT is non-nil and the cursor is on an
exec line, edit that line instead of inserting a new one. If the
exec line was commented out, also uncomment it."
(interactive "P")
(cond
((and edit (git-rebase-looking-at-exec))
(let ((new-line (git-rebase-read-exec-line
(match-string-no-properties 2 (thing-at-point 'line))))
(inhibit-read-only t))
(delete-region (point-at-bol) (point-at-eol))
(if (not (equal "" new-line))
(insert "exec " new-line)
(delete-char -1)
(forward-line))
(move-beginning-of-line nil)))
((git-rebase-looking-at-killed-exec)
(save-excursion
(beginning-of-line)
(let ((buffer-read-only nil))
(delete-char 1))))
(t
(let ((inhibit-read-only t)
(line (git-rebase-read-exec-line)))
(unless (equal "" line)
(move-end-of-line nil)
(newline)
(insert (concat "exec " line))))
(move-beginning-of-line nil))))
(defun git-rebase-read-exec-line (&optional initial-line)
(read-shell-command "Execute: " initial-line))
(defun git-rebase-undo (&optional arg)
"A thin wrapper around `undo', which allows undoing in read-only buffers."
(interactive "P")
(let ((inhibit-read-only t))
(undo arg)))
(defun git-rebase-show-commit (&optional arg)
"Show the commit on the current line if any."
(interactive "P")
(save-excursion
(goto-char (point-at-bol))
(when (looking-at git-rebase-action-line-re)
(let ((commit (match-string 2)))
(if (fboundp 'magit-show-commit)
(let ((default-directory (expand-file-name "../../")))
(magit-show-commit commit))
(shell-command (concat "git show " commit)))))))
(defun git-rebase-backward-line (&optional n)
"Move N lines backward (forward if N is negative).
Like `forward-line' but go into the opposite direction."
(interactive "p")
(forward-line (* n -1)))
;;; Mode
;;;###autoload
(define-derived-mode git-rebase-mode special-mode "Git Rebase"
"Major mode for editing of a Git rebase file.
Rebase files are generated when you run 'git rebase -i' or run
`magit-interactive-rebase'. They describe how Git should perform
the rebase. See the documentation for git-rebase (e.g., by
running 'man git-rebase' at the command line) for details."
(setq font-lock-defaults '(git-rebase-mode-font-lock-keywords t t))
(when git-rebase-remove-instructions
(let ((inhibit-read-only t))
(flush-lines "^\\($\\|#\\)"))))
(defvar git-rebase-mode-font-lock-keywords
`((,git-rebase-action-line-re
(1 font-lock-keyword-face)
(2 'git-rebase-hash)
(3 'git-rebase-description))
(,git-rebase-exec-line-re 1 font-lock-keyword-face)
("^#.*" 0 font-lock-comment-face)
(,git-rebase-dead-line-re 0 'git-rebase-killed-action t))
"Font lock keywords for Git-Rebase mode.")
(defun git-rebase-mode-show-keybindings ()
"Modify the \"Commands:\" section of the comment Git generates
at the bottom of the file so that in place of the one-letter
abbreviation for the command, it shows the command's keybinding.
By default, this is the same except for the \"pick\" command."
(save-excursion
(goto-char (point-min))
(while (search-forward-regexp "^# \\(.\\), \\([[:alpha:]]+\\) = " nil t)
(let ((start (match-beginning 1))
(end (match-end 1))
(command (intern (concat "git-rebase-" (match-string 2)))))
(when (fboundp command)
(let ((overlay (make-overlay start end)))
(overlay-put
overlay 'display
(key-description (where-is-internal command nil t)))))))))
(add-hook 'git-rebase-mode-hook 'git-rebase-mode-show-keybindings t)
(defun git-rebase-mode-disable-before-save-hook ()
(set (make-local-variable 'before-save-hook) nil))
(add-hook 'git-rebase-mode-hook 'git-rebase-mode-disable-before-save-hook)
;;;###autoload
(add-to-list 'auto-mode-alist
'("/git-rebase-todo\\'" . git-rebase-mode))
(provide 'git-rebase-mode)
;; Local Variables:
;; indent-tabs-mode: nil
;; End:
;;; git-rebase-mode.el ends here

Binary file not shown.

View file

@ -0,0 +1,57 @@
;;; let-alist-autoloads.el --- automatically extracted autoloads
;;
;;; Code:
;;;### (autoloads (let-alist) "let-alist" "let-alist.el" (21856 52888
;;;;;; 214937 951000))
;;; Generated autoloads from let-alist.el
(autoload 'let-alist "let-alist" "\
Let-bind dotted symbols to their cdrs in ALIST and execute BODY.
Dotted symbol is any symbol starting with a `.'. Only those present
in BODY are let-bound and this search is done at compile time.
For instance, the following code
(let-alist alist
(if (and .title .body)
.body
.site
.site.contents))
essentially expands to
(let ((.title (cdr (assq 'title alist)))
(.body (cdr (assq 'body alist)))
(.site (cdr (assq 'site alist)))
(.site.contents (cdr (assq 'contents (cdr (assq 'site alist))))))
(if (and .title .body)
.body
.site
.site.contents))
If you nest `let-alist' invocations, the inner one can't access
the variables of the outer one. You can, however, access alists
inside the original alist by using dots inside the symbol, as
displayed in the example above.
\(fn ALIST &rest BODY)" nil t)
(put 'let-alist 'lisp-indent-function '1)
;;;***
;;;### (autoloads nil nil ("let-alist-pkg.el") (21856 52888 307509
;;;;;; 151000))
;;;***
(provide 'let-alist-autoloads)
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; coding: utf-8
;; End:
;;; let-alist-autoloads.el ends here

View file

@ -0,0 +1 @@
(define-package "let-alist" "1.0.3" "Easily let-bind values of an assoc-list by their names" (quote nil))

Binary file not shown.

View file

@ -0,0 +1,162 @@
;;; let-alist.el --- Easily let-bind values of an assoc-list by their names -*- lexical-binding: t; -*-
;; Copyright (C) 2014 Free Software Foundation, Inc.
;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
;; Maintainer: Artur Malabarba <bruce.connor.am@gmail.com>
;; Version: 1.0.3
;; Keywords: extensions lisp
;; Prefix: let-alist
;; Separator: -
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; This package offers a single macro, `let-alist'. This macro takes a
;; first argument (whose value must be an alist) and a body.
;;
;; The macro expands to a let form containing body, where each dotted
;; symbol inside body is let-bound to their cdrs in the alist. Dotted
;; symbol is any symbol starting with a `.'. Only those present in
;; the body are let-bound and this search is done at compile time.
;;
;; For instance, the following code
;;
;; (let-alist alist
;; (if (and .title .body)
;; .body
;; .site
;; .site.contents))
;;
;; essentially expands to
;;
;; (let ((.title (cdr (assq 'title alist)))
;; (.body (cdr (assq 'body alist)))
;; (.site (cdr (assq 'site alist)))
;; (.site.contents (cdr (assq 'contents (cdr (assq 'site alist))))))
;; (if (and .title .body)
;; .body
;; .site
;; .site.contents))
;;
;; If you nest `let-alist' invocations, the inner one can't access
;; the variables of the outer one. You can, however, access alists
;; inside the original alist by using dots inside the symbol, as
;; displayed in the example above by the `.site.contents'.
;;
;;; Code:
(defun let-alist--deep-dot-search (data)
"Return alist of symbols inside DATA that start with a `.'.
Perform a deep search and return an alist where each car is the
symbol, and each cdr is the same symbol without the `.'."
(cond
((symbolp data)
(let ((name (symbol-name data)))
(when (string-match "\\`\\." name)
;; Return the cons cell inside a list, so it can be appended
;; with other results in the clause below.
(list (cons data (intern (replace-match "" nil nil name)))))))
((not (listp data)) nil)
(t (apply #'append
(mapcar #'let-alist--deep-dot-search data)))))
(defun let-alist--access-sexp (symbol variable)
"Return a sexp used to acess SYMBOL inside VARIABLE."
(let* ((clean (let-alist--remove-dot symbol))
(name (symbol-name clean)))
(if (string-match "\\`\\." name)
clean
(let-alist--list-to-sexp
(mapcar #'intern (nreverse (split-string name "\\.")))
variable))))
(defun let-alist--list-to-sexp (list var)
"Turn symbols LIST into recursive calls to `cdr' `assq' on VAR."
`(cdr (assq ',(car list)
,(if (cdr list) (let-alist--list-to-sexp (cdr list) var)
var))))
(defun let-alist--remove-dot (symbol)
"Return SYMBOL, sans an initial dot."
(let ((name (symbol-name symbol)))
(if (string-match "\\`\\." name)
(intern (replace-match "" nil nil name))
symbol)))
;;; The actual macro.
;;;###autoload
(defmacro let-alist (alist &rest body)
"Let-bind dotted symbols to their cdrs in ALIST and execute BODY.
Dotted symbol is any symbol starting with a `.'. Only those present
in BODY are let-bound and this search is done at compile time.
For instance, the following code
(let-alist alist
(if (and .title .body)
.body
.site
.site.contents))
essentially expands to
(let ((.title (cdr (assq 'title alist)))
(.body (cdr (assq 'body alist)))
(.site (cdr (assq 'site alist)))
(.site.contents (cdr (assq 'contents (cdr (assq 'site alist))))))
(if (and .title .body)
.body
.site
.site.contents))
If you nest `let-alist' invocations, the inner one can't access
the variables of the outer one. You can, however, access alists
inside the original alist by using dots inside the symbol, as
displayed in the example above."
(declare (indent 1) (debug t))
(let ((var (make-symbol "alist")))
`(let ((,var ,alist))
(let ,(mapcar (lambda (x) `(,(car x) ,(let-alist--access-sexp (car x) var)))
(delete-dups (let-alist--deep-dot-search body)))
,@body))))
;;;; ChangeLog:
;; 2014-12-22 Artur Malabarba <bruce.connor.am@gmail.com>
;;
;; packages/let-alist: Use `make-symbol' instead of `gensym'.
;;
;; 2014-12-20 Artur Malabarba <bruce.connor.am@gmail.com>
;;
;; packages/let-alist: Enable access to deeper alists
;;
;; 2014-12-14 Artur Malabarba <bruce.connor.am@gmail.com>
;;
;; let-alist.el: Add lexical binding. Version bump.
;;
;; 2014-12-11 Artur Malabarba <bruce.connor.am@gmail.com>
;;
;; let-alist: New package
;;
(provide 'let-alist)
;;; let-alist.el ends here

Binary file not shown.

View file

@ -0,0 +1,178 @@
Authors
=======
Also see https://github.com/magit/magit/graphs/contributors.
Names below are sorted alphabetically.
Author
------
- Marius Vollmer <marius.vollmer@gmail.com>
Maintainer
----------
- Jonas Bernoulli <jonas@bernoul.li>
Retired Maintainers
-------------------
- Nicolas Dudebout <nicolas.dudebout@gatech.edu>
- Peter J. Weisberg <pj@irregularexpressions.net>
- Phil Jackson <phil@shellarchive.co.uk>
- Rémi Vanicat <vanicat@debian.org>
- Yann Hodique <yann.hodique@gmail.com>
Contributors
------------
- aaa707 <aaa707b@gmail.com>
- Aaron Culich <aculich@gmail.com>
- Abdo Roig-Maranges <abdo.roig@gmail.com>
- acple <silentsphere110@gmail.com>
- Adam Spiers <emacs@adamspiers.org>
- Ævar Arnfjörð Bjarmason <avarab@gmail.com>
- Alan Falloon <alan.falloon@gmail.com>
- Alexey Voinov <alexey.v.voinov@gmail.com>
- Alex Ott <alexott@gmail.com>
- Andreas Fuchs <asf@boinkor.net>
- Andreas Liljeqvist <andreas.liljeqvist@robacks.se>
- Andreas Rottmann <a.rottmann@gmx.at>
- Andrei Chițu <andrei.chitu1@gmail.com>
- Andrew Kirkpatrick <andrew.kirkpatrick@adelaide.edu.au>
- Andrey Smirnov <andrew.smirnov@gmail.com>
- Bastian Beischer <beischer@physik.rwth-aachen.de>
- Ben Walton <bwalton@artsci.utoronto.ca>
- Bradley Wright <brad@intranation.com>
- Brandon W Maister <quodlibetor@gmail.com>
- Brian Warner <warner@lothar.com>
- Bryan Shell <bryan.shell@orbitz.com>
- Chris Bernard <cebernard@gmail.com>
- Chris Done <chrisdone@gmail.com>
- Chris Moore <dooglus@gmail.com>
- Chris Ring <chris@ringthis.com>
- Christian Dietrich <christian.dietrich@informatik.uni-erlangen.de>
- Christian Kluge <ckfrakturfreak@web.de>
- Christopher Monsanto <chris@monsan.to>
- Cornelius Mika <cornelius.mika@gmail.com>
- Craig Andera <candera@wangdera.com>
- Dale Hagglund <dale.hagglund@gmail.com>
- Damien Cassou <damien.cassou@gmail.com>
- Daniel Brockman <daniel@gointeractive.se>
- Daniel Farina <drfarina@acm.org>
- Daniel Hackney <dan@haxney.org>
- Dan LaManna <dan.lamanna@gmail.com>
- David Abrahams <dave@boostpro.com>
- David Hull <david.hull@openx.com>
- David Wallin <david.wallin@gmail.com>
- Divye Kapoor <divye@google.com>
- Dominique Quatravaux <domq@google.com>
- Eli Barzilay <eli@barzilay.org>
- Eric Davis <ed@npri.org>
- Eric Schulte <schulte.eric@gmail.com>
- Evgkeni Sampelnikof <esabof@gmail.com>
- Felix Geller <fgeller@gmail.com>
- Feng Li <fengli@blackmagicdesign.com>
- George Kadianakis <desnacked@gmail.com>
- Graham Clark <grclark@gmail.com>
- Greg A. Woods <woods@planix.com>
- Greg Sexton <gregsexton@gmail.com>
- Hannu Koivisto <azure@iki.fi>
- Hans-Peter Deifel <hpdeifel@gmx.de>
- Ian Eure <ian.eure@gmail.com>
- Jan Tatarik <jan.tatarik@xing.com>
- Jasper St. Pierre <jstpierre@mecheye.net>
- Jeff Bellegarde <jbellegarde@whitepages.com>
- Jeff Dairiki <dairiki@dairiki.org>
- Jesse Alama <jesse.alama@gmail.com>
- John Wiegley <johnw@newartisans.com>
- Jonas Bernoulli <jonas@bernoul.li>
- Jonathan Roes <jroes@jroes.net>
- Julien Danjou <julien@danjou.info>
- Justin Caratzas <justin.caratzas@gmail.com>
- Kimberly Wolk <kimwolk@hotmail.com>
- Kyle Meyer <kyle@kyleam.com>
- Laurent Laffont <laurent.laffont@gmail.com>
- Lele Gaifax <lele@metapensiero.it>
- Leo Liu <sdl.web@gmail.com>
- Leonardo Etcheverry <leo@kalio.net>
- Lluís Vilanova <vilanova@ac.upc.edu>
- Loic Dachary <loic@dachary.org>
- Luís Borges de Oliveira <lbo@siscog.pt>
- Luke Amdor <luke.amdor@gmail.com>
- Manuel Vázquez Acosta <mva.led@gmail.com>
- Marcel Wolf <mwolf@ml1.net>
- Marc Herbert <marc.herbert@gmail.com>
- Marcin Bachry <hegel666@gmail.com>
- Marco Craveiro <marco.craveiro@gmail.com>
- Marian Schubert <marian.schubert@gooddata.com>
- Marius Vollmer <marius.vollmer@gmail.com>
- Mark Hepburn <Mark.Hepburn@csiro.au>
- Matus Goljer <dota.keys@gmail.com>
- Miles Bader <miles@gnu.org>
- Mitchel Humpherys <mitch.special@gmail.com>
- Moritz Bunkus <moritz@bunkus.org>
- Nathan Weizenbaum <nex342@gmail.com>
- Nguyễn Tuấn Anh <ubolonton@gmail.com>
- Nic Ferier <nic@ferrier.me.uk>
- Nick Alcock <nick.alcock@oracle.com>
- Nick Alexander <nalexander@mozilla.com>
- Nick Dimiduk <ndimiduk@gmail.com>
- Nicolas Dudebout <nicolas.dudebout@gatech.edu>
- Nicolas Richard <theonewiththeevillook@yahoo.fr>
- Noam Postavsky <npostavs@users.sourceforge.net>
- Ole Arndt <oliver.arndt@cegedim.com>
- Óscar Fuentes <ofv@wanadoo.es>
- Paul Stadig <paul@stadig.name>
- Pavel Holejsovsky <pavel.holejsovsky@upek.com>
- Pekka Pessi <nospam@pessi.fi>
- Peter J. Weisberg <pj@irregularexpressions.net>
- Philippe Vaucher <philippe@stvs.ch>
- Philipp Haselwarter <philipp@haselwarter.org>
- Philip Weaver <philip.weaver@gmail.com>
- Phil Jackson <phil@shellarchive.co.uk>
- Pieter Praet <pieter@praet.org>
- Prathamesh Sonpatki <csonpatki@gmail.com>
- pskrz <dennis@walltowall.com>
- rabio <rabiodev@o2.pl>
- Raimon Grau <raimonster@gmail.com>
- Ramkumar Ramachandra <artagnon@gmail.com>
- Remco van 't Veer <rwvtveer@xs4all.nl>
- Rémi Vanicat <vanicat@debian.org>
- René Stadler <mail@renestadler.de>
- Robert Boone <robo4288@gmail.com>
- Robin Green <greenrd@greenrd.org>
- Roger Crew <crew@cs.stanford.edu>
- Romain Francoise <romain@orebokech.com>
- Ron Parker <rparker@a123systems.com>
- Roy Crihfield <rscrihf@gmail.com>
- Rüdiger Sonderfeld <ruediger@c-plusplus.de>
- Ryan C. Thompson <rct@thompsonclan.org>
- Samuel Bronson <naesten@gmail.com>
- Sanjoy Das <sanjoy@playingwithpointers.com>
- Sean Bryant <sbryant@hackinggibsons.com>
- Sebastian Wiesner <lunaryorn@gmail.com>
- Sébastien Gross <seb@chezwam.org>
- Seong-Kook Shin <cinsky@gmail.com>
- Sergey Pashinin <sergey@pashinin.com>
- Sergey Vinokurov <serg.foo@gmail.com>
- Servilio Afre Puentes <afrepues@mcmaster.ca>
- Štěpán Němec <stepnem@gmail.com>
- Steven Chow <steve@myfreestuffapp.com>
- Steven Thomas <sthomas314@gmail.com>
- Steve Purcell <steve@sanityinc.com>
- Suhail Shergill <suhailshergill@gmail.com>
- Takafumi Arakaki <aka.tkf@gmail.com>
- Teruki Shigitani <teruki.shigitani@gmail.com>
- Thierry Volpiatto <thierry.volpiatto@gmail.com>
- Thomas Frössman <thomasf@jossystem.se>
- Thomas Jost <thomas.jost@gmail.com>
- Thomas Riccardi <riccardi.thomas@gmail.com>
- Tibor Simko <tibor.simko@cern.ch>
- Timo Juhani Lindfors <timo.lindfors@iki.fi>
- Ting-Yu Lin <aethanyc@gmail.com>
- Tom Feist <shabble@metavore.org>
- Wilfred Hughes <me@wilfred.me.uk>
- Win Treese <treese@acm.org>
- Yann Hodique <yann.hodique@gmail.com>
- York Zhao <gtdplatform@gmail.com>

View file

@ -0,0 +1,355 @@
[![Build Status](https://travis-ci.org/magit/magit.svg?branch=master)](https://travis-ci.org/magit/magit)
[![Gratipay](http://img.shields.io/gratipay/magit.png)](https://www.gratipay.com/magit)
It's Magit! An Emacs mode for Git
==================================
**The Magit wiki contains a list of [frequently asked questions][faq],
*please* do consult it.**
Magit is an interface to the version control system [Git][git],
implemented as an [Emacs][emacs] extension.
Unlike the [Version Control][vc] package which is part of Emacs and
strives to provide a unified interface to various version control
systems, Magit only supports Git and can therefore better take
advantage of its native features.
Magit supports GNU Emacs 23.2 or later; 24.1 or later is recommended.
Magit supports Git 1.7.2.5 or later; 1.8.2 or later is recommended.
The minimal versions are those available in Debian oldstable.
Feature Freeze
==============
There are currently three "versions" of Magit. The `1.2.1` bugfix
release which is mostly the same as `1.2.0` released in 2012. The
`master` branch, which the packages on Melpa and Melpa-Stable are
built from. This hasn't seen many major changes since February of
this year. And the `next` branch which contains 99% of the work I
have done during the last eight months.
It's about time that `next` is merged and that a release is created.
For that reason I am not going to implement any new features being
proposed now, until after I have created a release. Magit isn't in a
complete feature freeze yet, there are certain new features that I do
want to be part of the next release.
**No *completely* new features are going to be implemented until after
the next release. However some "new" features are going to make it
into the release which replace existing but broken and/or misguided
features.**
This shouldn't keep you from making feature requests, but first
*please* check whether that feature already exists on `next` and don't
expect it to be implemented until after the release. For instructions
on how to install the `next` version of Magit see
[this](https://github.com/magit/magit/tree/next#installation) and
[that](https://github.com/magit/magit/issues/1220).
### Table of Contents
* [Getting Started](#getting-started)
* [Getting Help](#getting-help)
* [Contributions](#contributions)
* [Installation](#installation)
* [Installing from Melpa](#installing-from-melpa)
* [Installing from Marmalade](#installing-from-marmalade)
* [Installing from Git](#installing-from-git)
* [Installing from Tarball](#installing-from-tarball)
* [Dependencies](#dependencies)
Getting Started
===============
To get started with Magit, run <kbd>M-x magit-status</kbd>. If you
are inside a Git repository this opens a buffer that summarizes its
status. Otherwise you are first prompted for a repository. Read the
short help for `magit-status-mode` (<kbd>C-h m</kbd> in the status
buffer).
Then edit and save some files, refresh the status buffer
(<kbd>g</kbd>), stage changes (<kbd>s</kbd>) and commit (<kbd>c</kbd>)
them.
For more details consult the Magit user manual. You can read it with
<kbd>C-u C-h i magit.info</kbd> or [on the web][manual].
We can also recommend [this][mastering-intro] introduction from the
Mastering Emacs blog. It even describes some new features that are
not yet documented in the manual.
Magit also has a [website][website].
Getting Help
============
When something breaks please see the [FAQ][faq]. If that doesn't help
check the list of [all open issues][issues].
If everything else fails please open a [new issue][issues] or ask for
help on the [mailing list][group].
Contributions
=============
Magit is [hosted on Github][development]. Please contribute by
suggesting features on the [issue tracker][issues] or by making code
contributions using [pull requests][pulls]. Before opening a pull
request make sure to read the brief [guidelines][contributing].
Please also consider supporting development using
[gratipay][gratipay]. Thank you!
Magit was started by [Marius Vollmer][marius] and is now maintained
by [Jonas Bernoulli][jonas]. Other Magitians (former maintainers)
are [Nicolas Dudebout][nicolas], [Peter J. Weisberg][peter],
[Phil Jackson][phil], [Rémi Vanicat][remi], and [Yann Hodique][yann].
Many more people have [contributed code][contributors] and suggested
features.
Thanks to all of you, may (the history of) the source be with you!
Installation
============
Beginning with version 24.1 Emacs includes a package management
facility known as Elpa or `package.el`. Using an Elpa package
repository is the easiest and recommended way to install and update
Magit and its dependencies. Among other things using `package.el`
is recommended because that automatically takes care of installing
dependencies.
Magit is available from both of the two popular Elpa repositories,
[Marmalade][marmalade] (stable releases) and [Melpa][melpa]
(snapshots).
### Installing from Melpa
If you have already used Melpa to install some other package then
all you have to do is:
<kbd>M-x package-install RET magit RET</kbd>
This installs Magit as well as all of its dependencies and makes
them available in the current and future Emacs sessions.
If this is the first time you are using Melpa, then you have to
configure `package.el` once.
```lisp
(require 'package)
(add-to-list 'package-archives
'("melpa" . "http://melpa.milkbox.net/packages/") t)
```
Then evaluate these forms, update the package cache, and install
Magit as above. To update the cache use:
<kbd>M-x package-refresh-contents RET</kbd>
You might also want to have a look at the more detailed
[instructions][melpa-intro] provided by the Melpa project. Among
other things it explains how to install only some packages from Melpa
and others from Marmalade, and how to use `package.el` with older
versions of Emacs.
### Installing from Marmalade
For the time being we recommend that you install the development
version available from Melpa, because the latest Magit release (which
is what you get from Marmalade) is very outdated. If you are using
the development version of Emacs, then you have to do so, because it
contains an incompatible change that breaks the last Magit release.
### Installing from Git
If you want to contribute to Magit you should run it directly from the
Git repository.
First get the repository:
```sh
$ git clone git://github.com/magit/magit.git
```
Then you should byte compile the libraries and generate the
documentation, though that is not required:
```sh
$ make lisp docs
```
Unless all dependencies are installed at `../DEPENDENCY` you have to
tell `make` where to find them, e.g.:
```sh
$ EFLAGS="-L /path/to/git-modes" make lisp docs
```
Then add this to you init file:
```lisp
(add-to-list 'load-path "/path/to/git-modes")
(add-to-list 'load-path "/path/to/magit")
(eval-after-load 'info
'(progn (info-initialize)
(add-to-list 'Info-directory-list "/path/to/magit/")))
(require 'magit)
```
If you are using an Emacs version before 24.3, then you also have to
install `cl-lib` and tell `make` as well as Emacs where to find it.
To view available make targets use:
```sh
$ make help
```
To update use:
```sh
$ git pull
$ make lisp docs
```
Before creating a pull request always run:
```sh
$ make lisp test
```
You may also build Magit manually:
```sh
$ emacs -Q --batch -L . -L /path/to/DEPENCENCY -f batch-byte-compile *.el
$ makeinfo -o magit.info magit.texi
$ install-info --dir=dir magit.info
```
### Installing from Tarball
This is only intended for users who have been doing this sort of thing
for years. Installing from a tarball isn't particularly difficult but
because we are only providing this as an alternative method we are a
bit light on documentation, so it helps to have done this before.
Also most steps have to be repeated every time you want to update.
Because the latest Magit release is very outdated, please consider
installing the development version even if tarballs are your thing.
Download and unpack [magit-1.2.1.tar.gz][download]. Then build and
install as usual:
```sh
$ wget https://github.com/magit/magit/releases/download/1.2.1/magit-1.2.1.tar.gz
$ tar -xf magit-1.2.1.tar.gz
$ cd magit-1.2.1
$ make
$ sudo make install
```
This installs the Emacs lisp libraries, as well as the prebuilt
documentation from the tarball. You may alternatively build the
documentation yourself:
```sh
$ make docs
$ sudo make install-docs
```
By default the Emacs lisp libraries are installed in
`/usr/local/share/emacs/site-lisp/magit/`. Unless Emacs itself is
also installed in `/usr/local/` you have to add that directory to the
`load-path`.
```lisp
(add-to-list 'load-path "/usr/local/share/emacs/site-lisp/magit")
```
Then `magit` can be loaded:
```lisp
(require 'magit)
```
Add the above lines to your init file and restart Emacs.
Dependencies
============
If you install Magit using `package.el` then dependencies are
automatically being taken care of. Otherwise you have to track down
dependencies and install them manually.
* `cl-lib` is a new library in Emacs 24.3. Like the old `cl` it
provides various Common Lisp forms, but differs in that symbols are
prefixed with `cl-`. A forward compatibility `cl-lib` for older
versions of Emacs is available from the GNU Elpa repository. You
can install it using `package.el` or get it [here][cl-lib].
* `git-commit-mode` which is part of the [git-modes][git-modes]
repository and available as a separate package from Melpa.
* `git-rebase-mode` which is part of the [git-modes][git-modes]
repository and available as a separate package from Melpa.
### Optional Dependencies
The following libraries build on third-party tools or git subcommands
that are not installed by the Git base-package on some distributions:
* `magit-stgit.el` requires [`stgit`][stgit].
* `magit-svn.el` requires the official Git subcommand `svn`.
* `magit-topgit.el` requires [`topgit`][topgit].
* `magit-wip.el` requires [`git-wip`][git-wip].
### Dependencies of Tests
To run tests the following libraries are also required:
* `ert` is a tool for automated testing. It is part of Emacs
starting with version 24.1. You can also obtain an old version from
the former development [repository][ert].
[contributing]: https://github.com/magit/magit/blob/master/CONTRIBUTING.md
[contributors]: https://github.com/magit/magit/contributors
[development]: http://github.com/magit/magit
[download]: https://github.com/magit/magit/releases/download/1.2.1/magit-1.2.1.tar.gz
[faq]: https://github.com/magit/magit/wiki/FAQ
[group]: https://groups.google.com/forum/?fromgroups#!forum/magit
[issues]: https://github.com/magit/magit/issues
[knownissues]: https://github.com/magit/magit/wiki/Known-issues
[manual]: http://magit.github.io/documentation.html
[owners]: https://github.com/magit?tab=members
[pulls]: https://github.com/magit/magit/pulls
[screencast]: http://vimeo.com/2871241
[website]: http://magit.github.io
[jonas]: https://github.com/tarsius
[marius]: https://github.com/mvollmer
[nicolas]: https://github.com/dudebout
[peter]: https://github.com/pjweisberg
[phil]: https://github.com/philjackson
[remi]: https://github.com/vanicat
[yann]: https://github.com/sigma
[cl-lib]: http://elpa.gnu.org/packages/cl-lib.html
[emacs]: http://www.gnu.org/software/emacs
[ert]: https://github.com/ohler/ert
[git-wip]: https://github.com/bartman/git-wip
[git]: http://git-scm.com
[gitflow]: https://github.com/nvie/gitflow
[gratipay]: https://gratipay.com/magit
[git-modes]: https://github.com/magit/git-modes
[marmalade]: http://marmalade-repo.org
[mastering-intro]: http://www.masteringemacs.org/article/introduction-magit-emacs-mode-git
[melpa]: http://melpa.milkbox.net
[melpa-intro]: http://melpa.milkbox.net/#/getting-started
[stgit]: http://www.procode.org/stgit
[topgit]: https://github.com/greenrd/topgit
[vc]: http://www.gnu.org/software/emacs/manual/html_node/emacs/Version-Control.html

View file

@ -0,0 +1,18 @@
This is the file .../info/dir, which contains the
topmost node of the Info hierarchy, called (dir)Top.
The first time you invoke Info you start off looking at this node.

File: dir, Node: Top This is the top of the INFO tree
This (the Directory node) gives a menu of major topics.
Typing "q" exits, "?" lists all Info commands, "d" returns here,
"h" gives a primer for first-timers,
"mEmacs<Return>" visits the Emacs manual, etc.
In Emacs, you can click mouse button 2 on a menu item or cross reference
to select it.
* Menu:
Emacs
* Magit: (magit). Using Git from Emacs with Magit.

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,307 @@
;;; magit-blame.el --- blame support for Magit
;; Copyright (C) 2012-2014 The Magit Project Developers
;;
;; For a full list of contributors, see the AUTHORS.md file
;; at the top-level directory of this distribution and at
;; https://raw.github.com/magit/magit/master/AUTHORS.md
;; Author: Yann Hodique <yann.hodique@gmail.com>
;; Package: magit
;; Contains code from Egg (Emacs Got Git) <https://github.com/byplayer/egg>,
;; released under the GNU General Public License version 3 or later.
;; Magit is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; Magit is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with Magit. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; Control git-blame from Magit.
;; This code has been backported from Egg (Magit fork) to Magit.
;;; Code:
(eval-when-compile (require 'cl-lib))
(require 'magit)
(require 'easymenu)
;;; Options
(defgroup magit-blame nil
"Git-blame support for Magit."
:group 'magit-extensions)
(defcustom magit-blame-ignore-whitespace t
"Ignore whitespace when determining blame information."
:group 'magit-blame
:type 'boolean)
(defcustom magit-time-format-string "%Y-%m-%dT%T%z"
"How to format time in magit-blame header."
:group 'magit-blame
:type 'string)
(defface magit-blame-header
'((t :inherit magit-section-title))
"Face for blame header."
:group 'magit-faces)
(defface magit-blame-sha1
'((t :inherit (magit-log-sha1 magit-blame-header)))
"Face for blame sha1."
:group 'magit-faces)
(defface magit-blame-culprit
'((t :inherit magit-blame-header))
"Face for blame culprit."
:group 'magit-faces)
(defface magit-blame-time
'((t :inherit magit-blame-header))
"Face for blame time."
:group 'magit-faces)
(defface magit-blame-subject
'((t :inherit (magit-log-message magit-blame-header)))
"Face for blame tag line."
:group 'magit-faces)
;;; Keymaps
(defvar magit-blame-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd "l") 'magit-blame-locate-commit)
(define-key map (kbd "RET") 'magit-blame-locate-commit)
(define-key map (kbd "q") 'magit-blame-mode)
(define-key map (kbd "n") 'magit-blame-next-chunk)
(define-key map (kbd "p") 'magit-blame-previous-chunk)
map)
"Keymap for an annotated section.\\{magit-blame-map}")
(easy-menu-define magit-blame-mode-menu magit-blame-map
"Magit blame menu"
'("Blame"
["Locate Commit" magit-blame-locate-commit t]
["Next" magit-blame-next-chunk t]
["Previous" magit-blame-previous-chunk t]
"---"
["Quit" magit-blame-mode t]))
;;; Mode
(defvar-local magit-blame-buffer-read-only nil)
;;;###autoload
(define-minor-mode magit-blame-mode
"Display blame information inline."
:keymap magit-blame-map
:lighter " blame"
(unless (buffer-file-name)
(user-error "Current buffer has no associated file!"))
(when (and (buffer-modified-p)
(y-or-n-p (format "save %s first? " (buffer-file-name))))
(save-buffer))
(cond (magit-blame-mode
(setq magit-blame-buffer-read-only buffer-read-only)
(magit-blame-file-on (current-buffer))
(set-buffer-modified-p nil)
(setq buffer-read-only t))
(t
(magit-blame-file-off (current-buffer))
(set-buffer-modified-p nil)
(setq buffer-read-only magit-blame-buffer-read-only))))
(defun magit-blame-file-off (buffer)
(save-excursion
(save-restriction
(with-current-buffer buffer
(widen)
(mapc (lambda (ov)
(when (overlay-get ov :blame)
(delete-overlay ov)))
(overlays-in (point-min) (point-max)))))))
(defun magit-blame-file-on (buffer)
(magit-blame-file-off buffer)
(save-excursion
(with-current-buffer buffer
(save-restriction
(with-temp-buffer
(apply 'magit-git-insert "blame" "--porcelain"
`(,@(and magit-blame-ignore-whitespace (list "-w")) "--"
,(file-name-nondirectory (buffer-file-name buffer))))
(magit-blame-parse buffer (current-buffer)))))))
;;; Commands
(defun magit-blame-locate-commit (pos)
"Jump to a commit in the branch history from an annotated blame section."
(interactive "d")
(let ((overlays (overlays-at pos))
sha1)
(dolist (ov overlays)
(when (overlay-get ov :blame)
(setq sha1 (plist-get (nth 3 (overlay-get ov :blame)) :sha1))))
(when sha1
(magit-show-commit sha1))))
(defun magit-blame-next-chunk ()
"Go to the next blame chunk."
(interactive)
(let ((next (next-single-property-change (point) :blame)))
(when next
(goto-char next))))
(defun magit-blame-previous-chunk ()
"Go to the previous blame chunk."
(interactive)
(let ((prev (previous-single-property-change (point) :blame)))
(when prev
(goto-char prev))))
;;; Parse
(defun magit-blame-decode-time (unixtime &optional tz)
"Decode UNIXTIME into (HIGH LOW) format.
The second argument TZ can be used to add the timezone in (-)HHMM
format to UNIXTIME. UNIXTIME should be either a number
containing seconds since epoch or Emacs's (HIGH LOW . IGNORED)
format."
(when (numberp tz)
(unless (numberp unixtime)
(setq unixtime (float-time unixtime)))
(let* ((ptz (abs tz))
(min (+ (* (/ ptz 100) 60)
(mod ptz 100))))
(setq unixtime (+ (* (if (< tz 0) (- min) min) 60) unixtime))))
(when (numberp unixtime)
(setq unixtime (seconds-to-time unixtime)))
unixtime)
(defun magit-blame-format-time-string (format &optional unixtime tz)
"Use FORMAT to format the time UNIXTIME, or now if omitted.
UNIXTIME is specified as a number containing seconds since epoch
or Emacs's (HIGH LOW . IGNORED) format. The optional argument TZ
can be used to set the time zone. If TZ is a number it is
treated as a (-)HHMM offset to Universal Time. If TZ is not
a number and non-nil the time is printed in UTC. If TZ is nil
the local zime zone is used. The format of the function is
similar to `format-time-string' except for %Z which is not
officially supported at the moment."
(unless unixtime
(setq unixtime (current-time)))
(when (numberp tz) ;; TODO add support for %Z
(setq format (replace-regexp-in-string "%z" (format "%+05d" tz) format)))
(format-time-string format (magit-blame-decode-time unixtime tz) tz))
(defun magit-blame-parse (target-buf blame-buf)
"Parse blame-info in buffer BLAME-BUF and decorate TARGET-BUF buffer."
(save-match-data
(let ((blank (propertize " " 'face 'magit-blame-header))
(nl (propertize "\n" 'face 'magit-blame-header))
(commit-hash (make-hash-table :test 'equal :size 577))
commit commit-info old-line new-line num old-file subject author
author-time author-timezone info ov beg end blame)
(with-current-buffer blame-buf
(goto-char (point-min))
;; search for a ful commit info
(while (re-search-forward
"^\\([0-9a-f]\\{40\\}\\) \\([0-9]+\\) \\([0-9]+\\) \\([0-9]+\\)$"
nil t)
(setq commit (match-string-no-properties 1)
old-line (string-to-number
(match-string-no-properties 2))
new-line (string-to-number
(match-string-no-properties 3))
num (string-to-number
(match-string-no-properties 4)))
;; was this commit already seen (and stored in the hash)?
(setq commit-info (gethash commit commit-hash))
;; Nope, this is the 1st time, the full commit-info follow.
(unless commit-info
(re-search-forward "^author \\(.+\\)$")
(setq author (match-string-no-properties 1))
(re-search-forward "^author-time \\(.+\\)$")
(setq author-time (string-to-number
(match-string-no-properties 1)))
(re-search-forward "^author-tz \\(.+\\)$")
(setq author-timezone (string-to-number
(match-string-no-properties 1)))
(re-search-forward "^summary \\(.+\\)$")
(setq subject (match-string-no-properties 1))
(re-search-forward "^filename \\(.+\\)$")
(setq old-file (match-string-no-properties 1))
(setq commit-info (list :sha1 commit :author author
:author-time author-time
:author-timezone author-timezone
:subject subject :file old-file))
;; save it in the hash
(puthash commit commit-info commit-hash))
;; add the current blame-block into the list INFO.
(setq info (cons (list old-line new-line num commit-info)
info))))
;; now do from beginning
(setq info (nreverse info))
(with-current-buffer target-buf
;; for every blame chunk
(dolist (chunk info)
(setq commit-info (nth 3 chunk)
old-line (nth 0 chunk)
new-line (nth 1 chunk)
num (nth 2 chunk)
commit (plist-get commit-info :sha1)
author (plist-get commit-info :author)
author-time (plist-get commit-info :author-time)
author-timezone (plist-get commit-info :author-timezone)
subject (plist-get commit-info :subject))
(goto-char (point-min))
(forward-line (1- new-line))
(setq beg (line-beginning-position)
end (save-excursion
(forward-line num)
(line-beginning-position)))
;; mark the blame chunk
(put-text-property beg end :blame chunk)
;; make an overlay with blame info as 'before-string
;; on the current chunk.
(setq ov (make-overlay beg end))
(overlay-put ov :blame chunk)
(setq blame (concat
(propertize (substring-no-properties commit 0 8)
'face 'magit-blame-sha1)
blank
(propertize (format "%-20s" author)
'face 'magit-blame-culprit)
blank
(propertize (magit-blame-format-time-string
magit-time-format-string
author-time author-timezone)
'face 'magit-blame-time)
blank
(propertize subject 'face 'magit-blame-subject)
blank nl))
(overlay-put ov 'before-string blame))))))
(provide 'magit-blame)
;; Local Variables:
;; indent-tabs-mode: nil
;; End:
;;; magit-blame.el ends here

Binary file not shown.

View file

@ -0,0 +1,735 @@
;;; magit-key-mode.el --- interactively tune git invocation
;; Copyright (C) 2010-2014 The Magit Project Developers
;;
;; For a full list of contributors, see the AUTHORS.md file
;; at the top-level directory of this distribution and at
;; https://raw.github.com/magit/magit/master/AUTHORS.md
;; Author: Phil Jackson <phil@shellarchive.co.uk>
;; Package: magit
;; Magit is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; Magit is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with Magit. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; This library implements `magit-key-mode' which is used throughout
;; Magit to let the user interactively select the command, switches
;; and options to call Git with. It can be though of as a way to
;; provide "postfix" arguments.
;;; Code:
(require 'magit)
(eval-when-compile (require 'cl-lib))
(defvar magit-key-mode-keymaps)
(defvar magit-key-mode-last-buffer)
(defvar magit-pre-key-mode-window-conf)
;;; Options
(defcustom magit-key-mode-show-usage t
"Whether to show usage information when entering a popup."
:group 'magit
:type 'boolean)
;;; Faces
(defface magit-key-mode-header-face
'((t :inherit font-lock-keyword-face))
"Face for key mode header lines."
:group 'magit-faces)
(defface magit-key-mode-button-face
'((t :inherit font-lock-builtin-face))
"Face for key mode buttons."
:group 'magit-faces)
(defface magit-key-mode-switch-face
'((t :inherit font-lock-warning-face))
"Face for key mode switches."
:group 'magit-faces)
(defface magit-key-mode-args-face
'((t :inherit widget-field))
"Face for key mode switch arguments."
:group 'magit-faces)
;;; Keygroups
;;;###autoload
(defvar magit-key-mode-groups
'((dispatch
(actions
("b" "Branching" magit-key-mode-popup-branching)
("B" "Bisecting" magit-key-mode-popup-bisecting)
("c" "Committing" magit-key-mode-popup-committing)
("d" "Diff worktree" magit-diff-working-tree)
("D" "Diff" magit-diff)
("f" "Fetching" magit-key-mode-popup-fetching)
("F" "Pulling" magit-key-mode-popup-pulling)
("g" "Refresh Buffers" magit-refresh-all)
("l" "Logging" magit-key-mode-popup-logging)
("m" "Merging" magit-key-mode-popup-merging)
("M" "Remoting" magit-key-mode-popup-remoting)
("P" "Pushing" magit-key-mode-popup-pushing)
("o" "Submoduling" magit-key-mode-popup-submodule)
("r" "Rewriting" magit-key-mode-popup-rewriting)
("R" "Rebasing" magit-rebase-step)
("s" "Show Status" magit-status)
("S" "Stage all" magit-stage-all)
("t" "Tagging" magit-key-mode-popup-tagging)
("U" "Unstage all" magit-unstage-all)
("v" "Show Commit" magit-show-commit)
("V" "Show File" magit-show)
("w" "Wazzup" magit-wazzup)
("X" "Reset worktree" magit-reset-working-tree)
("y" "Cherry" magit-cherry)
("z" "Stashing" magit-key-mode-popup-stashing)
("!" "Running" magit-key-mode-popup-running)
("$" "Show Process" magit-display-process)))
(logging
(man-page "git-log")
(actions
("l" "Short" magit-log)
("L" "Long" magit-log-long)
("h" "Head Reflog" magit-reflog-head)
("f" "File log" magit-file-log)
("rl" "Ranged short" magit-log-ranged)
("rL" "Ranged long" magit-log-long-ranged)
("rh" "Reflog" magit-reflog))
(switches
("-m" "Only merge commits" "--merges")
("-s" "No merge commits" "--no-merges")
("-do" "Date Order" "--date-order")
("-f" "First parent" "--first-parent")
("-i" "Case insensitive patterns" "-i")
("-pr" "Pickaxe regex" "--pickaxe-regex")
("-g" "Show Graph" "--graph")
("-n" "Name only" "--name-only")
("-am" "All match" "--all-match")
("-al" "All" "--all"))
(arguments
("=r" "Relative" "--relative=" read-directory-name)
("=c" "Committer" "--committer=" read-from-minibuffer)
("=>" "Since" "--since=" read-from-minibuffer)
("=<" "Before" "--before=" read-from-minibuffer)
("=a" "Author" "--author=" read-from-minibuffer)
("=g" "Grep messages" "--grep=" read-from-minibuffer)
("=G" "Grep patches" "-G" read-from-minibuffer)
("=L" "Trace evolution of line range [long log only]"
"-L" magit-read-file-trace)
("=s" "Pickaxe search" "-S" read-from-minibuffer)
("=b" "Branches" "--branches=" read-from-minibuffer)
("=R" "Remotes" "--remotes=" read-from-minibuffer)))
(running
(actions
("!" "Git Subcommand (from root)" magit-git-command-topdir)
(":" "Git Subcommand (from pwd)" magit-git-command)
("g" "Git Gui" magit-run-git-gui)
("k" "Gitk" magit-run-gitk)))
(fetching
(man-page "git-fetch")
(actions
("f" "Current" magit-fetch-current)
("a" "All" magit-remote-update)
("o" "Other" magit-fetch))
(switches
("-p" "Prune" "--prune")))
(pushing
(man-page "git-push")
(actions
("P" "Push" magit-push)
("t" "Push tags" magit-push-tags))
(switches
("-f" "Force" "--force")
("-d" "Dry run" "-n")
("-u" "Set upstream" "-u")))
(pulling
(man-page "git-pull")
(actions
("F" "Pull" magit-pull))
(switches
("-f" "Force" "--force")
("-r" "Rebase" "--rebase")))
(branching
(man-page "git-branch")
(actions
("v" "Branch manager" magit-branch-manager)
("b" "Checkout" magit-checkout)
("c" "Create" magit-create-branch)
("r" "Rename" magit-rename-branch)
("k" "Delete" magit-delete-branch))
(switches
("-t" "Set upstream configuration" "--track")
("-m" "Merged to HEAD" "--merged")
("-M" "Merged to master" "--merged=master")
("-n" "Not merged to HEAD" "--no-merged")
("-N" "Not merged to master" "--no-merged=master"))
(arguments
("=c" "Contains" "--contains=" magit-read-rev-with-default)
("=m" "Merged" "--merged=" magit-read-rev-with-default)
("=n" "Not merged" "--no-merged=" magit-read-rev-with-default)))
(remoting
(man-page "git-remote")
(actions
("v" "Remote manager" magit-branch-manager)
("a" "Add" magit-add-remote)
("r" "Rename" magit-rename-remote)
("k" "Remove" magit-remove-remote)))
(tagging
(man-page "git-tag")
(actions
("t" "Create" magit-tag)
("k" "Delete" magit-delete-tag))
(switches
("-a" "Annotate" "--annotate")
("-f" "Force" "--force")
("-s" "Sign" "--sign")))
(stashing
(man-page "git-stash")
(actions
("v" "View" magit-diff-stash)
("z" "Save" magit-stash)
("s" "Snapshot" magit-stash-snapshot)
("a" "Apply" magit-stash-apply)
("p" "Pop" magit-stash-pop)
("k" "Drop" magit-stash-drop))
(switches
("-k" "Keep index" "--keep-index")
("-u" "Include untracked files" "--include-untracked")
("-a" "Include all files" "--all")))
(committing
(man-page "git-commit")
(actions
("c" "Commit" magit-commit)
("a" "Amend" magit-commit-amend)
("e" "Extend" magit-commit-extend)
("r" "Reword" magit-commit-reword)
("f" "Fixup" magit-commit-fixup)
("s" "Squash" magit-commit-squash))
(switches
("-a" "Stage all modified and deleted files" "--all")
("-e" "Allow empty commit" "--allow-empty")
("-v" "Show diff of changes to be committed" "--verbose")
("-n" "Bypass git hooks" "--no-verify")
("-s" "Add Signed-off-by line" "--signoff")
("-R" "Claim authorship and reset author date" "--reset-author"))
(arguments
("=A" "Override the author" "--author=" read-from-minibuffer)
("=S" "Sign using gpg" "--gpg-sign=" magit-read-gpg-secret-key)))
(merging
(man-page "git-merge")
(actions
("m" "Merge" magit-merge)
("A" "Abort" magit-merge-abort))
(switches
("-ff" "Fast-forward only" "--ff-only")
("-nf" "No fast-forward" "--no-ff")
("-sq" "Squash" "--squash"))
(arguments
("-st" "Strategy" "--strategy=" read-from-minibuffer)))
(rewriting
(actions
("b" "Begin" magit-rewrite-start)
("s" "Stop" magit-rewrite-stop)
("a" "Abort" magit-rewrite-abort)
("f" "Finish" magit-rewrite-finish)
("d" "Diff pending" magit-rewrite-diff-pending)
("*" "Set unused" magit-rewrite-set-unused)
("." "Set used" magit-rewrite-set-used)))
(apply-mailbox
(man-page "git-am")
(actions
("J" "Apply Mailbox" magit-apply-mailbox))
(switches
("-s" "add a Signed-off-by line to the commit message" "--signoff")
("-3" "allow fall back on 3way merging if needed" "--3way")
("-k" "pass -k flag to git-mailinfo" "--keep")
("-c" "strip everything before a scissors line" "--scissors")
("-p" "pass it through git-apply" "-p")
("-r" "override error message when patch failure occurs" "--resolvemsg")
("-d" "lie about committer date" "--committer-date-is-author-date")
("-D" "use current timestamp for author date" "--ignore-date")
("-b" "pass -b flag to git-mailinfo" "--keep-non-patch"))
(arguments
("=p" "format the patch(es) are in" "--patch-format=" read-from-minibuffer)))
(submodule
(man-page "git-submodule")
(actions
("u" "Update" magit-submodule-update)
("b" "Both update and init" magit-submodule-update-init)
("i" "Init" magit-submodule-init)
("s" "Sync" magit-submodule-sync)))
(bisecting
(man-page "git-bisect")
(actions
("b" "Bad" magit-bisect-bad)
("g" "Good" magit-bisect-good)
("k" "Skip" magit-bisect-skip)
("r" "Reset" magit-bisect-reset)
("s" "Start" magit-bisect-start)
("u" "Run" magit-bisect-run)))
(diff-options
(actions
("s" "Set" magit-set-diff-options)
("d" "Set default" magit-set-default-diff-options)
("c" "Save default" magit-save-default-diff-options)
("r" "Reset to default" magit-reset-diff-options)
("h" "Toggle Hunk Refinement" magit-diff-toggle-refine-hunk))
(switches
("-m" "Show smallest possible diff" "--minimal")
("-p" "Use patience diff algorithm" "--patience")
("-h" "Use histogram diff algorithm" "--histogram")
("-b" "Ignore whitespace changes" "--ignore-space-change")
("-w" "Ignore all whitespace" "--ignore-all-space")
("-W" "Show surrounding functions" "--function-context"))
))
"Holds the key, help, function mapping for the log-mode.
If you modify this make sure you reset `magit-key-mode-keymaps'
to nil.")
(defun magit-key-mode-delete-group (group)
"Delete a group from `magit-key-mode-keymaps'."
(let ((items (assoc group magit-key-mode-groups)))
(when items
;; reset the cache
(setq magit-key-mode-keymaps nil)
;; delete the whole group
(setq magit-key-mode-groups
(delq items magit-key-mode-groups))
;; unbind the defun
(magit-key-mode-de-generate group))
magit-key-mode-groups))
(defun magit-key-mode-add-group (group)
"Add a new group to `magit-key-mode-keymaps'.
If there already is a group of that name then this will
completely remove it and put in its place an empty one of the
same name."
(when (assoc group magit-key-mode-groups)
(magit-key-mode-delete-group group))
(setq magit-key-mode-groups
(cons (list group (list 'actions) (list 'switches) (list 'arguments))
magit-key-mode-groups)))
(defun magit-key-mode-key-defined-p (for-group key)
"Return t if KEY is defined as any option within FOR-GROUP.
The option may be a switch, argument or action."
(catch 'result
(let ((options (magit-key-mode-options-for-group for-group)))
(dolist (type '(actions switches arguments))
(when (assoc key (assoc type options))
(throw 'result t))))))
(defun magit-key-mode-update-group (for-group thing &rest args)
"Abstraction for setting values in `magit-key-mode-keymaps'."
(let* ((options (magit-key-mode-options-for-group for-group))
(things (assoc thing options))
(key (car args)))
(if (cdr things)
(if (magit-key-mode-key-defined-p for-group key)
(error "%s is already defined in the %s group." key for-group)
(setcdr (cdr things) (cons args (cddr things))))
(setcdr things (list args)))
(setq magit-key-mode-keymaps nil)
things))
(defun magit-key-mode-insert-argument (for-group key desc arg read-func)
"Add a new binding KEY in FOR-GROUP which will use READ-FUNC
to receive input to apply to argument ARG git is run. DESC should
be a brief description of the binding."
(magit-key-mode-update-group for-group 'arguments key desc arg read-func))
(defun magit-key-mode-insert-switch (for-group key desc switch)
"Add a new binding KEY in FOR-GROUP which will add SWITCH to git's
command line when it runs. DESC should be a brief description of
the binding."
(magit-key-mode-update-group for-group 'switches key desc switch))
(defun magit-key-mode-insert-action (for-group key desc func)
"Add a new binding KEY in FOR-GROUP which will run command FUNC.
DESC should be a brief description of the binding."
(magit-key-mode-update-group for-group 'actions key desc func))
(defun magit-key-mode-options-for-group (for-group)
"Retrieve the options for the group FOR-GROUP.
This includes switches, commands and arguments."
(or (cdr (assoc for-group magit-key-mode-groups))
(error "Unknown group '%s'" for-group)))
;;; Commands
(defun magit-key-mode-help (for-group)
"Provide help for a key within FOR-GROUP.
The user is prompted for the key."
(let* ((opts (magit-key-mode-options-for-group for-group))
(man-page (cadr (assoc 'man-page opts)))
(seq (read-key-sequence
(format "Enter command prefix%s: "
(if man-page
(format ", `?' for man `%s'" man-page)
""))))
(actions (cdr (assoc 'actions opts))))
(cond
;; if it is an action popup the help for the to-be-run function
((assoc seq actions) (describe-function (nth 2 (assoc seq actions))))
;; if there is "?" show a man page if there is one
((equal seq "?")
(if man-page
(man man-page)
(error "No man page associated with `%s'" for-group)))
(t (error "No help associated with `%s'" seq)))))
(defun magit-key-mode-exec-at-point ()
"Run action/args/option at point."
(interactive)
(let ((key (or (get-text-property (point) 'key-group-executor)
(error "Nothing at point to do."))))
(call-interactively (lookup-key (current-local-map) key))))
(defun magit-key-mode-jump-to-next-exec ()
"Jump to the next action/args/option point."
(interactive)
(let* ((oldp (point))
(old (get-text-property oldp 'key-group-executor))
(p (if (= oldp (point-max)) (point-min) (1+ oldp))))
(while (let ((new (get-text-property p 'key-group-executor)))
(and (not (= p oldp)) (or (not new) (eq new old))))
(setq p (if (= p (point-max)) (point-min) (1+ p))))
(goto-char p)
(skip-chars-forward " ")))
;;; Keymaps
(defvar magit-key-mode-keymaps nil
"This will be filled lazily with proper keymaps.
These keymaps are created using `define-key' as they're requested.")
(defun magit-key-mode-build-keymap (for-group)
"Construct a normal looking keymap for the key mode to use.
Put it in `magit-key-mode-keymaps' for fast lookup."
(let* ((options (magit-key-mode-options-for-group for-group))
(actions (cdr (assoc 'actions options)))
(switches (cdr (assoc 'switches options)))
(arguments (cdr (assoc 'arguments options)))
(map (make-sparse-keymap)))
(suppress-keymap map 'nodigits)
;; ret dwim
(define-key map (kbd "RET") 'magit-key-mode-exec-at-point)
;; tab jumps to the next "button"
(define-key map (kbd "TAB") 'magit-key-mode-jump-to-next-exec)
;; all maps should `quit' with `C-g' or `q'
(define-key map (kbd "C-g") `(lambda ()
(interactive)
(magit-key-mode-command nil)))
(define-key map (kbd "q") `(lambda ()
(interactive)
(magit-key-mode-command nil)))
;; run help
(define-key map (kbd "?") `(lambda ()
(interactive)
(magit-key-mode-help ',for-group)))
(let ((defkey (lambda (k action)
(when (and (lookup-key map (car k))
(not (numberp (lookup-key map (car k)))))
(message "Warning: overriding binding for `%s' in %S"
(car k) for-group)
(ding)
(sit-for 2))
(define-key map (car k)
`(lambda () (interactive) ,action)))))
(dolist (k actions)
(funcall defkey k `(magit-key-mode-command ',(nth 2 k))))
(dolist (k switches)
(funcall defkey k `(magit-key-mode-toggle-option ',for-group ,(nth 2 k))))
(dolist (k arguments)
(funcall defkey k `(magit-key-mode-add-argument
',for-group ,(nth 2 k) ',(nth 3 k)))))
(push (cons for-group map) magit-key-mode-keymaps)
map))
;;; Toggling and Running
(defvar magit-key-mode-prefix nil
"Prefix argument to the command that brought up the key-mode window.
For internal use. Used by the command that's eventually invoked.")
(defvar magit-key-mode-current-args nil
"A hash-table of current argument set.
These will eventually make it to the git command-line.")
(defvar magit-key-mode-current-options nil
"Current option set.
These will eventually make it to the git command-line.")
(defvar magit-custom-options nil
"List of custom options to pass to Git.
Do not customize this (used in the `magit-key-mode' implementation).")
(defun magit-key-mode-command (func)
(let ((current-prefix-arg (or current-prefix-arg magit-key-mode-prefix))
(magit-custom-options magit-key-mode-current-options))
(maphash (lambda (k v)
(push (concat k v) magit-custom-options))
magit-key-mode-current-args)
(set-window-configuration magit-pre-key-mode-window-conf)
(kill-buffer magit-key-mode-last-buffer)
(when func
(setq this-command func)
(call-interactively this-command))))
(defun magit-key-mode-add-argument (for-group arg-name input-func)
(let ((input (funcall input-func (concat arg-name ": "))))
(puthash arg-name input magit-key-mode-current-args)
(magit-key-mode-redraw for-group)))
(defun magit-key-mode-toggle-option (for-group option-name)
"Toggles the appearance of OPTION-NAME in `magit-key-mode-current-options'."
(if (member option-name magit-key-mode-current-options)
(setq magit-key-mode-current-options
(delete option-name magit-key-mode-current-options))
(add-to-list 'magit-key-mode-current-options option-name))
(magit-key-mode-redraw for-group))
;;; Mode
(defvar magit-key-mode-buf-name "*magit-key: %s*"
"Format string to create the name of the magit-key buffer.")
(defvar magit-key-mode-last-buffer nil
"Store the last magit-key buffer used.")
(defvar magit-pre-key-mode-window-conf nil
"Will hold the pre-menu configuration of magit.")
(defun magit-key-mode (for-group &optional original-opts)
"Mode for magit key selection.
All commands, switches and options can be toggled/actioned with
the key combination highlighted before the description."
(interactive)
;; save the window config to restore it as was (no need to make this
;; buffer local)
(setq magit-pre-key-mode-window-conf
(current-window-configuration))
;; setup the mode, draw the buffer
(let ((buf (get-buffer-create (format magit-key-mode-buf-name
(symbol-name for-group)))))
(setq magit-key-mode-last-buffer buf)
(split-window-vertically)
(other-window 1)
(switch-to-buffer buf)
(kill-all-local-variables)
(set (make-local-variable 'scroll-margin) 0)
(set (make-local-variable
'magit-key-mode-current-options)
original-opts)
(set (make-local-variable
'magit-key-mode-current-args)
(make-hash-table))
(set (make-local-variable 'magit-key-mode-prefix) current-prefix-arg)
(magit-key-mode-redraw for-group))
(when magit-key-mode-show-usage
(message (concat "Type a prefix key to toggle it. "
"Run 'actions' with their prefixes. "
"'?' for more help."))))
(defun magit-key-mode-get-key-map (for-group)
"Get or build the keymap for FOR-GROUP."
(or (cdr (assoc for-group magit-key-mode-keymaps))
(magit-key-mode-build-keymap for-group)))
(defun magit-key-mode-redraw (for-group)
"(re)draw the magit key buffer."
(let ((buffer-read-only nil)
(current-exec (get-text-property (point) 'key-group-executor))
(new-exec-pos)
(old-point (point))
(is-first (zerop (buffer-size)))
(actions-p nil))
(erase-buffer)
(make-local-variable 'font-lock-defaults)
(use-local-map (magit-key-mode-get-key-map for-group))
(setq actions-p (magit-key-mode-draw for-group))
(delete-trailing-whitespace)
(setq mode-name "magit-key-mode" major-mode 'magit-key-mode)
(when current-exec
(setq new-exec-pos
(cdr (assoc current-exec
(magit-key-mode-build-exec-point-alist)))))
(cond ((and is-first actions-p)
(goto-char actions-p)
(magit-key-mode-jump-to-next-exec))
(new-exec-pos
(goto-char new-exec-pos)
(skip-chars-forward " "))
(t
(goto-char old-point))))
(setq buffer-read-only t)
(fit-window-to-buffer))
(defun magit-key-mode-build-exec-point-alist ()
(save-excursion
(goto-char (point-min))
(let* ((exec (get-text-property (point) 'key-group-executor))
(exec-alist (and exec `((,exec . ,(point))))))
(cl-do nil ((eobp) (nreverse exec-alist))
(when (not (eq exec (get-text-property (point) 'key-group-executor)))
(setq exec (get-text-property (point) 'key-group-executor))
(when exec (push (cons exec (point)) exec-alist)))
(forward-char)))))
;;; Draw Buffer
(defun magit-key-mode-draw-header (header)
"Draw a header with the correct face."
(insert (propertize header 'face 'magit-key-mode-header-face) "\n"))
(defvar magit-key-mode-args-in-cols nil
"When true, draw arguments in columns as with switches and options.")
(defun magit-key-mode-draw-args (args)
"Draw the args part of the menu."
(magit-key-mode-draw-buttons
"Args"
args
(lambda (x)
(format "(%s) %s"
(nth 2 x)
(propertize (gethash (nth 2 x) magit-key-mode-current-args "")
'face 'magit-key-mode-args-face)))
(not magit-key-mode-args-in-cols)))
(defun magit-key-mode-draw-switches (switches)
"Draw the switches part of the menu."
(magit-key-mode-draw-buttons
"Switches"
switches
(lambda (x)
(format "(%s)" (let ((s (nth 2 x)))
(if (member s magit-key-mode-current-options)
(propertize s 'face 'magit-key-mode-switch-face)
s))))))
(defun magit-key-mode-draw-actions (actions)
"Draw the actions part of the menu."
(magit-key-mode-draw-buttons "Actions" actions nil))
(defun magit-key-mode-draw-buttons (section xs maker
&optional one-col-each)
(when xs
(magit-key-mode-draw-header section)
(magit-key-mode-draw-in-cols
(mapcar (lambda (x)
(let* ((head (propertize (car x) 'face 'magit-key-mode-button-face))
(desc (nth 1 x))
(more (and maker (funcall maker x)))
(text (format " %s: %s%s%s"
head desc (if more " " "") (or more ""))))
(propertize text 'key-group-executor (car x))))
xs)
one-col-each)))
(defun magit-key-mode-draw-in-cols (strings one-col-each)
"Given a list of strings, print in columns (using `insert').
If ONE-COL-EACH is true then don't columify, but rather, draw
each item on one line."
(let ((longest-act (apply 'max (mapcar 'length strings))))
(while strings
(let ((str (car strings)))
(let ((padding (make-string (- (+ longest-act 3) (length str)) ? )))
(insert str)
(if (or one-col-each
(and (> (+ (length padding) ;
(current-column)
longest-act)
(window-width))
(cdr strings)))
(insert "\n")
(insert padding))))
(setq strings (cdr strings))))
(insert "\n"))
(defun magit-key-mode-draw (for-group)
"Draw actions, switches and parameters.
Return the point before the actions part, if any, nil otherwise."
(let* ((options (magit-key-mode-options-for-group for-group))
(switches (cdr (assoc 'switches options)))
(arguments (cdr (assoc 'arguments options)))
(actions (cdr (assoc 'actions options)))
(p nil))
(magit-key-mode-draw-switches switches)
(magit-key-mode-draw-args arguments)
(when actions (setq p (point-marker)))
(magit-key-mode-draw-actions actions)
(insert "\n")
p))
;;; Generate Groups
(defun magit-key-mode-de-generate (group)
"Unbind the function for GROUP."
(fmakunbound
(intern (concat "magit-key-mode-popup-" (symbol-name group)))))
(defun magit-key-mode-generate (group)
"Generate the key-group menu for GROUP."
(let ((opts (magit-key-mode-options-for-group group)))
(eval
`(defun ,(intern (concat "magit-key-mode-popup-" (symbol-name group))) nil
,(concat "Key menu for " (symbol-name group))
(interactive)
(magit-key-mode
(quote ,group)
;; As a tempory kludge it is okay to do this here.
,(cl-case group
(logging
'(list "--graph"))
(diff-options
'(when (local-variable-p 'magit-diff-options)
magit-diff-options))))))))
;; create the interactive functions for the key mode popups (which are
;; applied in the top-level key maps)
(mapc (lambda (g)
(magit-key-mode-generate (car g)))
magit-key-mode-groups)
;;;###autoload (mapc (lambda (g) (eval `(autoload ',(intern (concat "magit-key-mode-popup-" (symbol-name (car g)))) "magit-key-mode" ,(concat "Key menu for " (symbol-name (car g))) t))) magit-key-mode-groups)
(provide 'magit-key-mode)
;; Local Variables:
;; indent-tabs-mode: nil
;; End:
;;; magit-key-mode.el ends here

Binary file not shown.

View file

@ -0,0 +1,9 @@
(define-package "magit" "20141114.934" "control Git from Emacs"
'((cl-lib "0.3")
(git-commit-mode "0.14.0")
(git-rebase-mode "0.14.0"))
:keywords
'("vc" "tools"))
;; Local Variables:
;; no-byte-compile: t
;; End:

View file

@ -0,0 +1,142 @@
;;; magit-wip.el --- git-wip plug-in for Magit
;; Copyright (C) 2012-2014 The Magit Project Developers
;;
;; For a full list of contributors, see the AUTHORS.md file
;; at the top-level directory of this distribution and at
;; https://raw.github.com/magit/magit/master/AUTHORS.md
;; Author: Jonas Bernoulli <jonas@bernoul.li>
;; Keywords: vc tools
;; Package: magit
;; Magit is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; Magit is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with Magit. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; This plug-in provides support for special work-in-progress refs.
;; This requires the third-party git command "git wip" which is available
;; from https://github.com/bartman/git-wip.
;; To enable `magit-wip-save-mode' enable `global-magit-wip-save-mode'
;; and use the Magit extension mechanism to select the repositories in
;; which you want to use a work-in-progress ref.
;;
;; (global-magit-wip-save-mode 1)
;;
;; $ git config --add magit.extension wip-save # or
;; $ git config --global --add magit.extension wip-save
;; Note that `global-magit-wip-save-mode' is the only mode that uses the
;; extension mechanism for file-visiting buffers all other global modes
;; making use of it to turn on local modes in Magit buffers.
;;; Code:
(require 'magit)
(require 'format-spec)
(defun magit-wip-mode (&rest ignore)
(message "magit-wip-mode is obsolete and doesn't do anything"))
(make-obsolete 'magit-wip-mode "This mode is a noop now" "2.0.0")
;;; Options
(defgroup magit-wip nil
"Git-Wip support for Magit."
:group 'magit-extensions)
(defcustom magit-wip-commit-message "WIP %r"
"Commit message for git-wip commits.
The following `format'-like specs are supported:
%f the full name of the file being saved
%g the root of the git repository
%r the name of the file being saved,
relative to the repository root."
:group 'magit-wip
:type 'string)
(defcustom magit-wip-echo-area-message "Wrote %f (wip)"
"Message shown in the echo area after creating a git-wip commit.
The following `format'-like specs are supported:
%f the full name of the file being saved
%g the root of the git repository
%r the name of the file being saved,
relative to the repository root."
:group 'magit-wip
:type '(choice (const :tag "No message" nil) string))
(defvar magit-wip-save-mode-lighter " Wip")
;;; Mode
;;;###autoload
(define-minor-mode magit-wip-save-mode
"Magit support for committing to a work-in-progress ref.
When this minor mode is turned on and a file is saved inside a
writable git repository then it is also committed to a special
work-in-progress ref."
:lighter magit-wip-save-mode-lighter
(if magit-wip-save-mode
(add-hook 'after-save-hook 'magit-wip-save t t)
(remove-hook 'after-save-hook 'magit-wip-save t)))
;;;###autoload
(define-globalized-minor-mode global-magit-wip-save-mode
magit-wip-save-mode turn-on-magit-wip-save
:group 'magit-wip)
(defun turn-on-magit-wip-save ()
"Conditionally turn on magit-wip-save-mode.
Turn on magit-wip-save-mode if the buffer is a file in a git
repository where wip-save is enabled in git config.
You can activate it with git config magit.extension wip-save."
(when (and (buffer-file-name)
(magit-get-top-dir)
(member "wip-save" (magit-get-all "magit.extension")))
(if (magit-git-success "wip" "-h")
(magit-wip-save-mode 1)
(message "Git command 'git wip' cannot be found"))))
(defun magit-wip-save ()
(let* ((filename (expand-file-name (file-truename (buffer-file-name))))
(filedir (file-name-directory filename))
(toplevel (magit-get-top-dir filedir))
(blobname (file-relative-name filename toplevel))
(spec `((?f . ,filename)
(?r . ,blobname)
(?g . ,toplevel))))
(when (and toplevel (file-writable-p toplevel)
(not (member blobname
(let ((default-directory filedir))
(magit-git-lines
"ls-files" "--other" "--ignored"
"--exclude-standard" "--full-name")))))
(magit-run-git "wip" "save"
(format-spec magit-wip-commit-message spec)
"--editor" "--" filename)
(when magit-wip-echo-area-message
(message (format-spec magit-wip-echo-area-message spec))))))
(provide 'magit-wip)
;; Local Variables:
;; indent-tabs-mode: nil
;; End:
;;; magit-wip.el ends here

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,186 @@
Authors
=======
Also see https://github.com/magit/magit/graphs/contributors.
Names below are sorted alphabetically.
Author
------
- Marius Vollmer <marius.vollmer@gmail.com>
Maintainer
----------
- Jonas Bernoulli <jonas@bernoul.li>
Retired Maintainers
-------------------
- Nicolas Dudebout <nicolas.dudebout@gatech.edu>
- Peter J. Weisberg <pj@irregularexpressions.net>
- Phil Jackson <phil@shellarchive.co.uk>
- Rémi Vanicat <vanicat@debian.org>
- Yann Hodique <yann.hodique@gmail.com>
Contributors
------------
- aaa707 <aaa707b@gmail.com>
- Aaron Culich <aculich@gmail.com>
- Abdo Roig-Maranges <abdo.roig@gmail.com>
- acple <silentsphere110@gmail.com>
- Adam Spiers <emacs@adamspiers.org>
- Ævar Arnfjörð Bjarmason <avarab@gmail.com>
- Alan Falloon <alan.falloon@gmail.com>
- Alexey Voinov <alexey.v.voinov@gmail.com>
- Alex Ott <alexott@gmail.com>
- Andreas Fuchs <asf@boinkor.net>
- Andreas Liljeqvist <andreas.liljeqvist@robacks.se>
- Andreas Rottmann <a.rottmann@gmx.at>
- Andrei Chițu <andrei.chitu1@gmail.com>
- Andrew Kirkpatrick <andrew.kirkpatrick@adelaide.edu.au>
- Andrew Schwartzmeyer <andrew@schwartzmeyer.com>
- Andrey Smirnov <andrew.smirnov@gmail.com>
- Bastian Beischer <beischer@physik.rwth-aachen.de>
- Ben Walton <bwalton@artsci.utoronto.ca>
- Bradley Wright <brad@intranation.com>
- Brandon W Maister <quodlibetor@gmail.com>
- Brian Warner <warner@lothar.com>
- Bryan Shell <bryan.shell@orbitz.com>
- Chris Bernard <cebernard@gmail.com>
- Chris Done <chrisdone@gmail.com>
- Chris Moore <dooglus@gmail.com>
- Chris Ring <chris@ringthis.com>
- Christian Dietrich <christian.dietrich@informatik.uni-erlangen.de>
- Christian Kluge <ckfrakturfreak@web.de>
- Christopher Monsanto <chris@monsan.to>
- Cornelius Mika <cornelius.mika@gmail.com>
- Craig Andera <candera@wangdera.com>
- Dale Hagglund <dale.hagglund@gmail.com>
- Damien Cassou <damien.cassou@gmail.com>
- Daniel Brockman <daniel@gointeractive.se>
- Daniel Farina <drfarina@acm.org>
- Daniel Hackney <dan@haxney.org>
- Dan LaManna <dan.lamanna@gmail.com>
- David Abrahams <dave@boostpro.com>
- David Hull <david.hull@openx.com>
- David Wallin <david.wallin@gmail.com>
- Dennis Paskorz <dennis@walltowall.com>
- Divye Kapoor <divye@google.com>
- Dominique Quatravaux <domq@google.com>
- Eli Barzilay <eli@barzilay.org>
- Eric Davis <ed@npri.org>
- Eric Schulte <schulte.eric@gmail.com>
- Evgkeni Sampelnikof <esabof@gmail.com>
- Felix Geller <fgeller@gmail.com>
- Feng Li <fengli@blackmagicdesign.com>
- Geoff Shannon <geoffpshannon@gmail.com>
- George Kadianakis <desnacked@gmail.com>
- Graham Clark <grclark@gmail.com>
- Greg A. Woods <woods@planix.com>
- Greg Sexton <gregsexton@gmail.com>
- Hannu Koivisto <azure@iki.fi>
- Hans-Peter Deifel <hpdeifel@gmx.de>
- Ian Eure <ian.eure@gmail.com>
- Jan Tatarik <jan.tatarik@xing.com>
- Jasper St. Pierre <jstpierre@mecheye.net>
- Jeff Bellegarde <jbellegarde@whitepages.com>
- Jeff Dairiki <dairiki@dairiki.org>
- Jesse Alama <jesse.alama@gmail.com>
- John Wiegley <johnw@newartisans.com>
- Jonas Bernoulli <jonas@bernoul.li>
- Jonathan Roes <jroes@jroes.net>
- Jordan Greenberg <jordan@softwareslave.com>
- Julien Danjou <julien@danjou.info>
- Justin Caratzas <justin.caratzas@gmail.com>
- Kimberly Wolk <kimwolk@hotmail.com>
- Kyle Meyer <kyle@kyleam.com>
- Laurent Laffont <laurent.laffont@gmail.com>
- Leandro Facchinetti <me@leafac.com>
- Lele Gaifax <lele@metapensiero.it>
- Leo Liu <sdl.web@gmail.com>
- Leonardo Etcheverry <leo@kalio.net>
- Lluís Vilanova <vilanova@ac.upc.edu>
- Loic Dachary <loic@dachary.org>
- Luís Borges de Oliveira <lbo@siscog.pt>
- Luke Amdor <luke.amdor@gmail.com>
- Manuel Vázquez Acosta <mva.led@gmail.com>
- Marcel Wolf <mwolf@ml1.net>
- Marc Herbert <marc.herbert@gmail.com>
- Marcin Bachry <hegel666@gmail.com>
- Marco Craveiro <marco.craveiro@gmail.com>
- Marian Schubert <marian.schubert@gooddata.com>
- Marius Vollmer <marius.vollmer@gmail.com>
- Mark Hepburn <Mark.Hepburn@csiro.au>
- Matus Goljer <dota.keys@gmail.com>
- Miles Bader <miles@gnu.org>
- Mitchel Humpherys <mitch.special@gmail.com>
- Moritz Bunkus <moritz@bunkus.org>
- Nathan Weizenbaum <nex342@gmail.com>
- Nguyễn Tuấn Anh <ubolonton@gmail.com>
- Nic Ferier <nic@ferrier.me.uk>
- Nick Alcock <nick.alcock@oracle.com>
- Nick Alexander <nalexander@mozilla.com>
- Nick Dimiduk <ndimiduk@gmail.com>
- Nicolas Dudebout <nicolas.dudebout@gatech.edu>
- Nicolas Richard <theonewiththeevillook@yahoo.fr>
- Noam Postavsky <npostavs@users.sourceforge.net>
- Ole Arndt <oliver.arndt@cegedim.com>
- Óscar Fuentes <ofv@wanadoo.es>
- Paul Stadig <paul@stadig.name>
- Pavel Holejsovsky <pavel.holejsovsky@upek.com>
- Pekka Pessi <nospam@pessi.fi>
- Peter J. Weisberg <pj@irregularexpressions.net>
- Peter Vasil <mail@petervasil.net>
- Philippe Vaucher <philippe.vaucher@gmail.com>
- Philipp Haselwarter <philipp@haselwarter.org>
- Philip Weaver <philip.weaver@gmail.com>
- Phil Jackson <phil@shellarchive.co.uk>
- Pieter Praet <pieter@praet.org>
- Prathamesh Sonpatki <csonpatki@gmail.com>
- rabio <rabiodev@o2.pl>
- Rafael Laboissiere <rafael@laboissiere.net>
- Raimon Grau <raimonster@gmail.com>
- Ramkumar Ramachandra <artagnon@gmail.com>
- Remco van 't Veer <rwvtveer@xs4all.nl>
- Rémi Vanicat <vanicat@debian.org>
- René Stadler <mail@renestadler.de>
- Robert Boone <robo4288@gmail.com>
- Robin Green <greenrd@greenrd.org>
- Roger Crew <crew@cs.stanford.edu>
- Romain Francoise <romain@orebokech.com>
- Ron Parker <rparker@a123systems.com>
- Roy Crihfield <rscrihf@gmail.com>
- Rüdiger Sonderfeld <ruediger@c-plusplus.de>
- Rüdiger Sonderfeld <ruediger@c-plusplus.net>
- Ryan C. Thompson <rct@thompsonclan.org>
- Samuel Bronson <naesten@gmail.com>
- Sanjoy Das <sanjoy@playingwithpointers.com>
- Sean Bryant <sbryant@hackinggibsons.com>
- Sebastian Wiesner <lunaryorn@gmail.com>
- Sébastien Gross <seb@chezwam.org>
- Seong-Kook Shin <cinsky@gmail.com>
- Sergey Pashinin <sergey@pashinin.com>
- Sergey Vinokurov <serg.foo@gmail.com>
- Servilio Afre Puentes <afrepues@mcmaster.ca>
- Štěpán Němec <stepnem@gmail.com>
- Steven Chow <steve@myfreestuffapp.com>
- Steven E. Harris <seh@panix.com>
- Steven Thomas <sthomas314@gmail.com>
- Steve Purcell <steve@sanityinc.com>
- Suhail Shergill <suhailshergill@gmail.com>
- Takafumi Arakaki <aka.tkf@gmail.com>
- Teruki Shigitani <teruki.shigitani@gmail.com>
- Thierry Volpiatto <thierry.volpiatto@gmail.com>
- Thomas Frössman <thomasf@jossystem.se>
- Thomas Jost <thomas.jost@gmail.com>
- Thomas Riccardi <riccardi.thomas@gmail.com>
- Tibor Simko <tibor.simko@cern.ch>
- Timo Juhani Lindfors <timo.lindfors@iki.fi>
- Ting-Yu Lin <aethanyc@gmail.com>
- Tom Feist <shabble@metavore.org>
- Wilfred Hughes <me@wilfred.me.uk>
- Win Treese <treese@acm.org>
- Yann Hodique <yann.hodique@gmail.com>
- York Zhao <gtdplatform@gmail.com>

View file

@ -0,0 +1,123 @@
It's Magit! A Git Porcelain inside Emacs
=========================================
Magit is an interface to the version control system [Git][git],
implemented as an [Emacs][emacs] package.
Unlike the [VC][vc] package which is part of Emacs and strives to
provide a unified interface to various version control systems, Magit
only supports Git and can therefore better take advantage of its
native features.
*Magit supports GNU Emacs 23.2 or later; 24.1 or later is recommended.*
*Magit supports Git 1.7.2.5 or later; 1.8.2 or later is recommended.*
### Table of Contents
* [Installation](#installation)
* [Getting Started](#getting-started)
* [Getting Help](#getting-help)
* [Contributions](#contributions)
* [Dependencies](#dependencies)
Installation
============
We recommend that you use Emacs' package manager (`package.el`),
to install Magit from your preferred Elpa archive ([Melpa][melpa],
[Melpa-Stable][melpa-stable], or [Marmalade][marmalade]). If you
haven't used the package manager before, or would like to install
directly from Magit's Git repository, then consult the detailed
[installation instructions][install].
Getting Started
===============
To get started with Magit show a summary of its status in a
new buffer using <kbd>M-x magit-status RET</kbd>. Navigate the
buffer using <kbd>n</kbd> and <kbd>p</kbd>, and toggle sections using
<kbd>TAB</kbd>. Edit and save some files, refresh the status buffer
using <kbd>g</kbd>, stage files or individual hunks using <kbd>s</kbd>
and initiate a commit using <kbd>c c</kbd> the staged changes. When
done writing the commit message use <kbd>C-c C-c</kbd> to actually
create the commit.
For more details consult the user manual. You can read it with
<kbd>C-u C-h i magit.info RET</kbd> or [on the web][manual]. Magit
also has a [website][website].
Getting Help
============
When something doesn't work as expected please see the [FAQ][faq], and
the list of [open issues][issues], and use the search box at the top
of the latter to find older related issues. If everything else fails
ask for help on the [Emacs Stackexchange][emacsstack] site or the
[mailing list][group].
Contributions
=============
Magit is [hosted on Github][development]. Please contribute by
reporting bugs and suggesting features on the [issue tracker][issues]
or by making code contributions using [pull requests][pulls]. Before
opening a pull request read the brief
[contribution guidelines][contributing].
Please also consider supporting development by making a
[monetary donation][donations]. Thank you!
Magit was started by [Marius Vollmer][marius] and is now maintained
by [Jonas Bernoulli][jonas]. Other Magitians (former maintainers)
are [Nicolas Dudebout][nicolas], [Peter J. Weisberg][peter],
[Phil Jackson][phil], [Rémi Vanicat][remi], and [Yann Hodique][yann].
Many more people have [contributed code][stats-authors] and suggested
features.
Thanks to all of you, may (the history of) the source be with you!
Dependencies
============
If you install Magit using Emacs' package manager then dependencies
are automatically being taken care of. Otherwise you have to track
down dependencies and install them manually.
Magit requires the libraries `git-commit-mode` and `git-rebase-mode`
which are part of the [magit/git-modes][git-modes] repository and are
distributed as separate packages.
The library `magit-wip` additionally requires the [`git-wip`][git-wip]
script, which you have to install manually.
[contributing]: https://github.com/magit/magit/blob/master/CONTRIBUTING.md
[development]: http://github.com/magit/magit
[donations]: http://magit.vc/donations.html
[emacsstack]: http://emacs.stackexchange.com/questions/tagged/magit
[faq]: https://github.com/magit/magit/wiki/FAQ
[group]: https://groups.google.com/forum/?fromgroups#!forum/magit
[install]: https://github.com/magit/magit/wiki/Installation
[issues]: https://github.com/magit/magit/issues
[manual]: http://magit.vc/manual/master
[pulls]: https://github.com/magit/magit/pulls
[stats-authors]: http://magit.vc/stats/authors.html
[website]: http://magit.vc
[jonas]: http://emacsair.me
[marius]: https://github.com/mvollmer
[nicolas]: http://dudebout.com
[peter]: https://github.com/pjweisberg
[phil]: https://github.com/philjackson
[remi]: https://github.com/vanicat
[yann]: http://www.hodique.info
[emacs]: http://www.gnu.org/software/emacs
[git-wip]: https://github.com/bartman/git-wip
[git]: http://git-scm.com
[git-modes]: https://github.com/magit/git-modes
[marmalade]: http://marmalade-repo.org
[melpa]: http://melpa.org
[melpa-stable]: http://stable.melpa.org
[vc]: http://www.gnu.org/software/emacs/manual/html_node/emacs/Version-Control.html

View file

@ -0,0 +1,18 @@
This is the file .../info/dir, which contains the
topmost node of the Info hierarchy, called (dir)Top.
The first time you invoke Info you start off looking at this node.

File: dir, Node: Top This is the top of the INFO tree
This (the Directory node) gives a menu of major topics.
Typing "q" exits, "?" lists all Info commands, "d" returns here,
"h" gives a primer for first-timers,
"mEmacs<Return>" visits the Emacs manual, etc.
In Emacs, you can click mouse button 2 on a menu item or cross reference
to select it.
* Menu:
Emacs
* Magit (1.4.0): (magit). Using Git from Emacs with Magit. (1.4.0)

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,307 @@
;;; magit-blame.el --- blame support for Magit
;; Copyright (C) 2012-2015 The Magit Project Developers
;;
;; For a full list of contributors, see the AUTHORS.md file
;; at the top-level directory of this distribution and at
;; https://raw.github.com/magit/magit/master/AUTHORS.md
;; Author: Yann Hodique <yann.hodique@gmail.com>
;; Package: magit
;; Contains code from Egg (Emacs Got Git) <https://github.com/byplayer/egg>,
;; released under the GNU General Public License version 3 or later.
;; Magit is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; Magit is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with Magit. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; Control git-blame from Magit.
;; This code has been backported from Egg (Magit fork) to Magit.
;;; Code:
(eval-when-compile (require 'cl-lib))
(require 'magit)
(require 'easymenu)
;;; Options
(defgroup magit-blame nil
"Git-blame support for Magit."
:group 'magit-extensions)
(defcustom magit-blame-ignore-whitespace t
"Ignore whitespace when determining blame information."
:group 'magit-blame
:type 'boolean)
(defcustom magit-time-format-string "%Y-%m-%dT%T%z"
"How to format time in magit-blame header."
:group 'magit-blame
:type 'string)
(defface magit-blame-header
'((t :inherit magit-section-title))
"Face for blame header."
:group 'magit-faces)
(defface magit-blame-sha1
'((t :inherit (magit-log-sha1 magit-blame-header)))
"Face for blame sha1."
:group 'magit-faces)
(defface magit-blame-culprit
'((t :inherit magit-blame-header))
"Face for blame culprit."
:group 'magit-faces)
(defface magit-blame-time
'((t :inherit magit-blame-header))
"Face for blame time."
:group 'magit-faces)
(defface magit-blame-subject
'((t :inherit (magit-log-message magit-blame-header)))
"Face for blame tag line."
:group 'magit-faces)
;;; Keymaps
(defvar magit-blame-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd "l") 'magit-blame-locate-commit)
(define-key map (kbd "RET") 'magit-blame-locate-commit)
(define-key map (kbd "q") 'magit-blame-mode)
(define-key map (kbd "n") 'magit-blame-next-chunk)
(define-key map (kbd "p") 'magit-blame-previous-chunk)
map)
"Keymap for an annotated section.\\{magit-blame-map}")
(easy-menu-define magit-blame-mode-menu magit-blame-map
"Magit blame menu"
'("Blame"
["Locate Commit" magit-blame-locate-commit t]
["Next" magit-blame-next-chunk t]
["Previous" magit-blame-previous-chunk t]
"---"
["Quit" magit-blame-mode t]))
;;; Mode
(defvar-local magit-blame-buffer-read-only nil)
;;;###autoload
(define-minor-mode magit-blame-mode
"Display blame information inline."
:keymap magit-blame-map
:lighter " blame"
(unless (buffer-file-name)
(user-error "Current buffer has no associated file!"))
(when (and (buffer-modified-p)
(y-or-n-p (format "save %s first? " (buffer-file-name))))
(save-buffer))
(cond (magit-blame-mode
(setq magit-blame-buffer-read-only buffer-read-only)
(magit-blame-file-on (current-buffer))
(set-buffer-modified-p nil)
(setq buffer-read-only t))
(t
(magit-blame-file-off (current-buffer))
(set-buffer-modified-p nil)
(setq buffer-read-only magit-blame-buffer-read-only))))
(defun magit-blame-file-off (buffer)
(save-excursion
(save-restriction
(with-current-buffer buffer
(widen)
(mapc (lambda (ov)
(when (overlay-get ov :blame)
(delete-overlay ov)))
(overlays-in (point-min) (point-max)))))))
(defun magit-blame-file-on (buffer)
(magit-blame-file-off buffer)
(save-excursion
(with-current-buffer buffer
(save-restriction
(with-temp-buffer
(apply 'magit-git-insert "blame" "--porcelain"
`(,@(and magit-blame-ignore-whitespace (list "-w")) "--"
,(file-name-nondirectory (buffer-file-name buffer))))
(magit-blame-parse buffer (current-buffer)))))))
;;; Commands
(defun magit-blame-locate-commit (pos)
"Jump to a commit in the branch history from an annotated blame section."
(interactive "d")
(let ((overlays (overlays-at pos))
sha1)
(dolist (ov overlays)
(when (overlay-get ov :blame)
(setq sha1 (plist-get (nth 3 (overlay-get ov :blame)) :sha1))))
(when sha1
(magit-show-commit sha1))))
(defun magit-blame-next-chunk ()
"Go to the next blame chunk."
(interactive)
(let ((next (next-single-property-change (point) :blame)))
(when next
(goto-char next))))
(defun magit-blame-previous-chunk ()
"Go to the previous blame chunk."
(interactive)
(let ((prev (previous-single-property-change (point) :blame)))
(when prev
(goto-char prev))))
;;; Parse
(defun magit-blame-decode-time (unixtime &optional tz)
"Decode UNIXTIME into (HIGH LOW) format.
The second argument TZ can be used to add the timezone in (-)HHMM
format to UNIXTIME. UNIXTIME should be either a number
containing seconds since epoch or Emacs's (HIGH LOW . IGNORED)
format."
(when (numberp tz)
(unless (numberp unixtime)
(setq unixtime (float-time unixtime)))
(let* ((ptz (abs tz))
(min (+ (* (/ ptz 100) 60)
(mod ptz 100))))
(setq unixtime (+ (* (if (< tz 0) (- min) min) 60) unixtime))))
(when (numberp unixtime)
(setq unixtime (seconds-to-time unixtime)))
unixtime)
(defun magit-blame-format-time-string (format &optional unixtime tz)
"Use FORMAT to format the time UNIXTIME, or now if omitted.
UNIXTIME is specified as a number containing seconds since epoch
or Emacs's (HIGH LOW . IGNORED) format. The optional argument TZ
can be used to set the time zone. If TZ is a number it is
treated as a (-)HHMM offset to Universal Time. If TZ is not
a number and non-nil the time is printed in UTC. If TZ is nil
the local zime zone is used. The format of the function is
similar to `format-time-string' except for %Z which is not
officially supported at the moment."
(unless unixtime
(setq unixtime (current-time)))
(when (numberp tz) ;; TODO add support for %Z
(setq format (replace-regexp-in-string "%z" (format "%+05d" tz) format)))
(format-time-string format (magit-blame-decode-time unixtime tz) tz))
(defun magit-blame-parse (target-buf blame-buf)
"Parse blame-info in buffer BLAME-BUF and decorate TARGET-BUF buffer."
(save-match-data
(let ((blank (propertize " " 'face 'magit-blame-header))
(nl (propertize "\n" 'face 'magit-blame-header))
(commit-hash (make-hash-table :test 'equal :size 577))
commit commit-info old-line new-line num old-file subject author
author-time author-timezone info ov beg end blame)
(with-current-buffer blame-buf
(goto-char (point-min))
;; search for a ful commit info
(while (re-search-forward
"^\\([0-9a-f]\\{40\\}\\) \\([0-9]+\\) \\([0-9]+\\) \\([0-9]+\\)$"
nil t)
(setq commit (match-string-no-properties 1)
old-line (string-to-number
(match-string-no-properties 2))
new-line (string-to-number
(match-string-no-properties 3))
num (string-to-number
(match-string-no-properties 4)))
;; was this commit already seen (and stored in the hash)?
(setq commit-info (gethash commit commit-hash))
;; Nope, this is the 1st time, the full commit-info follow.
(unless commit-info
(re-search-forward "^author \\(.+\\)$")
(setq author (match-string-no-properties 1))
(re-search-forward "^author-time \\(.+\\)$")
(setq author-time (string-to-number
(match-string-no-properties 1)))
(re-search-forward "^author-tz \\(.+\\)$")
(setq author-timezone (string-to-number
(match-string-no-properties 1)))
(re-search-forward "^summary \\(.+\\)$")
(setq subject (match-string-no-properties 1))
(re-search-forward "^filename \\(.+\\)$")
(setq old-file (match-string-no-properties 1))
(setq commit-info (list :sha1 commit :author author
:author-time author-time
:author-timezone author-timezone
:subject subject :file old-file))
;; save it in the hash
(puthash commit commit-info commit-hash))
;; add the current blame-block into the list INFO.
(setq info (cons (list old-line new-line num commit-info)
info))))
;; now do from beginning
(setq info (nreverse info))
(with-current-buffer target-buf
;; for every blame chunk
(dolist (chunk info)
(setq commit-info (nth 3 chunk)
old-line (nth 0 chunk)
new-line (nth 1 chunk)
num (nth 2 chunk)
commit (plist-get commit-info :sha1)
author (plist-get commit-info :author)
author-time (plist-get commit-info :author-time)
author-timezone (plist-get commit-info :author-timezone)
subject (plist-get commit-info :subject))
(goto-char (point-min))
(forward-line (1- new-line))
(setq beg (line-beginning-position)
end (save-excursion
(forward-line num)
(line-beginning-position)))
;; mark the blame chunk
(put-text-property beg end :blame chunk)
;; make an overlay with blame info as 'before-string
;; on the current chunk.
(setq ov (make-overlay beg end))
(overlay-put ov :blame chunk)
(setq blame (concat
(propertize (substring-no-properties commit 0 8)
'face 'magit-blame-sha1)
blank
(propertize (format "%-20s" author)
'face 'magit-blame-culprit)
blank
(propertize (magit-blame-format-time-string
magit-time-format-string
author-time author-timezone)
'face 'magit-blame-time)
blank
(propertize subject 'face 'magit-blame-subject)
blank nl))
(overlay-put ov 'before-string blame))))))
(provide 'magit-blame)
;; Local Variables:
;; indent-tabs-mode: nil
;; End:
;;; magit-blame.el ends here

Binary file not shown.

View file

@ -0,0 +1,735 @@
;;; magit-key-mode.el --- interactively tune git invocation
;; Copyright (C) 2010-2015 The Magit Project Developers
;;
;; For a full list of contributors, see the AUTHORS.md file
;; at the top-level directory of this distribution and at
;; https://raw.github.com/magit/magit/master/AUTHORS.md
;; Author: Phil Jackson <phil@shellarchive.co.uk>
;; Package: magit
;; Magit is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; Magit is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with Magit. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; This library implements `magit-key-mode' which is used throughout
;; Magit to let the user interactively select the command, switches
;; and options to call Git with. It can be though of as a way to
;; provide "postfix" arguments.
;;; Code:
(require 'magit)
(eval-when-compile (require 'cl-lib))
(defvar magit-key-mode-keymaps)
(defvar magit-key-mode-last-buffer)
(defvar magit-pre-key-mode-window-conf)
;;; Options
(defcustom magit-key-mode-show-usage t
"Whether to show usage information when entering a popup."
:group 'magit
:type 'boolean)
;;; Faces
(defface magit-key-mode-header-face
'((t :inherit font-lock-keyword-face))
"Face for key mode header lines."
:group 'magit-faces)
(defface magit-key-mode-button-face
'((t :inherit font-lock-builtin-face))
"Face for key mode buttons."
:group 'magit-faces)
(defface magit-key-mode-switch-face
'((t :inherit font-lock-warning-face))
"Face for key mode switches."
:group 'magit-faces)
(defface magit-key-mode-args-face
'((t :inherit widget-field))
"Face for key mode switch arguments."
:group 'magit-faces)
;;; Keygroups
;;;###autoload
(defvar magit-key-mode-groups
'((dispatch
(actions
("b" "Branching" magit-key-mode-popup-branching)
("B" "Bisecting" magit-key-mode-popup-bisecting)
("c" "Committing" magit-key-mode-popup-committing)
("d" "Diff worktree" magit-diff-working-tree)
("D" "Diff" magit-diff)
("f" "Fetching" magit-key-mode-popup-fetching)
("F" "Pulling" magit-key-mode-popup-pulling)
("g" "Refresh Buffers" magit-refresh-all)
("l" "Logging" magit-key-mode-popup-logging)
("m" "Merging" magit-key-mode-popup-merging)
("M" "Remoting" magit-key-mode-popup-remoting)
("P" "Pushing" magit-key-mode-popup-pushing)
("o" "Submoduling" magit-key-mode-popup-submodule)
("r" "Rewriting" magit-key-mode-popup-rewriting)
("R" "Rebasing" magit-rebase-step)
("s" "Show Status" magit-status)
("S" "Stage all" magit-stage-all)
("t" "Tagging" magit-key-mode-popup-tagging)
("U" "Unstage all" magit-unstage-all)
("v" "Show Commit" magit-show-commit)
("V" "Show File" magit-show)
("w" "Wazzup" magit-wazzup)
("X" "Reset worktree" magit-reset-working-tree)
("y" "Cherry" magit-cherry)
("z" "Stashing" magit-key-mode-popup-stashing)
("!" "Running" magit-key-mode-popup-running)
("$" "Show Process" magit-process)))
(logging
(man-page "git-log")
(actions
("l" "Short" magit-log)
("L" "Long" magit-log-long)
("h" "Head Reflog" magit-reflog-head)
("f" "File log" magit-file-log)
("rl" "Ranged short" magit-log-ranged)
("rL" "Ranged long" magit-log-long-ranged)
("rh" "Reflog" magit-reflog))
(switches
("-m" "Only merge commits" "--merges")
("-s" "No merge commits" "--no-merges")
("-do" "Date Order" "--date-order")
("-f" "First parent" "--first-parent")
("-i" "Case insensitive patterns" "-i")
("-pr" "Pickaxe regex" "--pickaxe-regex")
("-g" "Show Graph" "--graph")
("-n" "Name only" "--name-only")
("-am" "All match" "--all-match")
("-al" "All" "--all"))
(arguments
("=r" "Relative" "--relative=" read-directory-name)
("=c" "Committer" "--committer=" read-from-minibuffer)
("=>" "Since" "--since=" read-from-minibuffer)
("=<" "Before" "--before=" read-from-minibuffer)
("=a" "Author" "--author=" read-from-minibuffer)
("=g" "Grep messages" "--grep=" read-from-minibuffer)
("=G" "Grep patches" "-G" read-from-minibuffer)
("=L" "Trace evolution of line range [long log only]"
"-L" magit-read-file-trace)
("=s" "Pickaxe search" "-S" read-from-minibuffer)
("=b" "Branches" "--branches=" read-from-minibuffer)
("=R" "Remotes" "--remotes=" read-from-minibuffer)))
(running
(actions
("!" "Git Subcommand (from root)" magit-git-command-topdir)
(":" "Git Subcommand (from pwd)" magit-git-command)
("g" "Git Gui" magit-run-git-gui)
("k" "Gitk" magit-run-gitk)))
(fetching
(man-page "git-fetch")
(actions
("f" "Current" magit-fetch-current)
("a" "All" magit-remote-update)
("o" "Other" magit-fetch))
(switches
("-p" "Prune" "--prune")))
(pushing
(man-page "git-push")
(actions
("P" "Push" magit-push)
("t" "Push tags" magit-push-tags))
(switches
("-f" "Force" "--force")
("-d" "Dry run" "-n")
("-u" "Set upstream" "-u")))
(pulling
(man-page "git-pull")
(actions
("F" "Pull" magit-pull))
(switches
("-f" "Force" "--force")
("-r" "Rebase" "--rebase")))
(branching
(man-page "git-branch")
(actions
("v" "Branch manager" magit-branch-manager)
("b" "Checkout" magit-checkout)
("c" "Create" magit-create-branch)
("r" "Rename" magit-rename-branch)
("k" "Delete" magit-delete-branch))
(switches
("-t" "Set upstream configuration" "--track")
("-m" "Merged to HEAD" "--merged")
("-M" "Merged to master" "--merged=master")
("-n" "Not merged to HEAD" "--no-merged")
("-N" "Not merged to master" "--no-merged=master"))
(arguments
("=c" "Contains" "--contains=" magit-read-rev-with-default)
("=m" "Merged" "--merged=" magit-read-rev-with-default)
("=n" "Not merged" "--no-merged=" magit-read-rev-with-default)))
(remoting
(man-page "git-remote")
(actions
("v" "Remote manager" magit-branch-manager)
("a" "Add" magit-add-remote)
("r" "Rename" magit-rename-remote)
("k" "Remove" magit-remove-remote)))
(tagging
(man-page "git-tag")
(actions
("t" "Create" magit-tag)
("k" "Delete" magit-delete-tag))
(switches
("-a" "Annotate" "--annotate")
("-f" "Force" "--force")
("-s" "Sign" "--sign")))
(stashing
(man-page "git-stash")
(actions
("v" "View" magit-diff-stash)
("z" "Save" magit-stash)
("s" "Snapshot" magit-stash-snapshot)
("a" "Apply" magit-stash-apply)
("p" "Pop" magit-stash-pop)
("k" "Drop" magit-stash-drop))
(switches
("-k" "Keep index" "--keep-index")
("-u" "Include untracked files" "--include-untracked")
("-a" "Include all files" "--all")))
(committing
(man-page "git-commit")
(actions
("c" "Commit" magit-commit)
("a" "Amend" magit-commit-amend)
("e" "Extend" magit-commit-extend)
("r" "Reword" magit-commit-reword)
("f" "Fixup" magit-commit-fixup)
("s" "Squash" magit-commit-squash))
(switches
("-a" "Stage all modified and deleted files" "--all")
("-e" "Allow empty commit" "--allow-empty")
("-v" "Show diff of changes to be committed" "--verbose")
("-n" "Bypass git hooks" "--no-verify")
("-s" "Add Signed-off-by line" "--signoff")
("-R" "Claim authorship and reset author date" "--reset-author"))
(arguments
("=A" "Override the author" "--author=" read-from-minibuffer)
("=S" "Sign using gpg" "--gpg-sign=" magit-read-gpg-secret-key)))
(merging
(man-page "git-merge")
(actions
("m" "Merge" magit-merge)
("A" "Abort" magit-merge-abort))
(switches
("-ff" "Fast-forward only" "--ff-only")
("-nf" "No fast-forward" "--no-ff")
("-sq" "Squash" "--squash"))
(arguments
("-st" "Strategy" "--strategy=" read-from-minibuffer)))
(rewriting
(actions
("b" "Begin" magit-rewrite-start)
("s" "Stop" magit-rewrite-stop)
("a" "Abort" magit-rewrite-abort)
("f" "Finish" magit-rewrite-finish)
("d" "Diff pending" magit-rewrite-diff-pending)
("*" "Set unused" magit-rewrite-set-unused)
("." "Set used" magit-rewrite-set-used)))
(apply-mailbox
(man-page "git-am")
(actions
("J" "Apply Mailbox" magit-apply-mailbox))
(switches
("-s" "add a Signed-off-by line to the commit message" "--signoff")
("-3" "allow fall back on 3way merging if needed" "--3way")
("-k" "pass -k flag to git-mailinfo" "--keep")
("-c" "strip everything before a scissors line" "--scissors")
("-p" "pass it through git-apply" "-p")
("-r" "override error message when patch failure occurs" "--resolvemsg")
("-d" "lie about committer date" "--committer-date-is-author-date")
("-D" "use current timestamp for author date" "--ignore-date")
("-b" "pass -b flag to git-mailinfo" "--keep-non-patch"))
(arguments
("=p" "format the patch(es) are in" "--patch-format=" read-from-minibuffer)))
(submodule
(man-page "git-submodule")
(actions
("u" "Update" magit-submodule-update)
("b" "Both update and init" magit-submodule-update-init)
("i" "Init" magit-submodule-init)
("s" "Sync" magit-submodule-sync)))
(bisecting
(man-page "git-bisect")
(actions
("b" "Bad" magit-bisect-bad)
("g" "Good" magit-bisect-good)
("k" "Skip" magit-bisect-skip)
("r" "Reset" magit-bisect-reset)
("s" "Start" magit-bisect-start)
("u" "Run" magit-bisect-run)))
(diff-options
(actions
("s" "Set" magit-set-diff-options)
("d" "Set default" magit-set-default-diff-options)
("c" "Save default" magit-save-default-diff-options)
("r" "Reset to default" magit-reset-diff-options)
("h" "Toggle Hunk Refinement" magit-diff-toggle-refine-hunk))
(switches
("-m" "Show smallest possible diff" "--minimal")
("-p" "Use patience diff algorithm" "--patience")
("-h" "Use histogram diff algorithm" "--histogram")
("-b" "Ignore whitespace changes" "--ignore-space-change")
("-w" "Ignore all whitespace" "--ignore-all-space")
("-W" "Show surrounding functions" "--function-context"))
))
"Holds the key, help, function mapping for the log-mode.
If you modify this make sure you reset `magit-key-mode-keymaps'
to nil.")
(defun magit-key-mode-delete-group (group)
"Delete a group from `magit-key-mode-keymaps'."
(let ((items (assoc group magit-key-mode-groups)))
(when items
;; reset the cache
(setq magit-key-mode-keymaps nil)
;; delete the whole group
(setq magit-key-mode-groups
(delq items magit-key-mode-groups))
;; unbind the defun
(magit-key-mode-de-generate group))
magit-key-mode-groups))
(defun magit-key-mode-add-group (group)
"Add a new group to `magit-key-mode-keymaps'.
If there already is a group of that name then this will
completely remove it and put in its place an empty one of the
same name."
(when (assoc group magit-key-mode-groups)
(magit-key-mode-delete-group group))
(setq magit-key-mode-groups
(cons (list group (list 'actions) (list 'switches) (list 'arguments))
magit-key-mode-groups)))
(defun magit-key-mode-key-defined-p (for-group key)
"Return t if KEY is defined as any option within FOR-GROUP.
The option may be a switch, argument or action."
(catch 'result
(let ((options (magit-key-mode-options-for-group for-group)))
(dolist (type '(actions switches arguments))
(when (assoc key (assoc type options))
(throw 'result t))))))
(defun magit-key-mode-update-group (for-group thing &rest args)
"Abstraction for setting values in `magit-key-mode-keymaps'."
(let* ((options (magit-key-mode-options-for-group for-group))
(things (assoc thing options))
(key (car args)))
(if (cdr things)
(if (magit-key-mode-key-defined-p for-group key)
(error "%s is already defined in the %s group." key for-group)
(setcdr (cdr things) (cons args (cddr things))))
(setcdr things (list args)))
(setq magit-key-mode-keymaps nil)
things))
(defun magit-key-mode-insert-argument (for-group key desc arg read-func)
"Add a new binding KEY in FOR-GROUP which will use READ-FUNC
to receive input to apply to argument ARG git is run. DESC should
be a brief description of the binding."
(magit-key-mode-update-group for-group 'arguments key desc arg read-func))
(defun magit-key-mode-insert-switch (for-group key desc switch)
"Add a new binding KEY in FOR-GROUP which will add SWITCH to git's
command line when it runs. DESC should be a brief description of
the binding."
(magit-key-mode-update-group for-group 'switches key desc switch))
(defun magit-key-mode-insert-action (for-group key desc func)
"Add a new binding KEY in FOR-GROUP which will run command FUNC.
DESC should be a brief description of the binding."
(magit-key-mode-update-group for-group 'actions key desc func))
(defun magit-key-mode-options-for-group (for-group)
"Retrieve the options for the group FOR-GROUP.
This includes switches, commands and arguments."
(or (cdr (assoc for-group magit-key-mode-groups))
(error "Unknown group '%s'" for-group)))
;;; Commands
(defun magit-key-mode-help (for-group)
"Provide help for a key within FOR-GROUP.
The user is prompted for the key."
(let* ((opts (magit-key-mode-options-for-group for-group))
(man-page (cadr (assoc 'man-page opts)))
(seq (read-key-sequence
(format "Enter command prefix%s: "
(if man-page
(format ", `?' for man `%s'" man-page)
""))))
(actions (cdr (assoc 'actions opts))))
(cond
;; if it is an action popup the help for the to-be-run function
((assoc seq actions) (describe-function (nth 2 (assoc seq actions))))
;; if there is "?" show a man page if there is one
((equal seq "?")
(if man-page
(man man-page)
(error "No man page associated with `%s'" for-group)))
(t (error "No help associated with `%s'" seq)))))
(defun magit-key-mode-exec-at-point ()
"Run action/args/option at point."
(interactive)
(let ((key (or (get-text-property (point) 'key-group-executor)
(error "Nothing at point to do."))))
(call-interactively (lookup-key (current-local-map) key))))
(defun magit-key-mode-jump-to-next-exec ()
"Jump to the next action/args/option point."
(interactive)
(let* ((oldp (point))
(old (get-text-property oldp 'key-group-executor))
(p (if (= oldp (point-max)) (point-min) (1+ oldp))))
(while (let ((new (get-text-property p 'key-group-executor)))
(and (not (= p oldp)) (or (not new) (eq new old))))
(setq p (if (= p (point-max)) (point-min) (1+ p))))
(goto-char p)
(skip-chars-forward " ")))
;;; Keymaps
(defvar magit-key-mode-keymaps nil
"This will be filled lazily with proper keymaps.
These keymaps are created using `define-key' as they're requested.")
(defun magit-key-mode-build-keymap (for-group)
"Construct a normal looking keymap for the key mode to use.
Put it in `magit-key-mode-keymaps' for fast lookup."
(let* ((options (magit-key-mode-options-for-group for-group))
(actions (cdr (assoc 'actions options)))
(switches (cdr (assoc 'switches options)))
(arguments (cdr (assoc 'arguments options)))
(map (make-sparse-keymap)))
(suppress-keymap map 'nodigits)
;; ret dwim
(define-key map (kbd "RET") 'magit-key-mode-exec-at-point)
;; tab jumps to the next "button"
(define-key map (kbd "TAB") 'magit-key-mode-jump-to-next-exec)
;; all maps should `quit' with `C-g' or `q'
(define-key map (kbd "C-g") `(lambda ()
(interactive)
(magit-key-mode-command nil)))
(define-key map (kbd "q") `(lambda ()
(interactive)
(magit-key-mode-command nil)))
;; run help
(define-key map (kbd "?") `(lambda ()
(interactive)
(magit-key-mode-help ',for-group)))
(let ((defkey (lambda (k action)
(when (and (lookup-key map (car k))
(not (numberp (lookup-key map (car k)))))
(message "Warning: overriding binding for `%s' in %S"
(car k) for-group)
(ding)
(sit-for 2))
(define-key map (car k)
`(lambda () (interactive) ,action)))))
(dolist (k actions)
(funcall defkey k `(magit-key-mode-command ',(nth 2 k))))
(dolist (k switches)
(funcall defkey k `(magit-key-mode-toggle-option ',for-group ,(nth 2 k))))
(dolist (k arguments)
(funcall defkey k `(magit-key-mode-add-argument
',for-group ,(nth 2 k) ',(nth 3 k)))))
(push (cons for-group map) magit-key-mode-keymaps)
map))
;;; Toggling and Running
(defvar magit-key-mode-prefix nil
"Prefix argument to the command that brought up the key-mode window.
For internal use. Used by the command that's eventually invoked.")
(defvar magit-key-mode-current-args nil
"A hash-table of current argument set.
These will eventually make it to the git command-line.")
(defvar magit-key-mode-current-options nil
"Current option set.
These will eventually make it to the git command-line.")
(defvar magit-custom-options nil
"List of custom options to pass to Git.
Do not customize this (used in the `magit-key-mode' implementation).")
(defun magit-key-mode-command (func)
(let ((current-prefix-arg (or current-prefix-arg magit-key-mode-prefix))
(magit-custom-options magit-key-mode-current-options))
(maphash (lambda (k v)
(push (concat k v) magit-custom-options))
magit-key-mode-current-args)
(set-window-configuration magit-pre-key-mode-window-conf)
(kill-buffer magit-key-mode-last-buffer)
(when func
(setq this-command func)
(call-interactively this-command))))
(defun magit-key-mode-add-argument (for-group arg-name input-func)
(let ((input (funcall input-func (concat arg-name ": "))))
(puthash arg-name input magit-key-mode-current-args)
(magit-key-mode-redraw for-group)))
(defun magit-key-mode-toggle-option (for-group option-name)
"Toggles the appearance of OPTION-NAME in `magit-key-mode-current-options'."
(if (member option-name magit-key-mode-current-options)
(setq magit-key-mode-current-options
(delete option-name magit-key-mode-current-options))
(add-to-list 'magit-key-mode-current-options option-name))
(magit-key-mode-redraw for-group))
;;; Mode
(defvar magit-key-mode-buf-name "*magit-key: %s*"
"Format string to create the name of the magit-key buffer.")
(defvar magit-key-mode-last-buffer nil
"Store the last magit-key buffer used.")
(defvar magit-pre-key-mode-window-conf nil
"Will hold the pre-menu configuration of magit.")
(defun magit-key-mode (for-group &optional original-opts)
"Mode for magit key selection.
All commands, switches and options can be toggled/actioned with
the key combination highlighted before the description."
(interactive)
;; save the window config to restore it as was (no need to make this
;; buffer local)
(setq magit-pre-key-mode-window-conf
(current-window-configuration))
;; setup the mode, draw the buffer
(let ((buf (get-buffer-create (format magit-key-mode-buf-name
(symbol-name for-group)))))
(setq magit-key-mode-last-buffer buf)
(split-window-vertically)
(other-window 1)
(switch-to-buffer buf)
(kill-all-local-variables)
(set (make-local-variable 'scroll-margin) 0)
(set (make-local-variable
'magit-key-mode-current-options)
original-opts)
(set (make-local-variable
'magit-key-mode-current-args)
(make-hash-table))
(set (make-local-variable 'magit-key-mode-prefix) current-prefix-arg)
(magit-key-mode-redraw for-group))
(when magit-key-mode-show-usage
(message (concat "Type a prefix key to toggle it. "
"Run 'actions' with their prefixes. "
"'?' for more help."))))
(defun magit-key-mode-get-key-map (for-group)
"Get or build the keymap for FOR-GROUP."
(or (cdr (assoc for-group magit-key-mode-keymaps))
(magit-key-mode-build-keymap for-group)))
(defun magit-key-mode-redraw (for-group)
"(re)draw the magit key buffer."
(let ((buffer-read-only nil)
(current-exec (get-text-property (point) 'key-group-executor))
(new-exec-pos)
(old-point (point))
(is-first (zerop (buffer-size)))
(actions-p nil))
(erase-buffer)
(make-local-variable 'font-lock-defaults)
(use-local-map (magit-key-mode-get-key-map for-group))
(setq actions-p (magit-key-mode-draw for-group))
(delete-trailing-whitespace)
(setq mode-name "magit-key-mode" major-mode 'magit-key-mode)
(when current-exec
(setq new-exec-pos
(cdr (assoc current-exec
(magit-key-mode-build-exec-point-alist)))))
(cond ((and is-first actions-p)
(goto-char actions-p)
(magit-key-mode-jump-to-next-exec))
(new-exec-pos
(goto-char new-exec-pos)
(skip-chars-forward " "))
(t
(goto-char old-point))))
(setq buffer-read-only t)
(fit-window-to-buffer))
(defun magit-key-mode-build-exec-point-alist ()
(save-excursion
(goto-char (point-min))
(let* ((exec (get-text-property (point) 'key-group-executor))
(exec-alist (and exec `((,exec . ,(point))))))
(cl-do nil ((eobp) (nreverse exec-alist))
(when (not (eq exec (get-text-property (point) 'key-group-executor)))
(setq exec (get-text-property (point) 'key-group-executor))
(when exec (push (cons exec (point)) exec-alist)))
(forward-char)))))
;;; Draw Buffer
(defun magit-key-mode-draw-header (header)
"Draw a header with the correct face."
(insert (propertize header 'face 'magit-key-mode-header-face) "\n"))
(defvar magit-key-mode-args-in-cols nil
"When true, draw arguments in columns as with switches and options.")
(defun magit-key-mode-draw-args (args)
"Draw the args part of the menu."
(magit-key-mode-draw-buttons
"Args"
args
(lambda (x)
(format "(%s) %s"
(nth 2 x)
(propertize (gethash (nth 2 x) magit-key-mode-current-args "")
'face 'magit-key-mode-args-face)))
(not magit-key-mode-args-in-cols)))
(defun magit-key-mode-draw-switches (switches)
"Draw the switches part of the menu."
(magit-key-mode-draw-buttons
"Switches"
switches
(lambda (x)
(format "(%s)" (let ((s (nth 2 x)))
(if (member s magit-key-mode-current-options)
(propertize s 'face 'magit-key-mode-switch-face)
s))))))
(defun magit-key-mode-draw-actions (actions)
"Draw the actions part of the menu."
(magit-key-mode-draw-buttons "Actions" actions nil))
(defun magit-key-mode-draw-buttons (section xs maker
&optional one-col-each)
(when xs
(magit-key-mode-draw-header section)
(magit-key-mode-draw-in-cols
(mapcar (lambda (x)
(let* ((head (propertize (car x) 'face 'magit-key-mode-button-face))
(desc (nth 1 x))
(more (and maker (funcall maker x)))
(text (format " %s: %s%s%s"
head desc (if more " " "") (or more ""))))
(propertize text 'key-group-executor (car x))))
xs)
one-col-each)))
(defun magit-key-mode-draw-in-cols (strings one-col-each)
"Given a list of strings, print in columns (using `insert').
If ONE-COL-EACH is true then don't columify, but rather, draw
each item on one line."
(let ((longest-act (apply 'max (mapcar 'length strings))))
(while strings
(let ((str (car strings)))
(let ((padding (make-string (- (+ longest-act 3) (length str)) ? )))
(insert str)
(if (or one-col-each
(and (> (+ (length padding) ;
(current-column)
longest-act)
(window-width))
(cdr strings)))
(insert "\n")
(insert padding))))
(setq strings (cdr strings))))
(insert "\n"))
(defun magit-key-mode-draw (for-group)
"Draw actions, switches and parameters.
Return the point before the actions part, if any, nil otherwise."
(let* ((options (magit-key-mode-options-for-group for-group))
(switches (cdr (assoc 'switches options)))
(arguments (cdr (assoc 'arguments options)))
(actions (cdr (assoc 'actions options)))
(p nil))
(magit-key-mode-draw-switches switches)
(magit-key-mode-draw-args arguments)
(when actions (setq p (point-marker)))
(magit-key-mode-draw-actions actions)
(insert "\n")
p))
;;; Generate Groups
(defun magit-key-mode-de-generate (group)
"Unbind the function for GROUP."
(fmakunbound
(intern (concat "magit-key-mode-popup-" (symbol-name group)))))
(defun magit-key-mode-generate (group)
"Generate the key-group menu for GROUP."
(let ((opts (magit-key-mode-options-for-group group)))
(eval
`(defun ,(intern (concat "magit-key-mode-popup-" (symbol-name group))) nil
,(concat "Key menu for " (symbol-name group))
(interactive)
(magit-key-mode
(quote ,group)
;; As a tempory kludge it is okay to do this here.
,(cl-case group
(logging
'(list "--graph"))
(diff-options
'(when (local-variable-p 'magit-diff-options)
magit-diff-options))))))))
;; create the interactive functions for the key mode popups (which are
;; applied in the top-level key maps)
(mapc (lambda (g)
(magit-key-mode-generate (car g)))
magit-key-mode-groups)
;;;###autoload (mapc (lambda (g) (eval `(autoload ',(intern (concat "magit-key-mode-popup-" (symbol-name (car g)))) "magit-key-mode" ,(concat "Key menu for " (symbol-name (car g))) t))) magit-key-mode-groups)
(provide 'magit-key-mode)
;; Local Variables:
;; indent-tabs-mode: nil
;; End:
;;; magit-key-mode.el ends here

Binary file not shown.

View file

@ -0,0 +1,9 @@
(define-package "magit" "20150608.1139" "control Git from Emacs"
'((cl-lib "0.5")
(git-commit-mode "1.0.0")
(git-rebase-mode "1.0.0"))
:keywords
'("vc" "tools"))
;; Local Variables:
;; no-byte-compile: t
;; End:

View file

@ -0,0 +1,143 @@
;;; magit-wip.el --- git-wip plug-in for Magit
;; Copyright (C) 2012-2015 The Magit Project Developers
;;
;; For a full list of contributors, see the AUTHORS.md file
;; at the top-level directory of this distribution and at
;; https://raw.github.com/magit/magit/master/AUTHORS.md
;; Author: Jonas Bernoulli <jonas@bernoul.li>
;; Keywords: vc tools
;; Package: magit
;; Magit is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; Magit is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with Magit. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; This plug-in provides support for special work-in-progress refs.
;; This requires the third-party git command "git wip" which is available
;; from https://github.com/bartman/git-wip.
;; To enable `magit-wip-save-mode' enable `global-magit-wip-save-mode'
;; and use the Magit extension mechanism to select the repositories in
;; which you want to use a work-in-progress ref.
;;
;; (global-magit-wip-save-mode 1)
;;
;; $ git config --add magit.extension wip-save # or
;; $ git config --global --add magit.extension wip-save
;; Note that `global-magit-wip-save-mode' is the only mode that uses the
;; extension mechanism for file-visiting buffers all other global modes
;; making use of it to turn on local modes in Magit buffers.
;;; Code:
(require 'magit)
(require 'format-spec)
(defun magit-wip-mode (&rest ignore)
(message "magit-wip-mode is obsolete and doesn't do anything"))
(make-obsolete 'magit-wip-mode "This mode is a noop now" "1.4.0")
;;; Options
(defgroup magit-wip nil
"Git-Wip support for Magit."
:group 'magit-extensions)
(defcustom magit-wip-commit-message "WIP %r"
"Commit message for git-wip commits.
The following `format'-like specs are supported:
%f the full name of the file being saved
%g the root of the git repository
%r the name of the file being saved,
relative to the repository root."
:group 'magit-wip
:type 'string)
(defcustom magit-wip-echo-area-message "Wrote %f (wip)"
"Message shown in the echo area after creating a git-wip commit.
The following `format'-like specs are supported:
%f the full name of the file being saved
%g the root of the git repository
%r the name of the file being saved,
relative to the repository root."
:group 'magit-wip
:type '(choice (const :tag "No message" nil) string))
(defvar magit-wip-save-mode-lighter " Wip")
;;; Mode
;;;###autoload
(define-minor-mode magit-wip-save-mode
"Magit support for committing to a work-in-progress ref.
When this minor mode is turned on and a file is saved inside a
writable git repository then it is also committed to a special
work-in-progress ref."
:lighter magit-wip-save-mode-lighter
(if magit-wip-save-mode
(add-hook 'after-save-hook 'magit-wip-save t t)
(remove-hook 'after-save-hook 'magit-wip-save t)))
;;;###autoload
(define-globalized-minor-mode global-magit-wip-save-mode
magit-wip-save-mode turn-on-magit-wip-save
:group 'magit-wip)
(defun turn-on-magit-wip-save ()
"Conditionally turn on magit-wip-save-mode.
Turn on magit-wip-save-mode if the buffer is a file in a git
repository where wip-save is enabled in git config.
You can activate it with git config magit.extension wip-save."
(when (and (buffer-file-name)
(magit-get-top-dir)
(magit-git-true "rev-parse" "--is-inside-work-tree")
(member "wip-save" (magit-get-all "magit.extension")))
(if (magit-git-success "wip" "-h")
(magit-wip-save-mode 1)
(message "Git command 'git wip' cannot be found"))))
(defun magit-wip-save ()
(let* ((filename (expand-file-name (file-truename (buffer-file-name))))
(filedir (file-name-directory filename))
(toplevel (magit-get-top-dir filedir))
(blobname (file-relative-name filename toplevel))
(spec `((?f . ,filename)
(?r . ,blobname)
(?g . ,toplevel))))
(when (and toplevel (file-writable-p toplevel)
(not (member blobname
(let ((default-directory filedir))
(magit-git-lines
"ls-files" "--other" "--ignored"
"--exclude-standard" "--full-name")))))
(magit-run-git "wip" "save"
(format-spec magit-wip-commit-message spec)
"--editor" "--" filename)
(when magit-wip-echo-area-message
(message (format-spec magit-wip-echo-area-message spec))))))
(provide 'magit-wip)
;; Local Variables:
;; indent-tabs-mode: nil
;; End:
;;; magit-wip.el ends here

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

11
elpa/magit-readme.txt Normal file
View file

@ -0,0 +1,11 @@
Invoking the magit-status function will show a buffer with the
status of the current git repository and its working tree. That
buffer offers key bindings for manipulating the status in simple
ways.
The status buffer mainly shows the difference between the working
tree and the index, and the difference between the index and the
current HEAD. You can add individual hunks from the working tree
to the index, and you can commit the index.
See the Magit User Manual for more information.

View file

@ -0,0 +1,131 @@
;;; pkg-info-autoloads.el --- automatically extracted autoloads
;;
;;; Code:
;;;### (autoloads (pkg-info-version-info pkg-info-package-version
;;;;;; pkg-info-defining-library-version pkg-info-defining-library-original-version
;;;;;; pkg-info-library-version pkg-info-library-original-version)
;;;;;; "pkg-info" "pkg-info.el" (21856 52889 706945 350000))
;;; Generated autoloads from pkg-info.el
(autoload 'pkg-info-library-original-version "pkg-info" "\
Get the original version in the header of LIBRARY.
The original version is stored in the X-Original-Version header.
This header is added by the MELPA package archive to preserve
upstream version numbers.
LIBRARY is either a symbol denoting a named feature, or a library
name as string.
If SHOW is non-nil, show the version in the minibuffer.
Return the version from the header of LIBRARY as list. Signal an
error if the LIBRARY was not found or had no X-Original-Version
header.
See Info node `(elisp)Library Headers' for more information
about library headers.
\(fn LIBRARY &optional SHOW)" t nil)
(autoload 'pkg-info-library-version "pkg-info" "\
Get the version in the header of LIBRARY.
LIBRARY is either a symbol denoting a named feature, or a library
name as string.
If SHOW is non-nil, show the version in the minibuffer.
Return the version from the header of LIBRARY as list. Signal an
error if the LIBRARY was not found or had no proper header.
See Info node `(elisp)Library Headers' for more information
about library headers.
\(fn LIBRARY &optional SHOW)" t nil)
(autoload 'pkg-info-defining-library-original-version "pkg-info" "\
Get the original version of the library defining FUNCTION.
The original version is stored in the X-Original-Version header.
This header is added by the MELPA package archive to preserve
upstream version numbers.
If SHOW is non-nil, show the version in mini-buffer.
This function is mainly intended to find the version of a major
or minor mode, i.e.
(pkg-info-defining-library-version 'flycheck-mode)
Return the version of the library defining FUNCTION. Signal an
error if FUNCTION is not a valid function, if its defining
library was not found, or if the library had no proper version
header.
\(fn FUNCTION &optional SHOW)" t nil)
(autoload 'pkg-info-defining-library-version "pkg-info" "\
Get the version of the library defining FUNCTION.
If SHOW is non-nil, show the version in mini-buffer.
This function is mainly intended to find the version of a major
or minor mode, i.e.
(pkg-info-defining-library-version 'flycheck-mode)
Return the version of the library defining FUNCTION. Signal an
error if FUNCTION is not a valid function, if its defining
library was not found, or if the library had no proper version
header.
\(fn FUNCTION &optional SHOW)" t nil)
(autoload 'pkg-info-package-version "pkg-info" "\
Get the version of an installed PACKAGE.
If SHOW is non-nil, show the version in the minibuffer.
Return the version as list, or nil if PACKAGE is not installed.
\(fn PACKAGE &optional SHOW)" t nil)
(autoload 'pkg-info-version-info "pkg-info" "\
Obtain complete version info for LIBRARY and PACKAGE.
LIBRARY is a symbol denoting a named feature, or a library name
as string. PACKAGE is a symbol denoting an ELPA package. If
omitted or nil, default to LIBRARY.
If SHOW is non-nil, show the version in the minibuffer.
When called interactively, prompt for LIBRARY. When called
interactively with prefix argument, prompt for PACKAGE as well.
Return a string with complete version information for LIBRARY.
This version information contains the version from the headers of
LIBRARY, and the version of the installed PACKAGE, the LIBRARY is
part of. If PACKAGE is not installed, or if the PACKAGE version
is the same as the LIBRARY version, do not include a package
version.
\(fn LIBRARY &optional PACKAGE SHOW)" t nil)
;;;***
;;;### (autoloads nil nil ("pkg-info-pkg.el") (21856 52889 805492
;;;;;; 379000))
;;;***
(provide 'pkg-info-autoloads)
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; coding: utf-8
;; End:
;;; pkg-info-autoloads.el ends here

View file

@ -0,0 +1 @@
(define-package "pkg-info" "20150517.443" "Information about packages" (quote ((epl "0.8"))))

Binary file not shown.

View file

@ -0,0 +1,331 @@
;;; pkg-info.el --- Information about packages -*- lexical-binding: t; -*-
;; Copyright (C) 2013-2015 Sebastian Wiesner <swiesner@lunaryorn.com>
;; Author: Sebastian Wiesner <swiesner@lunaryorn.com>
;; URL: https://github.com/lunaryorn/pkg-info.el
;; Package-Version: 20150517.443
;; Keywords: convenience
;; Version: 0.7-cvs
;; Package-Requires: ((epl "0.8"))
;; This file is not part of GNU Emacs.
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; This library extracts information from installed packages.
;;;; Functions:
;; `pkg-info-library-version' extracts the version from the header of a library.
;;
;; `pkg-info-defining-library-version' extracts the version from the header of a
;; library defining a function.
;;
;; `pkg-info-package-version' gets the version of an installed package.
;;
;; `pkg-info-format-version' formats a version list as human readable string.
;;
;; `pkg-info-version-info' returns complete version information for a specific
;; package.
;;
;; `pkg-info-get-melpa-recipe' gets the MELPA recipe for a package.
;;
;; `pkg-info-get-melpa-fetcher' gets the fetcher used to build a package on
;; MELPA.
;;
;; `pkg-info-wiki-package-p' determines whether a package was build from
;; EmacsWiki on MELPA.
;;; Code:
(require 'epl)
(require 'lisp-mnt)
(require 'find-func)
(require 'json) ; `json-read'
(require 'url-http) ; `url-http-parse-response'
(defvar url-http-end-of-headers)
;;; Version information
(defun pkg-info-format-version (version)
"Format VERSION as human-readable string.
Return a human-readable string representing VERSION."
;; XXX: Find a better, more flexible way of formatting?
(package-version-join version))
(defsubst pkg-info--show-version-and-return (version show)
"Show and return VERSION.
When SHOW is non-nil, show VERSION in minibuffer.
Return VERSION."
(when show
(message (if (listp version) (pkg-info-format-version version) version)))
version)
(defun pkg-info--read-library ()
"Read a library from minibuffer."
(completing-read "Load library: "
(apply-partially 'locate-file-completion-table
load-path
(get-load-suffixes))))
(defun pkg-info--read-function ()
"Read a function name from minibuffer."
(let ((input (completing-read "Function: " obarray #'boundp :require-match)))
(if (string= input "") nil (intern input))))
(defun pkg-info--read-package ()
"Read a package name from minibuffer."
(let* ((installed (epl-installed-packages))
(names (sort (mapcar (lambda (pkg)
(symbol-name (epl-package-name pkg)))
installed)
#'string<))
(default (car names)))
(completing-read "Installed package: " names nil 'require-match
nil nil default)))
(defun pkg-info-library-source (library)
"Get the source file of LIBRARY.
LIBRARY is either a symbol denoting a named feature, or a library
name as string.
Return the source file of LIBRARY as string."
(find-library-name (if (symbolp library) (symbol-name library) library)))
(defun pkg-info-defining-library (function)
"Get the source file of the library defining FUNCTION.
FUNCTION is a function symbol.
Return the file name of the library as string. Signal an error
if the library does not exist, or if the definition of FUNCTION
was not found."
(unless (functionp function)
(signal 'wrong-type-argument (list 'functionp function)))
(let ((library (symbol-file function 'defun)))
(unless library
(error "Can't find definition of %s" function))
library))
(defun pkg-info-x-original-version (file)
"Read the X-Original-Version header from FILE.
Return the value as version list, or return nil if FILE lacks
this header. Signal an error, if the value of the header is not
a valid version."
(let ((version-str (with-temp-buffer
(insert-file-contents file)
(lm-header "X-Original-Version"))))
(when version-str
(version-to-list version-str))))
;;;###autoload
(defun pkg-info-library-original-version (library &optional show)
"Get the original version in the header of LIBRARY.
The original version is stored in the X-Original-Version header.
This header is added by the MELPA package archive to preserve
upstream version numbers.
LIBRARY is either a symbol denoting a named feature, or a library
name as string.
If SHOW is non-nil, show the version in the minibuffer.
Return the version from the header of LIBRARY as list. Signal an
error if the LIBRARY was not found or had no X-Original-Version
header.
See Info node `(elisp)Library Headers' for more information
about library headers."
(interactive (list (pkg-info--read-library) t))
(let ((version (pkg-info-x-original-version
(pkg-info-library-source library))))
(if version
(pkg-info--show-version-and-return version show)
(error "Library %s has no original version" library))))
;;;###autoload
(defun pkg-info-library-version (library &optional show)
"Get the version in the header of LIBRARY.
LIBRARY is either a symbol denoting a named feature, or a library
name as string.
If SHOW is non-nil, show the version in the minibuffer.
Return the version from the header of LIBRARY as list. Signal an
error if the LIBRARY was not found or had no proper header.
See Info node `(elisp)Library Headers' for more information
about library headers."
(interactive (list (pkg-info--read-library) t))
(let* ((source (pkg-info-library-source library))
(version (epl-package-version (epl-package-from-file source))))
(pkg-info--show-version-and-return version show)))
;;;###autoload
(defun pkg-info-defining-library-original-version (function &optional show)
"Get the original version of the library defining FUNCTION.
The original version is stored in the X-Original-Version header.
This header is added by the MELPA package archive to preserve
upstream version numbers.
If SHOW is non-nil, show the version in mini-buffer.
This function is mainly intended to find the version of a major
or minor mode, i.e.
(pkg-info-defining-library-version 'flycheck-mode)
Return the version of the library defining FUNCTION. Signal an
error if FUNCTION is not a valid function, if its defining
library was not found, or if the library had no proper version
header."
(interactive (list (pkg-info--read-function) t))
(pkg-info-library-original-version (pkg-info-defining-library function) show))
;;;###autoload
(defun pkg-info-defining-library-version (function &optional show)
"Get the version of the library defining FUNCTION.
If SHOW is non-nil, show the version in mini-buffer.
This function is mainly intended to find the version of a major
or minor mode, i.e.
(pkg-info-defining-library-version 'flycheck-mode)
Return the version of the library defining FUNCTION. Signal an
error if FUNCTION is not a valid function, if its defining
library was not found, or if the library had no proper version
header."
(interactive (list (pkg-info--read-function) t))
(pkg-info-library-version (pkg-info-defining-library function) show))
;;;###autoload
(defun pkg-info-package-version (package &optional show)
"Get the version of an installed PACKAGE.
If SHOW is non-nil, show the version in the minibuffer.
Return the version as list, or nil if PACKAGE is not installed."
(interactive (list (pkg-info--read-package) t))
(let* ((name (if (stringp package) (intern package) package))
(package (car (epl-find-installed-packages name))))
(unless package
(error "Can't find installed package %s" name))
(pkg-info--show-version-and-return (epl-package-version package) show)))
;;;###autoload
(defun pkg-info-version-info (library &optional package show)
"Obtain complete version info for LIBRARY and PACKAGE.
LIBRARY is a symbol denoting a named feature, or a library name
as string. PACKAGE is a symbol denoting an ELPA package. If
omitted or nil, default to LIBRARY.
If SHOW is non-nil, show the version in the minibuffer.
When called interactively, prompt for LIBRARY. When called
interactively with prefix argument, prompt for PACKAGE as well.
Return a string with complete version information for LIBRARY.
This version information contains the version from the headers of
LIBRARY, and the version of the installed PACKAGE, the LIBRARY is
part of. If PACKAGE is not installed, or if the PACKAGE version
is the same as the LIBRARY version, do not include a package
version."
(interactive (list (pkg-info--read-library)
(when current-prefix-arg
(pkg-info--read-package))
t))
(let* ((package (or package (if (stringp library) (intern library) library)))
(orig-version (condition-case nil
(pkg-info-library-original-version library)
(error nil)))
;; If we have X-Original-Version, we assume that MELPA replaced the
;; library version with its generated version, so we use the
;; X-Original-Version header instead, and ignore the library version
;; header
(lib-version (or orig-version (pkg-info-library-version library)))
(pkg-version (condition-case nil
(pkg-info-package-version package)
(error nil)))
(version (if (and pkg-version
(not (version-list-= lib-version pkg-version)))
(format "%s (package: %s)"
(pkg-info-format-version lib-version)
(pkg-info-format-version pkg-version))
(pkg-info-format-version lib-version))))
(pkg-info--show-version-and-return version show)))
(defconst pkg-info-melpa-recipe-url "http://melpa.org/recipes.json"
"The URL from which to fetch MELPA recipes.")
(defvar pkg-info-melpa-recipes nil
"An alist of MELPA recipes.")
(defun pkg-info-retrieve-melpa-recipes ()
"Retrieve MELPA recipes from MELPA archive."
(let ((buffer (url-retrieve-synchronously pkg-info-melpa-recipe-url)))
(with-current-buffer buffer
(unwind-protect
(let ((response-code (url-http-parse-response)))
(unless (equal response-code 200)
(error "Failed to retrieve MELPA recipes from %s (code %s)"
pkg-info-melpa-recipe-url response-code))
(goto-char url-http-end-of-headers)
(json-read))
(when (and buffer (buffer-live-p buffer))
(kill-buffer buffer))))))
(defun pkg-info-get-melpa-recipes ()
"Get MELPA recipes."
(setq pkg-info-melpa-recipes
(or pkg-info-melpa-recipes
(pkg-info-retrieve-melpa-recipes))))
(defun pkg-info-get-melpa-recipe (package)
"Get the MELPA recipe for PACKAGE.
Return nil if PACKAGE is not on MELPA."
(cdr (assq package (pkg-info-get-melpa-recipes))))
(defun pkg-info-get-melpa-fetcher (package)
"Get the MELPA fetcher for PACKAGE."
(cdr (assq 'fetcher (pkg-info-get-melpa-recipe package))))
(defun pkg-info-wiki-package-p (package)
"Determine whether PACKAGE is build from the EmacsWiki."
(equal (pkg-info-get-melpa-fetcher package) "wiki"))
(provide 'pkg-info)
;; Local Variables:
;; indent-tabs-mode: nil
;; coding: utf-8
;; End:
;;; pkg-info.el ends here

Binary file not shown.

11
init.el
View file

@ -2,18 +2,25 @@
; Load files matching lisp.d/*.el
;
;; Added by Package.el. This must come before configurations of
;; installed packages. Don't delete this line. If you don't want it,
;; just comment it out by adding a semicolon to the start of the line.
;; You may delete these explanatory comments.
(package-initialize)
(mapc
(lambda (path) (load-file path))
(file-expand-wildcards "~/.emacs.d/lisp.d/*.el" t)
)
;END;
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(org-agenda-files (quote ("~/Documents/planning/categories/travel.org" "~/Documents/planning/categories/personal.org"))))
'(jabber-account-list (quote (("ken.maupin@animalaidpdx.org" (:network-server . "talk.google.com") (:connection-type . starttls)) ("ken@maniaphobic.org"))))
'(starttls-program "/usr/local/bin/gnutls-cli"))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.

3
lisp.d/config,elpa.el Normal file
View file

@ -0,0 +1,3 @@
(require 'package)
(add-to-list 'package-archives
'("melpa" . "http://melpa.milkbox.net/packages/") t)

View file

@ -0,0 +1,7 @@
;________________________________________
;
;
(server-start)
;

View file

@ -0,0 +1,7 @@
;________________________________________
;
;
(ido-mode)
;

3
lisp.d/config,magit.el Normal file
View file

@ -0,0 +1,3 @@
;DISABLED;(require 'magit)
(global-set-key "\C-xgs" 'magit-status)

View file

@ -7,6 +7,13 @@
(setq
calendar-week-start-day 1
org-agenda-files
'(
"~/Documents/planning/contexts"
"~/Documents/planning/creatures"
"~/Documents/planning/projects"
"~/Documents/planning/reference"
)
org-archive-location "../archive/%s::"
org-log-done 'time
org-todo-keywords '((sequence "PENDING" "IN_PROGRESS" "DONE"))
@ -18,6 +25,6 @@
; C-c O = view the agenda
;
(global-set-key "\C-cO" 'org-agenda)
(global-set-key "\C-cO" 'org-agenda-list)
;

View file

@ -0,0 +1,8 @@
;________________________________________
; YAML mode
;
;DISABLED;(add-to-list 'load-path
;DISABLED; (expand-file-name "~/Software/Emacs/Lisp/yaml-mode/current"))
;DISABLED;(require 'yaml-mode)
;DISABLED;(add-to-list 'auto-mode-alist '("\\.yml$" . yaml-mode))

View file

@ -1,22 +0,0 @@
;
; Augment the load path
;
(mapc
(lambda (path) (add-to-list 'load-path (expand-file-name path)))
'(
"~/Software/Emacs/Lisp/scala-mode2/current"
)
)
;
; Load libraries
; Order matters
;
(mapc
(lambda (library) (require library))
'(
scala-mode2
)
)