Added emacs scripts
This commit is contained in:
659
.emacs.d/elpa/archives/gnu/archive-contents
Normal file
659
.emacs.d/elpa/archives/gnu/archive-contents
Normal file
@@ -0,0 +1,659 @@
|
||||
(1
|
||||
(ace-window .
|
||||
[(0 8 1)
|
||||
((avy
|
||||
(0 1 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 9)
|
||||
((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 3)
|
||||
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 .
|
||||
[(20150525)
|
||||
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))])
|
||||
(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"))])
|
||||
(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"))]))
|
1
.emacs.d/elpa/archives/gnu/archive-contents.signed
Normal file
1
.emacs.d/elpa/archives/gnu/archive-contents.signed
Normal file
@@ -0,0 +1 @@
|
||||
Good signature from 474F05837FBDEF9B GNU ELPA Signing Agent <elpasign@elpa.gnu.org> (trust undefined) created at 2015-05-26T11:05:02+0200 using DSA
|
4468
.emacs.d/elpa/archives/marmalade/archive-contents
Normal file
4468
.emacs.d/elpa/archives/marmalade/archive-contents
Normal file
File diff suppressed because it is too large
Load Diff
2
.emacs.d/elpa/archives/melpa-stable/archive-contents
Normal file
2
.emacs.d/elpa/archives/melpa-stable/archive-contents
Normal file
File diff suppressed because one or more lines are too long
2
.emacs.d/elpa/archives/melpa/archive-contents
Normal file
2
.emacs.d/elpa/archives/melpa/archive-contents
Normal file
File diff suppressed because one or more lines are too long
26
.emacs.d/elpa/clojure-mode-4.0.1/clojure-mode-autoloads.el
Normal file
26
.emacs.d/elpa/clojure-mode-4.0.1/clojure-mode-autoloads.el
Normal file
@@ -0,0 +1,26 @@
|
||||
;;; clojure-mode-autoloads.el --- automatically extracted autoloads
|
||||
;;
|
||||
;;; Code:
|
||||
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
|
||||
|
||||
;;;### (autoloads nil "clojure-mode" "clojure-mode.el" (21860 25961
|
||||
;;;;;; 0 0))
|
||||
;;; Generated autoloads from clojure-mode.el
|
||||
|
||||
(autoload 'clojure-mode "clojure-mode" "\
|
||||
Major mode for editing Clojure code.
|
||||
|
||||
\\{clojure-mode-map}
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.\\(clj[sx]?\\|dtm\\|edn\\)\\'" . clojure-mode))
|
||||
|
||||
;;;***
|
||||
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; End:
|
||||
;;; clojure-mode-autoloads.el ends here
|
11
.emacs.d/elpa/clojure-mode-4.0.1/clojure-mode-autoloads.el~
Normal file
11
.emacs.d/elpa/clojure-mode-4.0.1/clojure-mode-autoloads.el~
Normal file
@@ -0,0 +1,11 @@
|
||||
;;; clojure-mode-autoloads.el --- automatically extracted autoloads
|
||||
;;
|
||||
;;; Code:
|
||||
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
|
||||
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; End:
|
||||
;;; clojure-mode-autoloads.el ends here
|
1
.emacs.d/elpa/clojure-mode-4.0.1/clojure-mode-pkg.el
Normal file
1
.emacs.d/elpa/clojure-mode-4.0.1/clojure-mode-pkg.el
Normal file
@@ -0,0 +1 @@
|
||||
(define-package "clojure-mode" "4.0.1" "Major mode for Clojure code" '((emacs "24.1")) :url "http://github.com/clojure-emacs/clojure-mode" :keywords '("languages" "clojure" "clojurescript" "lisp"))
|
BIN
.emacs.d/elpa/clojure-mode-4.0.1/clojure-mode-pkg.elc
Normal file
BIN
.emacs.d/elpa/clojure-mode-4.0.1/clojure-mode-pkg.elc
Normal file
Binary file not shown.
1080
.emacs.d/elpa/clojure-mode-4.0.1/clojure-mode.el
Normal file
1080
.emacs.d/elpa/clojure-mode-4.0.1/clojure-mode.el
Normal file
File diff suppressed because it is too large
Load Diff
BIN
.emacs.d/elpa/clojure-mode-4.0.1/clojure-mode.elc
Normal file
BIN
.emacs.d/elpa/clojure-mode-4.0.1/clojure-mode.elc
Normal file
Binary file not shown.
BIN
.emacs.d/elpa/gnupg/pubring.gpg
Normal file
BIN
.emacs.d/elpa/gnupg/pubring.gpg
Normal file
Binary file not shown.
0
.emacs.d/elpa/gnupg/pubring.gpg~
Normal file
0
.emacs.d/elpa/gnupg/pubring.gpg~
Normal file
0
.emacs.d/elpa/gnupg/secring.gpg
Normal file
0
.emacs.d/elpa/gnupg/secring.gpg
Normal file
BIN
.emacs.d/elpa/gnupg/trustdb.gpg
Normal file
BIN
.emacs.d/elpa/gnupg/trustdb.gpg
Normal file
Binary file not shown.
438
.emacs.d/elpa/haskell-mode-13.12/NEWS
Normal file
438
.emacs.d/elpa/haskell-mode-13.12/NEWS
Normal file
@@ -0,0 +1,438 @@
|
||||
Haskell Mode NEWS -*- org -*-
|
||||
|
||||
This file uses Org mode. Some useful (default) key-bindings:
|
||||
- Use "C-c C-n"/"C-c C-p" to jump to next/prev heading
|
||||
- Use "<tab>" to expand/collapse nodes
|
||||
- Use "<backtab>" to cycle visibility of all nodes
|
||||
- Use "C-c C-o" to open links
|
||||
|
||||
* Changes in 13.12
|
||||
|
||||
- Added haskell-bot.el
|
||||
|
||||
- Added support for cabal repl build targets
|
||||
|
||||
- Automatically add import lines via Hoogle
|
||||
|
||||
- Automatically add package to cabal file
|
||||
|
||||
- Added w3m-haddock.el
|
||||
|
||||
- Added debugger mode
|
||||
|
||||
- Added preliminary :present support
|
||||
|
||||
- Added haskell-sort-imports
|
||||
|
||||
- Added haskell-complete-module
|
||||
|
||||
- Support if and multi-way if in indentation
|
||||
|
||||
- Add support to generate tags on windows
|
||||
|
||||
- Add haskell-language-extensions variable
|
||||
|
||||
- Improve haskell-simple-indent mode
|
||||
|
||||
- Improve test cases
|
||||
|
||||
* Changes in 13.10
|
||||
|
||||
- Small fix for haskell-simple-indent: Certain indentation situations
|
||||
cause valname-string to be nil, which haskell-trim did not handle
|
||||
gracefully (naturally, since nil != "").
|
||||
|
||||
- Luke Hoersten's Shnippet merged in under snippets/.
|
||||
|
||||
- haskell-presentation-mode is now a haskell-mode derived mode.
|
||||
|
||||
- Small improvement to haskell-process-do-info (works on constructors
|
||||
now and underscored names).
|
||||
|
||||
- Add haskell-indent-spaces configuration variable.
|
||||
|
||||
- The command string to run cabal commands is slightly more
|
||||
configurable. See: C-h f haskell-process-do-cabal-format-string
|
||||
|
||||
* Changes in 13.8
|
||||
|
||||
See also [[https://github.com/haskell/haskell-mode/compare/v13.07...v13.08][detailed Git history]].
|
||||
|
||||
- Make `haskell-simple-indent-mode' a proper minor mode with `SInd` as
|
||||
mode-line lighter
|
||||
|
||||
- Support popular "λ> " prompt in inf-haskell by default
|
||||
|
||||
- Hide internal `*print-haskell-mode*' buffers
|
||||
(used when `haskell-interactive-mode-eval-mode' is active)
|
||||
|
||||
- Add tab-completion support for haskell-interactive-mode
|
||||
(requires `:complete' command support in GHCi)
|
||||
|
||||
- Add support to `haskell-process-do-info` to perform `:browse!` query
|
||||
on module name when called on import statement line
|
||||
|
||||
- `haskell-decl-scan-mode':
|
||||
- New customize group `haskell-decl-scan'
|
||||
- New flag `haskell-decl-scan-bindings-as-variables' for controlling
|
||||
whether to put value bindings into the "Variables" category.
|
||||
- New flag `haskell-decl-scan-add-to-menubar' for controlling
|
||||
whether to add "Declarations" menu entry to menu bar.
|
||||
- New manual section node `(haskell-mode)haskell-decl-scan-mode'
|
||||
|
||||
- Add support for [[http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#lambda-case][LambdaCase]] syntax extension to `haskell-indentation`
|
||||
|
||||
- Change `haskell-indentation-mode' to never jump back a whole line
|
||||
when pressing DEL. The old behavior can be restored by setting
|
||||
`haskell-indentation-delete-backward-jump-line' to t
|
||||
|
||||
- New convenience function `haskell-cabal-visit-file' for locating and
|
||||
visiting most likely `.cabal` file associated with current buffer
|
||||
|
||||
- Add support for [[http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#package-import][PackageImports]] and [[http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#safe-imports-ext][SafeHaskell]] syntax extensions to
|
||||
`haskell-decl-scan-mode' parser
|
||||
|
||||
- Add `turn-{on,off}-haskell-doc' commands as aliases for the existing
|
||||
`turn-{on,off}-haskell-doc-mode' commands
|
||||
|
||||
- Add support for "cabal repl" process type to `haskell-interactive-mode'
|
||||
|
||||
- Add new Haskell compilation sub-mode and associated `haskell-compile'
|
||||
command
|
||||
|
||||
* Changes in 13.7
|
||||
|
||||
See also [[https://github.com/haskell/haskell-mode/compare/v13.06...v13.07][detailed Git history]].
|
||||
|
||||
- Convert NEWS (this file) to Org mode style and include NEWS file in
|
||||
package and add command for visiting NEWS file
|
||||
(M-x haskell-mode-view-news)
|
||||
|
||||
- Officially drop support for versions prior to Emacs 23
|
||||
|
||||
- New work-in-progress Info manual for haskell-mode
|
||||
|
||||
- Remove deprecated `haskell-{hugs,ghci}' modules
|
||||
|
||||
- Font-locking changes:
|
||||
- Remove deprecated `turn-on-haskell-font-lock` function
|
||||
- Improve font-locking of type-signatures in presence of newlines
|
||||
- Use `font-lock-preprocessor-face' instead of the previously used
|
||||
`font-lock-warning-face` for CPP directives
|
||||
- Use `font-lock-warning-face` instead of the previously used
|
||||
`font-lock-preprocessor-face` for Git merge conflict annotations.
|
||||
|
||||
- Improvements to `haskell-move-nested' module:
|
||||
- Add support for operating on active regions
|
||||
- New interactive commands `haskell-move-nested-{left,right}` which
|
||||
support numeric prefix arguments for controlling the amount of
|
||||
shifting to apply.
|
||||
|
||||
- Add `haskell-unicode-input-method.el` to distribution
|
||||
(enable with `turn-on-haskell-unicode-input-method`)
|
||||
|
||||
- Fix all byte-compilation warnings
|
||||
|
||||
- Build-system:
|
||||
- For in-place installation, `haskell-site-file.el' is renamed
|
||||
to `haskell-mode-autoloads.el`
|
||||
- Auto-generate ELPA compatible README file by extracting header of
|
||||
haskell-mode.el
|
||||
- New "make check" target
|
||||
- Add Travis-CI build jobs for testing byte-compilation with
|
||||
multiple Emacs versions
|
||||
|
||||
- Reorganize customize settings
|
||||
- Add new convenience function for browsing all Haskell Mode settings
|
||||
(M-x haskell-customize)
|
||||
- Add `:link' keywords pointing to the new Info manual
|
||||
- Add `:group' keywords to modes to make (M-x customize-mode) work
|
||||
- Create new customization groups `haskell-interactive' and `inferior-haskell'
|
||||
to clean up namespace
|
||||
- Create new customization group `ghc-core` containing the two new
|
||||
customization variables `ghc-core-program` and `ghc-core-program-args`.
|
||||
|
||||
- Improvements to haskell-interactive-mode
|
||||
- Add support for deleting compile messages superseded by recompile/reloads
|
||||
(M-x customize-variable RET haskell-interactive-mode-delete-superseded-errors)
|
||||
- Fix `C-u M-x haskell-process-do-type` inserting bad signatures
|
||||
- Integrate with Emacs' `next-error` subsystem
|
||||
- Add "C-c C-f" binding to REPL keymap for enabling `next-error-follow-minor-mode'
|
||||
- Add support for `-ferror-spans`-style compile messages
|
||||
- Add `-ferror-spans` as default for `haskell-process-args-ghci`
|
||||
- Add optional argument to
|
||||
`haskell-session-{all,installed,project}-modules' to suppress
|
||||
session-creation. This is useful for yasnippet usage, see commit
|
||||
517fd7e for an example.
|
||||
- Change default for `haskell-process-path-ghci` to a static "ghci"
|
||||
- Fix `haskell-interactive-switch` not selecting the REPL window
|
||||
- Make `*haskell-process-log*` buffer configurable
|
||||
(controlled via new `haskell-process-log` customize option)
|
||||
|
||||
* Changes in 13.6
|
||||
|
||||
See also [[https://github.com/haskell/haskell-mode/compare/2_9_1...v13.06][detailed Git history]].
|
||||
|
||||
- Switch to new versioning scheme
|
||||
|
||||
- Switch to MELPA/Marmalade based packaging
|
||||
|
||||
- Cleanup/refactor build-system
|
||||
|
||||
- Enhance `M-x haskell-version` to report more detailed versioning
|
||||
information
|
||||
|
||||
- Make haskell-interactive-mode emulate comint/eshell history navigation
|
||||
(see commit 0e96843 for more details)
|
||||
|
||||
- Improvements to haskell-interactive-mode
|
||||
- Improve killing/restarting haskell-interactive sessions
|
||||
- Improve directory prompting and resolution
|
||||
- Fix redundant-import suggest trigger to support qualified imports
|
||||
- Detect all abbreviations of an user-inputted ":quit"
|
||||
- Fix regexps for recent GHC 7.x compiler messages
|
||||
- Customizable commandline args for GHCi
|
||||
(M-x customize-variable RET haskell-process-args-ghci)
|
||||
- New command to load or reload via prefix argument
|
||||
(M-x haskell-process-load-or-reload)
|
||||
- Fix haskell-interactive-mode prompt detection
|
||||
- Add cabal-ghci as supported process mode
|
||||
- Add a customization option for the visibility of multi-line errors
|
||||
(M-x customize-variable RET haskell-interactive-mode-hide-multi-line-errors)
|
||||
|
||||
- Add forward declarations to reduce Elisp bytecompile warnings
|
||||
|
||||
- Improvements to `haskell-indentation`
|
||||
- Add support for the UnicodeSyntax tokens `→`, `←`, and `∷`.
|
||||
- Indent "=" following data/type/newtype declarations.
|
||||
- Align "->"/"→" arrows in types under "::"/"∷"
|
||||
- Make customizable whether "<backspace>" deletes indentation too
|
||||
(via `haskell-indentation-delete-backward-indentation` and
|
||||
`haskell-indentation-delete-indentation`)
|
||||
- Properly indent 'rec' keyword, same as 'mdo'
|
||||
- Minor optimizations.
|
||||
|
||||
- Add support for "'"-prefixed constructors (-> DataKinds) to font-locking
|
||||
|
||||
- New experimental haskell session menu mode (M-x haskell-menu)
|
||||
|
||||
- Various minor cleanups/fixes/improvements...
|
||||
|
||||
* Changes in 2.9.1
|
||||
|
||||
See also [[https://github.com/haskell/haskell-mode/compare/2_9_0...2_9_1][detailed Git history]].
|
||||
|
||||
- Bugfix release adding missing autoload declaration
|
||||
|
||||
* Changes in 2.9.0
|
||||
|
||||
See also [[https://github.com/haskell/haskell-mode/compare/2_8_0...2_9_0][detailed Git history]].
|
||||
|
||||
- This is the first release after haskell-mode was migrated to GitHub
|
||||
|
||||
- New experimental `haskell-interactive-mode' module implementing a
|
||||
new REPL interaction mode for GHCi sessions to eventually replace
|
||||
the existing "inf-haskell" mode.
|
||||
|
||||
- New `haskell-process-cabal' command for interaction with cabal-install
|
||||
|
||||
- New `haskell-checkers' module
|
||||
|
||||
- Update haskell-cabal-mode font-lock keywords
|
||||
|
||||
- Improve scrolling of hoogle output (haskell-mode.el)
|
||||
|
||||
- Derive `haskell-mode` from `prog-mode` for Emacs 24+
|
||||
|
||||
- Add new binding for "<backtab>" to haskell-mode's keymap which
|
||||
unindents current line
|
||||
|
||||
- New modules `haskell-navigate-imports`, `haskell-sort-imports' and
|
||||
`haskell-align-imports' for operating on module import lines in
|
||||
Haskell source code
|
||||
|
||||
- Add new binding for "C-c C-." to haskell-mode's keymap to sort and
|
||||
realign Haskell module imports
|
||||
|
||||
- Add new binding for "C-c i" to haskell-mode's keymap to jump back and
|
||||
forth from/to the current Haskell module's module import section.
|
||||
|
||||
- New `inferior-haskell-kind' function for querying kind via GHCi's ":kind"
|
||||
|
||||
- New `inferior-haskell-send-decl' for sending declarations to GHCi
|
||||
(bound to "C-x C-d" by default)
|
||||
|
||||
- Add new `haskell-doc-use-inf-haskell` customization variable
|
||||
|
||||
- Add support for bird-style literate haskell editing and a new
|
||||
related customization variable
|
||||
`haskell-indentation-birdtrack-extra-space'
|
||||
|
||||
- Font locking improvements
|
||||
- Add support for Git's merge annotation
|
||||
(with `font-lock-preprocessor-face')
|
||||
- Improve `import', `foreign import' and `foreign export' font
|
||||
locking
|
||||
- Add support for `rec', `proc' and `mdo` as keywords
|
||||
- Make whitespace within `-- |' and `{- |' optional when possible
|
||||
|
||||
- New `haskell-move-nested` module providing utilities for
|
||||
interactively {in,de}denting nested "hanging" blocks.
|
||||
|
||||
- Add stylish-haskell support
|
||||
(enable via `haskell-stylish-on-save` customization variable)
|
||||
|
||||
- Add support for generating tags on save
|
||||
(enable via `haskell-tags-on-save' customization variable)
|
||||
|
||||
- Set sensible dabbrev defaults in haskell-mode
|
||||
|
||||
- Added `SCC` pragma insert/delete commands
|
||||
(`haskell-mode-insert-scc-at-point` and `haskell-mode-kill-scc-at-point')
|
||||
|
||||
- New experimental `haskell-mode-contextual-space' command
|
||||
|
||||
- And a couple more cleanups/fixes/improvements...
|
||||
|
||||
* Changes in 2.8.0 (since 2.7.0)
|
||||
|
||||
See also [[https://github.com/haskell/haskell-mode/compare/2_7_0...2_8_0][detailed Git history]].
|
||||
|
||||
- Minimal indentation support for arrow syntax
|
||||
|
||||
- Avoid opening a new inf-haskell window if one is already visible.
|
||||
Windows on other virtual desktops or iconified frames don't count.
|
||||
|
||||
- Force comint-process-echoes to nil
|
||||
|
||||
- Autolaunch haskell-mode for files starting with #!/usr/bin/runghc
|
||||
and similar
|
||||
|
||||
- Added minimal major mode for parsing GHC core files, courtesy of Johan Tibell.
|
||||
There is a corresponding Haskell menu entry.
|
||||
|
||||
- Allow configuration of where-clause indentation; M-x customize-group
|
||||
haskell-indentation.
|
||||
|
||||
* Changes since 2.6.4
|
||||
|
||||
- fill-paragraph (M-q) now only affects comments, and correctly
|
||||
handles Haddock commentary. adaptive-fill-mode is turned off, as it
|
||||
was interfering.
|
||||
|
||||
- Yet more unicode symbols
|
||||
|
||||
- Better support for unicode encoding of haskell source files
|
||||
|
||||
- mdo correctly indented
|
||||
|
||||
- Indentation fixes, fixes to the fixes, and fixes to the fixes to the
|
||||
fixes
|
||||
|
||||
- New command: M-x haskell-check, calls (by default) hlint on the
|
||||
current file. Also bound to C-c C-v.
|
||||
|
||||
You can also use the flymake minor mode with this.
|
||||
|
||||
* Changes since 2.5.1
|
||||
|
||||
- Parser corrections for haskell-indentation and haskell-decl-scan
|
||||
|
||||
- haskell-indentation: Pressing tab in the rightmost position now
|
||||
moves to the leftmost, by default with a warning.
|
||||
|
||||
- Typo fix: One haskell-indentation variable had ended up in the
|
||||
haskell-ntation customize group.
|
||||
|
||||
- haskell-hoogle aliased to hoogle, haskell-hayoo aliased to hayoo
|
||||
|
||||
- Courtesy of Alex Ott:
|
||||
- Additional unicode symbols for font-lock-symbols: () == /= >= <= !! && || sqrt
|
||||
- M-x haskell-hayoo search added, opens using browse-url
|
||||
- Bug-fix for inferior-haskell-type
|
||||
|
||||
- If haskell-indentation errors out, it now fail-safes to inserting
|
||||
a literal newline or deleting one character, for return and
|
||||
backspace respectively.
|
||||
|
||||
* Changes since 2.4:
|
||||
|
||||
- haskell-indentation, a new minor mode for indentation.
|
||||
|
||||
* Changes since 2.3:
|
||||
|
||||
- Update license to GPLv3.
|
||||
|
||||
- New derived major mode for .hsc files.
|
||||
|
||||
- Removed the C-c C-r binding to reload a file. You can still call
|
||||
inferior-haskell-reload-file (and/or bind it to your favorite key,
|
||||
including C-c C-r) or you can now use C-u C-c C-l.
|
||||
|
||||
- C-c C-d looks up the symbol at point in the Haddock docs.
|
||||
|
||||
- Haddock comments are highlighted with font-lock-doc-face if it exists.
|
||||
|
||||
- Use `tex' rather than `latex' for haskell-literate.
|
||||
|
||||
- inf-haskell.el tries to find the root of the module hierarchy to determine
|
||||
the root of a project (either by looking for a Cabal file or relying on
|
||||
the `module' declaration line). If all works well, this will make C-c C-l
|
||||
automatically switch to the root dir, so that dependencies in other
|
||||
directories are automatically found. If it doesn't, complain and/or set
|
||||
inferior-haskell-find-project-root to nil.
|
||||
|
||||
- The new command haskell-hoogle helps you query Hoogle from Emacs.
|
||||
|
||||
* Changes since 2.2:
|
||||
|
||||
- Trivial support for Cabal package description files.
|
||||
|
||||
- Minor bug fixes.
|
||||
|
||||
* Changes since 2.1:
|
||||
|
||||
- There are now commands to find type and info of identifiers by querying an
|
||||
inferior haskell process. Available under C-c C-t, C-c C-i, and C-c M-.
|
||||
|
||||
- Indentation now looks back further, until a line that has no indentation.
|
||||
To recover the earlier behavior of stopping at the first empty line
|
||||
instead, configure haskell-indent-look-past-empty-line.
|
||||
|
||||
- inf-haskell can wait until a file load completes and jump directly to the
|
||||
first error, like haskell-ghci and haskell-hugs used to do. See the var
|
||||
inferior-haskell-wait-and-jump.
|
||||
|
||||
* Changes since 2.0:
|
||||
|
||||
- inf-haskell uses ghci if hugs is absent.
|
||||
|
||||
- Fix up some binding conflicts (C-c C-o in haskell-doc)
|
||||
|
||||
- Many (hopefully minor) changes to the indentation.
|
||||
|
||||
- New symbols in haskell-font-lock-symbols-alist.
|
||||
|
||||
* Changes since 1.45:
|
||||
|
||||
- keybindings C-c <char> have been replaced by C-c C-<char> so as not
|
||||
to collide with minor modes.
|
||||
|
||||
- The following modules are now automatically activated without having to
|
||||
add anything to haskell-mode-hook:
|
||||
haskell-font-lock (just turn on global-font-lock-mode).
|
||||
haskell-decl-scan (just bind `imenu' to some key).
|
||||
|
||||
- In recent Emacsen, haskell-doc hooks into eldoc-mode.
|
||||
|
||||
- haskell-hugs and haskell-ghci are superceded by inf-haskell.
|
||||
|
||||
- Indentation rules have been improved when using layout inside parens/braces.
|
||||
|
||||
- Symbols like -> and \ can be displayed as actual arrows and lambdas.
|
||||
See haskell-font-lock-symbols.
|
||||
|
||||
- Tweaks to the font-lock settings. Among other things paren-matching
|
||||
with things like \(x,y) should work correctly now.
|
||||
|
||||
- New maintainer <monnier@gnu.org>.
|
18
.emacs.d/elpa/haskell-mode-13.12/dir
Normal file
18
.emacs.d/elpa/haskell-mode-13.12/dir
Normal 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
|
||||
* Haskell Mode: (haskell-mode). Haskell Development Environment for Emacs(en)
|
122
.emacs.d/elpa/haskell-mode-13.12/ghc-core.el
Normal file
122
.emacs.d/elpa/haskell-mode-13.12/ghc-core.el
Normal file
@@ -0,0 +1,122 @@
|
||||
;;; ghc-core.el --- Syntax highlighting module for GHC Core
|
||||
|
||||
;; Copyright (C) 2010 Johan Tibell
|
||||
|
||||
;; Author: Johan Tibell <johan.tibell@gmail.com>
|
||||
|
||||
;; 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 GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
;; Boston, MA 02110-1301, USA.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Purpose:
|
||||
;;
|
||||
;; To make it easier to read GHC Core output by providing highlighting
|
||||
;; and removal of commonly ignored annotations.
|
||||
|
||||
;;; Code:
|
||||
(require 'haskell-mode)
|
||||
(require 'haskell-font-lock)
|
||||
|
||||
(defgroup ghc-core nil
|
||||
"Major mode for viewing pretty printed GHC Core output."
|
||||
:link '(custom-manual "(haskell-mode)")
|
||||
:group 'haskell
|
||||
:prefix "ghc-core-")
|
||||
|
||||
(defcustom ghc-core-program
|
||||
"ghc"
|
||||
"Name of the GHC executable (excluding any arguments)."
|
||||
:type 'string
|
||||
:group 'ghc-core)
|
||||
|
||||
(defcustom ghc-core-program-args
|
||||
'("-O2")
|
||||
"Additional options to be passed to GHC when generating core output.
|
||||
GHC (see variable `ghc-core-program') is invoked with the basic
|
||||
command line options \"-ddump-simpl -c <source-file>\"
|
||||
followed by the additional options defined here.
|
||||
|
||||
The following `-ddump-simpl` options might be of interest:
|
||||
|
||||
- `-dsuppress-all'
|
||||
- `-dsuppress-uniques'
|
||||
- `-dsuppress-idinfo'
|
||||
- `-dsuppress-module-prefixes'
|
||||
- `-dsuppress-type-signatures'
|
||||
- `-dsuppress-type-applications'
|
||||
- `-dsuppress-coercions'
|
||||
|
||||
See `M-x manual-entry RET ghc' for more details."
|
||||
:type '(repeat (string :tag "Argument"))
|
||||
:group 'ghc-core)
|
||||
|
||||
(define-obsolete-variable-alias 'ghc-core-create-options 'ghc-core-program-args
|
||||
"haskell-mode 13.7")
|
||||
|
||||
(defun ghc-core-clean-region (start end)
|
||||
"Remove commonly ignored annotations and namespace prefixes
|
||||
in the region between START and END."
|
||||
(interactive "r")
|
||||
(save-restriction
|
||||
(narrow-to-region start end)
|
||||
(goto-char (point-min))
|
||||
(while (search-forward-regexp "GHC\.[^\.]*\." nil t)
|
||||
(replace-match "" nil t))
|
||||
(goto-char (point-min))
|
||||
(while (flush-lines "^ *GblId *$" nil))
|
||||
(goto-char (point-min))
|
||||
(while (flush-lines "^ *LclId *$" nil))
|
||||
(goto-char (point-min))
|
||||
(while (flush-lines (concat "^ *\\[\\(?:Arity [0-9]+\\|NoCafRefs\\|"
|
||||
"Str: DmdType\\|Worker \\)"
|
||||
"\\([^]]*\\n?\\).*\\] *$") nil))
|
||||
(goto-char (point-min))
|
||||
(while (search-forward "Main." nil t) (replace-match "" nil t))))
|
||||
|
||||
(defun ghc-core-clean-buffer ()
|
||||
"Remove commonly ignored annotations and namespace prefixes
|
||||
in the current buffer."
|
||||
(interactive)
|
||||
(ghc-core-clean-region (point-min) (point-max)))
|
||||
|
||||
;;;###autoload
|
||||
(defun ghc-core-create-core ()
|
||||
"Compile and load the current buffer as tidy core."
|
||||
(interactive)
|
||||
(save-buffer)
|
||||
(let* ((core-buffer (generate-new-buffer "ghc-core"))
|
||||
(neh (lambda () (kill-buffer core-buffer))))
|
||||
(add-hook 'next-error-hook neh)
|
||||
(apply #'call-process ghc-core-program nil core-buffer nil
|
||||
"-ddump-simpl" "-c" (buffer-file-name) ghc-core-program-args)
|
||||
(display-buffer core-buffer)
|
||||
(with-current-buffer core-buffer
|
||||
(ghc-core-mode))
|
||||
(remove-hook 'next-error-hook neh)))
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.hcr\\'" . ghc-core-mode))
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.dump-simpl\\'" . ghc-core-mode))
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode ghc-core-mode haskell-mode "GHC-Core"
|
||||
"Major mode for GHC Core files.")
|
||||
|
||||
(provide 'ghc-core)
|
||||
;;; ghc-core.el ends here
|
BIN
.emacs.d/elpa/haskell-mode-13.12/ghc-core.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/ghc-core.elc
Normal file
Binary file not shown.
68
.emacs.d/elpa/haskell-mode-13.12/ghci-script-mode.el
Normal file
68
.emacs.d/elpa/haskell-mode-13.12/ghci-script-mode.el
Normal file
@@ -0,0 +1,68 @@
|
||||
;;; ghci-script-mode.el --- GHCi scripts major mode
|
||||
|
||||
;; Copyright (c) 2014 Chris Done. All rights reserved.
|
||||
|
||||
;; 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'haskell)
|
||||
|
||||
(defvar ghci-script-mode-keywords
|
||||
;; The comment syntax can't be described simply in syntax-table.
|
||||
;; We could use font-lock-syntactic-keywords, but is it worth it?
|
||||
'(("^[ \t]*--.*" . font-lock-comment-face)
|
||||
("^ *\\([^ \t:]+\\):" (1 font-lock-keyword-face))
|
||||
("^:[a-z{]+ *\\+" . font-lock-keyword-face)
|
||||
("^:[a-z{]+ " . font-lock-keyword-face)))
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode ghci-script-mode text-mode "GHCi-Script"
|
||||
"Major mode for working with .ghci files."
|
||||
(set (make-local-variable 'adaptive-fill-mode) nil)
|
||||
(set (make-local-variable 'comment-start) "-- ")
|
||||
(set (make-local-variable 'comment-padding) 0)
|
||||
(set (make-local-variable 'comment-start-skip) "[-{]-[ \t]*")
|
||||
(set (make-local-variable 'comment-end) "")
|
||||
(set (make-local-variable 'comment-end-skip) "[ \t]*\\(-}\\|\\s>\\)")
|
||||
(set (make-local-variable 'indent-line-function) 'haskell-mode-suggest-indent-choice)
|
||||
(set (make-local-variable 'font-lock-defaults)
|
||||
'(ghci-script-mode-keywords t t nil nil))
|
||||
(set (make-local-variable 'indent-tabs-mode) nil)
|
||||
(set (make-local-variable 'tab-width) 8)
|
||||
(when (boundp 'electric-indent-inhibit)
|
||||
(setq electric-indent-inhibit t))
|
||||
(set (make-local-variable 'dabbrev-case-fold-search) nil)
|
||||
(set (make-local-variable 'dabbrev-case-distinction) nil)
|
||||
(set (make-local-variable 'dabbrev-case-replace) nil)
|
||||
(set (make-local-variable 'dabbrev-abbrev-char-regexp) "\\sw\\|[.]")
|
||||
(setq haskell-literate nil))
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.ghci\\'" . ghci-script-mode))
|
||||
|
||||
(define-key ghci-script-mode-map (kbd "C-c C-l") 'ghci-script-mode-load)
|
||||
|
||||
(defun ghci-script-mode-load ()
|
||||
(interactive)
|
||||
"Load the current script file into the GHCi session."
|
||||
(let ((buffer (haskell-session-interactive-buffer (haskell-session)))
|
||||
(filename (buffer-file-name)))
|
||||
(save-buffer)
|
||||
(with-current-buffer buffer
|
||||
(set-marker haskell-interactive-mode-prompt-start (point-max))
|
||||
(haskell-interactive-mode-run-expr
|
||||
(concat ":script " filename)))))
|
||||
|
||||
(provide 'ghci-script-mode)
|
BIN
.emacs.d/elpa/haskell-mode-13.12/ghci-script-mode.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/ghci-script-mode.elc
Normal file
Binary file not shown.
230
.emacs.d/elpa/haskell-mode-13.12/haskell-align-imports.el
Normal file
230
.emacs.d/elpa/haskell-mode-13.12/haskell-align-imports.el
Normal file
@@ -0,0 +1,230 @@
|
||||
;;; haskell-align-imports.el --- Align the import lines in a Haskell file
|
||||
|
||||
;; Copyright (C) 2010 Chris Done
|
||||
|
||||
;; Author: Chris Done <chrisdone@gmail.com>
|
||||
|
||||
;; 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:
|
||||
|
||||
;; Consider the following imports list:
|
||||
;;
|
||||
;; import One
|
||||
;; import Two as A
|
||||
;; import qualified Three
|
||||
;; import qualified Four as PRELUDE
|
||||
;; import Five (A)
|
||||
;; import Six (A,B)
|
||||
;; import qualified Seven (A,B)
|
||||
;; import "abc" Eight
|
||||
;; import "abc" Nine as TWO
|
||||
;; import qualified "abc" Ten
|
||||
;; import qualified "defg" Eleven as PRELUDE
|
||||
;; import "barmu" Twelve (A)
|
||||
;; import "zotconpop" Thirteen (A,B)
|
||||
;; import qualified "z" Fourteen (A,B)
|
||||
;; import Fifteen hiding (A)
|
||||
;; import Sixteen as TWO hiding (A)
|
||||
;; import qualified Seventeen hiding (A)
|
||||
;; import qualified Eighteen as PRELUDE hiding (A)
|
||||
;; import "abc" Nineteen hiding (A)
|
||||
;; import "abc" Twenty as TWO hiding (A)
|
||||
;;
|
||||
;; When haskell-align-imports is run within the same buffer, the
|
||||
;; import list is transformed to:
|
||||
;;
|
||||
;; import "abc" Eight
|
||||
;; import qualified Eighteen as PRELUDE hiding (A)
|
||||
;; import qualified "defg" Eleven as PRELUDE
|
||||
;; import Fifteen hiding (A)
|
||||
;; import Five (A)
|
||||
;; import qualified Four as PRELUDE
|
||||
;; import qualified "z" Fourteen (A,B)
|
||||
;; import "abc" Nine as TWO
|
||||
;; import "abc" Nineteen hiding (A)
|
||||
;; import One
|
||||
;; import qualified Seven (A,B)
|
||||
;; import qualified Seventeen hiding (A)
|
||||
;; import Six (A,B)
|
||||
;; import Sixteen as TWO hiding (A)
|
||||
;; import qualified "abc" Ten
|
||||
;; import "zotconpop" Thirteen (A,B)
|
||||
;; import qualified Three
|
||||
;; import "barmu" Twelve (A)
|
||||
;; import "abc" Twenty as TWO hiding (A)
|
||||
;; import Two as A
|
||||
;;
|
||||
;; If you want everything after module names to be padded out, too,
|
||||
;; customize `haskell-align-imports-pad-after-name', and you'll get:
|
||||
;;
|
||||
;; import One
|
||||
;; import Two as A
|
||||
;; import qualified Three
|
||||
;; import qualified Four as PRELUDE
|
||||
;; import Five (A)
|
||||
;; import Six (A,B)
|
||||
;; import qualified Seven (A,B)
|
||||
;; import "abc" Eight
|
||||
;; import "abc" Nine as TWO
|
||||
;; import qualified "abc" Ten
|
||||
;; import qualified "defg" Eleven as PRELUDE
|
||||
;; import "barmu" Twelve (A)
|
||||
;; import "zotconpop" Thirteen (A,B)
|
||||
;; import qualified "z" Fourteen (A,B)
|
||||
;; import Fifteen hiding (A)
|
||||
;; import Sixteen as TWO hiding (A)
|
||||
;; import qualified Seventeen hiding (A)
|
||||
;; import qualified Eighteen as PRELUDE hiding (A)
|
||||
;; import "abc" Nineteen hiding (A)
|
||||
;; import "abc" Twenty as TWO hiding (A)
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'cl-lib)
|
||||
|
||||
(defvar haskell-align-imports-regexp
|
||||
(concat "^\\(import[ ]+\\)"
|
||||
"\\(qualified \\)?"
|
||||
"[ ]*\\(\"[^\"]*\" \\)?"
|
||||
"[ ]*\\([A-Za-z0-9_.']+\\)"
|
||||
"[ ]*\\([ ]*as [A-Z][^ ]*\\)?"
|
||||
"[ ]*\\((.*)\\)?"
|
||||
"\\([ ]*hiding (.*)\\)?"
|
||||
"\\( -- .*\\)?[ ]*$")
|
||||
"Regex used for matching components of an import.")
|
||||
|
||||
(defcustom haskell-align-imports-pad-after-name
|
||||
nil
|
||||
"Pad layout after the module name also."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-align-imports ()
|
||||
"Align all the imports in the buffer."
|
||||
(interactive)
|
||||
(when (haskell-align-imports-line-match)
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(let* ((imports (haskell-align-imports-collect))
|
||||
(padding (haskell-align-imports-padding imports)))
|
||||
(mapc (lambda (x)
|
||||
(goto-char (cdr x))
|
||||
(delete-region (point) (line-end-position))
|
||||
(insert (haskell-align-imports-chomp
|
||||
(haskell-align-imports-fill padding (car x)))))
|
||||
imports))))
|
||||
nil)
|
||||
|
||||
(defun haskell-align-imports-line-match ()
|
||||
"Try to match the current line as a regexp."
|
||||
(let ((line (buffer-substring-no-properties (line-beginning-position)
|
||||
(line-end-position))))
|
||||
(if (string-match "^import " line)
|
||||
line
|
||||
nil)))
|
||||
|
||||
(defun haskell-align-imports-collect ()
|
||||
"Collect a list of mark / import statement pairs."
|
||||
(let ((imports '()))
|
||||
(while (not (or (equal (point) (point-max)) (haskell-align-imports-after-imports-p)))
|
||||
(let ((line (haskell-align-imports-line-match-it)))
|
||||
(when line
|
||||
(let ((match
|
||||
(haskell-align-imports-merge-parts
|
||||
(cl-loop for i from 1 to 8
|
||||
collect (haskell-align-imports-chomp (match-string i line))))))
|
||||
(setq imports (cons (cons match (line-beginning-position))
|
||||
imports)))))
|
||||
(forward-line))
|
||||
imports))
|
||||
|
||||
(defun haskell-align-imports-merge-parts (l)
|
||||
"Merge together parts of an import statement that shouldn't be separated."
|
||||
(let ((parts (apply #'vector l))
|
||||
(join (lambda (ls)
|
||||
(cl-reduce (lambda (a b)
|
||||
(concat a
|
||||
(if (and (> (length a) 0)
|
||||
(> (length b) 0))
|
||||
" "
|
||||
"")
|
||||
b))
|
||||
ls))))
|
||||
(if haskell-align-imports-pad-after-name
|
||||
(list (funcall join (list (aref parts 0)
|
||||
(aref parts 1)
|
||||
(aref parts 2)))
|
||||
(aref parts 3)
|
||||
(funcall join (list (aref parts 4)
|
||||
(aref parts 5)
|
||||
(aref parts 6)))
|
||||
(aref parts 7))
|
||||
(list (funcall join (list (aref parts 0)
|
||||
(aref parts 1)
|
||||
(aref parts 2)))
|
||||
(funcall join (list (aref parts 3)
|
||||
(aref parts 4)
|
||||
(aref parts 5)
|
||||
(aref parts 6)
|
||||
(aref parts 7)))))))
|
||||
|
||||
(defun haskell-align-imports-chomp (str)
|
||||
"Chomp leading and tailing whitespace from STR."
|
||||
(if str
|
||||
(replace-regexp-in-string "\\(^[[:space:]\n]*\\|[[:space:]\n]*$\\)" ""
|
||||
str)
|
||||
""))
|
||||
|
||||
(defun haskell-align-imports-padding (imports)
|
||||
"Find the padding for each part of the import statements."
|
||||
(if (null imports)
|
||||
imports
|
||||
(cl-reduce (lambda (a b) (cl-mapcar #'max a b))
|
||||
(mapcar (lambda (x) (mapcar #'length (car x)))
|
||||
imports))))
|
||||
|
||||
(defun haskell-align-imports-fill (padding line)
|
||||
"Fill an import line using the padding worked out from all statements."
|
||||
(mapconcat #'identity
|
||||
(cl-mapcar (lambda (pad part)
|
||||
(if (> (length part) 0)
|
||||
(concat part (make-string (- pad (length part)) ? ))
|
||||
(make-string pad ? )))
|
||||
padding
|
||||
line)
|
||||
" "))
|
||||
|
||||
(defun haskell-align-imports-line-match-it ()
|
||||
"Try to match the current line as a regexp."
|
||||
(let ((line (buffer-substring-no-properties (line-beginning-position)
|
||||
(line-end-position))))
|
||||
(if (string-match haskell-align-imports-regexp line)
|
||||
line
|
||||
nil)))
|
||||
|
||||
(defun haskell-align-imports-after-imports-p ()
|
||||
"Are we after the imports list?"
|
||||
(save-excursion
|
||||
(goto-char (line-beginning-position))
|
||||
(not (not (search-forward-regexp "\\( = \\|\\<instance\\>\\| :: \\| ∷ \\)"
|
||||
(line-end-position) t 1)))))
|
||||
|
||||
(provide 'haskell-align-imports)
|
||||
|
||||
;;; haskell-align-imports.el ends here
|
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-align-imports.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-align-imports.elc
Normal file
Binary file not shown.
178
.emacs.d/elpa/haskell-mode-13.12/haskell-bot.el
Normal file
178
.emacs.d/elpa/haskell-mode-13.12/haskell-bot.el
Normal file
@@ -0,0 +1,178 @@
|
||||
;;; haskell-bot.el --- A Lambdabot interaction mode
|
||||
|
||||
;; Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2001 Chris Webb
|
||||
;; Copyright (C) 1998, 1999 Guy Lapalme
|
||||
|
||||
;; Keywords: inferior mode, Bot interaction mode, Haskell
|
||||
|
||||
;;; 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 GNU Emacs; see the file COPYING. If not, write to the
|
||||
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
;; Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Purpose:
|
||||
;;
|
||||
;; To send a Haskell buffer to another buffer running a Bot
|
||||
;; interpreter.
|
||||
;;
|
||||
;; This mode is derived from version 1.1 of Guy Lapalme's
|
||||
;; haskell-hugs.el, which can be obtained from:
|
||||
;;
|
||||
;; http://www.iro.umontreal.ca/~lapalme/Hugs-interaction.html
|
||||
;;
|
||||
;; This in turn was adapted from Chris Van Humbeeck's hugs-mode.el,
|
||||
;; which can be obtained from:
|
||||
;;
|
||||
;; http://www-i2.informatik.rwth-aachen.de/Forschung/FP/Haskell/hugs-mode.el
|
||||
;;
|
||||
;;
|
||||
;; Installation:
|
||||
;;
|
||||
;; To use with Moss and Thorn's haskell-mode.el
|
||||
;;
|
||||
;; http://www.haskell.org/haskell-mode
|
||||
;;
|
||||
;; add this to .emacs:
|
||||
;;
|
||||
;; (add-hook 'haskell-mode-hook 'turn-on-haskell-bot)
|
||||
;;
|
||||
;;
|
||||
;; Customisation:
|
||||
;;
|
||||
;; The name of the Bot interpreter is in haskell-bot-program-name.
|
||||
;;
|
||||
;; Arguments can be sent to the Bot interpreter when it is started by
|
||||
;; setting haskell-bot-program-args (empty by default) to a list of
|
||||
;; string args to pass it. This value can be set interactively by
|
||||
;; calling C-c C-s with an argument (i.e. C-u C-c C-s).
|
||||
;;
|
||||
;; `haskell-bot-hook' is invoked in the *bot* buffer once Bot is
|
||||
;; started.
|
||||
;;
|
||||
;; All functions/variables start with `turn-{on,off}-haskell-bot' or
|
||||
;; `haskell-bot-'.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'comint)
|
||||
|
||||
(defgroup haskell-bot nil
|
||||
"Major mode for interacting with an inferior Bot session."
|
||||
:group 'haskell
|
||||
:prefix "haskell-bot-")
|
||||
|
||||
(define-derived-mode haskell-bot-mode comint-mode "Lambdabot")
|
||||
|
||||
;; Bot interface:
|
||||
|
||||
(require 'comint)
|
||||
(require 'shell)
|
||||
|
||||
(defvar haskell-bot-process nil
|
||||
"The active Bot subprocess corresponding to current buffer.")
|
||||
|
||||
(defvar haskell-bot-process-buffer nil
|
||||
"*Buffer used for communication with Bot subprocess for current buffer.")
|
||||
|
||||
(defcustom haskell-bot-program-name "lambdabot"
|
||||
"*The name of the Bot interpreter program."
|
||||
:type 'string
|
||||
:group 'haskell-bot)
|
||||
|
||||
(defcustom haskell-bot-program-args nil
|
||||
"*A list of string args to pass when starting the Bot interpreter."
|
||||
:type '(repeat string)
|
||||
:group 'haskell-bot)
|
||||
|
||||
(defvar haskell-bot-load-end nil
|
||||
"Position of the end of the last load command.")
|
||||
|
||||
(defvar haskell-bot-error-pos nil
|
||||
"Position of the end of the last load command.")
|
||||
|
||||
(defvar haskell-bot-send-end nil
|
||||
"Position of the end of the last send command.")
|
||||
|
||||
(defvar haskell-bot-comint-prompt-regexp
|
||||
"^lambdabot> "
|
||||
"A regexp that matches the Bot prompt.")
|
||||
|
||||
(defun haskell-bot-start-process (arg)
|
||||
"Start a Bot process and invoke `haskell-bot-hook' if not nil.
|
||||
Prompt for a list of args if called with an argument."
|
||||
(interactive "P")
|
||||
(if arg
|
||||
;; XXX [CDW] Fix to use more natural 'string' version of the
|
||||
;; XXX arguments rather than a sexp.
|
||||
(setq haskell-bot-program-args
|
||||
(read-minibuffer (format "List of args for %s:"
|
||||
haskell-bot-program-name)
|
||||
(prin1-to-string haskell-bot-program-args))))
|
||||
|
||||
;; Start the Bot process in a new comint buffer.
|
||||
(message "Starting Lambdabot process `%s'." haskell-bot-program-name)
|
||||
(setq haskell-bot-process-buffer
|
||||
(apply 'make-comint
|
||||
"lambdabot" haskell-bot-program-name nil
|
||||
haskell-bot-program-args))
|
||||
(setq haskell-bot-process
|
||||
(get-buffer-process haskell-bot-process-buffer))
|
||||
|
||||
;; Select Bot buffer temporarily.
|
||||
(set-buffer haskell-bot-process-buffer)
|
||||
(haskell-bot-mode)
|
||||
(setq comint-prompt-regexp haskell-bot-comint-prompt-regexp)
|
||||
|
||||
;; History syntax of comint conflicts with Haskell, e.g. !!, so better
|
||||
;; turn it off.
|
||||
(setq comint-input-autoexpand nil)
|
||||
(setq comint-process-echoes nil)
|
||||
(run-hooks 'haskell-bot-hook)
|
||||
|
||||
;; Clear message area.
|
||||
(message ""))
|
||||
|
||||
(defun haskell-bot-wait-for-output ()
|
||||
"Wait until output arrives and go to the last input."
|
||||
(while (progn
|
||||
(goto-char comint-last-input-end)
|
||||
(not (re-search-forward comint-prompt-regexp nil t)))
|
||||
(accept-process-output haskell-bot-process)))
|
||||
|
||||
(defun haskell-bot-send (&rest string)
|
||||
"Send `haskell-bot-process' the arguments (one or more strings).
|
||||
A newline is sent after the strings and they are inserted into the
|
||||
current buffer after the last output."
|
||||
(haskell-bot-wait-for-output) ; wait for prompt
|
||||
(goto-char (point-max)) ; position for this input
|
||||
(apply 'insert string)
|
||||
(comint-send-input)
|
||||
(setq haskell-bot-send-end (marker-position comint-last-input-end)))
|
||||
|
||||
(defun haskell-bot-show-bot-buffer ()
|
||||
"Go to the *bot* buffer."
|
||||
(interactive)
|
||||
(if (or (not haskell-bot-process-buffer)
|
||||
(not (buffer-live-p haskell-bot-process-buffer)))
|
||||
(haskell-bot-start-process nil))
|
||||
(pop-to-buffer haskell-bot-process-buffer))
|
||||
|
||||
(provide 'haskell-bot)
|
||||
|
||||
;;; haskell-bot.el ends here
|
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-bot.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-bot.elc
Normal file
Binary file not shown.
49
.emacs.d/elpa/haskell-mode-13.12/haskell-c.el
Normal file
49
.emacs.d/elpa/haskell-mode-13.12/haskell-c.el
Normal file
@@ -0,0 +1,49 @@
|
||||
;;; haskell-c.el --- Major mode for *.hsc files
|
||||
|
||||
;; Copyright (C) 2007 Stefan Monnier
|
||||
|
||||
;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
;; 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 GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
;; Boston, MA 02110-1301, USA.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'haskell-mode)
|
||||
(require 'haskell-font-lock)
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.hsc\\'" . haskell-c-mode))
|
||||
|
||||
(defvar haskell-c-font-lock-keywords
|
||||
`(("^#[ \t]*[[:alnum:]]+" (0 font-lock-preprocessor-face))
|
||||
,@haskell-font-lock-symbols))
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode haskell-c-mode haskell-mode "Haskell-C"
|
||||
"Major mode for Haskell FFI files."
|
||||
(set (make-local-variable 'font-lock-keywords)
|
||||
(cons 'haskell-c-font-lock-keywords
|
||||
(cdr font-lock-keywords))))
|
||||
|
||||
(provide 'haskell-c)
|
||||
|
||||
;;; haskell-c.el ends here
|
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-c.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-c.elc
Normal file
Binary file not shown.
951
.emacs.d/elpa/haskell-mode-13.12/haskell-cabal.el
Normal file
951
.emacs.d/elpa/haskell-mode-13.12/haskell-cabal.el
Normal file
@@ -0,0 +1,951 @@
|
||||
;;; haskell-cabal.el --- Support for Cabal packages
|
||||
|
||||
;; Copyright (C) 2007, 2008 Stefan Monnier
|
||||
|
||||
;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
;; 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 GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
;; Boston, MA 02110-1301, USA.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Todo:
|
||||
|
||||
;; - distinguish continued lines from indented lines.
|
||||
;; - indent-line-function.
|
||||
;; - outline-minor-mode.
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; (defun haskell-cabal-extract-fields-from-doc ()
|
||||
;; (require 'xml)
|
||||
;; (with-no-warnings (require 'cl))
|
||||
;; (let ((section (completing-read
|
||||
;; "Section: "
|
||||
;; '("general-fields" "library" "executable" "buildinfo"))))
|
||||
;; (goto-char (point-min))
|
||||
;; (search-forward (concat "<sect3 id=\"" section "\">")))
|
||||
;; (let* ((xml (xml-parse-region
|
||||
;; (progn (search-forward "<variablelist>") (match-beginning 0))
|
||||
;; (progn (search-forward "</variablelist>") (point))))
|
||||
;; (varlist (remove-if-not 'consp (cddar xml)))
|
||||
;; (syms (mapcar (lambda (entry) (caddr (assq 'literal (assq 'term entry))))
|
||||
;; varlist))
|
||||
;; (fields (mapcar (lambda (sym) (substring-no-properties sym 0 -1)) syms)))
|
||||
;; fields))
|
||||
|
||||
(require 'cl-lib)
|
||||
(require 'haskell-utils)
|
||||
|
||||
(defconst haskell-cabal-general-fields
|
||||
;; Extracted with (haskell-cabal-extract-fields-from-doc "general-fields")
|
||||
'("name" "version" "cabal-version" "license" "license-file" "copyright"
|
||||
"author" "maintainer" "stability" "homepage" "package-url" "synopsis"
|
||||
"description" "category" "tested-with" "build-depends" "data-files"
|
||||
"extra-source-files" "extra-tmp-files"))
|
||||
|
||||
(defconst haskell-cabal-library-fields
|
||||
;; Extracted with (haskell-cabal-extract-fields-from-doc "library")
|
||||
'("exposed-modules"))
|
||||
|
||||
(defconst haskell-cabal-executable-fields
|
||||
;; Extracted with (haskell-cabal-extract-fields-from-doc "executable")
|
||||
'("executable" "main-is"))
|
||||
|
||||
(defconst haskell-cabal-buildinfo-fields
|
||||
;; Extracted with (haskell-cabal-extract-fields-from-doc "buildinfo")
|
||||
'("buildable" "other-modules" "hs-source-dirs" "extensions" "ghc-options"
|
||||
"ghc-prof-options" "hugs-options" "nhc-options" "includes"
|
||||
"install-includes" "include-dirs" "c-sources" "extra-libraries"
|
||||
"extra-lib-dirs" "cc-options" "ld-options" "frameworks"))
|
||||
|
||||
(defvar haskell-cabal-mode-syntax-table
|
||||
(let ((st (make-syntax-table)))
|
||||
;; The comment syntax can't be described simply in syntax-table.
|
||||
;; We could use font-lock-syntactic-keywords, but is it worth it?
|
||||
;; (modify-syntax-entry ?- ". 12" st)
|
||||
(modify-syntax-entry ?\n ">" st)
|
||||
(modify-syntax-entry ?. "w" st)
|
||||
(modify-syntax-entry ?- "w" st)
|
||||
st))
|
||||
|
||||
(defvar haskell-cabal-font-lock-keywords
|
||||
;; The comment syntax can't be described simply in syntax-table.
|
||||
;; We could use font-lock-syntactic-keywords, but is it worth it?
|
||||
'(("^[ \t]*--.*" . font-lock-comment-face)
|
||||
("^ *\\([^ \t:]+\\):" (1 font-lock-keyword-face))
|
||||
("^\\(Library\\)[ \t]*\\({\\|$\\)" (1 font-lock-keyword-face))
|
||||
("^\\(Executable\\|Test-Suite\\|Benchmark\\)[ \t]+\\([^\n \t]*\\)"
|
||||
(1 font-lock-keyword-face) (2 font-lock-function-name-face))
|
||||
("^\\(Flag\\)[ \t]+\\([^\n \t]*\\)"
|
||||
(1 font-lock-keyword-face) (2 font-lock-constant-face))
|
||||
("^\\(Source-Repository\\)[ \t]+\\(head\\|this\\)"
|
||||
(1 font-lock-keyword-face) (2 font-lock-constant-face))
|
||||
("^ *\\(if\\)[ \t]+.*\\({\\|$\\)" (1 font-lock-keyword-face))
|
||||
("^ *\\(}[ \t]*\\)?\\(else\\)[ \t]*\\({\\|$\\)"
|
||||
(2 font-lock-keyword-face))))
|
||||
|
||||
(defvar haskell-cabal-buffers nil
|
||||
"List of Cabal buffers.")
|
||||
|
||||
(defun haskell-cabal-buffers-clean (&optional buffer)
|
||||
(let ((bufs ()))
|
||||
(dolist (buf haskell-cabal-buffers)
|
||||
(if (and (buffer-live-p buf) (not (eq buf buffer))
|
||||
(with-current-buffer buf (derived-mode-p 'haskell-cabal-mode)))
|
||||
(push buf bufs)))
|
||||
(setq haskell-cabal-buffers bufs)))
|
||||
|
||||
(defun haskell-cabal-unregister-buffer ()
|
||||
(haskell-cabal-buffers-clean (current-buffer)))
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.cabal\\'" . haskell-cabal-mode))
|
||||
|
||||
(defvar haskell-cabal-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map (kbd "C-c C-s") 'haskell-cabal-subsection-arrange-lines)
|
||||
(define-key map (kbd "C-M-n") 'haskell-cabal-next-section)
|
||||
(define-key map (kbd "C-M-p") 'haskell-cabal-previous-section)
|
||||
(define-key map (kbd "M-n") 'haskell-cabal-next-subsection)
|
||||
(define-key map (kbd "M-p") 'haskell-cabal-previous-subsection)
|
||||
(define-key map (kbd "C-<down>") 'haskell-cabal-next-subsection)
|
||||
(define-key map (kbd "C-<up>") 'haskell-cabal-previous-subsection)
|
||||
(define-key map (kbd "C-c C-f") 'haskell-cabal-find-or-create-source-file)
|
||||
(define-key map (kbd "M-g l") 'haskell-cabal-goto-library-section)
|
||||
(define-key map (kbd "M-g e") 'haskell-cabal-goto-executable-section)
|
||||
(define-key map (kbd "M-g b") 'haskell-cabal-goto-benchmark-section)
|
||||
(define-key map (kbd "M-g t") 'haskell-cabal-goto-test-suite-section)
|
||||
map))
|
||||
(defvar haskell-cabal-mode-map (make-sparse-keymap))
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode haskell-cabal-mode fundamental-mode "Haskell-Cabal"
|
||||
"Major mode for Cabal package description files."
|
||||
(set (make-local-variable 'font-lock-defaults)
|
||||
'(haskell-cabal-font-lock-keywords t t nil nil))
|
||||
(add-to-list 'haskell-cabal-buffers (current-buffer))
|
||||
(add-hook 'change-major-mode-hook 'haskell-cabal-unregister-buffer nil 'local)
|
||||
(add-hook 'kill-buffer-hook 'haskell-cabal-unregister-buffer nil 'local)
|
||||
(set (make-local-variable 'comment-start) "-- ")
|
||||
(set (make-local-variable 'comment-start-skip) "\\(^[ \t]*\\)--[ \t]*")
|
||||
(set (make-local-variable 'comment-end) "")
|
||||
(set (make-local-variable 'comment-end-skip) "[ \t]*\\(\\s>\\|\n\\)")
|
||||
(set (make-local-variable 'indent-line-function) 'haskell-cabal-indent-line)
|
||||
(setq indent-tabs-mode nil)
|
||||
)
|
||||
|
||||
(defun haskell-cabal-get-setting (name)
|
||||
(save-excursion
|
||||
(let ((case-fold-search t))
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward
|
||||
(concat "^[ \t]*" (regexp-quote name)
|
||||
":[ \t]*\\(.*\\(\n[ \t]+[ \t\n].*\\)*\\)")
|
||||
nil t)
|
||||
(let ((val (match-string 1))
|
||||
(start 1))
|
||||
(when (match-end 2) ;Multiple lines.
|
||||
;; The documentation is not very precise about what to do about
|
||||
;; the \n and the indentation: are they part of the value or
|
||||
;; the encoding? I take the point of view that \n is part of
|
||||
;; the value (so that values can span multiple lines as well),
|
||||
;; and that only the first char in the indentation is part of
|
||||
;; the encoding, the rest is part of the value (otherwise, lines
|
||||
;; in the value cannot start with spaces or tabs).
|
||||
(while (string-match "^[ \t]\\(?:\\.$\\)?" val start)
|
||||
(setq start (1+ (match-beginning 0)))
|
||||
(setq val (replace-match "" t t val))))
|
||||
val)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-guess-setting (name)
|
||||
"Guess the specified setting of this project.
|
||||
If there is no valid .cabal file to get the setting from (or
|
||||
there is no corresponding setting with that name in the .cabal
|
||||
file), then this function returns nil."
|
||||
(interactive)
|
||||
(when (and name buffer-file-name)
|
||||
(let ((cabal-file (haskell-cabal-find-file (file-name-directory buffer-file-name))))
|
||||
(when (and cabal-file (file-readable-p cabal-file))
|
||||
(with-temp-buffer
|
||||
(insert-file-contents cabal-file)
|
||||
(haskell-cabal-get-setting name))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-cabal-get-dir ()
|
||||
"Get the Cabal dir for a new project. Various ways of figuring this out,
|
||||
and indeed just prompting the user. Do them all."
|
||||
(let* ((file (haskell-cabal-find-file))
|
||||
(dir (when file (file-name-directory file))))
|
||||
(haskell-utils-read-directory-name
|
||||
(format "Cabal dir%s: " (if file (format " (guessed from %s)" (file-relative-name file)) ""))
|
||||
dir)))
|
||||
|
||||
(defun haskell-cabal-compute-checksum (dir)
|
||||
"Compute MD5 checksum of package description file in DIR.
|
||||
Return nil if no Cabal description file could be located via
|
||||
`haskell-cabal-find-pkg-desc'."
|
||||
(let ((cabal-file (haskell-cabal-find-pkg-desc dir)))
|
||||
(when cabal-file
|
||||
(with-temp-buffer
|
||||
(insert-file-contents cabal-file)
|
||||
(md5 (buffer-string))))))
|
||||
|
||||
(defun haskell-cabal-find-file (&optional dir)
|
||||
"Search for package description file upwards starting from DIR.
|
||||
If DIR is nil, `default-directory' is used as starting point for
|
||||
directory traversal. Upward traversal is aborted if file owner
|
||||
changes. Uses`haskell-cabal-find-pkg-desc' internally."
|
||||
(catch 'found
|
||||
(let ((user (nth 2 (file-attributes (or dir default-directory))))
|
||||
;; Abbreviate, so as to stop when we cross ~/.
|
||||
(root (abbreviate-file-name (or dir default-directory))))
|
||||
;; traverse current dir up to root as long as file owner doesn't change
|
||||
(while (and root (equal user (nth 2 (file-attributes root))))
|
||||
(let ((cabal-file (haskell-cabal-find-pkg-desc root)))
|
||||
(when cabal-file
|
||||
(throw 'found cabal-file)))
|
||||
|
||||
(let ((proot (file-name-directory (directory-file-name root))))
|
||||
(if (equal proot root) ;; fix-point reached?
|
||||
(throw 'found nil)
|
||||
(setq root proot))))
|
||||
nil)))
|
||||
|
||||
(defun haskell-cabal-find-pkg-desc (dir &optional allow-multiple)
|
||||
"Find a package description file in the directory DIR.
|
||||
Returns nil if none or multiple \".cabal\" files were found. If
|
||||
ALLOW-MULTIPLE is non nil, in case of multiple \".cabal\" files,
|
||||
a list is returned instead of failing with a nil result."
|
||||
;; This is basically a port of Cabal's
|
||||
;; Distribution.Simple.Utils.findPackageDesc function
|
||||
;; http://hackage.haskell.org/packages/archive/Cabal/1.16.0.3/doc/html/Distribution-Simple-Utils.html
|
||||
;; but without the exception throwing.
|
||||
(let* ((cabal-files
|
||||
(cl-remove-if 'file-directory-p
|
||||
(cl-remove-if-not 'file-exists-p
|
||||
(directory-files dir t ".\\.cabal\\'")))))
|
||||
(cond
|
||||
((= (length cabal-files) 1) (car cabal-files)) ;; exactly one candidate found
|
||||
(allow-multiple cabal-files) ;; pass-thru multiple candidates
|
||||
(t nil))))
|
||||
|
||||
(defun haskell-cabal-find-dir (&optional dir)
|
||||
"Like `haskell-cabal-find-file' but returns directory instead.
|
||||
See `haskell-cabal-find-file' for meaning of DIR argument."
|
||||
(let ((cabal-file (haskell-cabal-find-file dir)))
|
||||
(when cabal-file
|
||||
(file-name-directory cabal-file))))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-cabal-visit-file (other-window)
|
||||
"Locate and visit package description file for file visited by current buffer.
|
||||
This uses `haskell-cabal-find-file' to locate the closest
|
||||
\".cabal\" file and open it. This command assumes a common Cabal
|
||||
project structure where the \".cabal\" file is in the top-folder
|
||||
of the project, and all files related to the project are in or
|
||||
below the top-folder. If called with non-nil prefix argument
|
||||
OTHER-WINDOW use `find-file-other-window'."
|
||||
(interactive "P")
|
||||
;; Note: We aren't allowed to rely on haskell-session here (which,
|
||||
;; in pathological cases, can have a different .cabal file
|
||||
;; associated with the current buffer)
|
||||
(if buffer-file-name
|
||||
(let ((cabal-file (haskell-cabal-find-file (file-name-directory buffer-file-name))))
|
||||
(if cabal-file
|
||||
(if other-window
|
||||
(find-file-other-window cabal-file)
|
||||
(find-file cabal-file))
|
||||
(error "Could not locate \".cabal\" file for %S" buffer-file-name)))
|
||||
(error "Cannot locate \".cabal\" file for buffers not visiting any file")))
|
||||
|
||||
(defvar haskell-cabal-commands
|
||||
'("install"
|
||||
"update"
|
||||
"list"
|
||||
"info"
|
||||
"upgrade"
|
||||
"fetch"
|
||||
"unpack"
|
||||
"check"
|
||||
"sdist"
|
||||
"upload"
|
||||
"report"
|
||||
"init"
|
||||
"configure"
|
||||
"build"
|
||||
"copy"
|
||||
"haddock"
|
||||
"clean"
|
||||
"hscolour"
|
||||
"register"
|
||||
"test"
|
||||
"help"))
|
||||
|
||||
|
||||
(defgroup haskell-cabal nil
|
||||
"Haskell cabal files"
|
||||
:group 'haskell
|
||||
)
|
||||
|
||||
(defcustom haskell-cabal-list-comma-position
|
||||
'before
|
||||
"Where to put the comma in lists"
|
||||
:safe t
|
||||
:group 'haskell-cabal
|
||||
:type '(choice (const before)
|
||||
(const after)))
|
||||
|
||||
(defconst haskell-cabal-section-header-regexp "^[[:alnum:]]" )
|
||||
(defconst haskell-cabal-subsection-header-regexp "^[ \t]*[[:alnum:]]\\w*:")
|
||||
(defconst haskell-cabal-comment-regexp "^[ \t]*--")
|
||||
(defconst haskell-cabal-empty-regexp "^[ \t]*$")
|
||||
(defconst haskell-cabal-conditional-regexp "^[ \t]*\\(\\if\\|else\\|}\\)")
|
||||
|
||||
(defun haskell-cabal-classify-line ()
|
||||
"Classify the current line into 'section-header 'subsection-header 'section-data 'comment and 'empty '"
|
||||
(save-excursion
|
||||
(beginning-of-line)
|
||||
(cond
|
||||
((looking-at haskell-cabal-subsection-header-regexp ) 'subsection-header)
|
||||
((looking-at haskell-cabal-section-header-regexp) 'section-header)
|
||||
((looking-at haskell-cabal-comment-regexp) 'comment)
|
||||
((looking-at haskell-cabal-empty-regexp ) 'empty)
|
||||
((looking-at haskell-cabal-conditional-regexp ) 'conditional)
|
||||
(t 'section-data))))
|
||||
|
||||
(defun haskell-cabal-header-p ()
|
||||
"Is the current line a section or subsection header?"
|
||||
(cl-case (haskell-cabal-classify-line)
|
||||
((section-header subsection-header) t)))
|
||||
|
||||
(defun haskell-cabal-section-header-p ()
|
||||
"Is the current line a section or subsection header?"
|
||||
(cl-case (haskell-cabal-classify-line)
|
||||
((section-header) t)))
|
||||
|
||||
|
||||
(defun haskell-cabal-section-beginning ()
|
||||
"Find the beginning of the current section"
|
||||
(save-excursion
|
||||
(while (not (or (bobp) (haskell-cabal-section-header-p)))
|
||||
(forward-line -1))
|
||||
(point)))
|
||||
|
||||
(defun haskell-cabal-beginning-of-section ()
|
||||
"go to the beginning of the section"
|
||||
(interactive)
|
||||
(goto-char (haskell-cabal-section-beginning))
|
||||
)
|
||||
|
||||
(defun haskell-cabal-section-end ()
|
||||
"Find the end of the current section"
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(if (re-search-forward "\n\\([ \t]*\n\\)*[[:alnum:]]" nil t)
|
||||
(match-beginning 0)
|
||||
(point-max))))
|
||||
|
||||
(defun haskell-cabal-end-of-section ()
|
||||
"go to the end of the section"
|
||||
(interactive)
|
||||
(goto-char (haskell-cabal-section-end)))
|
||||
|
||||
(defun haskell-cabal-next-section ()
|
||||
"Go to the next extion"
|
||||
(interactive)
|
||||
(when (haskell-cabal-section-header-p) (forward-line))
|
||||
(while (not (or (eobp) (haskell-cabal-section-header-p)))
|
||||
(forward-line)))
|
||||
|
||||
(defun haskell-cabal-previous-section ()
|
||||
"Go to the next extion"
|
||||
(interactive)
|
||||
(when (haskell-cabal-section-header-p) (forward-line -1))
|
||||
(while (not (or (bobp) (haskell-cabal-section-header-p)))
|
||||
(forward-line -1)))
|
||||
|
||||
(defun haskell-cabal-subsection-end ()
|
||||
"find the end of the current subsection"
|
||||
(save-excursion
|
||||
(haskell-cabal-beginning-of-subsection)
|
||||
(forward-line)
|
||||
(while (and (not (eobp))
|
||||
(member (haskell-cabal-classify-line) '(empty section-data)))
|
||||
(forward-line))
|
||||
(unless (eobp) (forward-line -1))
|
||||
(while (and (equal (haskell-cabal-classify-line) 'empty)
|
||||
(not (bobp)))
|
||||
(forward-line -1))
|
||||
(end-of-line)
|
||||
(point)))
|
||||
|
||||
(defun haskell-cabal-end-of-subsection ()
|
||||
"go to the end of the current subsection"
|
||||
(interactive)
|
||||
(goto-char (haskell-cabal-subsection-end)))
|
||||
|
||||
(defun haskell-cabal-section ()
|
||||
"Get the name and data of the associated section"
|
||||
(save-excursion
|
||||
(haskell-cabal-beginning-of-section)
|
||||
(when (and (haskell-cabal-section-header-p)
|
||||
(looking-at "^\\(\\w+\\)[ \t]*\\(.*\\)$"))
|
||||
(list :name (match-string-no-properties 1)
|
||||
:value (match-string-no-properties 2)
|
||||
:beginning (match-beginning 0)
|
||||
:end (haskell-cabal-section-end)))))
|
||||
|
||||
|
||||
(defun haskell-cabal-subsection ()
|
||||
"Get the name and bounds of of the current subsection"
|
||||
(save-excursion
|
||||
(haskell-cabal-beginning-of-subsection)
|
||||
(when (looking-at "\\([ \t]*\\(\\w*\\):\\)[ \t]*")
|
||||
(list :name (match-string-no-properties 2)
|
||||
:beginning (match-end 0)
|
||||
:end (save-match-data (haskell-cabal-subsection-end))
|
||||
:data-start-column (save-excursion (goto-char (match-end 0))
|
||||
(current-column)
|
||||
)))))
|
||||
|
||||
|
||||
(defun haskell-cabal-section-name (section)
|
||||
(plist-get section :name))
|
||||
|
||||
(defun haskell-cabal-section-value (section)
|
||||
(plist-get section :value))
|
||||
|
||||
(defun haskell-cabal-section-start (section)
|
||||
(plist-get section :beginning))
|
||||
|
||||
(defun haskell-cabal-section-data-start-column (section)
|
||||
(plist-get section :data-start-column))
|
||||
|
||||
(defmacro haskell-cabal-with-subsection (subsection replace &rest funs)
|
||||
"Copy subsection data into a temporary buffer, save indentation
|
||||
and execute FORMS
|
||||
|
||||
If REPLACE is non-nil the subsection data is replaced with the
|
||||
resultung buffer-content"
|
||||
(let ((section (make-symbol "section"))
|
||||
(beg (make-symbol "beg"))
|
||||
(end (make-symbol "end"))
|
||||
(start-col (make-symbol "start-col"))
|
||||
(section-data (make-symbol "section-data")))
|
||||
`(let* ((,section ,subsection)
|
||||
(,beg (plist-get ,section :beginning))
|
||||
(,end (plist-get ,section :end))
|
||||
(,start-col (plist-get ,section :data-start-column))
|
||||
(,section-data (buffer-substring ,beg ,end))
|
||||
(section-name (plist-get ,section :name )))
|
||||
(save-excursion
|
||||
(prog1
|
||||
(with-temp-buffer
|
||||
(setq indent-tabs-mode nil)
|
||||
(indent-to ,start-col)
|
||||
(insert ,section-data)
|
||||
(goto-char (point-min))
|
||||
(prog1
|
||||
(progn (haskell-cabal-save-indentation ,@funs))
|
||||
(goto-char (point-min))
|
||||
(when (looking-at (format "[ ]\\{0,%d\\}" (1+ ,start-col)))
|
||||
(replace-match ""))
|
||||
|
||||
(setq ,section-data (buffer-substring (point-min) (point-max)))))
|
||||
,@(when replace
|
||||
`((delete-region ,beg ,end)
|
||||
(goto-char ,beg)
|
||||
(insert ,section-data))))))))
|
||||
|
||||
(defmacro haskell-cabal-each-line (&rest fun)
|
||||
"Execute FOMRS on each line"
|
||||
`(save-excursion
|
||||
(while (< (point) (point-max))
|
||||
,@fun
|
||||
(forward-line))))
|
||||
|
||||
(defun haskell-cabal-chomp-line ()
|
||||
"Remove leading and trailing whitespaces from current line"
|
||||
(beginning-of-line)
|
||||
(when (looking-at "^[ \t]*\\([^ \t]\\|\\(?:[^ \t].*[^ \t]\\)\\)[ \t]*$")
|
||||
(replace-match (match-string 1) nil t)
|
||||
t))
|
||||
|
||||
|
||||
(defun haskell-cabal-min-indentation (&optional beg end)
|
||||
"Compute largest common whitespace prefix of each line in between BEG and END"
|
||||
(save-excursion
|
||||
(goto-char (or beg (point-min)))
|
||||
(let ((min-indent nil))
|
||||
(while (< (point) (or end (point-max)))
|
||||
(let ((indent (current-indentation)))
|
||||
(if (and (not (haskell-cabal-ignore-line-p))
|
||||
(or (not min-indent)
|
||||
(< indent min-indent)))
|
||||
(setq min-indent indent)))
|
||||
(forward-line))
|
||||
min-indent)))
|
||||
|
||||
(defun haskell-cabal-ignore-line-p ()
|
||||
"Does line only contain whitespaces and comments?"
|
||||
(save-excursion
|
||||
(beginning-of-line)
|
||||
(looking-at "^[ \t]*\\(?:--.*\\)?$")))
|
||||
|
||||
(defun haskell-cabal-kill-indentation ()
|
||||
"Remove longest common whitespace prefix from each line"
|
||||
(goto-char (point-min))
|
||||
(let ((indent (haskell-cabal-min-indentation)))
|
||||
(haskell-cabal-each-line (unless (haskell-cabal-ignore-line-p)
|
||||
(delete-char indent)) )
|
||||
indent))
|
||||
|
||||
(defun haskell-cabal-add-indentation (indent)
|
||||
(goto-char (point-min))
|
||||
(haskell-cabal-each-line
|
||||
(unless (haskell-cabal-ignore-line-p)
|
||||
(indent-to indent))))
|
||||
|
||||
|
||||
(defmacro haskell-cabal-save-indentation (&rest funs)
|
||||
"Strip indentation from each line, execute FORMS and reinstate indentation
|
||||
so that the indentation of the FIRST LINE matches"
|
||||
(let ((old-l1-indent (make-symbol "new-l1-indent"))
|
||||
(new-l1-indent (make-symbol "old-l1-indent"))
|
||||
(res nil))
|
||||
`(let ( (,old-l1-indent (save-excursion
|
||||
(goto-char (point-min))
|
||||
(current-indentation))))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(haskell-cabal-kill-indentation)
|
||||
,@funs)
|
||||
(progn
|
||||
(goto-char (point-min))
|
||||
(let ((,new-l1-indent (current-indentation)))
|
||||
(haskell-cabal-add-indentation (- ,old-l1-indent
|
||||
,new-l1-indent))))))))
|
||||
|
||||
(defun haskell-cabal-strip-list ()
|
||||
"strip commas from comma-seperated list"
|
||||
(goto-char (point-min))
|
||||
;; split list items on single line
|
||||
(while (re-search-forward
|
||||
"\\([^ \t,\n]\\)[ \t]*,[ \t]*\\([^ \t,\n]\\)" nil t)
|
||||
(replace-match "\\1\n\\2" nil nil))
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^\\([ \t]*\\),\\([ \t]*\\)" nil t)
|
||||
(replace-match "" nil nil))
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward ",[ \t]*$" nil t)
|
||||
(replace-match "" nil nil))
|
||||
(goto-char (point-min))
|
||||
(haskell-cabal-each-line (haskell-cabal-chomp-line)))
|
||||
|
||||
(defun haskell-cabal-listify ()
|
||||
"Add commas so that buffer contains a comma-seperated list"
|
||||
(cl-case haskell-cabal-list-comma-position
|
||||
('before
|
||||
(goto-char (point-min))
|
||||
(while (haskell-cabal-ignore-line-p) (forward-line))
|
||||
(indent-to 2)
|
||||
(forward-line)
|
||||
(haskell-cabal-each-line
|
||||
(unless (haskell-cabal-ignore-line-p)
|
||||
(insert ", "))))
|
||||
('after
|
||||
(goto-char (point-max))
|
||||
(while (not (bobp))
|
||||
(unless (haskell-cabal-ignore-line-p)
|
||||
(forward-line -1)
|
||||
(end-of-line)
|
||||
(insert ",")
|
||||
(beginning-of-line))))))
|
||||
|
||||
|
||||
|
||||
(defmacro haskell-cabal-with-cs-list (&rest funs)
|
||||
"format buffer so that each line contains a list element "
|
||||
`(progn
|
||||
(save-excursion (haskell-cabal-strip-list))
|
||||
(unwind-protect (progn ,@funs)
|
||||
(haskell-cabal-listify))))
|
||||
|
||||
|
||||
(defun haskell-cabal-sort-lines-key-fun ()
|
||||
(when (looking-at "[ \t]*--[ \t,]*")
|
||||
(goto-char (match-end 0)))
|
||||
nil)
|
||||
|
||||
(defmacro haskell-cabal-save-position (&rest forms)
|
||||
"Save position as mark, execute FORMs and go back to mark"
|
||||
`(prog2
|
||||
(haskell-cabal-mark)
|
||||
(progn ,@forms)
|
||||
(haskell-cabal-goto-mark)
|
||||
(haskell-cabal-remove-mark)))
|
||||
|
||||
(defun haskell-cabal-subsection-arrange-lines ()
|
||||
"Sort lines of current subsection"
|
||||
(interactive)
|
||||
(haskell-cabal-save-position
|
||||
(haskell-cabal-with-subsection
|
||||
(haskell-cabal-subsection) t
|
||||
(haskell-cabal-with-cs-list
|
||||
(sort-subr nil 'forward-line 'end-of-line
|
||||
'haskell-cabal-sort-lines-key-fun)
|
||||
))))
|
||||
|
||||
(defun haskell-cabal-subsection-beginning ()
|
||||
"find the beginning of the current subsection"
|
||||
(save-excursion
|
||||
(while (and (not (bobp))
|
||||
(not (haskell-cabal-header-p)))
|
||||
(forward-line -1))
|
||||
(back-to-indentation)
|
||||
(point)))
|
||||
|
||||
(defun haskell-cabal-beginning-of-subsection ()
|
||||
"go to the beginniing of the current subsection"
|
||||
(interactive)
|
||||
(goto-char (haskell-cabal-subsection-beginning)))
|
||||
|
||||
(defun haskell-cabal-next-subsection ()
|
||||
"go to the next subsection"
|
||||
(interactive)
|
||||
(if (haskell-cabal-header-p) (forward-line))
|
||||
(while (and (not (eobp))
|
||||
(not (haskell-cabal-header-p)))
|
||||
(forward-line))
|
||||
(haskell-cabal-forward-to-line-entry))
|
||||
|
||||
(defun haskell-cabal-previous-subsection ()
|
||||
"go to the next subsection"
|
||||
(interactive)
|
||||
(if (haskell-cabal-header-p) (forward-line -1))
|
||||
(while (and (not (bobp))
|
||||
(not (haskell-cabal-header-p)))
|
||||
(forward-line -1))
|
||||
(haskell-cabal-forward-to-line-entry)
|
||||
)
|
||||
|
||||
|
||||
(defun haskell-cabal-find-subsection-by (section pred)
|
||||
"Find sunsection with name NAME"
|
||||
(save-excursion
|
||||
(when section (goto-char (haskell-cabal-section-start section)))
|
||||
(let* ((end (if section (haskell-cabal-section-end) (point-max)))
|
||||
(found nil))
|
||||
(while (and (< (point) end)
|
||||
(not found))
|
||||
(let ((subsection (haskell-cabal-subsection)))
|
||||
(when (and subsection (funcall pred subsection))
|
||||
(setq found subsection)))
|
||||
(haskell-cabal-next-subsection))
|
||||
found)))
|
||||
|
||||
(defun haskell-cabal-find-subsection (section name)
|
||||
"Find sunsection with name NAME"
|
||||
(let ((downcase-name (downcase name)))
|
||||
(haskell-cabal-find-subsection-by
|
||||
section
|
||||
'(lambda (subsection)
|
||||
(string= (downcase (haskell-cabal-section-name subsection))
|
||||
downcase-name)))))
|
||||
|
||||
(defun haskell-cabal-goto-subsection (name)
|
||||
(let ((subsection (haskell-cabal-find-subsection (haskell-cabal-section) name)))
|
||||
(when subsection
|
||||
(goto-char (haskell-cabal-section-start subsection)))))
|
||||
|
||||
(defun haskell-cabal-goto-exposed-modules ()
|
||||
(interactive)
|
||||
(haskell-cabal-goto-subsection "exposed-modules"))
|
||||
|
||||
(defun haskell-cabal-subsection-entry-list (section name)
|
||||
"Get the data of a subsection as a list"
|
||||
(let ((subsection (haskell-cabal-find-subsection section name)))
|
||||
(when subsection
|
||||
(haskell-cabal-with-subsection
|
||||
subsection nil
|
||||
(haskell-cabal-with-cs-list
|
||||
(delete-matching-lines
|
||||
(format "\\(?:%s\\)\\|\\(?:%s\\)"
|
||||
haskell-cabal-comment-regexp
|
||||
haskell-cabal-empty-regexp)
|
||||
(point-min) (point-max))
|
||||
(split-string (buffer-substring-no-properties (point-min) (point-max))
|
||||
"\n" t))))))
|
||||
|
||||
(defun haskell-cabal-remove-mark ()
|
||||
(remove-list-of-text-properties (point-min) (point-max)
|
||||
'(haskell-cabal-marker)))
|
||||
|
||||
|
||||
(defun haskell-cabal-mark ()
|
||||
"Mark the current position with the text property haskell-cabal-marker"
|
||||
(haskell-cabal-remove-mark)
|
||||
(put-text-property (line-beginning-position) (line-end-position)
|
||||
'haskell-cabal-marker 'marked-line)
|
||||
(put-text-property (point) (1+ (point))
|
||||
'haskell-cabal-marker 'marked))
|
||||
|
||||
|
||||
(defun haskell-cabal-goto-mark ()
|
||||
"Go to marked line"
|
||||
(let ((marked-pos (text-property-any (point-min) (point-max)
|
||||
'haskell-cabal-marker
|
||||
'marked))
|
||||
(marked-line (text-property-any (point-min) (point-max)
|
||||
'haskell-cabal-marker
|
||||
'marked-line) )
|
||||
)
|
||||
(cond (marked-pos (goto-char marked-pos))
|
||||
(marked-line (goto-char marked-line)))))
|
||||
|
||||
(defmacro haskell-cabal-with-subsection-line (replace &rest forms)
|
||||
"Mark line and "
|
||||
`(progn
|
||||
(haskell-cabal-mark)
|
||||
(unwind-protect
|
||||
(haskell-cabal-with-subsection (haskell-cabal-subsection) ,replace
|
||||
(haskell-cabal-goto-mark)
|
||||
,@forms)
|
||||
(haskell-cabal-remove-mark))))
|
||||
|
||||
|
||||
(defun haskell-cabal-get-line-content ()
|
||||
(haskell-cabal-with-subsection-line
|
||||
nil
|
||||
(haskell-cabal-with-cs-list
|
||||
(haskell-cabal-goto-mark)
|
||||
(buffer-substring-no-properties (line-beginning-position)
|
||||
(line-end-position)))))
|
||||
|
||||
(defun haskell-cabal-module-to-filename (module)
|
||||
(concat (replace-regexp-in-string "[.]" "/" module ) ".hs"))
|
||||
|
||||
(defconst haskell-cabal-module-sections '("exposed-modules" "other-modules")
|
||||
"List of sections that contain module names"
|
||||
)
|
||||
|
||||
(defconst haskell-cabal-file-sections
|
||||
'("main-is" "c-sources" "data-files" "extra-source-files"
|
||||
"extra-doc-files" "extra-tmp-files" )
|
||||
"List of subsections that contain filenames"
|
||||
)
|
||||
|
||||
(defconst haskell-cabal-source-bearing-sections
|
||||
'("library" "executable" "test-suite" "benchmark"))
|
||||
|
||||
(defun haskell-cabal-source-section-p (section)
|
||||
(not (not (member (downcase (haskell-cabal-section-name section))
|
||||
haskell-cabal-source-bearing-sections))))
|
||||
|
||||
(defun haskell-cabal-line-filename ()
|
||||
"Expand filename in current line according to the subsection type
|
||||
|
||||
Module names in exposed-modules and other-modules are expanded by replacing each dot (.) in the module name with a foward slash (/) and appending \".hs\"
|
||||
|
||||
Example: Foo.Bar.Quux ==> Foo/Bar/Quux.hs
|
||||
|
||||
Source names from main-is and c-sources sections are left untouched
|
||||
|
||||
"
|
||||
(let ((entry (haskell-cabal-get-line-content))
|
||||
(subsection (downcase (haskell-cabal-section-name
|
||||
(haskell-cabal-subsection)))))
|
||||
(cond ((member subsection haskell-cabal-module-sections)
|
||||
(haskell-cabal-module-to-filename entry))
|
||||
((member subsection haskell-cabal-file-sections) entry))))
|
||||
|
||||
(defun haskell-cabal-join-paths (&rest args)
|
||||
"Crude hack to replace f-join"
|
||||
(mapconcat 'identity args "/")
|
||||
)
|
||||
|
||||
(defun haskell-cabal-find-or-create-source-file ()
|
||||
"Open the source file this line refers to"
|
||||
(interactive)
|
||||
(let* ((src-dirs (append (haskell-cabal-subsection-entry-list
|
||||
(haskell-cabal-section) "hs-source-dirs")
|
||||
'("")))
|
||||
(base-dir (file-name-directory (buffer-file-name)))
|
||||
(filename (haskell-cabal-line-filename)))
|
||||
(when filename
|
||||
(let ((candidates
|
||||
(delq nil (mapcar
|
||||
(lambda (dir)
|
||||
(let ((file (haskell-cabal-join-paths base-dir dir filename)))
|
||||
(when (and (file-readable-p file)
|
||||
(not (file-directory-p file)))
|
||||
file)))
|
||||
src-dirs))))
|
||||
(if (null candidates)
|
||||
(let* ((src-dir (haskell-cabal-join-paths base-dir (or (car src-dirs) "")))
|
||||
(newfile (haskell-cabal-join-paths src-dir filename))
|
||||
(subdir (file-name-directory newfile))
|
||||
(do-create-p (y-or-n-p (format "Create file %s ?" newfile))))
|
||||
(when do-create-p
|
||||
(find-file-other-window newfile )))
|
||||
(find-file-other-window (car candidates)))))))
|
||||
|
||||
|
||||
(defun haskell-cabal-find-section-type (type &optional wrap)
|
||||
(save-excursion
|
||||
(haskell-cabal-next-section)
|
||||
(while
|
||||
(not
|
||||
(or
|
||||
(eobp)
|
||||
(string=
|
||||
(downcase type)
|
||||
(downcase (haskell-cabal-section-name (haskell-cabal-section))))))
|
||||
(haskell-cabal-next-section))
|
||||
(if (eobp)
|
||||
(if wrap (progn
|
||||
(goto-char (point-min))
|
||||
(haskell-cabal-find-section-type type nil) )
|
||||
nil)
|
||||
(point))))
|
||||
|
||||
(defun haskell-cabal-goto-section-type (type)
|
||||
(let ((section (haskell-cabal-find-section-type type t)))
|
||||
(if section (goto-char section)
|
||||
(message "No %s section found" type))))
|
||||
|
||||
(defun haskell-cabal-goto-library-section ()
|
||||
(interactive)
|
||||
(haskell-cabal-goto-section-type "library"))
|
||||
|
||||
(defun haskell-cabal-goto-test-suite-section ()
|
||||
(interactive)
|
||||
(haskell-cabal-goto-section-type "test-suite"))
|
||||
|
||||
(defun haskell-cabal-goto-executable-section ()
|
||||
(interactive)
|
||||
(haskell-cabal-goto-section-type "executable"))
|
||||
|
||||
(defun haskell-cabal-goto-benchmark-section ()
|
||||
(interactive)
|
||||
(haskell-cabal-goto-section-type "benchmark"))
|
||||
|
||||
|
||||
|
||||
(defun haskell-cabal-line-entry-column ()
|
||||
"Column at which the line entry starts"
|
||||
(save-excursion
|
||||
(cl-case (haskell-cabal-classify-line)
|
||||
(section-data (beginning-of-line)
|
||||
(when (looking-at "[ ]*\\(?:,[ ]*\\)?")
|
||||
(goto-char (match-end 0))
|
||||
(current-column)))
|
||||
(subsection-header
|
||||
(haskell-cabal-section-data-start-column (haskell-cabal-subsection))))))
|
||||
|
||||
(defun haskell-cabal-forward-to-line-entry ()
|
||||
"go forward to the beginning of the line entry (but never move backwards)"
|
||||
(let ((col (haskell-cabal-line-entry-column)))
|
||||
(when (and col (< (current-column) col))
|
||||
(beginning-of-line)
|
||||
(forward-char col))))
|
||||
|
||||
(defun haskell-cabal-indent-line ()
|
||||
"Indent current line according to subsection"
|
||||
(interactive)
|
||||
(cl-case (haskell-cabal-classify-line)
|
||||
(section-data
|
||||
(save-excursion
|
||||
(let ((indent (haskell-cabal-section-data-start-column
|
||||
(haskell-cabal-subsection))))
|
||||
(indent-line-to indent)
|
||||
(beginning-of-line)
|
||||
(when (looking-at "[ ]*\\([ ]\\{2\\},[ ]*\\)")
|
||||
(replace-match ", " t t nil 1)))))
|
||||
(empty
|
||||
(indent-relative)))
|
||||
(haskell-cabal-forward-to-line-entry))
|
||||
|
||||
(defun haskell-cabal-map-sections (fun)
|
||||
"Execute fun over each section, collecting the result"
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(let ((results nil))
|
||||
(while (not (eobp))
|
||||
(let* ((section (haskell-cabal-section))
|
||||
(result (and section (funcall fun (haskell-cabal-section)))))
|
||||
(when section (setq results (cons result results))))
|
||||
(haskell-cabal-next-section))
|
||||
(nreverse results))))
|
||||
|
||||
(defun haskell-cabal-section-add-build-dependency (dependency &optional sort sec)
|
||||
"Add a build dependency to the build-depends section"
|
||||
(let* ((section (or sec (haskell-cabal-section)))
|
||||
(subsection (and section
|
||||
(haskell-cabal-find-subsection section "build-depends"))))
|
||||
(when subsection
|
||||
(haskell-cabal-with-subsection
|
||||
subsection t
|
||||
(haskell-cabal-with-cs-list
|
||||
(insert dependency)
|
||||
(insert "\n")
|
||||
(when sort
|
||||
(goto-char (point-min))
|
||||
(sort-subr nil 'forward-line 'end-of-line
|
||||
'haskell-cabal-sort-lines-key-fun)))))))
|
||||
|
||||
(defun haskell-cabal-add-build-dependency (dependency &optional sort silent)
|
||||
"Add a build dependencies to sections"
|
||||
(haskell-cabal-map-sections
|
||||
(lambda (section)
|
||||
(when (haskell-cabal-source-section-p section)
|
||||
(when (or silent
|
||||
(y-or-n-p (format "Add dependency %s to %s section %s?"
|
||||
dependency
|
||||
(haskell-cabal-section-name section)
|
||||
(haskell-cabal-section-value section))))
|
||||
(haskell-cabal-section-add-build-dependency dependency sort section)
|
||||
nil)))))
|
||||
|
||||
(defun haskell-cabal-add-dependency (package &optional version no-prompt
|
||||
sort silent)
|
||||
"Add PACKAGE (and optionally suffix -VERSION) to the cabal
|
||||
file. Prompts the user before doing so.
|
||||
|
||||
If VERSION is non-nil it will be appended as a minimum version.
|
||||
If NO-PROMPT is nil the minimum-version is read from the minibuffer
|
||||
When SORT is non-nil the package entries are sorted afterwards
|
||||
If SILENT ist nil the user is prompted for each source-section
|
||||
"
|
||||
(interactive
|
||||
(list (read-from-minibuffer "Package entry: ")
|
||||
nil t t nil))
|
||||
(save-window-excursion
|
||||
(find-file-other-window (haskell-cabal-find-file))
|
||||
(let ((entry (if no-prompt package
|
||||
(read-from-minibuffer
|
||||
"Package entry: "
|
||||
(concat package (if version (concat " >= " version) ""))))))
|
||||
(haskell-cabal-add-build-dependency entry sort silent)
|
||||
(when (or silent (y-or-n-p "Save cabal file?"))
|
||||
(save-buffer)))))
|
||||
|
||||
(provide 'haskell-cabal)
|
||||
|
||||
;;; haskell-cabal.el ends here
|
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-cabal.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-cabal.elc
Normal file
Binary file not shown.
177
.emacs.d/elpa/haskell-mode-13.12/haskell-checkers.el
Normal file
177
.emacs.d/elpa/haskell-mode-13.12/haskell-checkers.el
Normal file
@@ -0,0 +1,177 @@
|
||||
;;; haskell-checkers.el --- Emacs interface to haskell lint and style checkers
|
||||
|
||||
;; Copyright (C) 2009-2011 Alex Ott, Liam O'Reilly
|
||||
;;
|
||||
;; Author: Alex Ott <alexott@gmail.com>, Liam O'Reilly <csliam@swansea.ac.uk>
|
||||
;; Keywords: haskell, lint, hlint, style scanner
|
||||
;; Requirements: hlint, scan, haskell
|
||||
|
||||
;; 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 2 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:
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'compile)
|
||||
|
||||
(defgroup haskell-checkers nil
|
||||
"Run HLint as inferior of Emacs, parse error messages."
|
||||
:group 'tools
|
||||
:group 'haskell)
|
||||
|
||||
(defcustom hs-lint-command "hlint"
|
||||
"The default lint command for \\[hlint]."
|
||||
:type 'string
|
||||
:group 'haskell-checkers)
|
||||
|
||||
(defcustom hs-scan-command "scan"
|
||||
"The default scan command for \\[hs-scan]."
|
||||
:type 'string
|
||||
:group 'haskell-checkers)
|
||||
|
||||
(defcustom hs-scan-options ""
|
||||
"The default options for \\[hs-scan]."
|
||||
:type 'string
|
||||
:group 'haskell-checkers)
|
||||
|
||||
(defcustom hs-lint-options ""
|
||||
"The default options for \\[hlint]."
|
||||
:type 'string
|
||||
:group 'haskell-checkers)
|
||||
|
||||
(defcustom hs-checkers-save-files t
|
||||
"Save modified files when run checker or not (ask user)"
|
||||
:type 'boolean
|
||||
:group 'haskell-checkers)
|
||||
|
||||
(defcustom hs-checkers-replace-with-suggestions nil
|
||||
"Replace user's code with suggested replacements (hlint only)"
|
||||
:type 'boolean
|
||||
:group 'haskell-checkers)
|
||||
|
||||
(defcustom hs-checkers-replace-without-ask nil
|
||||
"Replace user's code with suggested replacements automatically (hlint only)"
|
||||
:type 'boolean
|
||||
:group 'haskell-checkers)
|
||||
|
||||
;; regex for replace HLint's suggestions
|
||||
;;
|
||||
;; ^\(.*?\):\([0-9]+\):\([0-9]+\): .*
|
||||
;; Found:
|
||||
;; \s +\(.*\)
|
||||
;; Why not:
|
||||
;; \s +\(.*\)
|
||||
|
||||
(defvar hs-lint-regex
|
||||
"^\\(.*?\\):\\([0-9]+\\):\\([0-9]+\\): .*[\n\C-m]Found:[\n\C-m]\\s +\\(.*\\)[\n\C-m]Why not:[\n\C-m]\\s +\\(.*\\)[\n\C-m]"
|
||||
"Regex for HLint messages")
|
||||
|
||||
(defun hs-checkers-make-short-string (str maxlen)
|
||||
(if (< (length str) maxlen)
|
||||
str
|
||||
(concat (substring str 0 (- maxlen 3)) "...")))
|
||||
|
||||
;; TODO: check, is it possible to adopt it for hs-scan?
|
||||
(defun hs-lint-replace-suggestions ()
|
||||
"Perform actual replacement of HLint's suggestions"
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward hs-lint-regex nil t)
|
||||
(let* ((fname (match-string 1))
|
||||
(fline (string-to-number (match-string 2)))
|
||||
(old-code (match-string 4))
|
||||
(new-code (match-string 5))
|
||||
(msg (concat "Replace '" (hs-checkers-make-short-string old-code 30)
|
||||
"' with '" (hs-checkers-make-short-string new-code 30) "'"))
|
||||
(bline 0)
|
||||
(eline 0)
|
||||
(spos 0)
|
||||
(new-old-code ""))
|
||||
(save-excursion
|
||||
(switch-to-buffer (get-file-buffer fname))
|
||||
(goto-char (point-min))
|
||||
(forward-line (1- fline))
|
||||
(beginning-of-line)
|
||||
(setq bline (point))
|
||||
(when (or hs-checkers-replace-without-ask
|
||||
(yes-or-no-p msg))
|
||||
(end-of-line)
|
||||
(setq eline (point))
|
||||
(beginning-of-line)
|
||||
(setq old-code (regexp-quote old-code))
|
||||
(while (string-match "\\\\ " old-code spos)
|
||||
(setq new-old-code (concat new-old-code
|
||||
(substring old-code spos (match-beginning 0))
|
||||
"\\ *"))
|
||||
(setq spos (match-end 0)))
|
||||
(setq new-old-code (concat new-old-code (substring old-code spos)))
|
||||
(remove-text-properties bline eline '(composition nil))
|
||||
(when (re-search-forward new-old-code eline t)
|
||||
(replace-match new-code nil t)))))))
|
||||
|
||||
(defun hs-lint-finish-hook (buf msg)
|
||||
"Function, that is executed at the end of HLint or scan execution"
|
||||
(if hs-checkers-replace-with-suggestions
|
||||
(hs-lint-replace-suggestions)
|
||||
(next-error 1 t)))
|
||||
|
||||
(defun hs-scan-finish-hook (buf msg)
|
||||
"Function, that is executed at the end of hs-scan execution"
|
||||
(next-error 1 t))
|
||||
|
||||
(defun hs-scan-make-command (file)
|
||||
"Generates command line for scan"
|
||||
(concat hs-scan-command " " hs-scan-options " \"" file "\""))
|
||||
|
||||
(defun hs-lint-make-command (file)
|
||||
"Generates command line for scan"
|
||||
(concat hs-lint-command " \"" file "\"" " " hs-lint-options))
|
||||
|
||||
(defmacro hs-checkers-setup (type name)
|
||||
"Performs setup of corresponding checker. Receives two arguments:
|
||||
type - checker's type (lint or scan) that is expanded into functions and hooks names
|
||||
name - user visible name for this mode"
|
||||
(let ((nm (concat "hs-" (symbol-name type))))
|
||||
`(progn
|
||||
;;;###autoload
|
||||
(defvar ,(intern (concat nm "-setup-hook")) nil
|
||||
,(concat "Hook, that will executed before running " name))
|
||||
(defun ,(intern (concat nm "-process-setup")) ()
|
||||
"Setup compilation variables and buffer for `hlint'."
|
||||
(run-hooks ',(intern (concat nm "-setup-hook"))))
|
||||
;;;###autoload
|
||||
(define-compilation-mode ,(intern (concat nm "-mode")) ,name
|
||||
,(concat "Mode to check Haskell source code using " name)
|
||||
(set (make-local-variable 'compilation-process-setup-function)
|
||||
',(intern (concat nm "-process-setup")))
|
||||
(set (make-local-variable 'compilation-disable-input) t)
|
||||
(set (make-local-variable 'compilation-scroll-output) nil)
|
||||
(set (make-local-variable 'compilation-finish-functions)
|
||||
(list ',(intern (concat nm "-finish-hook")))))
|
||||
;;;###autoload
|
||||
(defun ,(intern nm) ()
|
||||
,(concat "Run " name " for current buffer with haskell source")
|
||||
(interactive)
|
||||
(save-some-buffers hs-checkers-save-files)
|
||||
(compilation-start (,(intern (concat nm "-make-command")) buffer-file-name)
|
||||
',(intern (concat nm "-mode")))))
|
||||
))
|
||||
|
||||
(hs-checkers-setup lint "HLint")
|
||||
(hs-checkers-setup scan "HScan")
|
||||
|
||||
(provide 'haskell-checkers)
|
||||
|
||||
;;; haskell-checkers.el ends here
|
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-checkers.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-checkers.elc
Normal file
Binary file not shown.
65
.emacs.d/elpa/haskell-mode-13.12/haskell-collapse.el
Normal file
65
.emacs.d/elpa/haskell-mode-13.12/haskell-collapse.el
Normal file
@@ -0,0 +1,65 @@
|
||||
;;; haskell-collapse.el --- Collapse expressions
|
||||
|
||||
;; Copyright (c) 2014 Chris Done. All rights reserved.
|
||||
|
||||
;; 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(define-button-type 'haskell-collapse-toggle-button
|
||||
'action 'haskell-collapse-toggle-button-callback
|
||||
'follow-link t
|
||||
'help-echo "Click to expand…")
|
||||
|
||||
(defun haskell-collapse (beg end)
|
||||
"Collapse."
|
||||
(interactive "r")
|
||||
(goto-char end)
|
||||
(let ((break nil))
|
||||
(while (and (not break)
|
||||
(search-backward-regexp "[[({]" beg t 1))
|
||||
(unless (elt (syntax-ppss) 3)
|
||||
(let ((orig (point)))
|
||||
(haskell-collapse-sexp)
|
||||
(goto-char orig)
|
||||
(forward-char -1)
|
||||
(when (= (point) orig)
|
||||
(setq break t)))))))
|
||||
|
||||
(defun haskell-collapse-sexp ()
|
||||
"Collapse the sexp starting at point."
|
||||
(let ((beg (point)))
|
||||
(forward-sexp)
|
||||
(let ((end (point)))
|
||||
(let ((o (make-overlay beg end)))
|
||||
(overlay-put o 'invisible t)
|
||||
(let ((start (point)))
|
||||
(insert "…")
|
||||
(let ((button (make-text-button start (point)
|
||||
:type 'haskell-collapse-toggle-button)))
|
||||
(button-put button 'overlay o)
|
||||
(button-put button 'hide-on-click t)))))))
|
||||
|
||||
(defun haskell-collapse-toggle-button-callback (btn)
|
||||
"The callback to toggle the overlay visibility."
|
||||
(let ((overlay (button-get btn 'overlay)))
|
||||
(when overlay
|
||||
(overlay-put overlay
|
||||
'invisible
|
||||
(not (overlay-get overlay
|
||||
'invisible)))))
|
||||
(button-put btn 'invisible t)
|
||||
(delete-region (button-start btn) (button-end btn)))
|
||||
|
||||
(provide 'haskell-collapse)
|
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-collapse.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-collapse.elc
Normal file
Binary file not shown.
825
.emacs.d/elpa/haskell-mode-13.12/haskell-commands.el
Normal file
825
.emacs.d/elpa/haskell-mode-13.12/haskell-commands.el
Normal file
@@ -0,0 +1,825 @@
|
||||
;;; haskell-commands.el --- Commands that can be run on the process
|
||||
|
||||
;; Copyright (c) 2014 Chris Done. All rights reserved.
|
||||
|
||||
;; 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'cl-lib)
|
||||
(require 'etags)
|
||||
(require 'haskell-compat)
|
||||
(require 'haskell-process)
|
||||
(require 'haskell-font-lock)
|
||||
(require 'haskell-interactive-mode)
|
||||
(require 'haskell-session)
|
||||
(require 'highlight-uses-mode)
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-process-restart ()
|
||||
"Restart the inferior Haskell process."
|
||||
(interactive)
|
||||
(haskell-process-reset (haskell-interactive-process))
|
||||
(haskell-process-set (haskell-interactive-process) 'command-queue nil)
|
||||
(haskell-process-start (haskell-interactive-session)))
|
||||
|
||||
(defun haskell-process-start (session)
|
||||
"Start the inferior Haskell process."
|
||||
(let ((existing-process (get-process (haskell-session-name (haskell-interactive-session)))))
|
||||
(when (processp existing-process)
|
||||
(haskell-interactive-mode-echo session "Restarting process ...")
|
||||
(haskell-process-set (haskell-session-process session) 'is-restarting t)
|
||||
(delete-process existing-process)))
|
||||
(let ((process (or (haskell-session-process session)
|
||||
(haskell-process-make (haskell-session-name session))))
|
||||
(old-queue (haskell-process-get (haskell-session-process session)
|
||||
'command-queue)))
|
||||
(haskell-session-set-process session process)
|
||||
(haskell-process-set-session process session)
|
||||
(haskell-process-set-cmd process nil)
|
||||
(haskell-process-set (haskell-session-process session) 'is-restarting nil)
|
||||
(let ((default-directory (haskell-session-cabal-dir session))
|
||||
(log-and-command (haskell-process-compute-process-log-and-command session (haskell-process-type))))
|
||||
(haskell-session-pwd session)
|
||||
(haskell-process-set-process
|
||||
process
|
||||
(progn
|
||||
(haskell-process-log (propertize (format "%S" log-and-command)))
|
||||
(apply #'start-process (cdr log-and-command)))))
|
||||
(progn (set-process-sentinel (haskell-process-process process) 'haskell-process-sentinel)
|
||||
(set-process-filter (haskell-process-process process) 'haskell-process-filter))
|
||||
(haskell-process-send-startup process)
|
||||
(unless (eq 'cabal-repl (haskell-process-type)) ;; "cabal repl" sets the proper CWD
|
||||
(haskell-process-change-dir session
|
||||
process
|
||||
(haskell-session-current-dir session)))
|
||||
(haskell-process-set process 'command-queue
|
||||
(append (haskell-process-get (haskell-session-process session)
|
||||
'command-queue)
|
||||
old-queue))
|
||||
process))
|
||||
|
||||
(defun haskell-process-send-startup (process)
|
||||
"Send the necessary start messages."
|
||||
(haskell-process-queue-command
|
||||
process
|
||||
(make-haskell-command
|
||||
:state process
|
||||
|
||||
:go (lambda (process)
|
||||
(haskell-process-send-string process ":set prompt \"\\4\"")
|
||||
(haskell-process-send-string process "Prelude.putStrLn \"\"")
|
||||
(haskell-process-send-string process ":set -v1"))
|
||||
|
||||
:live (lambda (process buffer)
|
||||
(when (haskell-process-consume
|
||||
process
|
||||
"^\*\*\* WARNING: \\(.+\\) is writable by someone else, IGNORING!$")
|
||||
(let ((path (match-string 1 buffer)))
|
||||
(haskell-session-modify
|
||||
(haskell-process-session process)
|
||||
'ignored-files
|
||||
(lambda (files)
|
||||
(cl-remove-duplicates (cons path files) :test 'string=)))
|
||||
(haskell-interactive-mode-compile-warning
|
||||
(haskell-process-session process)
|
||||
(format "GHCi is ignoring: %s (run M-x haskell-process-unignore)"
|
||||
path)))))
|
||||
|
||||
:complete (lambda (process _)
|
||||
(haskell-interactive-mode-echo
|
||||
(haskell-process-session process)
|
||||
(concat (nth (random (length haskell-process-greetings))
|
||||
haskell-process-greetings)
|
||||
(when haskell-process-show-debug-tips
|
||||
"
|
||||
If I break, you can:
|
||||
1. Restart: M-x haskell-process-restart
|
||||
2. Configure logging: C-h v haskell-process-log (useful for debugging)
|
||||
3. General config: M-x customize-mode
|
||||
4. Hide these tips: C-h v haskell-process-show-debug-tips")))))))
|
||||
|
||||
(defun haskell-commands-process ()
|
||||
"Get the Haskell session, throws an error if not available."
|
||||
(or (haskell-session-process (haskell-session-maybe))
|
||||
(error "No Haskell session/process associated with this
|
||||
buffer. Maybe run M-x haskell-session-change?")))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-process-clear ()
|
||||
"Clear the current process."
|
||||
(interactive)
|
||||
(haskell-process-reset (haskell-commands-process))
|
||||
(haskell-process-set (haskell-commands-process) 'command-queue nil))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-process-interrupt ()
|
||||
"Interrupt the process (SIGINT)."
|
||||
(interactive)
|
||||
(interrupt-process (haskell-process-process (haskell-commands-process))))
|
||||
|
||||
(defun haskell-process-reload-with-fbytecode (process module-buffer)
|
||||
"Reload FILE-NAME with -fbyte-code set, and then restore -fobject-code."
|
||||
(haskell-process-queue-without-filters process ":set -fbyte-code")
|
||||
(haskell-process-touch-buffer process module-buffer)
|
||||
(haskell-process-queue-without-filters process ":reload")
|
||||
(haskell-process-queue-without-filters process ":set -fobject-code"))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-process-touch-buffer (process buffer)
|
||||
"Updates mtime on the file for BUFFER by queing a touch on
|
||||
PROCESS."
|
||||
(interactive)
|
||||
(haskell-process-queue-command
|
||||
process
|
||||
(make-haskell-command
|
||||
:state (cons process buffer)
|
||||
:go (lambda (state)
|
||||
(haskell-process-send-string
|
||||
(car state)
|
||||
(format ":!%s %s"
|
||||
"touch"
|
||||
(shell-quote-argument (buffer-file-name
|
||||
(cdr state))))))
|
||||
:complete (lambda (state _)
|
||||
(with-current-buffer (cdr state)
|
||||
(clear-visited-file-modtime))))))
|
||||
|
||||
(defvar url-http-response-status)
|
||||
(defvar url-http-end-of-headers)
|
||||
|
||||
(defun haskell-process-hayoo-ident (ident)
|
||||
"Hayoo for IDENT, returns a list of modules asyncronously through CALLBACK."
|
||||
;; We need a real/simulated closure, because otherwise these
|
||||
;; variables will be unbound when the url-retrieve callback is
|
||||
;; called.
|
||||
;; TODO: Remove when this code is converted to lexical bindings by
|
||||
;; default (Emacs 24.1+)
|
||||
(let ((url (format haskell-process-hayoo-query-url (url-hexify-string ident))))
|
||||
(with-current-buffer (url-retrieve-synchronously url)
|
||||
(if (= 200 url-http-response-status)
|
||||
(progn
|
||||
(goto-char url-http-end-of-headers)
|
||||
(let* ((res (json-read))
|
||||
(results (assoc-default 'result res)))
|
||||
;; TODO: gather packages as well, and when we choose a
|
||||
;; given import, check that we have the package in the
|
||||
;; cabal file as well.
|
||||
(cl-mapcan (lambda (r)
|
||||
;; append converts from vector -> list
|
||||
(append (assoc-default 'resultModules r) nil))
|
||||
results)))
|
||||
(warn "HTTP error %s fetching %s" url-http-response-status url)))))
|
||||
|
||||
(defun haskell-process-hoogle-ident (ident)
|
||||
"Hoogle for IDENT, returns a list of modules."
|
||||
(with-temp-buffer
|
||||
(let ((hoogle-error (call-process "hoogle" nil t nil "search" "--exact" ident)))
|
||||
(goto-char (point-min))
|
||||
(unless (or (/= 0 hoogle-error)
|
||||
(looking-at "^No results found")
|
||||
(looking-at "^package "))
|
||||
(while (re-search-forward "^\\([^ ]+\\).*$" nil t)
|
||||
(replace-match "\\1" nil nil))
|
||||
(cl-remove-if (lambda (a) (string= "" a))
|
||||
(split-string (buffer-string)
|
||||
"\n"))))))
|
||||
|
||||
(defun haskell-process-haskell-docs-ident (ident)
|
||||
"Search with haskell-docs for IDENT, returns a list of modules."
|
||||
(cl-remove-if-not (lambda (a) (string-match "^[A-Z][A-Za-b0-9_'.]+$" a))
|
||||
(split-string (shell-command-to-string (concat "haskell-docs --modules " ident))
|
||||
"\n")))
|
||||
|
||||
(defun haskell-process-import-modules (process modules)
|
||||
"Import `modules' with :m +, and send any import statements
|
||||
from `module-buffer'."
|
||||
(when haskell-process-auto-import-loaded-modules
|
||||
(haskell-process-queue-command
|
||||
process
|
||||
(make-haskell-command
|
||||
:state (cons process modules)
|
||||
:go (lambda (state)
|
||||
(haskell-process-send-string
|
||||
(car state)
|
||||
(format ":m + %s" (mapconcat 'identity (cdr state) " "))))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-describe (ident)
|
||||
"Describe the given identifier."
|
||||
(interactive (list (read-from-minibuffer "Describe identifier: "
|
||||
(haskell-ident-at-point))))
|
||||
(let ((results (read (shell-command-to-string
|
||||
(concat "haskell-docs --sexp "
|
||||
ident)))))
|
||||
(help-setup-xref (list #'haskell-describe ident)
|
||||
(called-interactively-p 'interactive))
|
||||
(save-excursion
|
||||
(with-help-window (help-buffer)
|
||||
(with-current-buffer (help-buffer)
|
||||
(if results
|
||||
(cl-loop for result in results
|
||||
do (insert (propertize ident 'font-lock-face
|
||||
'((:inherit font-lock-type-face
|
||||
:underline t)))
|
||||
" is defined in "
|
||||
(let ((module (cadr (assoc 'module result))))
|
||||
(if module
|
||||
(concat module " ")
|
||||
""))
|
||||
(cadr (assoc 'package result))
|
||||
"\n\n")
|
||||
do (let ((type (cadr (assoc 'type result))))
|
||||
(when type
|
||||
(insert (haskell-fontify-as-mode type 'haskell-mode)
|
||||
"\n")))
|
||||
do (let ((args (cadr (assoc 'type results))))
|
||||
(cl-loop for arg in args
|
||||
do (insert arg "\n"))
|
||||
(insert "\n"))
|
||||
do (insert (cadr (assoc 'documentation result)))
|
||||
do (insert "\n\n"))
|
||||
(insert "No results for " ident)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-rgrep (&optional prompt)
|
||||
"Grep the effective project for the symbol at point. Very
|
||||
useful for codebase navigation. Prompts for an arbitrary regexp
|
||||
given a prefix arg."
|
||||
(interactive "P")
|
||||
(let ((sym (if prompt
|
||||
(read-from-minibuffer "Look for: ")
|
||||
(haskell-ident-at-point))))
|
||||
(rgrep sym
|
||||
"*.hs" ;; TODO: common Haskell extensions.
|
||||
(haskell-session-current-dir (haskell-interactive-session)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-process-do-info (&optional prompt-value)
|
||||
"Print info on the identifier at point.
|
||||
If PROMPT-VALUE is non-nil, request identifier via mini-buffer."
|
||||
(interactive "P")
|
||||
(haskell-process-do-simple-echo
|
||||
(let ((ident (replace-regexp-in-string
|
||||
"^!\\([A-Z_a-z]\\)"
|
||||
"\\1"
|
||||
(if prompt-value
|
||||
(read-from-minibuffer "Info: " (haskell-ident-at-point))
|
||||
(haskell-ident-at-point))))
|
||||
(modname (unless prompt-value
|
||||
(haskell-utils-parse-import-statement-at-point))))
|
||||
(if modname
|
||||
(format ":browse! %s" modname)
|
||||
(format (if (string-match "^[a-zA-Z_]" ident)
|
||||
":info %s"
|
||||
":info (%s)")
|
||||
(or ident
|
||||
(haskell-ident-at-point)))))
|
||||
'haskell-mode))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-process-do-type (&optional insert-value)
|
||||
"Print the type of the given expression."
|
||||
(interactive "P")
|
||||
(if insert-value
|
||||
(haskell-process-insert-type)
|
||||
(haskell-process-do-simple-echo
|
||||
(let ((ident (haskell-ident-at-point)))
|
||||
;; TODO: Generalize all these `string-match' of ident calls into
|
||||
;; one function.
|
||||
(format (if (string-match "^[_[:lower:][:upper:]]" ident)
|
||||
":type %s"
|
||||
":type (%s)")
|
||||
ident))
|
||||
'haskell-mode)))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-mode-jump-to-def-or-tag (&optional next-p)
|
||||
"Jump to the definition (by consulting GHCi), or (fallback)
|
||||
jump to the tag.
|
||||
|
||||
Remember: If GHCi is busy doing something, this will delay, but
|
||||
it will always be accurate, in contrast to tags, which always
|
||||
work but are not always accurate.
|
||||
If the definition or tag is found, the location from which you jumped
|
||||
will be pushed onto `xref--marker-ring', so you can return to that
|
||||
position with `xref-pop-marker-stack'."
|
||||
(interactive "P")
|
||||
(let ((initial-loc (point-marker))
|
||||
(loc (haskell-mode-find-def (haskell-ident-at-point))))
|
||||
(if loc
|
||||
(haskell-mode-handle-generic-loc loc)
|
||||
(call-interactively 'haskell-mode-tag-find))
|
||||
(unless (equal initial-loc (point-marker))
|
||||
(save-excursion
|
||||
(goto-char initial-loc)
|
||||
(set-mark-command nil)
|
||||
;; Store position for return with `xref-pop-marker-stack'
|
||||
(xref-push-marker-stack)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-mode-goto-loc ()
|
||||
"Go to the location of the thing at point. Requires the :loc-at
|
||||
command from GHCi."
|
||||
(interactive)
|
||||
(let ((loc (haskell-mode-loc-at)))
|
||||
(when loc
|
||||
(haskell-mode-goto-span loc))))
|
||||
|
||||
(defun haskell-mode-goto-span (span)
|
||||
"Jump to the span, whatever file and line and column it needs
|
||||
to to get there."
|
||||
(xref-push-marker-stack)
|
||||
(find-file (expand-file-name (plist-get span :path)
|
||||
(haskell-session-cabal-dir (haskell-interactive-session))))
|
||||
(goto-char (point-min))
|
||||
(forward-line (1- (plist-get span :start-line)))
|
||||
(forward-char (plist-get span :start-col)))
|
||||
|
||||
(defun haskell-process-insert-type ()
|
||||
"Get the identifer at the point and insert its type, if
|
||||
possible, using GHCi's :type."
|
||||
(let ((process (haskell-interactive-process))
|
||||
(query (let ((ident (haskell-ident-at-point)))
|
||||
(format (if (string-match "^[_[:lower:][:upper:]]" ident)
|
||||
":type %s"
|
||||
":type (%s)")
|
||||
ident))))
|
||||
(haskell-process-queue-command
|
||||
process
|
||||
(make-haskell-command
|
||||
:state (list process query (current-buffer))
|
||||
:go (lambda (state)
|
||||
(haskell-process-send-string (nth 0 state)
|
||||
(nth 1 state)))
|
||||
:complete (lambda (state response)
|
||||
(cond
|
||||
;; TODO: Generalize this into a function.
|
||||
((or (string-match "^Top level" response)
|
||||
(string-match "^<interactive>" response))
|
||||
(message response))
|
||||
(t
|
||||
(with-current-buffer (nth 2 state)
|
||||
(goto-char (line-beginning-position))
|
||||
(insert (format "%s\n" (replace-regexp-in-string "\n$" "" response)))))))))))
|
||||
|
||||
(defun haskell-mode-find-def (ident)
|
||||
"Find definition location of identifier. Uses the GHCi process
|
||||
to find the location.
|
||||
|
||||
Returns:
|
||||
|
||||
(library <package> <module>)
|
||||
(file <path> <line> <col>)
|
||||
(module <name>)
|
||||
"
|
||||
(let ((reply (haskell-process-queue-sync-request
|
||||
(haskell-interactive-process)
|
||||
(format (if (string-match "^[a-zA-Z_]" ident)
|
||||
":info %s"
|
||||
":info (%s)")
|
||||
ident))))
|
||||
(let ((match (string-match "-- Defined \\(at\\|in\\) \\(.+\\)$" reply)))
|
||||
(when match
|
||||
(let ((defined (match-string 2 reply)))
|
||||
(let ((match (string-match "\\(.+?\\):\\([0-9]+\\):\\([0-9]+\\)$" defined)))
|
||||
(cond
|
||||
(match
|
||||
(list 'file
|
||||
(expand-file-name (match-string 1 defined)
|
||||
(haskell-session-current-dir (haskell-interactive-session)))
|
||||
(string-to-number (match-string 2 defined))
|
||||
(string-to-number (match-string 3 defined))))
|
||||
(t
|
||||
(let ((match (string-match "`\\(.+?\\):\\(.+?\\)'$" defined)))
|
||||
(if match
|
||||
(list 'library
|
||||
(match-string 1 defined)
|
||||
(match-string 2 defined))
|
||||
(let ((match (string-match "`\\(.+?\\)'$" defined)))
|
||||
(if match
|
||||
(list 'module
|
||||
(match-string 1 defined))))))))))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-mode-jump-to-def (ident)
|
||||
"Jump to definition of identifier at point."
|
||||
(interactive (list (haskell-ident-at-point)))
|
||||
(let ((loc (haskell-mode-find-def ident)))
|
||||
(when loc
|
||||
(haskell-mode-handle-generic-loc loc))))
|
||||
|
||||
(defun haskell-mode-handle-generic-loc (loc)
|
||||
"Either jump to or display a generic location. Either a file or
|
||||
a library."
|
||||
(cl-case (car loc)
|
||||
(file (haskell-mode-jump-to-loc (cdr loc)))
|
||||
(library (message "Defined in `%s' (%s)."
|
||||
(elt loc 2)
|
||||
(elt loc 1)))
|
||||
(module (message "Defined in `%s'."
|
||||
(elt loc 1)))))
|
||||
|
||||
(defun haskell-mode-loc-at ()
|
||||
"Get the location at point. Requires the :loc-at command from
|
||||
GHCi."
|
||||
(let ((pos (or (when (region-active-p)
|
||||
(cons (region-beginning)
|
||||
(region-end)))
|
||||
(haskell-spanable-pos-at-point)
|
||||
(cons (point)
|
||||
(point)))))
|
||||
(when pos
|
||||
(let ((reply (haskell-process-queue-sync-request
|
||||
(haskell-interactive-process)
|
||||
(save-excursion
|
||||
(format ":loc-at %s %d %d %d %d %s"
|
||||
(buffer-file-name)
|
||||
(progn (goto-char (car pos))
|
||||
(line-number-at-pos))
|
||||
(1+ (current-column)) ;; GHC uses 1-based columns.
|
||||
(progn (goto-char (cdr pos))
|
||||
(line-number-at-pos))
|
||||
(1+ (current-column)) ;; GHC uses 1-based columns.
|
||||
(buffer-substring-no-properties (car pos)
|
||||
(cdr pos)))))))
|
||||
(if reply
|
||||
(if (string-match "\\(.*?\\):(\\([0-9]+\\),\\([0-9]+\\))-(\\([0-9]+\\),\\([0-9]+\\))"
|
||||
reply)
|
||||
(list :path (match-string 1 reply)
|
||||
:start-line (string-to-number (match-string 2 reply))
|
||||
;; ;; GHC uses 1-based columns.
|
||||
:start-col (1- (string-to-number (match-string 3 reply)))
|
||||
:end-line (string-to-number (match-string 4 reply))
|
||||
;; GHC uses 1-based columns.
|
||||
:end-col (1- (string-to-number (match-string 5 reply))))
|
||||
(error (propertize reply 'face 'compilation-error)))
|
||||
(error (propertize "No reply. Is :loc-at supported?"
|
||||
'face 'compilation-error)))))))
|
||||
|
||||
(defun haskell-mode-type-at ()
|
||||
"Get the type of the thing at point. Requires the :type-at
|
||||
command from GHCi."
|
||||
(let ((pos (or (when (region-active-p)
|
||||
(cons (region-beginning)
|
||||
(region-end)))
|
||||
(haskell-spanable-pos-at-point)
|
||||
(cons (point)
|
||||
(point)))))
|
||||
(when pos
|
||||
(replace-regexp-in-string
|
||||
"\n$"
|
||||
""
|
||||
(save-excursion
|
||||
(haskell-process-queue-sync-request
|
||||
(haskell-interactive-process)
|
||||
(replace-regexp-in-string
|
||||
"\n"
|
||||
" "
|
||||
(format ":type-at %s %d %d %d %d %s"
|
||||
(buffer-file-name)
|
||||
(progn (goto-char (car pos))
|
||||
(line-number-at-pos))
|
||||
(1+ (current-column))
|
||||
(progn (goto-char (cdr pos))
|
||||
(line-number-at-pos))
|
||||
(1+ (current-column))
|
||||
(buffer-substring-no-properties (car pos)
|
||||
(cdr pos))))))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-process-cd (&optional not-interactive)
|
||||
"Change directory."
|
||||
(interactive)
|
||||
(let* ((session (haskell-interactive-session))
|
||||
(dir (haskell-session-pwd session t)))
|
||||
(haskell-process-log
|
||||
(propertize (format "Changing directory to %s ...\n" dir)
|
||||
'face font-lock-comment-face))
|
||||
(haskell-process-change-dir session
|
||||
(haskell-interactive-process)
|
||||
dir)))
|
||||
|
||||
(defun haskell-session-pwd (session &optional change)
|
||||
"Prompt for the current directory."
|
||||
(or (unless change
|
||||
(haskell-session-get session 'current-dir))
|
||||
(progn (haskell-session-set-current-dir
|
||||
session
|
||||
(haskell-utils-read-directory-name
|
||||
(if change "Change directory: " "Set current directory: ")
|
||||
(or (haskell-session-get session 'current-dir)
|
||||
(haskell-session-get session 'cabal-dir)
|
||||
(if (buffer-file-name)
|
||||
(file-name-directory (buffer-file-name))
|
||||
"~/"))))
|
||||
(haskell-session-get session 'current-dir))))
|
||||
|
||||
(defun haskell-process-change-dir (session process dir)
|
||||
"Change the directory of the current process."
|
||||
(haskell-process-queue-command
|
||||
process
|
||||
(make-haskell-command
|
||||
:state (list session process dir)
|
||||
:go
|
||||
(lambda (state)
|
||||
(haskell-process-send-string
|
||||
(cadr state) (format ":cd %s" (cl-caddr state))))
|
||||
|
||||
:complete
|
||||
(lambda (state _)
|
||||
(haskell-session-set-current-dir (car state) (cl-caddr state))
|
||||
(haskell-interactive-mode-echo (car state)
|
||||
(format "Changed directory: %s"
|
||||
(cl-caddr state)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-process-cabal-macros ()
|
||||
"Send the cabal macros string."
|
||||
(interactive)
|
||||
(haskell-process-queue-without-filters (haskell-interactive-process)
|
||||
":set -optP-include -optPdist/build/autogen/cabal_macros.h"))
|
||||
|
||||
(defun haskell-process-do-try-info (sym)
|
||||
"Get info of `sym' and echo in the minibuffer."
|
||||
(let ((process (haskell-interactive-process)))
|
||||
(haskell-process-queue-command
|
||||
process
|
||||
(make-haskell-command
|
||||
:state (cons process sym)
|
||||
:go (lambda (state)
|
||||
(haskell-process-send-string
|
||||
(car state)
|
||||
(if (string-match "^[A-Za-z_]" (cdr state))
|
||||
(format ":info %s" (cdr state))
|
||||
(format ":info (%s)" (cdr state)))))
|
||||
:complete (lambda (state response)
|
||||
(unless (or (string-match "^Top level" response)
|
||||
(string-match "^<interactive>" response))
|
||||
(haskell-mode-message-line response)))))))
|
||||
|
||||
(defun haskell-process-do-try-type (sym)
|
||||
"Get type of `sym' and echo in the minibuffer."
|
||||
(let ((process (haskell-interactive-process)))
|
||||
(haskell-process-queue-command
|
||||
process
|
||||
(make-haskell-command
|
||||
:state (cons process sym)
|
||||
:go (lambda (state)
|
||||
(haskell-process-send-string
|
||||
(car state)
|
||||
(if (string-match "^[A-Za-z_]" (cdr state))
|
||||
(format ":type %s" (cdr state))
|
||||
(format ":type (%s)" (cdr state)))))
|
||||
:complete (lambda (state response)
|
||||
(unless (or (string-match "^Top level" response)
|
||||
(string-match "^<interactive>" response))
|
||||
(haskell-mode-message-line response)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-mode-show-type-at (&optional insert-value)
|
||||
"Show the type of the thing at point."
|
||||
(interactive "P")
|
||||
(let ((ty (haskell-mode-type-at))
|
||||
(orig (point)))
|
||||
(if insert-value
|
||||
(let ((ident-pos (haskell-ident-pos-at-point)))
|
||||
(cond
|
||||
((region-active-p)
|
||||
(delete-region (region-beginning)
|
||||
(region-end))
|
||||
(insert "(" ty ")")
|
||||
(goto-char (1+ orig)))
|
||||
((= (line-beginning-position) (car ident-pos))
|
||||
(goto-char (line-beginning-position))
|
||||
(insert (haskell-fontify-as-mode ty 'haskell-mode)
|
||||
"\n"))
|
||||
(t
|
||||
(save-excursion
|
||||
(let ((col (save-excursion (goto-char (car ident-pos))
|
||||
(current-column))))
|
||||
(save-excursion (insert "\n")
|
||||
(indent-to col))
|
||||
(insert (haskell-fontify-as-mode ty 'haskell-mode)))))))
|
||||
(message "%s" (haskell-fontify-as-mode ty 'haskell-mode)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-process-generate-tags (&optional and-then-find-this-tag)
|
||||
"Regenerate the TAGS table."
|
||||
(interactive)
|
||||
(let ((process (haskell-interactive-process)))
|
||||
(haskell-process-queue-command
|
||||
process
|
||||
(make-haskell-command
|
||||
:state (cons process and-then-find-this-tag)
|
||||
:go (lambda (state)
|
||||
(if (eq system-type 'windows-nt)
|
||||
(haskell-process-send-string
|
||||
(car state)
|
||||
(format ":!powershell -Command \"& { cd %s ; hasktags -e -x (ls -fi *.hs *.lhs *.hsc -exclude \\\"#*#\\\" -name -r) ; exit }\""
|
||||
(haskell-session-cabal-dir
|
||||
(haskell-process-session (car state)))))
|
||||
(haskell-process-send-string
|
||||
(car state)
|
||||
(format ":!cd %s && %s | %s"
|
||||
(haskell-session-cabal-dir
|
||||
(haskell-process-session (car state)))
|
||||
"find . -name '*.hs' -print0 -or -name '*.lhs' -print0 -or -name '*.hsc' -print0"
|
||||
"xargs -0 hasktags -e -x"))))
|
||||
:complete (lambda (state response)
|
||||
(when (cdr state)
|
||||
(let ((tags-file-name
|
||||
(haskell-session-tags-filename
|
||||
(haskell-process-session (car state)))))
|
||||
(find-tag (cdr state))))
|
||||
(haskell-mode-message-line "Tags generated."))))))
|
||||
|
||||
(defun haskell-process-add-cabal-autogen ()
|
||||
"Add <cabal-project-dir>/dist/build/autogen/ to the ghci search
|
||||
path. This allows modules such as 'Path_...', generated by cabal,
|
||||
to be loaded by ghci."
|
||||
(unless (eq 'cabal-repl (haskell-process-type)) ;; redundant with "cabal repl"
|
||||
(let*
|
||||
((session (haskell-interactive-session))
|
||||
(cabal-dir (haskell-session-cabal-dir session))
|
||||
(ghci-gen-dir (format "%sdist/build/autogen/" cabal-dir)))
|
||||
(haskell-process-queue-without-filters
|
||||
(haskell-interactive-process)
|
||||
(format ":set -i%s" ghci-gen-dir)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-process-unignore ()
|
||||
"Unignore any files that were specified as being ignored by the
|
||||
inferior GHCi process."
|
||||
(interactive)
|
||||
(let ((session (haskell-interactive-session))
|
||||
(changed nil))
|
||||
(if (null (haskell-session-get session
|
||||
'ignored-files))
|
||||
(message "Nothing to unignore!")
|
||||
(cl-loop for file in (haskell-session-get session
|
||||
'ignored-files)
|
||||
do (cl-case (read-event
|
||||
(propertize (format "Set permissions? %s (y, n, v: stop and view file)"
|
||||
file)
|
||||
'face 'minibuffer-prompt))
|
||||
(?y
|
||||
(haskell-process-unignore-file session file)
|
||||
(setq changed t))
|
||||
(?v
|
||||
(find-file file)
|
||||
(cl-return))))
|
||||
(when (and changed
|
||||
(y-or-n-p "Restart GHCi process now? "))
|
||||
(haskell-process-restart)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-session-change-target (target)
|
||||
"Set the build target for cabal repl"
|
||||
(interactive "sNew build target:")
|
||||
(let* ((session haskell-session)
|
||||
(old-target (haskell-session-get session 'target)))
|
||||
(when session
|
||||
(haskell-session-set-target session target)
|
||||
(when (and (not (string= old-target target))
|
||||
(y-or-n-p "Target changed, restart haskell process?"))
|
||||
(haskell-process-start session)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-mode-stylish-buffer ()
|
||||
"Apply stylish-haskell to the current buffer."
|
||||
(interactive)
|
||||
(let ((column (current-column))
|
||||
(line (line-number-at-pos)))
|
||||
(haskell-mode-buffer-apply-command "stylish-haskell")
|
||||
(goto-char (point-min))
|
||||
(forward-line (1- line))
|
||||
(goto-char (+ column (point)))))
|
||||
|
||||
(defun haskell-mode-buffer-apply-command (cmd)
|
||||
"Execute shell command CMD with current buffer as input and
|
||||
replace the whole buffer with the output. If CMD fails the buffer
|
||||
remains unchanged."
|
||||
(set-buffer-modified-p t)
|
||||
(let* ((chomp (lambda (str)
|
||||
(while (string-match "\\`\n+\\|^\\s-+\\|\\s-+$\\|\n+\\'" str)
|
||||
(setq str (replace-match "" t t str)))
|
||||
str))
|
||||
(errout (lambda (fmt &rest args)
|
||||
(let* ((warning-fill-prefix " "))
|
||||
(display-warning cmd (apply 'format fmt args) :warning))))
|
||||
(filename (buffer-file-name (current-buffer)))
|
||||
(cmd-prefix (replace-regexp-in-string " .*" "" cmd))
|
||||
(tmp-file (make-temp-file cmd-prefix))
|
||||
(err-file (make-temp-file cmd-prefix))
|
||||
(default-directory (if (and (boundp 'haskell-session)
|
||||
haskell-session)
|
||||
(haskell-session-cabal-dir haskell-session)
|
||||
default-directory))
|
||||
(errcode (with-temp-file tmp-file
|
||||
(call-process cmd filename
|
||||
(list (current-buffer) err-file) nil)))
|
||||
(stderr-output
|
||||
(with-temp-buffer
|
||||
(insert-file-contents err-file)
|
||||
(funcall chomp (buffer-substring-no-properties (point-min) (point-max)))))
|
||||
(stdout-output
|
||||
(with-temp-buffer
|
||||
(insert-file-contents tmp-file)
|
||||
(buffer-substring-no-properties (point-min) (point-max)))))
|
||||
(if (string= "" stderr-output)
|
||||
(if (string= "" stdout-output)
|
||||
(funcall errout
|
||||
"Error: %s produced no output, leaving buffer alone" cmd)
|
||||
(save-restriction
|
||||
(widen)
|
||||
;; command successful, insert file with replacement to preserve
|
||||
;; markers.
|
||||
(insert-file-contents tmp-file nil nil nil t)))
|
||||
;; non-null stderr, command must have failed
|
||||
(funcall errout "%s failed: %s" cmd stderr-output))
|
||||
(delete-file tmp-file)
|
||||
(delete-file err-file)))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-mode-find-uses ()
|
||||
"Find uses of the identifier at point, highlight them all."
|
||||
(interactive)
|
||||
(let ((spans (haskell-mode-uses-at)))
|
||||
(unless (null spans)
|
||||
(highlight-uses-mode 1)
|
||||
(cl-loop for span in spans
|
||||
do (haskell-mode-make-use-highlight span)))))
|
||||
|
||||
(defun haskell-mode-make-use-highlight (span)
|
||||
"Make a highlight overlay at the given span."
|
||||
(save-window-excursion
|
||||
(save-excursion
|
||||
(haskell-mode-goto-span span)
|
||||
(save-excursion
|
||||
(highlight-uses-mode-highlight
|
||||
(progn
|
||||
(goto-char (point-min))
|
||||
(forward-line (1- (plist-get span :start-line)))
|
||||
(forward-char (plist-get span :start-col))
|
||||
(point))
|
||||
(progn
|
||||
(goto-char (point-min))
|
||||
(forward-line (1- (plist-get span :end-line)))
|
||||
(forward-char (plist-get span :end-col))
|
||||
(point)))))))
|
||||
|
||||
(defun haskell-mode-uses-at ()
|
||||
"Get the locations of uses for the ident at point. Requires
|
||||
the :uses command from GHCi."
|
||||
(let ((pos (or (when (region-active-p)
|
||||
(cons (region-beginning)
|
||||
(region-end)))
|
||||
(haskell-ident-pos-at-point)
|
||||
(cons (point)
|
||||
(point)))))
|
||||
(when pos
|
||||
(let ((reply (haskell-process-queue-sync-request
|
||||
(haskell-interactive-process)
|
||||
(save-excursion
|
||||
(format ":uses %s %d %d %d %d %s"
|
||||
(buffer-file-name)
|
||||
(progn (goto-char (car pos))
|
||||
(line-number-at-pos))
|
||||
(1+ (current-column)) ;; GHC uses 1-based columns.
|
||||
(progn (goto-char (cdr pos))
|
||||
(line-number-at-pos))
|
||||
(1+ (current-column)) ;; GHC uses 1-based columns.
|
||||
(buffer-substring-no-properties (car pos)
|
||||
(cdr pos)))))))
|
||||
(if reply
|
||||
(let ((lines (split-string reply "\n" t)))
|
||||
(cl-remove-if
|
||||
#'null
|
||||
(mapcar (lambda (line)
|
||||
(if (string-match "\\(.*?\\):(\\([0-9]+\\),\\([0-9]+\\))-(\\([0-9]+\\),\\([0-9]+\\))"
|
||||
line)
|
||||
(list :path (match-string 1 line)
|
||||
:start-line (string-to-number (match-string 2 line))
|
||||
;; ;; GHC uses 1-based columns.
|
||||
:start-col (1- (string-to-number (match-string 3 line)))
|
||||
:end-line (string-to-number (match-string 4 line))
|
||||
;; GHC uses 1-based columns.
|
||||
:end-col (1- (string-to-number (match-string 5 line))))
|
||||
(error (propertize line 'face 'compilation-error))))
|
||||
lines)))
|
||||
(error (propertize "No reply. Is :uses supported?"
|
||||
'face 'compilation-error)))))))
|
||||
|
||||
(provide 'haskell-commands)
|
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-commands.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-commands.elc
Normal file
Binary file not shown.
64
.emacs.d/elpa/haskell-mode-13.12/haskell-compat.el
Normal file
64
.emacs.d/elpa/haskell-mode-13.12/haskell-compat.el
Normal file
@@ -0,0 +1,64 @@
|
||||
;;; haskell-compat.el --- legacy/compatibility backports for haskell-mode
|
||||
;;
|
||||
;; Filename: haskell-compat.el
|
||||
;; Description: legacy/compatibility backports for haskell-mode
|
||||
|
||||
;; 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;;; Code:
|
||||
(require 'etags)
|
||||
(require 'ring)
|
||||
(require 'outline)
|
||||
(require 'xref nil t)
|
||||
|
||||
(eval-when-compile
|
||||
(setq byte-compile-warnings '(not cl-functions obsolete)))
|
||||
|
||||
;; Missing in Emacs23, stolen from Emacs24's `subr.el'
|
||||
(unless (fboundp 'process-live-p)
|
||||
(defun process-live-p (process)
|
||||
"Returns non-nil if PROCESS is alive.
|
||||
A process is considered alive if its status is `run', `open',
|
||||
`listen', `connect' or `stop'."
|
||||
(memq (process-status process)
|
||||
'(run open listen connect stop))))
|
||||
|
||||
;; Cross-referencing commands have been replaced since Emacs 25.1.
|
||||
;; These aliases are required to provide backward compatibility.
|
||||
(unless (fboundp 'xref-push-marker-stack)
|
||||
(defalias 'xref-pop-marker-stack 'pop-tag-mark)
|
||||
|
||||
(defun xref-push-marker-stack ()
|
||||
"Add point to the marker stack."
|
||||
(ring-insert find-tag-marker-ring (point-marker))))
|
||||
|
||||
(unless (fboundp 'outline-hide-sublevels)
|
||||
(defalias 'outline-hide-sublevels 'hide-sublevels))
|
||||
|
||||
(unless (fboundp 'outline-show-subtree)
|
||||
(defalias 'outline-show-subtree 'show-subtree))
|
||||
|
||||
(unless (fboundp 'outline-hide-sublevels)
|
||||
(defalias 'outline-hide-sublevels 'hide-sublevels))
|
||||
|
||||
(unless (fboundp 'outline-show-subtree)
|
||||
(defalias 'outline-show-subtree 'show-subtree))
|
||||
|
||||
(provide 'haskell-compat)
|
||||
|
||||
;;; haskell-compat.el ends here
|
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-compat.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-compat.elc
Normal file
Binary file not shown.
158
.emacs.d/elpa/haskell-mode-13.12/haskell-compile.el
Normal file
158
.emacs.d/elpa/haskell-mode-13.12/haskell-compile.el
Normal file
@@ -0,0 +1,158 @@
|
||||
;;; haskell-compile.el --- Haskell/GHC compilation sub-mode
|
||||
|
||||
;; Copyright (C) 2013 Herbert Valerio Riedel
|
||||
|
||||
;; Author: Herbert Valerio Riedel <hvr@gnu.org>
|
||||
|
||||
;; 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 of the License, 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Simple GHC-centric compilation sub-mode; see info node
|
||||
;; `(haskell-mode)compilation' for more information
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'compile)
|
||||
(require 'haskell-cabal)
|
||||
|
||||
(defgroup haskell-compile nil
|
||||
"Settings for Haskell compilation mode"
|
||||
:link '(custom-manual "(haskell-mode)compilation")
|
||||
:group 'haskell)
|
||||
|
||||
(defcustom haskell-compile-cabal-build-command
|
||||
"cd %s && cabal build --ghc-option=-ferror-spans"
|
||||
"Default build command to use for `haskell-cabal-build' when a cabal file is detected.
|
||||
The `%s' placeholder is replaced by the cabal package top folder."
|
||||
:group 'haskell-compile
|
||||
:type 'string)
|
||||
|
||||
(defcustom haskell-compile-cabal-build-alt-command
|
||||
"cd %s && cabal clean -s && cabal build --ghc-option=-ferror-spans"
|
||||
"Alternative build command to use when `haskell-cabal-build' is called with a negative prefix argument.
|
||||
The `%s' placeholder is replaced by the cabal package top folder."
|
||||
:group 'haskell-compile
|
||||
:type 'string)
|
||||
|
||||
(defcustom haskell-compile-command
|
||||
"ghc -Wall -ferror-spans -fforce-recomp -c %s"
|
||||
"Default build command to use for `haskell-cabal-build' when no cabal file is detected.
|
||||
The `%s' placeholder is replaced by the current buffer's filename."
|
||||
:group 'haskell-compile
|
||||
:type 'string)
|
||||
|
||||
(defcustom haskell-compile-ghc-filter-linker-messages
|
||||
t
|
||||
"Filter out unremarkable \"Loading package...\" linker messages during compilation."
|
||||
:group 'haskell-compile
|
||||
:type 'boolean)
|
||||
|
||||
(defconst haskell-compilation-error-regexp-alist
|
||||
`((,(concat
|
||||
"^\\(?1:[^ \t\r\n]+?\\):"
|
||||
"\\(?:"
|
||||
"\\(?2:[0-9]+\\):\\(?4:[0-9]+\\)\\(?:-\\(?5:[0-9]+\\)\\)?" ;; "121:1" & "12:3-5"
|
||||
"\\|"
|
||||
"(\\(?2:[0-9]+\\),\\(?4:[0-9]+\\))-(\\(?3:[0-9]+\\),\\(?5:[0-9]+\\))" ;; "(289,5)-(291,36)"
|
||||
"\\)"
|
||||
":\\(?6: Warning:\\)?")
|
||||
1 (2 . 3) (4 . 5) (6 . nil)) ;; error/warning locus
|
||||
|
||||
;; multiple declarations
|
||||
("^ \\(?:Declared at:\\| \\) \\(?1:[^ \t\r\n]+\\):\\(?2:[0-9]+\\):\\(?4:[0-9]+\\)$"
|
||||
1 2 4 0) ;; info locus
|
||||
|
||||
;; this is the weakest pattern as it's subject to line wrapping et al.
|
||||
(" at \\(?1:[^ \t\r\n]+\\):\\(?2:[0-9]+\\):\\(?4:[0-9]+\\)\\(?:-\\(?5:[0-9]+\\)\\)?[)]?$"
|
||||
1 2 (4 . 5) 0)) ;; info locus
|
||||
"Regexps used for matching GHC compile messages.
|
||||
See `compilation-error-regexp-alist' for semantics.")
|
||||
|
||||
(defvar haskell-compilation-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(set-keymap-parent map compilation-mode-map))
|
||||
"Keymap for `haskell-compilation-mode' buffers.
|
||||
This is a child of `compilation-mode-map'.")
|
||||
|
||||
(defun haskell-compilation-filter-hook ()
|
||||
"Local `compilation-filter-hook' for `haskell-compilation-mode'."
|
||||
|
||||
(when haskell-compile-ghc-filter-linker-messages
|
||||
(delete-matching-lines "^Loading package [^ \t\r\n]+ [.]+ linking [.]+ done\\.$"
|
||||
(if (boundp 'compilation-filter-start) ;; available since Emacs 24.2
|
||||
(save-excursion (goto-char compilation-filter-start)
|
||||
(line-beginning-position))
|
||||
(point-min))
|
||||
(point))))
|
||||
|
||||
(define-compilation-mode haskell-compilation-mode "HsCompilation"
|
||||
"Haskell/GHC specific `compilation-mode' derivative.
|
||||
This mode provides support for GHC 7.[46]'s compile
|
||||
messages. Specifically, also the `-ferror-spans` source location
|
||||
format is supported, as well as info-locations within compile
|
||||
messages pointing to additional source locations.
|
||||
|
||||
See Info node `(haskell-mode)compilation' for more details."
|
||||
(set (make-local-variable 'compilation-error-regexp-alist)
|
||||
haskell-compilation-error-regexp-alist)
|
||||
|
||||
(add-hook 'compilation-filter-hook
|
||||
'haskell-compilation-filter-hook nil t)
|
||||
)
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-compile (&optional edit-command)
|
||||
"Compile the Haskell program including the current buffer.
|
||||
Tries to locate the next cabal description in current or parent
|
||||
folders via `haskell-cabal-find-dir' and if found, invoke
|
||||
`haskell-compile-cabal-build-command' from the cabal package root
|
||||
folder. If no cabal package could be detected,
|
||||
`haskell-compile-command' is used instead.
|
||||
|
||||
If prefix argument EDIT-COMMAND is non-nil (and not a negative
|
||||
prefix `-'), `haskell-compile' prompts for custom compile
|
||||
command.
|
||||
|
||||
If EDIT-COMMAND contains the negative prefix argument `-',
|
||||
`haskell-compile' calls the alternative command defined in
|
||||
`haskell-compile-cabal-build-alt-command' if a cabal package was
|
||||
detected.
|
||||
|
||||
`haskell-compile' uses `haskell-compilation-mode' which is
|
||||
derived from `compilation-mode'. See Info
|
||||
node `(haskell-mode)compilation' for more details."
|
||||
(interactive "P")
|
||||
(save-some-buffers (not compilation-ask-about-save)
|
||||
(if (boundp 'compilation-save-buffers-predicate) ;; since Emacs 24.1(?)
|
||||
compilation-save-buffers-predicate))
|
||||
(let* ((cabdir (haskell-cabal-find-dir))
|
||||
(command1 (if (eq edit-command '-)
|
||||
haskell-compile-cabal-build-alt-command
|
||||
haskell-compile-cabal-build-command))
|
||||
(srcname (buffer-file-name))
|
||||
(command (if cabdir
|
||||
(format command1 cabdir)
|
||||
(if (and srcname (derived-mode-p 'haskell-mode))
|
||||
(format haskell-compile-command srcname)
|
||||
command1))))
|
||||
(when (and edit-command (not (eq edit-command '-)))
|
||||
(setq command (compilation-read-command command)))
|
||||
|
||||
(compilation-start command 'haskell-compilation-mode)))
|
||||
|
||||
(provide 'haskell-compile)
|
||||
;;; haskell-compile.el ends here
|
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-compile.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-compile.elc
Normal file
Binary file not shown.
132
.emacs.d/elpa/haskell-mode-13.12/haskell-complete-module.el
Normal file
132
.emacs.d/elpa/haskell-mode-13.12/haskell-complete-module.el
Normal file
@@ -0,0 +1,132 @@
|
||||
;;; haskell-complete-module.el --- A fast way to complete Haskell module names
|
||||
|
||||
;; Copyright (c) 2014 Chris Done. All rights reserved.
|
||||
|
||||
;; 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'cl-lib)
|
||||
|
||||
(defcustom haskell-complete-module-preferred
|
||||
'()
|
||||
"Override ordering of module results by specifying preferred modules."
|
||||
:group 'haskell
|
||||
:type '(repeat string))
|
||||
|
||||
(defcustom haskell-complete-module-max-display
|
||||
10
|
||||
"Maximum items to display in minibuffer."
|
||||
:group 'haskell
|
||||
:type 'number)
|
||||
|
||||
(defun haskell-complete-module-read (prompt candidates)
|
||||
"Interactively auto-complete from a list of candidates."
|
||||
(let ((continue t)
|
||||
(stack (list))
|
||||
(pattern "")
|
||||
(result nil))
|
||||
(delete-dups candidates)
|
||||
(setq candidates
|
||||
(sort candidates
|
||||
(lambda (a b)
|
||||
(let ((a-mem (member a haskell-complete-module-preferred))
|
||||
(b-mem (member b haskell-complete-module-preferred)))
|
||||
(cond
|
||||
((and a-mem (not b-mem))
|
||||
t)
|
||||
((and b-mem (not a-mem))
|
||||
nil)
|
||||
(t
|
||||
(string< a b)))))))
|
||||
(while (not result)
|
||||
(let ((key
|
||||
(key-description
|
||||
(vector
|
||||
(read-key
|
||||
(concat (propertize prompt 'face 'minibuffer-prompt)
|
||||
(propertize pattern 'face 'font-lock-type-face)
|
||||
"{"
|
||||
(mapconcat #'identity
|
||||
(let* ((i 0))
|
||||
(cl-loop for candidate in candidates
|
||||
while (<= i haskell-complete-module-max-display)
|
||||
do (cl-incf i)
|
||||
collect (cond ((> i haskell-complete-module-max-display)
|
||||
"...")
|
||||
((= i 1)
|
||||
(propertize candidate 'face 'ido-first-match-face))
|
||||
(t candidate))))
|
||||
" | ")
|
||||
"}"))))))
|
||||
(cond
|
||||
((string= key "C-g")
|
||||
(keyboard-quit))
|
||||
((string= key "DEL")
|
||||
(unless (null stack)
|
||||
(setq candidates (pop stack)))
|
||||
(unless (string= "" pattern)
|
||||
(setq pattern (substring pattern 0 -1))))
|
||||
((string= key "RET")
|
||||
(setq result (or (car candidates)
|
||||
pattern)))
|
||||
((string= key "<left>")
|
||||
(setq candidates
|
||||
(append (last candidates)
|
||||
(butlast candidates))))
|
||||
((string= key "<right>")
|
||||
(setq candidates
|
||||
(append (cdr candidates)
|
||||
(list (car candidates)))))
|
||||
(t
|
||||
(when (string-match "[A-Za-z0-9_'.]+" key)
|
||||
(push candidates stack)
|
||||
(setq pattern (concat pattern key))
|
||||
(setq candidates (haskell-complete-module pattern candidates)))))))
|
||||
result))
|
||||
|
||||
(defun haskell-complete-module (pattern candidates)
|
||||
"Filter the CANDIDATES using PATTERN."
|
||||
(let ((case-fold-search t))
|
||||
(cl-loop for candidate in candidates
|
||||
when (haskell-complete-module-match pattern candidate)
|
||||
collect candidate)))
|
||||
|
||||
(defun haskell-complete-module-match (pattern text)
|
||||
"Match PATTERN against TEXT."
|
||||
(string-match (haskell-complete-module-regexp pattern)
|
||||
text))
|
||||
|
||||
(defun haskell-complete-module-regexp (pattern)
|
||||
"Make a regular expression for the given module pattern. Example:
|
||||
|
||||
\"c.m.s\" -> \"^c[^.]*\\.m[^.]*\\.s[^.]*\"
|
||||
|
||||
"
|
||||
(let ((components (mapcar #'haskell-complete-module-component
|
||||
(split-string pattern "\\." t))))
|
||||
(concat "^"
|
||||
(mapconcat #'identity
|
||||
components
|
||||
"\\."))))
|
||||
|
||||
(defun haskell-complete-module-component (component)
|
||||
"Make a regular expression for the given component. Example:
|
||||
|
||||
\"co\" -> \"c[^.]*o[^.]*\"
|
||||
|
||||
"
|
||||
(replace-regexp-in-string "\\(.\\)" "\\1[^.]*" component))
|
||||
|
||||
(provide 'haskell-complete-module)
|
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-complete-module.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-complete-module.elc
Normal file
Binary file not shown.
362
.emacs.d/elpa/haskell-mode-13.12/haskell-customize.el
Normal file
362
.emacs.d/elpa/haskell-mode-13.12/haskell-customize.el
Normal file
@@ -0,0 +1,362 @@
|
||||
;;; haskell-customize.el --- Customization settings
|
||||
|
||||
;; Copyright (c) 2014 Chris Done. All rights reserved.
|
||||
|
||||
;; 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'cl-lib)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Customization variables
|
||||
|
||||
(defgroup haskell nil
|
||||
"Major mode for editing Haskell programs."
|
||||
:link '(custom-manual "(haskell-mode)")
|
||||
:group 'languages
|
||||
:prefix "haskell-")
|
||||
|
||||
(defvar haskell-mode-pkg-base-dir (file-name-directory load-file-name)
|
||||
"Package base directory of installed `haskell-mode'.
|
||||
Used for locating additional package data files.")
|
||||
|
||||
(defcustom haskell-completing-read-function 'ido-completing-read
|
||||
"Default function to use for completion."
|
||||
:group 'haskell
|
||||
:type '(choice
|
||||
(function-item :tag "ido" :value ido-completing-read)
|
||||
(function-item :tag "helm" :value helm--completing-read-default)
|
||||
(function-item :tag "completing-read" :value completing-read)
|
||||
(function :tag "Custom function")))
|
||||
|
||||
(defcustom haskell-process-type
|
||||
'auto
|
||||
"The inferior Haskell process type to use."
|
||||
:type '(choice (const auto) (const ghci) (const cabal-repl) (const cabal-dev) (const cabal-ghci))
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-process-wrapper-function
|
||||
#'identity
|
||||
"Wrap or transform haskell process commands using this function.
|
||||
|
||||
Can be set to a custom function which takes a list of arguments
|
||||
and returns a possibly-modified list.
|
||||
|
||||
The following example function arranges for all haskell process
|
||||
commands to be started in the current nix-shell environment:
|
||||
|
||||
(lambda (argv) (append (list \"nix-shell\" \"-I\" \".\" \"--command\" )
|
||||
(list (mapconcat 'identity argv \" \"))))
|
||||
|
||||
See Info Node `(emacs)Directory Variables' for a way to set this option on
|
||||
a per-project basis."
|
||||
:group 'haskell-interactive
|
||||
:type '(choice
|
||||
(function-item :tag "None" :value identity)
|
||||
(function :tag "Custom function")))
|
||||
|
||||
(defcustom haskell-ask-also-kill-buffers
|
||||
t
|
||||
"Ask whether to kill all associated buffers when a session
|
||||
process is killed."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Configuration
|
||||
|
||||
(defvar haskell-process-end-hook nil
|
||||
"Hook for when the haskell process ends.")
|
||||
|
||||
(defgroup haskell-interactive nil
|
||||
"Settings for REPL interaction via `haskell-interactive-mode'"
|
||||
:link '(custom-manual "(haskell-mode)haskell-interactive-mode")
|
||||
:group 'haskell)
|
||||
|
||||
(defcustom haskell-process-path-ghci
|
||||
"ghci"
|
||||
"The path for starting ghci."
|
||||
:group 'haskell-interactive
|
||||
:type '(choice string (repeat string)))
|
||||
|
||||
(defcustom haskell-process-path-cabal
|
||||
"cabal"
|
||||
"Path to the `cabal' executable."
|
||||
:group 'haskell-interactive
|
||||
:type '(choice string (repeat string)))
|
||||
|
||||
(defcustom haskell-process-path-cabal-ghci
|
||||
"cabal-ghci"
|
||||
"The path for starting cabal-ghci."
|
||||
:group 'haskell-interactive
|
||||
:type '(choice string (repeat string)))
|
||||
|
||||
(defcustom haskell-process-path-cabal-dev
|
||||
"cabal-dev"
|
||||
"The path for starting cabal-dev."
|
||||
:group 'haskell-interactive
|
||||
:type '(choice string (repeat string)))
|
||||
|
||||
(defcustom haskell-process-args-ghci
|
||||
'("-ferror-spans")
|
||||
"Any arguments for starting ghci."
|
||||
:group 'haskell-interactive
|
||||
:type '(repeat (string :tag "Argument")))
|
||||
|
||||
(defcustom haskell-process-args-cabal-repl
|
||||
'("--ghc-option=-ferror-spans")
|
||||
"Additional arguments to for `cabal repl' invocation.
|
||||
Note: The settings in `haskell-process-path-ghci' and
|
||||
`haskell-process-args-ghci' are not automatically reused as `cabal repl'
|
||||
currently invokes `ghc --interactive'. Use
|
||||
`--with-ghc=<path-to-executable>' if you want to use a different
|
||||
interactive GHC frontend; use `--ghc-option=<ghc-argument>' to
|
||||
pass additional flags to `ghc'."
|
||||
:group 'haskell-interactive
|
||||
:type '(repeat (string :tag "Argument")))
|
||||
|
||||
(defcustom haskell-process-do-cabal-format-string
|
||||
":!cd %s && %s"
|
||||
"The way to run cabal comands. It takes two arguments -- the directory and the command.
|
||||
See `haskell-process-do-cabal' for more details."
|
||||
:group 'haskell-interactive
|
||||
:type 'string)
|
||||
|
||||
(defcustom haskell-process-log
|
||||
nil
|
||||
"Enable debug logging to \"*haskell-process-log*\" buffer."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-process-show-debug-tips
|
||||
t
|
||||
"Show debugging tips when starting the process."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-notify-p
|
||||
nil
|
||||
"Notify using notifications.el (if loaded)?"
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-process-suggest-no-warn-orphans
|
||||
t
|
||||
"Suggest adding -fno-warn-orphans pragma to file when getting orphan warnings."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-process-suggest-hoogle-imports
|
||||
nil
|
||||
"Suggest to add import statements using Hoogle as a backend."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-process-suggest-hayoo-imports
|
||||
nil
|
||||
"Suggest to add import statements using Hayoo as a backend."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-process-hayoo-query-url
|
||||
"http://hayoo.fh-wedel.de/json/?query=%s"
|
||||
"Query url for json hayoo results."
|
||||
:type 'string
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-process-suggest-haskell-docs-imports
|
||||
nil
|
||||
"Suggest to add import statements using haskell-docs as a backend."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-process-suggest-add-package
|
||||
t
|
||||
"Suggest to add packages to your .cabal file when Cabal says it
|
||||
is a member of the hidden package, blah blah."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-process-suggest-language-pragmas
|
||||
t
|
||||
"Suggest adding LANGUAGE pragmas recommended by GHC."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-process-suggest-remove-import-lines
|
||||
nil
|
||||
"Suggest removing import lines as warned by GHC."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-process-suggest-overloaded-strings
|
||||
t
|
||||
"Suggest adding OverloadedStrings pragma to file when getting type mismatches with [Char]."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-process-check-cabal-config-on-load
|
||||
t
|
||||
"Check changes cabal config on loading Haskell files and
|
||||
restart the GHCi process if changed.."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-process-prompt-restart-on-cabal-change
|
||||
t
|
||||
"Ask whether to restart the GHCi process when the Cabal file
|
||||
has changed?"
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-process-auto-import-loaded-modules
|
||||
nil
|
||||
"Auto import the modules reported by GHC to have been loaded?"
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-process-reload-with-fbytecode
|
||||
nil
|
||||
"When using -fobject-code, auto reload with -fbyte-code (and
|
||||
then restore the -fobject-code) so that all module info and
|
||||
imports become available?"
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-process-use-presentation-mode
|
||||
nil
|
||||
"Use presentation mode to show things like type info instead of
|
||||
printing to the message area."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-process-suggest-restart
|
||||
t
|
||||
"Suggest restarting the process when it has died"
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-interactive-mode-scroll-to-bottom
|
||||
nil
|
||||
"Scroll to bottom in the REPL always."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-interactive-popup-errors
|
||||
t
|
||||
"Popup errors in a separate buffer."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-interactive-mode-collapse
|
||||
nil
|
||||
"Collapse printed results."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-interactive-types-for-show-ambiguous
|
||||
t
|
||||
"Show types when there's no Show instance or there's an
|
||||
ambiguous class constraint."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-interactive-mode-eval-pretty
|
||||
nil
|
||||
"Print eval results that can be parsed as Show instances prettily. Requires sexp-show (on Hackage)."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defvar haskell-interactive-prompt "λ> "
|
||||
"The prompt to use.")
|
||||
|
||||
(defcustom haskell-interactive-mode-eval-mode
|
||||
nil
|
||||
"Use the given mode's font-locking to render some text."
|
||||
:type '(choice function (const :tag "None" nil))
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-interactive-mode-hide-multi-line-errors
|
||||
nil
|
||||
"Hide collapsible multi-line compile messages by default."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-interactive-mode-delete-superseded-errors
|
||||
t
|
||||
"Whether to delete compile messages superseded by recompile/reloads."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-interactive-mode-include-file-name
|
||||
t
|
||||
"Include the file name of the module being compiled when
|
||||
printing compilation messages."
|
||||
:type 'boolean
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-import-mapping
|
||||
'()
|
||||
"Support a mapping from module to import lines.
|
||||
|
||||
E.g. '((\"Data.Map\" . \"import qualified Data.Map as M
|
||||
import Data.Map (Map)
|
||||
\"))
|
||||
|
||||
This will import
|
||||
|
||||
import qualified Data.Map as M
|
||||
import Data.Map (Map)
|
||||
|
||||
when Data.Map is the candidate.
|
||||
|
||||
"
|
||||
:type '(repeat (cons (string :tag "Module name")
|
||||
(string :tag "Import lines")))
|
||||
:group 'haskell-interactive)
|
||||
|
||||
(defcustom haskell-language-extensions
|
||||
'()
|
||||
"Language extensions in use. Should be in format: -XFoo, -XNoFoo etc."
|
||||
:group 'shm
|
||||
:type '(repeat 'string))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Accessor functions
|
||||
|
||||
(defun haskell-process-type ()
|
||||
"Return `haskell-process-type', or a guess if that variable is 'auto."
|
||||
(if (eq 'auto haskell-process-type)
|
||||
(if (locate-dominating-file
|
||||
default-directory
|
||||
(lambda (d)
|
||||
(or (file-directory-p (expand-file-name ".cabal-sandbox" d))
|
||||
(cl-find-if (lambda (f) (string-match-p ".\\.cabal\\'" f)) (directory-files d)))))
|
||||
'cabal-repl
|
||||
'ghci)
|
||||
haskell-process-type))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-customize ()
|
||||
"Browse the haskell customize sub-tree.
|
||||
This calls 'customize-browse' with haskell as argument and makes
|
||||
sure all haskell customize definitions have been loaded."
|
||||
(interactive)
|
||||
;; make sure all modules with (defcustom ...)s are loaded
|
||||
(mapc 'require
|
||||
'(haskell-checkers haskell-compile haskell-doc haskell-font-lock haskell-indentation haskell-indent haskell-interactive-mode haskell-menu haskell-process haskell-yas inf-haskell))
|
||||
(customize-browse 'haskell))
|
||||
|
||||
(provide 'haskell-customize)
|
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-customize.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-customize.elc
Normal file
Binary file not shown.
738
.emacs.d/elpa/haskell-mode-13.12/haskell-debug.el
Normal file
738
.emacs.d/elpa/haskell-mode-13.12/haskell-debug.el
Normal file
@@ -0,0 +1,738 @@
|
||||
;;; haskell-debug.el --- Debugging mode via GHCi
|
||||
|
||||
;; Copyright (c) 2014 Chris Done. All rights reserved.
|
||||
|
||||
;; 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'cl-lib)
|
||||
(require 'haskell-session)
|
||||
(require 'haskell-process)
|
||||
(require 'haskell-interactive-mode)
|
||||
(require 'haskell-font-lock)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Configuration
|
||||
|
||||
(defgroup haskell-debug nil
|
||||
"Settings for debugging support."
|
||||
:link '(custom-manual "(haskell-mode)haskell-debug")
|
||||
:group 'haskell)
|
||||
|
||||
(defface haskell-debug-warning-face
|
||||
'((t :inherit 'compilation-warning))
|
||||
"Face for warnings."
|
||||
:group 'haskell-debug)
|
||||
|
||||
(defface haskell-debug-trace-number-face
|
||||
'((t :weight bold :background "#f5f5f5"))
|
||||
"Face for numbers in backtrace."
|
||||
:group 'haskell-debug)
|
||||
|
||||
(defface haskell-debug-newline-face
|
||||
'((t :weight bold :background "#f0f0f0"))
|
||||
"Face for newlines in trace steps."
|
||||
:group 'haskell-debug)
|
||||
|
||||
(defface haskell-debug-keybinding-face
|
||||
'((t :inherit 'font-lock-type-face :weight bold))
|
||||
"Face for keybindings."
|
||||
:group 'haskell-debug)
|
||||
|
||||
(defface haskell-debug-heading-face
|
||||
'((t :inherit 'font-lock-keyword-face))
|
||||
"Face for headings."
|
||||
:group 'haskell-debug)
|
||||
|
||||
(defface haskell-debug-muted-face
|
||||
'((t :foreground "#999"))
|
||||
"Face for muteds."
|
||||
:group 'haskell-debug)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Mode
|
||||
|
||||
(define-derived-mode haskell-debug-mode
|
||||
text-mode "Debug"
|
||||
"Major mode for debugging Haskell via GHCi.")
|
||||
|
||||
(define-key haskell-debug-mode-map (kbd "g") 'haskell-debug/refresh)
|
||||
(define-key haskell-debug-mode-map (kbd "s") 'haskell-debug/step)
|
||||
(define-key haskell-debug-mode-map (kbd "t") 'haskell-debug/trace)
|
||||
(define-key haskell-debug-mode-map (kbd "d") 'haskell-debug/delete)
|
||||
(define-key haskell-debug-mode-map (kbd "b") 'haskell-debug/break-on-function)
|
||||
(define-key haskell-debug-mode-map (kbd "a") 'haskell-debug/abandon)
|
||||
(define-key haskell-debug-mode-map (kbd "c") 'haskell-debug/continue)
|
||||
(define-key haskell-debug-mode-map (kbd "p") 'haskell-debug/previous)
|
||||
(define-key haskell-debug-mode-map (kbd "n") 'haskell-debug/next)
|
||||
(define-key haskell-debug-mode-map (kbd "RET") 'haskell-debug/select)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Globals
|
||||
|
||||
(defvar haskell-debug-history-cache nil
|
||||
"Cache of the tracing history.")
|
||||
|
||||
(defvar haskell-debug-bindings-cache nil
|
||||
"Cache of the current step's bindings.")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Macros
|
||||
|
||||
(defmacro haskell-debug-with-breakpoints (&rest body)
|
||||
"Breakpoints need to exist to start stepping."
|
||||
`(if (haskell-debug-get-breakpoints)
|
||||
,@body
|
||||
(error "No breakpoints to step into!")))
|
||||
|
||||
(defmacro haskell-debug-with-modules (&rest body)
|
||||
"Modules need to exist to do debugging stuff."
|
||||
`(if (haskell-debug-get-modules)
|
||||
,@body
|
||||
(error "No modules loaded!")))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Interactive functions
|
||||
|
||||
(defun haskell-debug/select ()
|
||||
"Select whatever is at point."
|
||||
(interactive)
|
||||
(cond
|
||||
((get-text-property (point) 'break)
|
||||
(let ((break (get-text-property (point) 'break)))
|
||||
(haskell-debug-highlight (plist-get break :path)
|
||||
(plist-get break :span))))
|
||||
((get-text-property (point) 'module)
|
||||
(let ((break (get-text-property (point) 'module)))
|
||||
(haskell-debug-highlight (plist-get break :path))))))
|
||||
|
||||
(defun haskell-debug/abandon ()
|
||||
"Abandon the current computation."
|
||||
(interactive)
|
||||
(haskell-debug-with-breakpoints
|
||||
(haskell-process-queue-sync-request (haskell-debug-process) ":abandon")
|
||||
(message "Computation abandoned.")
|
||||
(setq haskell-debug-history-cache nil)
|
||||
(setq haskell-debug-bindings-cache nil)
|
||||
(haskell-debug/refresh)))
|
||||
|
||||
(defun haskell-debug/continue ()
|
||||
"Continue the current computation."
|
||||
(interactive)
|
||||
(haskell-debug-with-breakpoints
|
||||
(haskell-process-queue-sync-request (haskell-debug-process) ":continue")
|
||||
(message "Computation continued.")
|
||||
(setq haskell-debug-history-cache nil)
|
||||
(setq haskell-debug-bindings-cache nil)
|
||||
(haskell-debug/refresh)))
|
||||
|
||||
(defun haskell-debug/break-on-function ()
|
||||
"Break on function IDENT."
|
||||
(interactive)
|
||||
(haskell-debug-with-modules
|
||||
(let ((ident (read-from-minibuffer "Function: "
|
||||
(haskell-ident-at-point))))
|
||||
(haskell-process-queue-sync-request
|
||||
(haskell-debug-process)
|
||||
(concat ":break "
|
||||
ident))
|
||||
(message "Breaking on function: %s" ident)
|
||||
(haskell-debug/refresh))))
|
||||
|
||||
(defun haskell-debug/start-step (expr)
|
||||
"Start stepping EXPR."
|
||||
(interactive (list (read-from-minibuffer "Expression to step through: ")))
|
||||
(haskell-debug/step expr))
|
||||
|
||||
(defun haskell-debug/breakpoint-numbers ()
|
||||
"List breakpoint numbers."
|
||||
(interactive)
|
||||
(let ((breakpoints (mapcar (lambda (breakpoint)
|
||||
(number-to-string (plist-get breakpoint :number)))
|
||||
(haskell-debug-get-breakpoints))))
|
||||
(if (null breakpoints)
|
||||
(message "No breakpoints.")
|
||||
(message "Breakpoint(s): %s"
|
||||
(mapconcat #'identity
|
||||
breakpoints
|
||||
", ")))))
|
||||
|
||||
(defun haskell-debug/next ()
|
||||
"Go to next step to inspect bindings."
|
||||
(interactive)
|
||||
(haskell-debug-with-breakpoints
|
||||
(haskell-debug-navigate "forward")))
|
||||
|
||||
(defun haskell-debug/previous ()
|
||||
"Go to previous step to inspect the bindings."
|
||||
(interactive)
|
||||
(haskell-debug-with-breakpoints
|
||||
(haskell-debug-navigate "back")))
|
||||
|
||||
(defun haskell-debug/refresh ()
|
||||
"Refresh the debugger buffer."
|
||||
(interactive)
|
||||
(with-current-buffer (haskell-debug-buffer-name (haskell-debug-session))
|
||||
(cd (haskell-session-current-dir (haskell-debug-session)))
|
||||
(let ((inhibit-read-only t)
|
||||
(p (point)))
|
||||
(erase-buffer)
|
||||
(insert (propertize (concat "Debugging "
|
||||
(haskell-session-name (haskell-debug-session))
|
||||
"\n\n")
|
||||
'face `((:weight bold))))
|
||||
(let ((modules (haskell-debug-get-modules))
|
||||
(breakpoints (haskell-debug-get-breakpoints))
|
||||
(context (haskell-debug-get-context))
|
||||
(history (haskell-debug-get-history)))
|
||||
(unless modules
|
||||
(insert (propertize "You have to load a module to start debugging."
|
||||
'face
|
||||
'haskell-debug-warning-face)
|
||||
"\n\n"))
|
||||
(haskell-debug-insert-bindings modules breakpoints context)
|
||||
(when modules
|
||||
(haskell-debug-insert-current-context context history)
|
||||
(haskell-debug-insert-breakpoints breakpoints))
|
||||
(haskell-debug-insert-modules modules))
|
||||
(insert "\n")
|
||||
(goto-char (min (point-max) p)))))
|
||||
|
||||
(defun haskell-debug/delete ()
|
||||
"Delete whatever's at the point."
|
||||
(interactive)
|
||||
(cond
|
||||
((get-text-property (point) 'break)
|
||||
(let ((break (get-text-property (point) 'break)))
|
||||
(when (y-or-n-p (format "Delete breakpoint #%d?"
|
||||
(plist-get break :number)))
|
||||
(haskell-process-queue-sync-request
|
||||
(haskell-debug-process)
|
||||
(format ":delete %d"
|
||||
(plist-get break :number)))
|
||||
(haskell-debug/refresh))))))
|
||||
|
||||
(defun haskell-debug/trace ()
|
||||
"Trace the expression."
|
||||
(interactive)
|
||||
(haskell-debug-with-modules
|
||||
(haskell-debug-with-breakpoints
|
||||
(let ((expr (read-from-minibuffer "Expression to trace: "
|
||||
(haskell-ident-at-point))))
|
||||
(haskell-process-queue-sync-request
|
||||
(haskell-debug-process)
|
||||
(concat ":trace " expr))
|
||||
(message "Tracing expression: %s" expr)
|
||||
(haskell-debug/refresh)))))
|
||||
|
||||
(defun haskell-debug/step (&optional expr)
|
||||
"Step into the next function."
|
||||
(interactive)
|
||||
(haskell-debug-with-breakpoints
|
||||
(let* ((breakpoints (haskell-debug-get-breakpoints))
|
||||
(context (haskell-debug-get-context))
|
||||
(string
|
||||
(haskell-process-queue-sync-request
|
||||
(haskell-debug-process)
|
||||
(if expr
|
||||
(concat ":step " expr)
|
||||
":step"))))
|
||||
(cond
|
||||
((string= string "not stopped at a breakpoint\n")
|
||||
(if haskell-debug-bindings-cache
|
||||
(progn (setq haskell-debug-bindings-cache nil)
|
||||
(haskell-debug/refresh))
|
||||
(call-interactively 'haskell-debug/start-step)))
|
||||
(t (let ((maybe-stopped-at (haskell-debug-parse-stopped-at string)))
|
||||
(cond
|
||||
(maybe-stopped-at
|
||||
(setq haskell-debug-bindings-cache
|
||||
maybe-stopped-at)
|
||||
(message "Computation paused.")
|
||||
(haskell-debug/refresh))
|
||||
(t
|
||||
(if context
|
||||
(message "Computation finished.")
|
||||
(when (y-or-n-p "Computation completed without breaking. Reload the module and retry?")
|
||||
(message "Reloading and resetting breakpoints...")
|
||||
(haskell-interactive-mode-reset-error (haskell-debug-session))
|
||||
(cl-loop for break in breakpoints
|
||||
do (haskell-process-queue-sync-request
|
||||
(haskell-debug-process)
|
||||
(concat ":load " (plist-get break :path))))
|
||||
(cl-loop for break in breakpoints
|
||||
do (haskell-debug-break break))
|
||||
(haskell-debug/step expr)))))))))
|
||||
(haskell-debug/refresh)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Internal functions
|
||||
|
||||
(defun haskell-debug-session ()
|
||||
"Get the Haskell session."
|
||||
(or (haskell-session-maybe)
|
||||
(error "No Haskell session associated with this debug
|
||||
buffer. Please just close the buffer and start again.")))
|
||||
|
||||
(defun haskell-debug-process ()
|
||||
"Get the Haskell session."
|
||||
(or (haskell-session-process (haskell-session-maybe))
|
||||
(error "No Haskell session associated with this debug
|
||||
buffer. Please just close the buffer and start again.")))
|
||||
|
||||
(defun haskell-debug-buffer-name (session)
|
||||
"The debug buffer name for the current session."
|
||||
(format "*debug:%s*"
|
||||
(haskell-session-name session)))
|
||||
|
||||
(defun haskell-debug-get-breakpoints ()
|
||||
"Get the list of breakpoints currently set."
|
||||
(let ((string (haskell-process-queue-sync-request
|
||||
(haskell-debug-process)
|
||||
":show breaks")))
|
||||
(if (string= string "No active breakpoints.\n")
|
||||
(list)
|
||||
(mapcar #'haskell-debug-parse-break-point
|
||||
(haskell-debug-split-string string)))))
|
||||
|
||||
(defun haskell-debug-get-modules ()
|
||||
"Get the list of modules currently set."
|
||||
(let ((string (haskell-process-queue-sync-request
|
||||
(haskell-debug-process)
|
||||
":show modules")))
|
||||
(if (string= string "")
|
||||
(list)
|
||||
(mapcar #'haskell-debug-parse-module
|
||||
(haskell-debug-split-string string)))))
|
||||
|
||||
(defun haskell-debug-get-context ()
|
||||
"Get the current context."
|
||||
(let ((string (haskell-process-queue-sync-request
|
||||
(haskell-debug-process)
|
||||
":show context")))
|
||||
(if (string= string "")
|
||||
nil
|
||||
(haskell-debug-parse-context string))))
|
||||
|
||||
(defun haskell-debug-get-history ()
|
||||
"Get the step history."
|
||||
(let ((string (haskell-process-queue-sync-request
|
||||
(haskell-debug-process)
|
||||
":history")))
|
||||
(if (or (string= string "")
|
||||
(string= string "Not stopped at a breakpoint\n"))
|
||||
nil
|
||||
(if (string= string "Empty history. Perhaps you forgot to use :trace?\n")
|
||||
nil
|
||||
(let ((entries (mapcar #'haskell-debug-parse-history-entry
|
||||
(cl-remove-if (lambda (line) (or (string= "<end of history>" line)
|
||||
(string= "..." line)))
|
||||
(haskell-debug-split-string string)))))
|
||||
(setq haskell-debug-history-cache
|
||||
entries)
|
||||
entries)))))
|
||||
|
||||
(defun haskell-debug-insert-bindings (modules breakpoints context)
|
||||
"Insert a list of bindings."
|
||||
(if breakpoints
|
||||
(progn (haskell-debug-insert-binding "t" "trace an expression")
|
||||
(haskell-debug-insert-binding "s" "step into an expression")
|
||||
(haskell-debug-insert-binding "b" "breakpoint" t))
|
||||
(progn
|
||||
(when modules
|
||||
(haskell-debug-insert-binding "b" "breakpoint"))
|
||||
(when breakpoints
|
||||
(haskell-debug-insert-binding "s" "step into an expression" t))))
|
||||
(when breakpoints
|
||||
(haskell-debug-insert-binding "d" "delete breakpoint"))
|
||||
(when context
|
||||
(haskell-debug-insert-binding "a" "abandon context")
|
||||
(haskell-debug-insert-binding "c" "continue" t))
|
||||
(when context
|
||||
(haskell-debug-insert-binding "p" "previous step")
|
||||
(haskell-debug-insert-binding "n" "next step" t))
|
||||
(haskell-debug-insert-binding "g" "refresh" t)
|
||||
(insert "\n"))
|
||||
|
||||
(defun haskell-debug-insert-current-context (context history)
|
||||
"Insert the current context."
|
||||
(haskell-debug-insert-header "Context")
|
||||
(if context
|
||||
(haskell-debug-insert-context context history)
|
||||
(haskell-debug-insert-debug-finished))
|
||||
(insert "\n"))
|
||||
|
||||
(defun haskell-debug-insert-breakpoints (breakpoints)
|
||||
"insert the list of breakpoints."
|
||||
(haskell-debug-insert-header "Breakpoints")
|
||||
(if (null breakpoints)
|
||||
(haskell-debug-insert-muted "No active breakpoints.")
|
||||
(cl-loop for break in breakpoints
|
||||
do (insert (propertize (format "%d"
|
||||
(plist-get break :number))
|
||||
'face `((:weight bold))
|
||||
'break break)
|
||||
(haskell-debug-muted " - ")
|
||||
(propertize (plist-get break :module)
|
||||
'break break
|
||||
'break break)
|
||||
(haskell-debug-muted
|
||||
(format " (%d:%d)"
|
||||
(plist-get (plist-get break :span) :start-line)
|
||||
(plist-get (plist-get break :span) :start-col)))
|
||||
"\n")))
|
||||
(insert "\n"))
|
||||
|
||||
(defun haskell-debug-insert-modules (modules)
|
||||
"Insert the list of modules."
|
||||
(haskell-debug-insert-header "Modules")
|
||||
(if (null modules)
|
||||
(haskell-debug-insert-muted "No loaded modules.")
|
||||
(progn (cl-loop for module in modules
|
||||
do (insert (propertize (plist-get module :module)
|
||||
'module module
|
||||
'face `((:weight bold)))
|
||||
(haskell-debug-muted " - ")
|
||||
(propertize (file-name-nondirectory (plist-get module :path))
|
||||
'module module))
|
||||
do (insert "\n")))))
|
||||
|
||||
(defun haskell-debug-split-string (string)
|
||||
"Split GHCi's line-based output, stripping the trailing newline."
|
||||
(split-string string "\n" t))
|
||||
|
||||
(defun haskell-debug-parse-context (string)
|
||||
"Parse the context."
|
||||
(cond
|
||||
((string-match "^--> \\(.+\\)\n \\(.+\\)" string)
|
||||
(let ((name (match-string 1 string))
|
||||
(stopped (haskell-debug-parse-stopped-at (match-string 2 string))))
|
||||
(list :name name
|
||||
:path (plist-get stopped :path)
|
||||
:span (plist-get stopped :span))))))
|
||||
|
||||
(defun haskell-debug-insert-binding (binding desc &optional end)
|
||||
"Insert a helpful keybinding."
|
||||
(insert (propertize binding 'face 'haskell-debug-keybinding-face)
|
||||
(haskell-debug-muted " - ")
|
||||
desc
|
||||
(if end
|
||||
"\n"
|
||||
(haskell-debug-muted ", "))))
|
||||
|
||||
(defun haskell-debug-insert-header (title)
|
||||
"Insert a header title."
|
||||
(insert (propertize title
|
||||
'face 'haskell-debug-heading-face)
|
||||
"\n\n"))
|
||||
|
||||
(defun haskell-debug-insert-context (context history)
|
||||
"Insert the context and history."
|
||||
(when context
|
||||
(insert (propertize (plist-get context :name) 'face `((:weight bold)))
|
||||
(haskell-debug-muted " - ")
|
||||
(file-name-nondirectory (plist-get context :path))
|
||||
(haskell-debug-muted " (stopped)")
|
||||
"\n"))
|
||||
(when haskell-debug-bindings-cache
|
||||
(insert "\n")
|
||||
(let ((bindings haskell-debug-bindings-cache))
|
||||
(insert
|
||||
(haskell-debug-get-span-string
|
||||
(plist-get bindings :path)
|
||||
(plist-get bindings :span)))
|
||||
(insert "\n\n")
|
||||
(cl-loop for binding in (plist-get bindings :types)
|
||||
do (insert (haskell-fontify-as-mode binding 'haskell-mode)
|
||||
"\n"))))
|
||||
(let ((history (or history
|
||||
(list (haskell-debug-make-fake-history context)))))
|
||||
(when history
|
||||
(insert "\n")
|
||||
(haskell-debug-insert-history history))))
|
||||
|
||||
(defun haskell-debug-insert-debug-finished ()
|
||||
"Insert message that no debugging is happening, but if there is
|
||||
some old history, then display that."
|
||||
(if haskell-debug-history-cache
|
||||
(progn (haskell-debug-insert-muted "Finished debugging.")
|
||||
(insert "\n")
|
||||
(haskell-debug-insert-history haskell-debug-history-cache))
|
||||
(haskell-debug-insert-muted "Not debugging right now.")))
|
||||
|
||||
(defun haskell-debug-insert-muted (text)
|
||||
"Insert some muted text."
|
||||
(insert (haskell-debug-muted text)
|
||||
"\n"))
|
||||
|
||||
(defun haskell-debug-muted (text)
|
||||
"Make some muted text."
|
||||
(propertize text 'face 'haskell-debug-muted-face))
|
||||
|
||||
(defun haskell-debug-parse-logged (string)
|
||||
"Parse the logged breakpoint."
|
||||
(cond
|
||||
((string= "no more logged breakpoints\n" string)
|
||||
nil)
|
||||
((string= "already at the beginning of the history\n" string)
|
||||
nil)
|
||||
(t
|
||||
(with-temp-buffer
|
||||
(insert string)
|
||||
(goto-char (point-min))
|
||||
(list :path (progn (search-forward " at ")
|
||||
(buffer-substring-no-properties
|
||||
(point)
|
||||
(1- (search-forward ":"))))
|
||||
:span (haskell-debug-parse-span
|
||||
(buffer-substring-no-properties
|
||||
(point)
|
||||
(line-end-position)))
|
||||
:types (progn (forward-line)
|
||||
(haskell-debug-split-string
|
||||
(buffer-substring-no-properties
|
||||
(point)
|
||||
(point-max)))))))))
|
||||
|
||||
(defun haskell-debug-parse-stopped-at (string)
|
||||
"Parse the location stopped at from the given string.
|
||||
|
||||
For example:
|
||||
|
||||
Stopped at /home/foo/project/src/x.hs:6:25-36
|
||||
|
||||
"
|
||||
(let ((index (string-match "Stopped at \\([^:]+\\):\\(.+\\)\n?"
|
||||
string)))
|
||||
(when index
|
||||
(list :path (match-string 1 string)
|
||||
:span (haskell-debug-parse-span (match-string 2 string))
|
||||
:types (cdr (haskell-debug-split-string (substring string index)))))))
|
||||
|
||||
(defun haskell-debug-get-span-string (path span)
|
||||
"Get the string from the PATH and the SPAN."
|
||||
(save-window-excursion
|
||||
(find-file path)
|
||||
(buffer-substring
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(forward-line (1- (plist-get span :start-line)))
|
||||
(forward-char (1- (plist-get span :start-col)))
|
||||
(point))
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(forward-line (1- (plist-get span :end-line)))
|
||||
(forward-char (plist-get span :end-col))
|
||||
(point)))))
|
||||
|
||||
(defun haskell-debug-make-fake-history (context)
|
||||
"Make a fake history item."
|
||||
(list :index -1
|
||||
:path (plist-get context :path)
|
||||
:span (plist-get context :span)))
|
||||
|
||||
(defun haskell-debug-insert-history (history)
|
||||
"Insert tracing HISTORY."
|
||||
(let ((i (length history)))
|
||||
(cl-loop for span in history
|
||||
do (let ((string (haskell-debug-get-span-string
|
||||
(plist-get span :path)
|
||||
(plist-get span :span)))
|
||||
(index (plist-get span :index)))
|
||||
(insert (propertize (format "%4d" i)
|
||||
'face 'haskell-debug-trace-number-face)
|
||||
" "
|
||||
(haskell-debug-preview-span
|
||||
(plist-get span :span)
|
||||
string
|
||||
t)
|
||||
"\n")
|
||||
(setq i (1- i))))))
|
||||
|
||||
(defun haskell-debug-parse-span (string)
|
||||
"Parse a source span from a string.
|
||||
|
||||
Examples:
|
||||
|
||||
(5,1)-(6,37)
|
||||
6:25-36
|
||||
5:20
|
||||
|
||||
People like to make other people's lives interesting by making
|
||||
variances in source span notation."
|
||||
(cond
|
||||
((string-match "\\([0-9]+\\):\\([0-9]+\\)-\\([0-9]+\\)"
|
||||
string)
|
||||
(list :start-line (string-to-number (match-string 1 string))
|
||||
:start-col (string-to-number (match-string 2 string))
|
||||
:end-line (string-to-number (match-string 1 string))
|
||||
:end-col (string-to-number (match-string 3 string))))
|
||||
((string-match "\\([0-9]+\\):\\([0-9]+\\)"
|
||||
string)
|
||||
(list :start-line (string-to-number (match-string 1 string))
|
||||
:start-col (string-to-number (match-string 2 string))
|
||||
:end-line (string-to-number (match-string 1 string))
|
||||
:end-col (string-to-number (match-string 2 string))))
|
||||
((string-match "(\\([0-9]+\\),\\([0-9]+\\))-(\\([0-9]+\\),\\([0-9]+\\))"
|
||||
string)
|
||||
(list :start-line (string-to-number (match-string 1 string))
|
||||
:start-col (string-to-number (match-string 2 string))
|
||||
:end-line (string-to-number (match-string 3 string))
|
||||
:end-col (string-to-number (match-string 4 string))))
|
||||
(t (error "Unable to parse source span from string: %s"
|
||||
string))))
|
||||
|
||||
(defun haskell-debug-preview-span (span string &optional collapsed)
|
||||
"Make a one-line preview of the given expression."
|
||||
(with-temp-buffer
|
||||
(haskell-mode)
|
||||
(insert string)
|
||||
(when (/= 0 (plist-get span :start-col))
|
||||
(indent-rigidly (point-min)
|
||||
(point-max)
|
||||
1))
|
||||
(if (fboundp 'font-lock-ensure)
|
||||
(font-lock-ensure)
|
||||
(with-no-warnings (font-lock-fontify-buffer)))
|
||||
(when (/= 0 (plist-get span :start-col))
|
||||
(indent-rigidly (point-min)
|
||||
(point-max)
|
||||
-1))
|
||||
(goto-char (point-min))
|
||||
(if collapsed
|
||||
(replace-regexp-in-string
|
||||
"\n[ ]*"
|
||||
(propertize " " 'face 'haskell-debug-newline-face)
|
||||
(buffer-substring (point-min)
|
||||
(point-max)))
|
||||
(buffer-string))))
|
||||
|
||||
(defun haskell-debug-start (session)
|
||||
"Start the debug mode."
|
||||
(setq buffer-read-only t)
|
||||
(haskell-session-assign session)
|
||||
(haskell-debug/refresh))
|
||||
|
||||
(defun haskell-debug ()
|
||||
"Start the debugger for the current Haskell (GHCi) session."
|
||||
(interactive)
|
||||
(let ((session (haskell-debug-session)))
|
||||
(switch-to-buffer-other-window (haskell-debug-buffer-name session))
|
||||
(unless (eq major-mode 'haskell-debug-mode)
|
||||
(haskell-debug-mode)
|
||||
(haskell-debug-start session))))
|
||||
|
||||
(defun haskell-debug-break (break)
|
||||
"Set BREAK breakpoint in module at line/col."
|
||||
(haskell-process-queue-without-filters
|
||||
(haskell-debug-process)
|
||||
(format ":break %s %s %d"
|
||||
(plist-get break :module)
|
||||
(plist-get (plist-get break :span) :start-line)
|
||||
(plist-get (plist-get break :span) :start-col))))
|
||||
|
||||
(defun haskell-debug-navigate (direction)
|
||||
"Navigate in DIRECTION \"back\" or \"forward\"."
|
||||
(let ((string (haskell-process-queue-sync-request
|
||||
(haskell-debug-process)
|
||||
(concat ":" direction))))
|
||||
(let ((bindings (haskell-debug-parse-logged string)))
|
||||
(setq haskell-debug-bindings-cache
|
||||
bindings)
|
||||
(when (not bindings)
|
||||
(message "No more %s results!" direction)))
|
||||
(haskell-debug/refresh)))
|
||||
|
||||
(defun haskell-debug-session-debugging-p (session)
|
||||
"Does the session have a debugging buffer open?"
|
||||
(not (not (get-buffer (haskell-debug-buffer-name session)))))
|
||||
|
||||
(defun haskell-debug-highlight (path &optional span)
|
||||
"Highlight the file at span."
|
||||
(let ((p (make-overlay
|
||||
(line-beginning-position)
|
||||
(line-end-position))))
|
||||
(overlay-put p 'face `((:background "#eee")))
|
||||
(with-current-buffer
|
||||
(if span
|
||||
(save-window-excursion
|
||||
(find-file path)
|
||||
(current-buffer))
|
||||
(find-file path)
|
||||
(current-buffer))
|
||||
(let ((o (when span
|
||||
(make-overlay
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(forward-line (1- (plist-get span :start-line)))
|
||||
(forward-char (1- (plist-get span :start-col)))
|
||||
(point))
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(forward-line (1- (plist-get span :end-line)))
|
||||
(forward-char (plist-get span :end-col))
|
||||
(point))))))
|
||||
(when o
|
||||
(overlay-put o 'face `((:background "#eee"))))
|
||||
(sit-for 0.5)
|
||||
(when o
|
||||
(delete-overlay o))
|
||||
(delete-overlay p)))))
|
||||
|
||||
(defun haskell-debug-parse-history-entry (string)
|
||||
"Parse a history entry."
|
||||
(if (string-match "^\\([-0-9]+\\)[ ]+:[ ]+\\([A-Za-z0-9_':]+\\)[ ]+(\\([^:]+\\):\\(.+?\\))$"
|
||||
string)
|
||||
(list :index (string-to-number (match-string 1 string))
|
||||
:name (match-string 2 string)
|
||||
:path (match-string 3 string)
|
||||
:span (haskell-debug-parse-span (match-string 4 string)))
|
||||
(error "Unable to parse history entry: %s" string)))
|
||||
|
||||
(defun haskell-debug-parse-module (string)
|
||||
"Parse a module and path.
|
||||
|
||||
For example:
|
||||
|
||||
X ( /home/foo/X.hs, interpreted )
|
||||
|
||||
"
|
||||
(if (string-match "^\\([^ ]+\\)[ ]+( \\([^ ]+?\\), [a-z]+ )$"
|
||||
string)
|
||||
(list :module (match-string 1 string)
|
||||
:path (match-string 2 string))
|
||||
(error "Unable to parse module from string: %s"
|
||||
string)))
|
||||
|
||||
(defun haskell-debug-parse-break-point (string)
|
||||
"Parse a breakpoint number, module and location from a string.
|
||||
|
||||
For example:
|
||||
|
||||
[13] Main /home/foo/src/x.hs:(5,1)-(6,37)
|
||||
|
||||
"
|
||||
(if (string-match "^\\[\\([0-9]+\\)\\] \\([^ ]+\\) \\([^:]+\\):\\(.+\\)$"
|
||||
string)
|
||||
(list :number (string-to-number (match-string 1 string))
|
||||
:module (match-string 2 string)
|
||||
:path (match-string 3 string)
|
||||
:span (haskell-debug-parse-span (match-string 4 string)))
|
||||
(error "Unable to parse breakpoint from string: %s"
|
||||
string)))
|
||||
|
||||
(provide 'haskell-debug)
|
||||
|
||||
;;; haskell-debug.el ends here
|
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-debug.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-debug.elc
Normal file
Binary file not shown.
604
.emacs.d/elpa/haskell-mode-13.12/haskell-decl-scan.el
Normal file
604
.emacs.d/elpa/haskell-mode-13.12/haskell-decl-scan.el
Normal file
@@ -0,0 +1,604 @@
|
||||
;;; haskell-decl-scan.el --- Declaration scanning module for Haskell Mode
|
||||
|
||||
;; Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 1997-1998 Graeme E Moss
|
||||
|
||||
;; Author: 1997-1998 Graeme E Moss <gem@cs.york.ac.uk>
|
||||
;; Maintainer: Stefan Monnier <monnier@gnu.org>
|
||||
;; Keywords: declarations menu files Haskell
|
||||
;; URL: http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/CONTRIB/haskell-modes/emacs/haskell-decl-scan.el?rev=HEAD
|
||||
|
||||
;; 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Purpose:
|
||||
;;
|
||||
;; Top-level declarations are scanned and placed in a menu. Supports
|
||||
;; full Latin1 Haskell 1.4 as well as literate scripts.
|
||||
;;
|
||||
;;
|
||||
;; Installation:
|
||||
;;
|
||||
;; To turn declaration scanning on for all Haskell buffers under the
|
||||
;; Haskell mode of Moss&Thorn, add this to .emacs:
|
||||
;;
|
||||
;; (add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan)
|
||||
;;
|
||||
;; Otherwise, call `turn-on-haskell-decl-scan'.
|
||||
;;
|
||||
;;
|
||||
;; Customisation:
|
||||
;;
|
||||
;; M-x customize-group haskell-decl-scan
|
||||
;;
|
||||
;;
|
||||
;; History:
|
||||
;;
|
||||
;; If you have any problems or suggestions, after consulting the list
|
||||
;; below, email gem@cs.york.ac.uk quoting the version of the library
|
||||
;; you are using, the version of Emacs you are using, and a small
|
||||
;; example of the problem or suggestion. Note that this library
|
||||
;; requires a reasonably recent version of Emacs.
|
||||
;;
|
||||
;; Uses `imenu' under Emacs.
|
||||
;;
|
||||
;; Version 1.2:
|
||||
;; Added support for LaTeX-style literate scripts.
|
||||
;;
|
||||
;; Version 1.1:
|
||||
;; Use own syntax table. Fixed bug for very small buffers. Use
|
||||
;; markers instead of pointers (markers move with the text).
|
||||
;;
|
||||
;; Version 1.0:
|
||||
;; Brought over from Haskell mode v1.1.
|
||||
;;
|
||||
;;
|
||||
;; Present Limitations/Future Work (contributions are most welcome!):
|
||||
;;
|
||||
;; . Declarations requiring information extending beyond starting line
|
||||
;; don't get scanned properly, eg.
|
||||
;; > class Eq a =>
|
||||
;; > Test a
|
||||
;;
|
||||
;; . Comments placed in the midst of the first few lexemes of a
|
||||
;; declaration will cause havoc, eg.
|
||||
;; > infixWithComments :: Int -> Int -> Int
|
||||
;; > x {-nastyComment-} `infixWithComments` y = x + y
|
||||
;; but are not worth worrying about.
|
||||
;;
|
||||
;; . Would be nice to scan other top-level declarations such as
|
||||
;; methods of a class, datatype field labels... any more?
|
||||
;;
|
||||
;; . Support for GreenCard?
|
||||
;;
|
||||
;; . Re-running (literate-)haskell-imenu should not cause the problems
|
||||
;; that it does. The ability to turn off scanning would also be
|
||||
;; useful. (Note that re-running (literate-)haskell-mode seems to
|
||||
;; cause no problems.)
|
||||
|
||||
;; All functions/variables start with
|
||||
;; `(turn-(on/off)-)haskell-decl-scan' or `haskell-ds-'.
|
||||
|
||||
;; The imenu support is based on code taken from `hugs-mode',
|
||||
;; thanks go to Chris Van Humbeeck.
|
||||
|
||||
;; Version.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'cl-lib)
|
||||
(require 'haskell-mode)
|
||||
(require 'syntax)
|
||||
(require 'imenu)
|
||||
|
||||
(defgroup haskell-decl-scan nil
|
||||
"Haskell declaration scanning (`imenu' support)."
|
||||
:link '(custom-manual "(haskell-mode)haskell-decl-scan-mode")
|
||||
:group 'haskell
|
||||
:prefix "haskell-decl-scan-")
|
||||
|
||||
(defcustom haskell-decl-scan-bindings-as-variables nil
|
||||
"Whether to put top-level value bindings into a \"Variables\" category."
|
||||
:group 'haskell-decl-scan
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom haskell-decl-scan-add-to-menubar t
|
||||
"Whether to add a \"Declarations\" menu entry to menu bar."
|
||||
:group 'haskell-decl-scan
|
||||
:type 'boolean)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; General declaration scanning functions.
|
||||
|
||||
(defvar haskell-ds-start-keywords-re
|
||||
(concat "\\(\\<"
|
||||
"class\\|data\\|i\\(mport\\|n\\(fix\\(\\|[lr]\\)\\|stance\\)\\)\\|"
|
||||
"module\\|primitive\\|type\\|newtype"
|
||||
"\\)\\>")
|
||||
"Keywords that may start a declaration.")
|
||||
|
||||
(defvar haskell-ds-syntax-table
|
||||
(let ((table (copy-syntax-table haskell-mode-syntax-table)))
|
||||
(modify-syntax-entry ?\' "w" table)
|
||||
(modify-syntax-entry ?_ "w" table)
|
||||
(modify-syntax-entry ?\\ "_" table)
|
||||
table)
|
||||
"Syntax table used for Haskell declaration scanning.")
|
||||
|
||||
|
||||
(defun haskell-ds-get-variable (prefix)
|
||||
"Return variable involved in value binding or type signature.
|
||||
Assumes point is looking at the regexp PREFIX followed by the
|
||||
start of a declaration (perhaps in the middle of a series of
|
||||
declarations concerning a single variable). Otherwise return nil.
|
||||
Point is not changed."
|
||||
;; I think I can now handle all declarations bar those with comments
|
||||
;; nested before the second lexeme.
|
||||
(save-excursion
|
||||
(with-syntax-table haskell-ds-syntax-table
|
||||
(if (looking-at prefix) (goto-char (match-end 0)))
|
||||
;; Keyword.
|
||||
(if (looking-at haskell-ds-start-keywords-re)
|
||||
nil
|
||||
(or ;; Parenthesized symbolic variable.
|
||||
(and (looking-at "(\\(\\s_+\\))") (match-string-no-properties 1))
|
||||
;; General case.
|
||||
(if (looking-at
|
||||
(if (eq ?\( (char-after))
|
||||
;; Skip paranthesised expression.
|
||||
(progn
|
||||
(forward-sexp)
|
||||
;; Repeating this code and avoiding moving point if
|
||||
;; possible speeds things up.
|
||||
"\\(\\'\\)?\\s-*\\(\\s_+\\|`\\(\\sw+\\)`\\)")
|
||||
"\\(\\sw+\\)?\\s-*\\(\\s_+\\|`\\(\\sw+\\)`\\)"))
|
||||
(let ((match2 (match-string-no-properties 2)))
|
||||
;; Weed out `::', `∷',`=' and `|' from potential infix
|
||||
;; symbolic variable.
|
||||
(if (member match2 '("::" "∷" "=" "|"))
|
||||
;; Variable identifier.
|
||||
(match-string-no-properties 1)
|
||||
(if (eq (aref match2 0) ?\`)
|
||||
;; Infix variable identifier.
|
||||
(match-string-no-properties 3)
|
||||
;; Infix symbolic variable.
|
||||
match2))))
|
||||
;; Variable identifier.
|
||||
(and (looking-at "\\sw+") (match-string-no-properties 0)))))))
|
||||
|
||||
(defun haskell-ds-move-to-start-regexp (inc regexp)
|
||||
"Move to beginning of line that succeeds/precedes (INC = 1/-1)
|
||||
current line that starts with REGEXP and is not in `font-lock-comment-face'."
|
||||
;; Making this defsubst instead of defun appears to have little or
|
||||
;; no effect on efficiency. It is probably not called enough to do
|
||||
;; so.
|
||||
(while (and (= (forward-line inc) 0)
|
||||
(or (not (looking-at regexp))
|
||||
(eq (get-text-property (point) 'face)
|
||||
'font-lock-comment-face)))))
|
||||
|
||||
(defun haskell-ds-move-to-start-regexp-skipping-comments (inc regexp)
|
||||
"Like haskell-ds-move-to-start-regexp, but uses syntax-ppss to
|
||||
skip comments"
|
||||
(let (p)
|
||||
(cl-loop
|
||||
do (setq p (point))
|
||||
(haskell-ds-move-to-start-regexp inc regexp)
|
||||
while (and (nth 4 (syntax-ppss))
|
||||
(/= p (point))))))
|
||||
|
||||
(defvar literate-haskell-ds-line-prefix "> ?"
|
||||
"Regexp matching start of a line of Bird-style literate code.
|
||||
Current value is \"> \" as we assume top-level declarations start
|
||||
at column 3. Must not contain the special \"^\" regexp as we may
|
||||
not use the regexp at the start of a regexp string. Note this is
|
||||
only for `imenu' support.")
|
||||
|
||||
(defvar haskell-ds-start-decl-re "\\(\\sw\\|(\\)"
|
||||
"The regexp that starts a Haskell declaration.")
|
||||
|
||||
(defvar literate-haskell-ds-start-decl-re
|
||||
(concat literate-haskell-ds-line-prefix haskell-ds-start-decl-re)
|
||||
"The regexp that starts a Bird-style literate Haskell declaration.")
|
||||
|
||||
(defun haskell-ds-move-to-decl (direction bird-literate fix)
|
||||
"General function for moving to the start of a declaration,
|
||||
either forwards or backwards from point, with normal or with Bird-style
|
||||
literate scripts. If DIRECTION is t, then forward, else backward. If
|
||||
BIRD-LITERATE is t, then treat as Bird-style literate scripts, else
|
||||
normal scripts. Returns point if point is left at the start of a
|
||||
declaration, and nil otherwise, ie. because point is at the beginning
|
||||
or end of the buffer and no declaration starts there. If FIX is t,
|
||||
then point does not move if already at the start of a declaration."
|
||||
;; As `haskell-ds-get-variable' cannot separate an infix variable
|
||||
;; identifier out of a value binding with non-alphanumeric first
|
||||
;; argument, this function will treat such value bindings as
|
||||
;; separate from the declarations surrounding it.
|
||||
(let ( ;; The variable typed or bound in the current series of
|
||||
;; declarations.
|
||||
name
|
||||
;; The variable typed or bound in the new declaration.
|
||||
newname
|
||||
;; Hack to solve hard problem for Bird-style literate scripts
|
||||
;; that start with a declaration. We are in the abyss if
|
||||
;; point is before start of this declaration.
|
||||
abyss
|
||||
(line-prefix (if bird-literate literate-haskell-ds-line-prefix ""))
|
||||
;; The regexp to match for the start of a declaration.
|
||||
(start-decl-re (if bird-literate
|
||||
literate-haskell-ds-start-decl-re
|
||||
haskell-ds-start-decl-re))
|
||||
(increment (if direction 1 -1))
|
||||
(bound (if direction (point-max) (point-min))))
|
||||
;; Change syntax table.
|
||||
(with-syntax-table haskell-ds-syntax-table
|
||||
;; move to beginning of line that starts the "current
|
||||
;; declaration" (dependent on DIRECTION and FIX), and then get
|
||||
;; the variable typed or bound by this declaration, if any.
|
||||
(let ( ;; Where point was at call of function.
|
||||
(here (point))
|
||||
;; Where the declaration on this line (if any) starts.
|
||||
(start (progn
|
||||
(beginning-of-line)
|
||||
;; Checking the face to ensure a declaration starts
|
||||
;; here seems to be the only addition to make this
|
||||
;; module support LaTeX-style literate scripts.
|
||||
(if (and (looking-at start-decl-re)
|
||||
(not (elt (syntax-ppss) 4)))
|
||||
(match-beginning 1)))))
|
||||
(if (and start
|
||||
;; This complicated boolean determines whether we
|
||||
;; should include the declaration that starts on the
|
||||
;; current line as the "current declaration" or not.
|
||||
(or (and (or (and direction (not fix))
|
||||
(and (not direction) fix))
|
||||
(>= here start))
|
||||
(and (or (and direction fix)
|
||||
(and (not direction) (not fix)))
|
||||
(> here start))))
|
||||
;; If so, we are already at start of the current line, so
|
||||
;; do nothing.
|
||||
()
|
||||
;; If point was before start of a declaration on the first
|
||||
;; line of the buffer (possible for Bird-style literate
|
||||
;; scripts) then we are in the abyss.
|
||||
(if (and start (bobp))
|
||||
(setq abyss t)
|
||||
;; Otherwise we move to the start of the first declaration
|
||||
;; on a line preceding the current one, skipping comments
|
||||
(haskell-ds-move-to-start-regexp-skipping-comments -1 start-decl-re))))
|
||||
;; If we are in the abyss, position and return as appropriate.
|
||||
(if abyss
|
||||
(if (not direction)
|
||||
nil
|
||||
(re-search-forward (concat "\\=" line-prefix) nil t)
|
||||
(point))
|
||||
;; Get the variable typed or bound by this declaration, if any.
|
||||
(setq name (haskell-ds-get-variable line-prefix))
|
||||
(if (not name)
|
||||
;; If no such variable, stop at the start of this
|
||||
;; declaration if moving backward, or move to the next
|
||||
;; declaration if moving forward.
|
||||
(if direction
|
||||
(haskell-ds-move-to-start-regexp-skipping-comments 1 start-decl-re))
|
||||
;; If there is a variable, find the first
|
||||
;; succeeding/preceding declaration that does not type or
|
||||
;; bind it. Check for reaching start/end of buffer and
|
||||
;; comments.
|
||||
(haskell-ds-move-to-start-regexp-skipping-comments increment start-decl-re)
|
||||
(while (and (/= (point) bound)
|
||||
(and (setq newname (haskell-ds-get-variable line-prefix))
|
||||
(string= name newname)))
|
||||
(setq name newname)
|
||||
(haskell-ds-move-to-start-regexp-skipping-comments increment start-decl-re))
|
||||
;; If we are going backward, and have either reached a new
|
||||
;; declaration or the beginning of a buffer that does not
|
||||
;; start with a declaration, move forward to start of next
|
||||
;; declaration (which must exist). Otherwise, we are done.
|
||||
(if (and (not direction)
|
||||
(or (and (looking-at start-decl-re)
|
||||
(not (string= name
|
||||
;; Note we must not use
|
||||
;; newname here as this may
|
||||
;; not have been set if we
|
||||
;; have reached the beginning
|
||||
;; of the buffer.
|
||||
(haskell-ds-get-variable
|
||||
line-prefix))))
|
||||
(and (not (looking-at start-decl-re))
|
||||
(bobp))))
|
||||
(haskell-ds-move-to-start-regexp-skipping-comments 1 start-decl-re)))
|
||||
;; Store whether we are at the start of a declaration or not.
|
||||
;; Used to calculate final result.
|
||||
(let ((at-start-decl (looking-at start-decl-re)))
|
||||
;; If we are at the beginning of a line, move over
|
||||
;; line-prefix, if present at point.
|
||||
(if (bolp)
|
||||
(re-search-forward (concat "\\=" line-prefix) (point-max) t))
|
||||
;; Return point if at the start of a declaration and nil
|
||||
;; otherwise.
|
||||
(if at-start-decl (point) nil))))))
|
||||
|
||||
(defun haskell-ds-bird-p ()
|
||||
(and (boundp 'haskell-literate) (eq haskell-literate 'bird)))
|
||||
|
||||
(defun haskell-ds-backward-decl ()
|
||||
"Move backward to the first character that starts a top-level declaration.
|
||||
A series of declarations concerning one variable is treated as one
|
||||
declaration by this function. So, if point is within a top-level
|
||||
declaration then move it to the start of that declaration. If point
|
||||
is already at the start of a top-level declaration, then move it to
|
||||
the start of the preceding declaration. Returns point if point is
|
||||
left at the start of a declaration, and nil otherwise, ie. because
|
||||
point is at the beginning of the buffer and no declaration starts
|
||||
there."
|
||||
(interactive)
|
||||
(haskell-ds-move-to-decl nil (haskell-ds-bird-p) nil))
|
||||
|
||||
(defun haskell-ds-forward-decl ()
|
||||
"As `haskell-ds-backward-decl' but forward."
|
||||
(interactive)
|
||||
(haskell-ds-move-to-decl t (haskell-ds-bird-p) nil))
|
||||
|
||||
(defun haskell-ds-generic-find-next-decl (bird-literate)
|
||||
"Find the name, position and type of the declaration at or after point.
|
||||
Return ((NAME . (START-POSITION . NAME-POSITION)) . TYPE)
|
||||
if one exists and nil otherwise. The start-position is at the start
|
||||
of the declaration, and the name-position is at the start of the name
|
||||
of the declaration. The name is a string, the positions are buffer
|
||||
positions and the type is one of the symbols \"variable\", \"datatype\",
|
||||
\"class\", \"import\" and \"instance\"."
|
||||
(let ( ;; The name, type and name-position of the declaration to
|
||||
;; return.
|
||||
name
|
||||
type
|
||||
name-pos
|
||||
;; Buffer positions marking the start and end of the space
|
||||
;; containing a declaration.
|
||||
start
|
||||
end)
|
||||
;; Change to declaration scanning syntax.
|
||||
(with-syntax-table haskell-ds-syntax-table
|
||||
;; Stop when we are at the end of the buffer or when a valid
|
||||
;; declaration is grabbed.
|
||||
(while (not (or (eobp) name))
|
||||
;; Move forward to next declaration at or after point.
|
||||
(haskell-ds-move-to-decl t bird-literate t)
|
||||
;; Start and end of search space is currently just the starting
|
||||
;; line of the declaration.
|
||||
(setq start (point)
|
||||
end (line-end-position))
|
||||
(cond
|
||||
;; If the start of the top-level declaration does not begin
|
||||
;; with a starting keyword, then (if legal) must be a type
|
||||
;; signature or value binding, and the variable concerned is
|
||||
;; grabbed.
|
||||
((not (looking-at haskell-ds-start-keywords-re))
|
||||
(setq name (haskell-ds-get-variable ""))
|
||||
(if name
|
||||
(progn
|
||||
(setq type 'variable)
|
||||
(re-search-forward (regexp-quote name) end t)
|
||||
(setq name-pos (match-beginning 0)))))
|
||||
;; User-defined datatype declaration.
|
||||
((re-search-forward "\\=\\(data\\|newtype\\|type\\)\\>" end t)
|
||||
(re-search-forward "=>" end t)
|
||||
(if (looking-at "[ \t]*\\(\\sw+\\)")
|
||||
(progn
|
||||
(setq name (match-string-no-properties 1))
|
||||
(setq name-pos (match-beginning 1))
|
||||
(setq type 'datatype))))
|
||||
;; Class declaration.
|
||||
((re-search-forward "\\=class\\>" end t)
|
||||
(re-search-forward "=>" end t)
|
||||
(if (looking-at "[ \t]*\\(\\sw+\\)")
|
||||
(progn
|
||||
(setq name (match-string-no-properties 1))
|
||||
(setq name-pos (match-beginning 1))
|
||||
(setq type 'class))))
|
||||
;; Import declaration.
|
||||
((looking-at "import[ \t]+\\(?:safe[\t ]+\\)?\\(?:qualified[ \t]+\\)?\\(?:\"[^\"]*\"[\t ]+\\)?\\(\\(?:\\sw\\|.\\)+\\)")
|
||||
(setq name (match-string-no-properties 1))
|
||||
(setq name-pos (match-beginning 1))
|
||||
(setq type 'import))
|
||||
;; Instance declaration.
|
||||
((re-search-forward "\\=instance[ \t]+" end t)
|
||||
(re-search-forward "=>[ \t]+" end t)
|
||||
;; The instance "title" starts just after the `instance' (and
|
||||
;; any context) and finishes just before the _first_ `where'
|
||||
;; if one exists. This solution is ugly, but I can't find a
|
||||
;; nicer one---a simple regexp will pick up the last `where',
|
||||
;; which may be rare but nevertheless...
|
||||
(setq name-pos (point))
|
||||
(setq name (buffer-substring-no-properties
|
||||
(point)
|
||||
(progn
|
||||
;; Look for a `where'.
|
||||
(if (re-search-forward "\\<where\\>" end t)
|
||||
;; Move back to just before the `where'.
|
||||
(progn
|
||||
(re-search-backward "\\s-where")
|
||||
(point))
|
||||
;; No `where' so move to last non-whitespace
|
||||
;; before `end'.
|
||||
(progn
|
||||
(goto-char end)
|
||||
(skip-chars-backward " \t")
|
||||
(point))))))
|
||||
;; If we did not manage to extract a name, cancel this
|
||||
;; declaration (eg. when line ends in "=> ").
|
||||
(if (string-match "^[ \t]*$" name) (setq name nil))
|
||||
(setq type 'instance)))
|
||||
;; Move past start of current declaration.
|
||||
(goto-char end))
|
||||
;; If we have a valid declaration then return it, otherwise return
|
||||
;; nil.
|
||||
(if name
|
||||
(cons (cons name (cons (copy-marker start t) (copy-marker name-pos t)))
|
||||
type)
|
||||
nil))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Declaration scanning via `imenu'.
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-ds-create-imenu-index ()
|
||||
"Function for finding `imenu' declarations in Haskell mode.
|
||||
Finds all declarations (classes, variables, imports, instances and
|
||||
datatypes) in a Haskell file for the `imenu' package."
|
||||
;; Each list has elements of the form `(INDEX-NAME . INDEX-POSITION)'.
|
||||
;; These lists are nested using `(INDEX-TITLE . INDEX-ALIST)'.
|
||||
(let* ((bird-literate (haskell-ds-bird-p))
|
||||
(index-alist '())
|
||||
(index-class-alist '()) ;; Classes
|
||||
(index-var-alist '()) ;; Variables
|
||||
(index-imp-alist '()) ;; Imports
|
||||
(index-inst-alist '()) ;; Instances
|
||||
(index-type-alist '()) ;; Datatypes
|
||||
;; Variables for showing progress.
|
||||
(bufname (buffer-name))
|
||||
(divisor-of-progress (max 1 (/ (buffer-size) 100)))
|
||||
;; The result we wish to return.
|
||||
result)
|
||||
(goto-char (point-min))
|
||||
;; Loop forwards from the beginning of the buffer through the
|
||||
;; starts of the top-level declarations.
|
||||
(while (< (point) (point-max))
|
||||
(message "Scanning declarations in %s... (%3d%%)" bufname
|
||||
(/ (- (point) (point-min)) divisor-of-progress))
|
||||
;; Grab the next declaration.
|
||||
(setq result (haskell-ds-generic-find-next-decl bird-literate))
|
||||
(if result
|
||||
;; If valid, extract the components of the result.
|
||||
(let* ((name-posns (car result))
|
||||
(name (car name-posns))
|
||||
(posns (cdr name-posns))
|
||||
(start-pos (car posns))
|
||||
(type (cdr result))
|
||||
;; Place `(name . start-pos)' in the correct alist.
|
||||
(sym (cdr (assq type
|
||||
'((variable . index-var-alist)
|
||||
(datatype . index-type-alist)
|
||||
(class . index-class-alist)
|
||||
(import . index-imp-alist)
|
||||
(instance . index-inst-alist))))))
|
||||
(set sym (cons (cons name start-pos) (symbol-value sym))))))
|
||||
;; Now sort all the lists, label them, and place them in one list.
|
||||
(message "Sorting declarations in %s..." bufname)
|
||||
(when index-type-alist
|
||||
(push (cons "Datatypes"
|
||||
(sort index-type-alist 'haskell-ds-imenu-label-cmp))
|
||||
index-alist))
|
||||
(when index-inst-alist
|
||||
(push (cons "Instances"
|
||||
(sort index-inst-alist 'haskell-ds-imenu-label-cmp))
|
||||
index-alist))
|
||||
(when index-imp-alist
|
||||
(push (cons "Imports"
|
||||
(sort index-imp-alist 'haskell-ds-imenu-label-cmp))
|
||||
index-alist))
|
||||
(when index-class-alist
|
||||
(push (cons "Classes"
|
||||
(sort index-class-alist 'haskell-ds-imenu-label-cmp))
|
||||
index-alist))
|
||||
(when index-var-alist
|
||||
(if haskell-decl-scan-bindings-as-variables
|
||||
(push (cons "Variables"
|
||||
(sort index-var-alist 'haskell-ds-imenu-label-cmp))
|
||||
index-alist)
|
||||
(setq index-alist (append index-alist
|
||||
(sort index-var-alist 'haskell-ds-imenu-label-cmp)))))
|
||||
(message "Sorting declarations in %s...done" bufname)
|
||||
;; Return the alist.
|
||||
index-alist))
|
||||
|
||||
(defun haskell-ds-imenu-label-cmp (el1 el2)
|
||||
"Predicate to compare labels in lists from `haskell-ds-create-imenu-index'."
|
||||
(string< (car el1) (car el2)))
|
||||
|
||||
(defun haskell-ds-imenu ()
|
||||
"Install `imenu' for Haskell scripts."
|
||||
(setq imenu-create-index-function 'haskell-ds-create-imenu-index)
|
||||
(when haskell-decl-scan-add-to-menubar
|
||||
(imenu-add-to-menubar "Declarations")))
|
||||
|
||||
;; The main functions to turn on declaration scanning.
|
||||
;;;###autoload
|
||||
(defun turn-on-haskell-decl-scan ()
|
||||
"Unconditionally activate `haskell-decl-scan-mode'."
|
||||
(interactive)
|
||||
(haskell-decl-scan-mode))
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode haskell-decl-scan-mode
|
||||
"Toggle Haskell declaration scanning minor mode on or off.
|
||||
With a prefix argument ARG, enable minor mode if ARG is
|
||||
positive, and disable it otherwise. If called from Lisp, enable
|
||||
the mode if ARG is omitted or nil, and toggle it if ARG is `toggle'.
|
||||
|
||||
See also info node `(haskell-mode)haskell-decl-scan-mode' for
|
||||
more details about this minor mode.
|
||||
|
||||
Top-level declarations are scanned and listed in the menu item
|
||||
\"Declarations\" (if enabled via option
|
||||
`haskell-decl-scan-add-to-menubar'). Selecting an item from this
|
||||
menu will take point to the start of the declaration.
|
||||
|
||||
\\[beginning-of-defun] and \\[end-of-defun] move forward and backward to the start of a declaration.
|
||||
|
||||
This may link with `haskell-doc-mode'.
|
||||
|
||||
For non-literate and LaTeX-style literate scripts, we assume the
|
||||
common convention that top-level declarations start at the first
|
||||
column. For Bird-style literate scripts, we assume the common
|
||||
convention that top-level declarations start at the third column,
|
||||
ie. after \"> \".
|
||||
|
||||
Anything in `font-lock-comment-face' is not considered for a
|
||||
declaration. Therefore, using Haskell font locking with comments
|
||||
coloured in `font-lock-comment-face' improves declaration scanning.
|
||||
|
||||
Literate Haskell scripts are supported: If the value of
|
||||
`haskell-literate' (set automatically by `literate-haskell-mode')
|
||||
is `bird', a Bird-style literate script is assumed. If it is nil
|
||||
or `tex', a non-literate or LaTeX-style literate script is
|
||||
assumed, respectively.
|
||||
|
||||
Invokes `haskell-decl-scan-mode-hook' on activation."
|
||||
:group 'haskell-decl-scan
|
||||
|
||||
(kill-local-variable 'beginning-of-defun-function)
|
||||
(kill-local-variable 'end-of-defun-function)
|
||||
(kill-local-variable 'imenu-create-index-function)
|
||||
(unless haskell-decl-scan-mode
|
||||
;; How can we cleanly remove the "Declarations" menu?
|
||||
(when haskell-decl-scan-add-to-menubar
|
||||
(local-set-key [menu-bar index] nil)))
|
||||
|
||||
(when haskell-decl-scan-mode
|
||||
(set (make-local-variable 'beginning-of-defun-function)
|
||||
'haskell-ds-backward-decl)
|
||||
(set (make-local-variable 'end-of-defun-function)
|
||||
'haskell-ds-forward-decl)
|
||||
(haskell-ds-imenu)))
|
||||
|
||||
|
||||
;; Provide ourselves:
|
||||
|
||||
(provide 'haskell-decl-scan)
|
||||
|
||||
;;; haskell-decl-scan.el ends here
|
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-decl-scan.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-decl-scan.elc
Normal file
Binary file not shown.
1976
.emacs.d/elpa/haskell-mode-13.12/haskell-doc.el
Normal file
1976
.emacs.d/elpa/haskell-mode-13.12/haskell-doc.el
Normal file
File diff suppressed because it is too large
Load Diff
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-doc.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-doc.elc
Normal file
Binary file not shown.
709
.emacs.d/elpa/haskell-mode-13.12/haskell-font-lock.el
Normal file
709
.emacs.d/elpa/haskell-mode-13.12/haskell-font-lock.el
Normal file
@@ -0,0 +1,709 @@
|
||||
;;; haskell-font-lock.el --- Font locking module for Haskell Mode
|
||||
|
||||
;; Copyright 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
;; Copyright 1997-1998 Graeme E Moss, and Tommy Thorn
|
||||
|
||||
;; Author: 1997-1998 Graeme E Moss <gem@cs.york.ac.uk>
|
||||
;; 1997-1998 Tommy Thorn <thorn@irisa.fr>
|
||||
;; 2003 Dave Love <fx@gnu.org>
|
||||
;; Keywords: faces files Haskell
|
||||
|
||||
;; 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Purpose:
|
||||
;;
|
||||
;; To support fontification of standard Haskell keywords, symbols,
|
||||
;; functions, etc. Supports full Haskell 1.4 as well as LaTeX- and
|
||||
;; Bird-style literate scripts.
|
||||
;;
|
||||
;; Installation:
|
||||
;;
|
||||
;; To turn font locking on for all Haskell buffers under the Haskell
|
||||
;; mode of Moss&Thorn, add this to .emacs:
|
||||
;;
|
||||
;; (add-hook 'haskell-mode-hook 'turn-on-haskell-font-lock)
|
||||
;;
|
||||
;; Otherwise, call `turn-on-haskell-font-lock'.
|
||||
;;
|
||||
;;
|
||||
;; Customisation:
|
||||
;;
|
||||
;; The colours and level of font locking may be customised. See the
|
||||
;; documentation on `turn-on-haskell-font-lock' for more details.
|
||||
;;
|
||||
;; Present Limitations/Future Work (contributions are most welcome!):
|
||||
;;
|
||||
;; . Debatable whether `()' `[]' `(->)' `(,)' `(,,)' etc. should be
|
||||
;; highlighted as constructors or not. Should the `->' in
|
||||
;; `id :: a -> a' be considered a constructor or a keyword? If so,
|
||||
;; how do we distinguish this from `\x -> x'? What about the `\'?
|
||||
;;
|
||||
;; . XEmacs can support both `--' comments and `{- -}' comments
|
||||
;; simultaneously. If XEmacs is detected, this should be used.
|
||||
;;
|
||||
;; . Support for GreenCard?
|
||||
;;
|
||||
;;
|
||||
;; All functions/variables start with
|
||||
;; `(turn-(on/off)-)haskell-font-lock' or `haskell-fl-'.
|
||||
|
||||
;;; Change Log:
|
||||
|
||||
;; Version 1.3:
|
||||
;; From Dave Love:
|
||||
;; Support for proper behaviour (including with Unicode identifiers)
|
||||
;; in Emacs 21 only hacked in messily to avoid disturbing the old
|
||||
;; stuff. Needs integrating more cleanly. Allow literate comment
|
||||
;; face to be customized. Some support for fontifying definitions.
|
||||
;; (I'm not convinced the faces should be customizable -- fontlock
|
||||
;; faces are normally expected to be consistent.)
|
||||
;;
|
||||
;; Version 1.2:
|
||||
;; Added support for LaTeX-style literate scripts. Allow whitespace
|
||||
;; after backslash to end a line for string continuations.
|
||||
;;
|
||||
;; Version 1.1:
|
||||
;; Use own syntax table. Use backquote (neater). Stop ''' being
|
||||
;; highlighted as quoted character. Fixed `\"' fontification bug
|
||||
;; in comments.
|
||||
;;
|
||||
;; Version 1.0:
|
||||
;; Brought over from Haskell mode v1.1.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'cl-lib)
|
||||
(require 'haskell-mode)
|
||||
(require 'font-lock)
|
||||
|
||||
(defcustom haskell-font-lock-symbols nil
|
||||
"Display \\ and -> and such using symbols in fonts.
|
||||
This may sound like a neat trick, but be extra careful: it changes the
|
||||
alignment and can thus lead to nasty surprises w.r.t layout.
|
||||
If t, try to use whichever font is available. Otherwise you can
|
||||
set it to a particular font of your preference among `japanese-jisx0208'
|
||||
and `unicode'."
|
||||
:group 'haskell
|
||||
:type '(choice (const nil)
|
||||
(const t)
|
||||
(const unicode)
|
||||
(const japanese-jisx0208)))
|
||||
|
||||
(defconst haskell-font-lock-symbols-alist
|
||||
(append
|
||||
;; Prefer single-width Unicode font for lambda.
|
||||
(and (fboundp 'decode-char)
|
||||
(memq haskell-font-lock-symbols '(t unicode))
|
||||
(list (cons "\\" (decode-char 'ucs 955))))
|
||||
;; The symbols can come from a JIS0208 font.
|
||||
(and (fboundp 'make-char) (fboundp 'charsetp) (charsetp 'japanese-jisx0208)
|
||||
(memq haskell-font-lock-symbols '(t japanese-jisx0208))
|
||||
(list (cons "not" (make-char 'japanese-jisx0208 34 76))
|
||||
(cons "\\" (make-char 'japanese-jisx0208 38 75))
|
||||
(cons "->" (make-char 'japanese-jisx0208 34 42))
|
||||
(cons "<-" (make-char 'japanese-jisx0208 34 43))
|
||||
(cons "=>" (make-char 'japanese-jisx0208 34 77))
|
||||
;; FIXME: I'd like to either use ∀ or ∃ depending on how the
|
||||
;; `forall' keyword is used, but currently the rest of the
|
||||
;; code assumes that such ambiguity doesn't happen :-(
|
||||
(cons "forall" (make-char 'japanese-jisx0208 34 79))))
|
||||
;; Or a unicode font.
|
||||
(and (fboundp 'decode-char)
|
||||
(memq haskell-font-lock-symbols '(t unicode))
|
||||
(list (cons "not" (decode-char 'ucs 172))
|
||||
(cons "->" (decode-char 'ucs 8594))
|
||||
(cons "<-" (decode-char 'ucs 8592))
|
||||
(cons "=>" (decode-char 'ucs 8658))
|
||||
(cons "()" (decode-char 'ucs #X2205))
|
||||
(cons "==" (decode-char 'ucs #X2261))
|
||||
(cons "/=" (decode-char 'ucs #X2262))
|
||||
(cons ">=" (decode-char 'ucs #X2265))
|
||||
(cons "<=" (decode-char 'ucs #X2264))
|
||||
(cons "!!" (decode-char 'ucs #X203C))
|
||||
(cons "&&" (decode-char 'ucs #X2227))
|
||||
(cons "||" (decode-char 'ucs #X2228))
|
||||
(cons "sqrt" (decode-char 'ucs #X221A))
|
||||
(cons "undefined" (decode-char 'ucs #X22A5))
|
||||
(cons "pi" (decode-char 'ucs #X3C0))
|
||||
(cons "~>" (decode-char 'ucs 8669)) ;; Omega language
|
||||
;; (cons "~>" (decode-char 'ucs 8605)) ;; less desirable
|
||||
(cons "-<" (decode-char 'ucs 8610)) ;; Paterson's arrow syntax
|
||||
;; (cons "-<" (decode-char 'ucs 10521)) ;; nicer but uncommon
|
||||
(cons "::" (decode-char 'ucs 8759))
|
||||
(list "." (decode-char 'ucs 8728) ; (decode-char 'ucs 9675)
|
||||
;; Need a predicate here to distinguish the . used by
|
||||
;; forall <foo> . <bar>.
|
||||
'haskell-font-lock-dot-is-not-composition)
|
||||
(cons "forall" (decode-char 'ucs 8704)))))
|
||||
"Alist mapping Haskell symbols to chars.
|
||||
Each element has the form (STRING . CHAR) or (STRING CHAR PREDICATE).
|
||||
STRING is the Haskell symbol.
|
||||
CHAR is the character with which to represent this symbol.
|
||||
PREDICATE if present is a function of one argument (the start position
|
||||
of the symbol) which should return non-nil if this mapping should be disabled
|
||||
at that position.")
|
||||
|
||||
(defun haskell-font-lock-dot-is-not-composition (start)
|
||||
"Return non-nil if the \".\" at START is not a composition operator.
|
||||
This is the case if the \".\" is part of a \"forall <tvar> . <type>\"."
|
||||
(save-excursion
|
||||
(goto-char start)
|
||||
(re-search-backward "\\<forall\\>[^.\"]*\\="
|
||||
(line-beginning-position) t)))
|
||||
|
||||
(defface haskell-keyword-face
|
||||
'((t :inherit font-lock-keyword-face))
|
||||
"Face used to highlight Haskell keywords."
|
||||
:group 'haskell)
|
||||
|
||||
(defface haskell-constructor-face
|
||||
'((t :inherit font-lock-type-face))
|
||||
"Face used to highlight Haskell constructors."
|
||||
:group 'haskell)
|
||||
|
||||
;; This used to be `font-lock-variable-name-face' but it doesn't result in
|
||||
;; a highlighting that's consistent with other modes (it's mostly used
|
||||
;; for function defintions).
|
||||
(defface haskell-definition-face
|
||||
'((t :inherit font-lock-function-name-face))
|
||||
"Face used to highlight Haskell definitions."
|
||||
:group 'haskell)
|
||||
|
||||
;; This is probably just wrong, but it used to use
|
||||
;; `font-lock-function-name-face' with a result that was not consistent with
|
||||
;; other major modes, so I just exchanged with `haskell-definition-face'.
|
||||
(defface haskell-operator-face
|
||||
'((t :inherit font-lock-variable-name-face))
|
||||
"Face used to highlight Haskell operators."
|
||||
:group 'haskell)
|
||||
|
||||
(defface haskell-pragma-face
|
||||
'((t :inherit font-lock-comment-face))
|
||||
"Face used to highlight Haskell pragmas."
|
||||
:group 'haskell)
|
||||
|
||||
(defface haskell-default-face
|
||||
'((t :inherit default))
|
||||
"Face used to highlight ordinary Haskell code."
|
||||
:group 'haskell)
|
||||
|
||||
(defface haskell-literate-comment-face
|
||||
'((t :inherit font-lock-doc-face))
|
||||
"Face with which to fontify literate comments.
|
||||
Inherit from `default' to avoid fontification of them."
|
||||
:group 'haskell)
|
||||
|
||||
;; These variables exist only for backward compatibility.
|
||||
(defvar haskell-keyword-face 'haskell-keyword-face)
|
||||
(defvar haskell-constructor-face 'haskell-constructor-face)
|
||||
(defvar haskell-definition-face 'haskell-definition-face)
|
||||
(defvar haskell-operator-face 'haskell-operator-face)
|
||||
(defvar haskell-pragma-face 'haskell-pragma-face)
|
||||
(defvar haskell-default-face 'haskell-default-face)
|
||||
(defvar haskell-literate-comment-face 'haskell-literate-comment-face)
|
||||
|
||||
(defun haskell-font-lock-compose-symbol (alist)
|
||||
"Compose a sequence of ascii chars into a symbol.
|
||||
Regexp match data 0 points to the chars."
|
||||
;; Check that the chars should really be composed into a symbol.
|
||||
(let* ((start (match-beginning 0))
|
||||
(end (match-end 0))
|
||||
(syntaxes (cond
|
||||
((eq (char-syntax (char-after start)) ?w) '(?w))
|
||||
;; Special case for the . used for qualified names.
|
||||
((and (eq (char-after start) ?\.) (= end (1+ start)))
|
||||
'(?_ ?\\ ?w))
|
||||
(t '(?_ ?\\))))
|
||||
sym-data)
|
||||
(if (or (memq (char-syntax (or (char-before start) ?\ )) syntaxes)
|
||||
(memq (char-syntax (or (char-after end) ?\ )) syntaxes)
|
||||
(or (elt (syntax-ppss) 3) (elt (syntax-ppss) 4))
|
||||
(and (consp (setq sym-data (cdr (assoc (match-string 0) alist))))
|
||||
(let ((pred (cadr sym-data)))
|
||||
(setq sym-data (car sym-data))
|
||||
(funcall pred start))))
|
||||
;; No composition for you. Let's actually remove any composition
|
||||
;; we may have added earlier and which is now incorrect.
|
||||
(remove-text-properties start end '(composition))
|
||||
;; That's a symbol alright, so add the composition.
|
||||
(compose-region start end sym-data)))
|
||||
;; Return nil because we're not adding any face property.
|
||||
nil)
|
||||
|
||||
(defun haskell-font-lock-symbols-keywords ()
|
||||
(when (fboundp 'compose-region)
|
||||
(let ((alist nil))
|
||||
(dolist (x haskell-font-lock-symbols-alist)
|
||||
(when (and (if (fboundp 'char-displayable-p)
|
||||
(char-displayable-p (if (consp (cdr x)) (cadr x) (cdr x)))
|
||||
(if (fboundp 'latin1-char-displayable-p)
|
||||
(latin1-char-displayable-p (if (consp (cdr x))
|
||||
(cadr x)
|
||||
(cdr x)))
|
||||
t))
|
||||
(not (assoc (car x) alist))) ; Not yet in alist.
|
||||
(push x alist)))
|
||||
(when alist
|
||||
`((,(regexp-opt (mapcar 'car alist) t)
|
||||
(0 (haskell-font-lock-compose-symbol ',alist)
|
||||
;; In Emacs-21, if the `override' field is nil, the face
|
||||
;; expressions is only evaluated if the text has currently
|
||||
;; no face. So force evaluation by using `keep'.
|
||||
keep)))))))
|
||||
|
||||
(defun haskell-font-lock-find-pragma (end)
|
||||
(catch 'haskell-font-lock-find-pragma
|
||||
(while (search-forward "{-#" end t)
|
||||
(let* ((begin (match-beginning 0))
|
||||
(ppss (save-excursion (syntax-ppss begin))))
|
||||
;; We're interested only when it's not in a string or a comment.
|
||||
(unless (or (nth 3 ppss)
|
||||
(nth 4 ppss))
|
||||
;; Find the end of the pragma.
|
||||
(let ((end (scan-lists begin 1 0)))
|
||||
;; Match data contains only the opening {-#, update it to cover the
|
||||
;; whole pragma.
|
||||
(set-match-data (list begin end))
|
||||
;; Move to the end so we don't start the next scan from inside the
|
||||
;; pragma we just found.
|
||||
(goto-char end)
|
||||
(throw 'haskell-font-lock-find-pragma t)))))
|
||||
;; Found no pragma.
|
||||
nil))
|
||||
|
||||
;; The font lock regular expressions.
|
||||
(defun haskell-font-lock-keywords-create (literate)
|
||||
"Create fontification definitions for Haskell scripts.
|
||||
Returns keywords suitable for `font-lock-keywords'."
|
||||
(let* (;; Bird-style literate scripts start a line of code with
|
||||
;; "^>", otherwise a line of code starts with "^".
|
||||
(line-prefix (if (eq literate 'bird) "^> ?" "^"))
|
||||
|
||||
;; Most names are borrowed from the lexical syntax of the Haskell
|
||||
;; report.
|
||||
;; Some of these definitions have been superseded by using the
|
||||
;; syntax table instead.
|
||||
|
||||
;; (ASCsymbol "-!#$%&*+./<=>?@\\\\^|~")
|
||||
;; Put the minus first to make it work in ranges.
|
||||
|
||||
;; We allow _ as the first char to fit GHC
|
||||
(varid "\\b[[:lower:]_][[:alnum:]'_]*\\b")
|
||||
;; We allow ' preceding conids because of DataKinds/PolyKinds
|
||||
(conid "\\b'?[[:upper:]][[:alnum:]'_]*\\b")
|
||||
(modid (concat "\\b" conid "\\(\\." conid "\\)*\\b"))
|
||||
(qvarid (concat modid "\\." varid))
|
||||
(qconid (concat modid "\\." conid))
|
||||
(sym
|
||||
;; We used to use the below for non-Emacs21, but I think the
|
||||
;; regexp based on syntax works for other emacsen as well. -- Stef
|
||||
;; (concat "[" symbol ":]+")
|
||||
;; Add backslash to the symbol-syntax chars. This seems to
|
||||
;; be thrown for some reason by backslash's escape syntax.
|
||||
"\\(\\s_\\|\\\\\\)+")
|
||||
|
||||
;; Reserved operations
|
||||
(reservedsym
|
||||
(concat "\\S."
|
||||
;; (regexp-opt '(".." "::" "=" "\\" "|" "<-" "->"
|
||||
;; "@" "~" "=>") t)
|
||||
"\\(->\\|→\\|\\.\\.\\|::\\|∷\\|<-\\|←\\|=>\\|[=@\\|~]\\)"
|
||||
"\\S."))
|
||||
;; Reserved identifiers
|
||||
(reservedid
|
||||
(concat "\\<"
|
||||
;; `as', `hiding', and `qualified' are part of the import
|
||||
;; spec syntax, but they are not reserved.
|
||||
;; `_' can go in here since it has temporary word syntax.
|
||||
;; (regexp-opt
|
||||
;; '("case" "class" "data" "default" "deriving" "do"
|
||||
;; "else" "if" "import" "in" "infix" "infixl"
|
||||
;; "infixr" "instance" "let" "module" "newtype" "of"
|
||||
;; "then" "type" "where" "_") t)
|
||||
"\\(_\\|c\\(ase\\|lass\\)\\|d\\(ata\\|e\\(fault\\|riving\\)\\|o\\)\\|else\\|i\\(mport\\|n\\(fix[lr]?\\|stance\\)\\|[fn]\\)\\|let\\|module\\|mdo\\|newtype\\|of\\|rec\\|proc\\|t\\(hen\\|ype\\)\\|where\\)"
|
||||
"\\>"))
|
||||
|
||||
;; This unreadable regexp matches strings and character
|
||||
;; constants. We need to do this with one regexp to handle
|
||||
;; stuff like '"':"'". The regexp is the composition of
|
||||
;; "([^"\\]|\\.)*" for strings and '([^\\]|\\.[^']*)' for
|
||||
;; characters, allowing for string continuations.
|
||||
;; Could probably be improved...
|
||||
(string-and-char
|
||||
(concat "\\(\\(\"\\|" line-prefix "[ \t]*\\\\\\)\\([^\"\\\\\n]\\|\\\\.\\)*\\(\"\\|\\\\[ \t]*$\\)\\|'\\([^'\\\\\n]\\|\\\\.[^'\n]*\\)'\\)"))
|
||||
|
||||
;; Top-level declarations
|
||||
(topdecl-var
|
||||
(concat line-prefix "\\(" varid "\\(?:\\s-*,\\s-*" varid "\\)*" "\\)\\s-*"
|
||||
;; optionally allow for a single newline after identifier
|
||||
;; NOTE: not supported for bird-style .lhs files
|
||||
(if (eq literate 'bird) nil "\\([\n]\\s-+\\)?")
|
||||
;; A toplevel declaration can be followed by a definition
|
||||
;; (=), a type (::) or (∷), a guard, or a pattern which can
|
||||
;; either be a variable, a constructor, a parenthesized
|
||||
;; thingy, or an integer or a string.
|
||||
"\\(" varid "\\|" conid "\\|::\\|∷\\|=\\||\\|\\s(\\|[0-9\"']\\)"))
|
||||
(topdecl-var2
|
||||
(concat line-prefix "\\(" varid "\\|" conid "\\)\\s-*`\\(" varid "\\)`"))
|
||||
(topdecl-bangpat
|
||||
(concat line-prefix "\\(" varid "\\)\\s-*!"))
|
||||
(topdecl-sym
|
||||
(concat line-prefix "\\(" varid "\\|" conid "\\)\\s-*\\(" sym "\\)"))
|
||||
(topdecl-sym2 (concat line-prefix "(\\(" sym "\\))"))
|
||||
|
||||
keywords)
|
||||
|
||||
(setq keywords
|
||||
`(;; NOTICE the ordering below is significant
|
||||
;;
|
||||
("^<<<<<<< .*$" 0 'font-lock-warning-face t)
|
||||
("^|||||||$" 0 'font-lock-warning-face t) ; "diff3" style
|
||||
("^=======$" 0 'font-lock-warning-face t)
|
||||
("^>>>>>>> .*$" 0 'font-lock-warning-face t)
|
||||
("^#.*$" 0 'font-lock-preprocessor-face t)
|
||||
|
||||
,@(haskell-font-lock-symbols-keywords)
|
||||
|
||||
(,reservedid 1 haskell-keyword-face)
|
||||
(,reservedsym 1 haskell-operator-face)
|
||||
;; Special case for `as', `hiding', `safe' and `qualified', which are
|
||||
;; keywords in import statements but are not otherwise reserved.
|
||||
("\\<import[ \t]+\\(?:\\(safe\\>\\)[ \t]*\\)?\\(?:\\(qualified\\>\\)[ \t]*\\)?\\(?:\"[^\"]*\"[\t ]*\\)?[^ \t\n()]+[ \t]*\\(?:\\(\\<as\\>\\)[ \t]*[^ \t\n()]+[ \t]*\\)?\\(\\<hiding\\>\\)?"
|
||||
(1 haskell-keyword-face nil lax)
|
||||
(2 haskell-keyword-face nil lax)
|
||||
(3 haskell-keyword-face nil lax)
|
||||
(4 haskell-keyword-face nil lax))
|
||||
|
||||
(,reservedsym 1 haskell-operator-face)
|
||||
;; Special case for `foreign import'
|
||||
;; keywords in foreign import statements but are not otherwise reserved.
|
||||
("\\<\\(foreign\\)[ \t]+\\(import\\)[ \t]+\\(?:\\(ccall\\|stdcall\\|cplusplus\\|jvm\\|dotnet\\)[ \t]+\\)?\\(?:\\(safe\\|unsafe\\|interruptible\\)[ \t]+\\)?"
|
||||
(1 haskell-keyword-face nil lax)
|
||||
(2 haskell-keyword-face nil lax)
|
||||
(3 haskell-keyword-face nil lax)
|
||||
(4 haskell-keyword-face nil lax))
|
||||
|
||||
(,reservedsym 1 haskell-operator-face)
|
||||
;; Special case for `foreign export'
|
||||
;; keywords in foreign export statements but are not otherwise reserved.
|
||||
("\\<\\(foreign\\)[ \t]+\\(export\\)[ \t]+\\(?:\\(ccall\\|stdcall\\|cplusplus\\|jvm\\|dotnet\\)[ \t]+\\)?"
|
||||
(1 haskell-keyword-face nil lax)
|
||||
(2 haskell-keyword-face nil lax)
|
||||
(3 haskell-keyword-face nil lax))
|
||||
|
||||
;; Toplevel Declarations.
|
||||
;; Place them *before* generic id-and-op highlighting.
|
||||
(,topdecl-var (1 haskell-definition-face))
|
||||
(,topdecl-var2 (2 haskell-definition-face))
|
||||
(,topdecl-bangpat (1 haskell-definition-face))
|
||||
(,topdecl-sym (2 haskell-definition-face))
|
||||
(,topdecl-sym2 (1 haskell-definition-face))
|
||||
|
||||
;; These four are debatable...
|
||||
("(\\(,*\\|->\\))" 0 haskell-constructor-face)
|
||||
("\\[\\]" 0 haskell-constructor-face)
|
||||
;; Expensive.
|
||||
(,(concat "`" varid "`") 0 haskell-operator-face)
|
||||
(,(concat "`" conid "`") 0 haskell-operator-face)
|
||||
(,(concat "`" qvarid "`") 0 haskell-operator-face)
|
||||
(,(concat "`" qconid "`") 0 haskell-operator-face)
|
||||
(,qvarid 0 haskell-default-face)
|
||||
(,qconid 0 haskell-constructor-face)
|
||||
;; Expensive.
|
||||
(,conid 0 haskell-constructor-face)
|
||||
|
||||
;; Very expensive.
|
||||
(,sym 0 (if (eq (char-after (match-beginning 0)) ?:)
|
||||
haskell-constructor-face
|
||||
haskell-operator-face))
|
||||
|
||||
(haskell-font-lock-find-pragma 0 haskell-pragma-face t)))
|
||||
(unless (boundp 'font-lock-syntactic-keywords)
|
||||
(cl-case literate
|
||||
(bird
|
||||
(setq keywords
|
||||
`(("^[^>\n].*$" 0 haskell-comment-face t)
|
||||
,@keywords
|
||||
("^>" 0 haskell-default-face t))))
|
||||
((latex tex)
|
||||
(setq keywords
|
||||
`((haskell-font-lock-latex-comments 0 'font-lock-comment-face t)
|
||||
,@keywords)))))
|
||||
keywords))
|
||||
|
||||
(defvar haskell-font-lock-latex-cache-pos nil
|
||||
"Position of cache point used by `haskell-font-lock-latex-cache-in-comment'.
|
||||
Should be at the start of a line.")
|
||||
(make-variable-buffer-local 'haskell-font-lock-latex-cache-pos)
|
||||
|
||||
(defvar haskell-font-lock-latex-cache-in-comment nil
|
||||
"If `haskell-font-lock-latex-cache-pos' is outside a
|
||||
\\begin{code}..\\end{code} block (and therefore inside a comment),
|
||||
this variable is set to t, otherwise nil.")
|
||||
(make-variable-buffer-local 'haskell-font-lock-latex-cache-in-comment)
|
||||
|
||||
(defun haskell-font-lock-latex-comments (end)
|
||||
"Sets `match-data' according to the region of the buffer before end
|
||||
that should be commented under LaTeX-style literate scripts."
|
||||
(let ((start (point)))
|
||||
(if (= start end)
|
||||
;; We're at the end. No more to fontify.
|
||||
nil
|
||||
(if (not (eq start haskell-font-lock-latex-cache-pos))
|
||||
;; If the start position is not cached, calculate the state
|
||||
;; of the start.
|
||||
(progn
|
||||
(setq haskell-font-lock-latex-cache-pos start)
|
||||
;; If the previous \begin{code} or \end{code} is a
|
||||
;; \begin{code}, then start is not in a comment, otherwise
|
||||
;; it is in a comment.
|
||||
(setq haskell-font-lock-latex-cache-in-comment
|
||||
(if (and
|
||||
(re-search-backward
|
||||
"^\\(\\(\\\\begin{code}\\)\\|\\(\\\\end{code}\\)\\)$"
|
||||
(point-min) t)
|
||||
(match-end 2))
|
||||
nil t))
|
||||
;; Restore position.
|
||||
(goto-char start)))
|
||||
(if haskell-font-lock-latex-cache-in-comment
|
||||
(progn
|
||||
;; If start is inside a comment, search for next \begin{code}.
|
||||
(re-search-forward "^\\\\begin{code}$" end 'move)
|
||||
;; Mark start to end of \begin{code} (if present, till end
|
||||
;; otherwise), as a comment.
|
||||
(set-match-data (list start (point)))
|
||||
;; Return point, as a normal regexp would.
|
||||
(point))
|
||||
;; If start is inside a code block, search for next \end{code}.
|
||||
(if (re-search-forward "^\\\\end{code}$" end t)
|
||||
;; If one found, mark it as a comment, otherwise finish.
|
||||
(point))))))
|
||||
|
||||
(defconst haskell-basic-syntactic-keywords
|
||||
'(;; Character constants (since apostrophe can't have string syntax).
|
||||
;; Beware: do not match something like 's-}' or '\n"+' since the first '
|
||||
;; might be inside a comment or a string.
|
||||
;; This still gets fooled with "'"'"'"'"'"', but ... oh well.
|
||||
("\\Sw\\('\\)\\([^\\'\n]\\|\\\\.[^\\'\n \"}]*\\)\\('\\)" (1 "|") (3 "|"))
|
||||
;; The \ is not escaping in \(x,y) -> x + y.
|
||||
("\\(\\\\\\)(" (1 "."))
|
||||
;; The second \ in a gap does not quote the subsequent char.
|
||||
;; It's probably not worth the trouble, tho.
|
||||
;; ("^[ \t]*\\(\\\\\\)" (1 "."))
|
||||
;; Deal with instances of `--' which don't form a comment
|
||||
("\\s_\\{3,\\}" (0 (cond ((numberp (nth 4 (syntax-ppss)))
|
||||
;; There are no such instances inside nestable comments
|
||||
nil)
|
||||
((string-match "\\`-*\\'" (match-string 0))
|
||||
;; Sequence of hyphens. Do nothing in
|
||||
;; case of things like `{---'.
|
||||
nil)
|
||||
(t "_")))) ; other symbol sequence
|
||||
))
|
||||
|
||||
(defconst haskell-bird-syntactic-keywords
|
||||
(cons '("^[^\n>]" (0 "<"))
|
||||
haskell-basic-syntactic-keywords))
|
||||
|
||||
(defconst haskell-latex-syntactic-keywords
|
||||
(append
|
||||
'(("^\\\\begin{code}\\(\n\\)" 1 "!")
|
||||
;; Note: buffer is widened during font-locking.
|
||||
("\\`\\(.\\|\n\\)" (1 "!")) ; start comment at buffer start
|
||||
("^\\(\\\\\\)end{code}$" 1 "!"))
|
||||
haskell-basic-syntactic-keywords))
|
||||
|
||||
(defcustom haskell-font-lock-haddock (boundp 'font-lock-doc-face)
|
||||
"If non-nil try to highlight Haddock comments specially."
|
||||
:type 'boolean
|
||||
:group 'haskell)
|
||||
|
||||
(defvar haskell-font-lock-seen-haddock nil)
|
||||
(make-variable-buffer-local 'haskell-font-lock-seen-haddock)
|
||||
|
||||
(defun haskell-syntactic-face-function (state)
|
||||
"`font-lock-syntactic-face-function' for Haskell."
|
||||
(cond
|
||||
((nth 3 state) font-lock-string-face) ; as normal
|
||||
;; Else comment. If it's from syntax table, use default face.
|
||||
((or (eq 'syntax-table (nth 7 state))
|
||||
(and (eq haskell-literate 'bird)
|
||||
(memq (char-before (nth 8 state)) '(nil ?\n))))
|
||||
haskell-literate-comment-face)
|
||||
;; Try and recognize Haddock comments. From what I gather from its
|
||||
;; documentation, its comments can take the following forms:
|
||||
;; a) {-| ... -}
|
||||
;; b) {-^ ... -}
|
||||
;; c) -- | ...
|
||||
;; d) -- ^ ...
|
||||
;; e) -- ...
|
||||
;; Where `e' is the tricky one: it is only a Haddock comment if it
|
||||
;; follows immediately another Haddock comment. Even an empty line
|
||||
;; breaks such a sequence of Haddock comments. It is not clear if `e'
|
||||
;; can follow any other case, so I interpreted it as following only cases
|
||||
;; c,d,e (not a or b). In any case, this `e' is expensive since it
|
||||
;; requires extra work for each and every non-Haddock comment, so I only
|
||||
;; go through the more expensive check if we've already seen a Haddock
|
||||
;; comment in the buffer.
|
||||
;;
|
||||
;; And then there are also haddock section headers that start with
|
||||
;; any number of stars:
|
||||
;; -- * ...
|
||||
((and haskell-font-lock-haddock
|
||||
(save-excursion
|
||||
(goto-char (nth 8 state))
|
||||
(or (looking-at "\\(?:{- ?\\|-- \\)[|^*$]")
|
||||
(and haskell-font-lock-seen-haddock
|
||||
(looking-at "--")
|
||||
(let ((doc nil)
|
||||
pos)
|
||||
(while (and (not doc)
|
||||
(setq pos (line-beginning-position))
|
||||
(forward-comment -1)
|
||||
(eq (line-beginning-position 2) pos)
|
||||
(looking-at "--\\([ \\t]*[|^*]\\)?"))
|
||||
(setq doc (match-beginning 1)))
|
||||
doc)))))
|
||||
(setq haskell-font-lock-seen-haddock t)
|
||||
font-lock-doc-face)
|
||||
(t font-lock-comment-face)))
|
||||
|
||||
(defconst haskell-font-lock-keywords
|
||||
(haskell-font-lock-keywords-create nil)
|
||||
"Font lock definitions for non-literate Haskell.")
|
||||
|
||||
(defconst haskell-font-lock-bird-literate-keywords
|
||||
(haskell-font-lock-keywords-create 'bird)
|
||||
"Font lock definitions for Bird-style literate Haskell.")
|
||||
|
||||
(defconst haskell-font-lock-latex-literate-keywords
|
||||
(haskell-font-lock-keywords-create 'latex)
|
||||
"Font lock definitions for LaTeX-style literate Haskell.")
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-font-lock-choose-keywords ()
|
||||
(let ((literate (if (boundp 'haskell-literate) haskell-literate)))
|
||||
(cl-case literate
|
||||
(bird haskell-font-lock-bird-literate-keywords)
|
||||
((latex tex) haskell-font-lock-latex-literate-keywords)
|
||||
(t haskell-font-lock-keywords))))
|
||||
|
||||
(defun haskell-font-lock-choose-syntactic-keywords ()
|
||||
(let ((literate (if (boundp 'haskell-literate) haskell-literate)))
|
||||
(cl-case literate
|
||||
(bird haskell-bird-syntactic-keywords)
|
||||
((latex tex) haskell-latex-syntactic-keywords)
|
||||
(t haskell-basic-syntactic-keywords))))
|
||||
|
||||
(defun haskell-font-lock-defaults-create ()
|
||||
"Locally set `font-lock-defaults' for Haskell."
|
||||
(set (make-local-variable 'font-lock-defaults)
|
||||
'(haskell-font-lock-choose-keywords
|
||||
nil nil ((?\' . "w") (?_ . "w")) nil
|
||||
(font-lock-syntactic-keywords
|
||||
. haskell-font-lock-choose-syntactic-keywords)
|
||||
(font-lock-syntactic-face-function
|
||||
. haskell-syntactic-face-function)
|
||||
;; Get help from font-lock-syntactic-keywords.
|
||||
(parse-sexp-lookup-properties . t))))
|
||||
|
||||
;; The main functions.
|
||||
(defun turn-on-haskell-font-lock ()
|
||||
"Turns on font locking in current buffer for Haskell 1.4 scripts.
|
||||
|
||||
Changes the current buffer's `font-lock-defaults', and adds the
|
||||
following variables:
|
||||
|
||||
`haskell-keyword-face' for reserved keywords and syntax,
|
||||
`haskell-constructor-face' for data- and type-constructors, class names,
|
||||
and module names,
|
||||
`haskell-operator-face' for symbolic and alphanumeric operators,
|
||||
`haskell-default-face' for ordinary code.
|
||||
|
||||
The variables are initialised to the following font lock default faces:
|
||||
|
||||
`haskell-keyword-face' `font-lock-keyword-face'
|
||||
`haskell-constructor-face' `font-lock-type-face'
|
||||
`haskell-operator-face' `font-lock-function-name-face'
|
||||
`haskell-default-face' <default face>
|
||||
|
||||
Two levels of fontification are defined: level one (the default)
|
||||
and level two (more colour). The former does not colour operators.
|
||||
Use the variable `font-lock-maximum-decoration' to choose
|
||||
non-default levels of fontification. For example, adding this to
|
||||
.emacs:
|
||||
|
||||
(setq font-lock-maximum-decoration '((haskell-mode . 2) (t . 0)))
|
||||
|
||||
uses level two fontification for `haskell-mode' and default level for
|
||||
all other modes. See documentation on this variable for further
|
||||
details.
|
||||
|
||||
To alter an attribute of a face, add a hook. For example, to change
|
||||
the foreground colour of comments to brown, add the following line to
|
||||
.emacs:
|
||||
|
||||
(add-hook 'haskell-font-lock-hook
|
||||
(lambda ()
|
||||
(set-face-foreground 'haskell-comment-face \"brown\")))
|
||||
|
||||
Note that the colours available vary from system to system. To see
|
||||
what colours are available on your system, call
|
||||
`list-colors-display' from emacs.
|
||||
|
||||
To turn font locking on for all Haskell buffers, add this to .emacs:
|
||||
|
||||
(add-hook 'haskell-mode-hook 'turn-on-haskell-font-lock)
|
||||
|
||||
To turn font locking on for the current buffer, call
|
||||
`turn-on-haskell-font-lock'. To turn font locking off in the current
|
||||
buffer, call `turn-off-haskell-font-lock'.
|
||||
|
||||
Bird-style literate Haskell scripts are supported: If the value of
|
||||
`haskell-literate-bird-style' (automatically set by the Haskell mode
|
||||
of Moss&Thorn) is non-nil, a Bird-style literate script is assumed.
|
||||
|
||||
Invokes `haskell-font-lock-hook' if not nil."
|
||||
(haskell-font-lock-defaults-create)
|
||||
(run-hooks 'haskell-font-lock-hook)
|
||||
(turn-on-font-lock))
|
||||
|
||||
(defun turn-off-haskell-font-lock ()
|
||||
"Turns off font locking in current buffer."
|
||||
(font-lock-mode -1))
|
||||
|
||||
(defun haskell-fontify-as-mode (text mode)
|
||||
"Fontify TEXT as MODE, returning the fontified text."
|
||||
(with-temp-buffer
|
||||
(funcall mode)
|
||||
(insert text)
|
||||
(if (fboundp 'font-lock-ensure)
|
||||
(font-lock-ensure)
|
||||
(with-no-warnings (font-lock-fontify-buffer)))
|
||||
(buffer-substring (point-min) (point-max))))
|
||||
|
||||
;; Provide ourselves:
|
||||
|
||||
(provide 'haskell-font-lock)
|
||||
|
||||
;; Local Variables:
|
||||
;; tab-width: 8
|
||||
;; End:
|
||||
|
||||
;;; haskell-font-lock.el ends here
|
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-font-lock.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-font-lock.elc
Normal file
Binary file not shown.
1590
.emacs.d/elpa/haskell-mode-13.12/haskell-indent.el
Normal file
1590
.emacs.d/elpa/haskell-mode-13.12/haskell-indent.el
Normal file
File diff suppressed because it is too large
Load Diff
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-indent.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-indent.elc
Normal file
Binary file not shown.
1098
.emacs.d/elpa/haskell-mode-13.12/haskell-indentation.el
Normal file
1098
.emacs.d/elpa/haskell-mode-13.12/haskell-indentation.el
Normal file
File diff suppressed because it is too large
Load Diff
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-indentation.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-indentation.elc
Normal file
Binary file not shown.
1125
.emacs.d/elpa/haskell-mode-13.12/haskell-interactive-mode.el
Normal file
1125
.emacs.d/elpa/haskell-mode-13.12/haskell-interactive-mode.el
Normal file
File diff suppressed because it is too large
Load Diff
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-interactive-mode.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-interactive-mode.elc
Normal file
Binary file not shown.
398
.emacs.d/elpa/haskell-mode-13.12/haskell-load.el
Normal file
398
.emacs.d/elpa/haskell-mode-13.12/haskell-load.el
Normal file
@@ -0,0 +1,398 @@
|
||||
;;; haskell-load.el --- Compiling and loading modules in the GHCi process
|
||||
|
||||
;; Copyright (c) 2014 Chris Done. All rights reserved.
|
||||
|
||||
;; 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'cl-lib)
|
||||
(require 'haskell-process)
|
||||
(require 'haskell-interactive-mode)
|
||||
(require 'haskell-modules)
|
||||
(require 'haskell-commands)
|
||||
(require 'haskell-session)
|
||||
|
||||
(defun haskell-process-look-config-changes (session)
|
||||
"Checks whether a cabal configuration file has
|
||||
changed. Restarts the process if that is the case."
|
||||
(let ((current-checksum (haskell-session-get session 'cabal-checksum))
|
||||
(new-checksum (haskell-cabal-compute-checksum
|
||||
(haskell-session-get session 'cabal-dir))))
|
||||
(when (not (string= current-checksum new-checksum))
|
||||
(haskell-interactive-mode-echo session (format "Cabal file changed: %s" new-checksum))
|
||||
(haskell-session-set-cabal-checksum session
|
||||
(haskell-session-get session 'cabal-dir))
|
||||
(unless (and haskell-process-prompt-restart-on-cabal-change
|
||||
(not (y-or-n-p "Cabal file changed; restart GHCi process? ")))
|
||||
(haskell-process-start (haskell-interactive-session))))))
|
||||
|
||||
(defun haskell-process-live-build (process buffer echo-in-repl)
|
||||
"Show live updates for loading files."
|
||||
(cond ((haskell-process-consume
|
||||
process
|
||||
(concat "\\[[ ]*\\([0-9]+\\) of \\([0-9]+\\)\\]"
|
||||
" Compiling \\([^ ]+\\)[ ]+"
|
||||
"( \\([^ ]+\\), \\([^ ]+\\) )[^\r\n]*[\r\n]+"))
|
||||
(haskell-process-echo-load-message process buffer echo-in-repl nil)
|
||||
t)
|
||||
((haskell-process-consume
|
||||
process
|
||||
(concat "\\[[ ]*\\([0-9]+\\) of \\([0-9]+\\)\\]"
|
||||
" Compiling \\[TH\\] \\([^ ]+\\)[ ]+"
|
||||
"( \\([^ ]+\\), \\([^ ]+\\) )[^\r\n]*[\r\n]+"))
|
||||
(haskell-process-echo-load-message process buffer echo-in-repl t)
|
||||
t)
|
||||
((haskell-process-consume process "Loading package \\([^ ]+\\) ... linking ... done.\n")
|
||||
(haskell-mode-message-line
|
||||
(format "Loading: %s"
|
||||
(match-string 1 buffer)))
|
||||
t)
|
||||
((haskell-process-consume
|
||||
process
|
||||
"^Preprocessing executables for \\(.+?\\)\\.\\.\\.")
|
||||
(let ((msg (format "Preprocessing: %s" (match-string 1 buffer))))
|
||||
(haskell-interactive-mode-echo
|
||||
(haskell-process-session process)
|
||||
msg)
|
||||
(haskell-mode-message-line msg)))
|
||||
((haskell-process-consume process "Linking \\(.+?\\) \\.\\.\\.")
|
||||
(let ((msg (format "Linking: %s" (match-string 1 buffer))))
|
||||
(haskell-interactive-mode-echo (haskell-process-session process) msg)
|
||||
(haskell-mode-message-line msg)))
|
||||
((haskell-process-consume process "\nBuilding \\(.+?\\)\\.\\.\\.")
|
||||
(let ((msg (format "Building: %s" (match-string 1 buffer))))
|
||||
(haskell-interactive-mode-echo
|
||||
(haskell-process-session process)
|
||||
msg)
|
||||
(haskell-mode-message-line msg)))))
|
||||
|
||||
(defun haskell-process-load-complete (session process buffer reload module-buffer &optional cont)
|
||||
"Handle the complete loading response. BUFFER is the string of
|
||||
text being sent over the process pipe. MODULE-BUFFER is the
|
||||
actual Emacs buffer of the module being loaded."
|
||||
(when (get-buffer (format "*%s:splices*" (haskell-session-name session)))
|
||||
(with-current-buffer (haskell-interactive-mode-splices-buffer session)
|
||||
(erase-buffer)))
|
||||
(cond ((haskell-process-consume process "Ok, modules loaded: \\(.+\\)\\.$")
|
||||
(let* ((modules (haskell-process-extract-modules buffer))
|
||||
(cursor (haskell-process-response-cursor process)))
|
||||
(haskell-process-set-response-cursor process 0)
|
||||
(let ((warning-count 0))
|
||||
(while (haskell-process-errors-warnings session process buffer)
|
||||
(setq warning-count (1+ warning-count)))
|
||||
(haskell-process-set-response-cursor process cursor)
|
||||
(if (and (not reload)
|
||||
haskell-process-reload-with-fbytecode)
|
||||
(haskell-process-reload-with-fbytecode process module-buffer)
|
||||
(haskell-process-import-modules process (car modules)))
|
||||
(haskell-mode-message-line
|
||||
(if reload "Reloaded OK." "OK."))
|
||||
(when cont
|
||||
(condition-case e
|
||||
(funcall cont t)
|
||||
(error (message "%S" e))
|
||||
(quit nil))))))
|
||||
((haskell-process-consume process "Failed, modules loaded: \\(.+\\)\\.$")
|
||||
(let* ((modules (haskell-process-extract-modules buffer))
|
||||
(cursor (haskell-process-response-cursor process)))
|
||||
(haskell-process-set-response-cursor process 0)
|
||||
(while (haskell-process-errors-warnings session process buffer))
|
||||
(haskell-process-set-response-cursor process cursor)
|
||||
(if (and (not reload) haskell-process-reload-with-fbytecode)
|
||||
(haskell-process-reload-with-fbytecode process module-buffer)
|
||||
(haskell-process-import-modules process (car modules)))
|
||||
(haskell-interactive-mode-compile-error session "Compilation failed.")
|
||||
(when cont
|
||||
(condition-case e
|
||||
(funcall cont nil)
|
||||
(error (message "%S" e))
|
||||
(quit nil)))))))
|
||||
|
||||
(defun haskell-process-suggest-imports (session file modules ident)
|
||||
"Given a list of MODULES, suggest adding them to the import section."
|
||||
(cl-assert session)
|
||||
(cl-assert file)
|
||||
(cl-assert ident)
|
||||
(let* ((process (haskell-session-process session))
|
||||
(suggested-already (haskell-process-suggested-imports process))
|
||||
(module (cond ((> (length modules) 1)
|
||||
(when (y-or-n-p (format "Identifier `%s' not in scope, choose module to import?"
|
||||
ident))
|
||||
(haskell-complete-module-read "Module: " modules)))
|
||||
((= (length modules) 1)
|
||||
(let ((module (car modules)))
|
||||
(unless (member module suggested-already)
|
||||
(haskell-process-set-suggested-imports process (cons module suggested-already))
|
||||
(when (y-or-n-p (format "Identifier `%s' not in scope, import `%s'?"
|
||||
ident
|
||||
module))
|
||||
module)))))))
|
||||
(when module
|
||||
(haskell-process-find-file session file)
|
||||
(haskell-add-import module))))
|
||||
|
||||
(defun haskell-process-trigger-suggestions (session msg file line)
|
||||
"Trigger prompting to add any extension suggestions."
|
||||
(cond ((let ((case-fold-search nil))
|
||||
(or (and (string-match " -X\\([A-Z][A-Za-z]+\\)" msg)
|
||||
(not (string-match "\\([A-Z][A-Za-z]+\\) is deprecated" msg)))
|
||||
(string-match "Use \\([A-Z][A-Za-z]+\\) to permit this" msg)
|
||||
(string-match "Use \\([A-Z][A-Za-z]+\\) to allow" msg)
|
||||
(string-match "use \\([A-Z][A-Za-z]+\\)" msg)
|
||||
(string-match "You need \\([A-Z][A-Za-z]+\\)" msg)))
|
||||
(when haskell-process-suggest-language-pragmas
|
||||
(haskell-process-suggest-pragma session "LANGUAGE" (match-string 1 msg) file)))
|
||||
((string-match " The \\(qualified \\)?import of[ ][‘`‛]\\([^ ]+\\)['’] is redundant" msg)
|
||||
(when haskell-process-suggest-remove-import-lines
|
||||
(haskell-process-suggest-remove-import session
|
||||
file
|
||||
(match-string 2 msg)
|
||||
line)))
|
||||
((string-match "Warning: orphan instance: " msg)
|
||||
(when haskell-process-suggest-no-warn-orphans
|
||||
(haskell-process-suggest-pragma session "OPTIONS" "-fno-warn-orphans" file)))
|
||||
((or (string-match "against inferred type [‘`‛]\\[Char\\]['’]" msg)
|
||||
(string-match "with actual type [‘`‛]\\[Char\\]['’]" msg))
|
||||
(when haskell-process-suggest-overloaded-strings
|
||||
(haskell-process-suggest-pragma session "LANGUAGE" "OverloadedStrings" file)))
|
||||
((string-match "^Not in scope: .*[‘`‛]\\(.+\\)['’]$" msg)
|
||||
(let* ((match1 (match-string 1 msg))
|
||||
(ident (if (string-match "^[A-Za-z0-9_'.]+\\.\\(.+\\)$" match1)
|
||||
;; Skip qualification.
|
||||
(match-string 1 match1)
|
||||
match1)))
|
||||
(when haskell-process-suggest-hoogle-imports
|
||||
(let ((modules (haskell-process-hoogle-ident ident)))
|
||||
(haskell-process-suggest-imports session file modules ident)))
|
||||
(when haskell-process-suggest-haskell-docs-imports
|
||||
(let ((modules (haskell-process-haskell-docs-ident ident)))
|
||||
(haskell-process-suggest-imports session file modules ident)))
|
||||
(when haskell-process-suggest-hayoo-imports
|
||||
(let ((modules (haskell-process-hayoo-ident ident)))
|
||||
(haskell-process-suggest-imports session file modules ident)))))
|
||||
((string-match "^[ ]+It is a member of the hidden package [‘`‛]\\(.+\\)['’].$" msg)
|
||||
(when haskell-process-suggest-add-package
|
||||
(haskell-process-suggest-add-package session msg)))))
|
||||
|
||||
(defun haskell-process-do-cabal (command)
|
||||
"Run a Cabal command."
|
||||
(let ((process (haskell-interactive-process)))
|
||||
(haskell-process-queue-command
|
||||
process
|
||||
(make-haskell-command
|
||||
:state (list (haskell-interactive-session) process command 0)
|
||||
|
||||
:go
|
||||
(lambda (state)
|
||||
(haskell-process-send-string
|
||||
(cadr state)
|
||||
(format haskell-process-do-cabal-format-string
|
||||
(haskell-session-cabal-dir (car state))
|
||||
(format "%s %s"
|
||||
(cl-ecase (haskell-process-type)
|
||||
('ghci haskell-process-path-cabal)
|
||||
('cabal-repl haskell-process-path-cabal)
|
||||
('cabal-ghci haskell-process-path-cabal)
|
||||
('cabal-dev haskell-process-path-cabal-dev))
|
||||
(cl-caddr state)))))
|
||||
|
||||
:live
|
||||
(lambda (state buffer)
|
||||
(let ((cmd (replace-regexp-in-string "^\\([a-z]+\\).*"
|
||||
"\\1"
|
||||
(cl-caddr state))))
|
||||
(cond ((or (string= cmd "build")
|
||||
(string= cmd "install"))
|
||||
(haskell-process-live-build (cadr state) buffer t))
|
||||
(t
|
||||
(haskell-process-cabal-live state buffer)))))
|
||||
|
||||
:complete
|
||||
(lambda (state response)
|
||||
(let* ((process (cadr state))
|
||||
(session (haskell-process-session process))
|
||||
(message-count 0)
|
||||
(cursor (haskell-process-response-cursor process)))
|
||||
(haskell-process-set-response-cursor process 0)
|
||||
(while (haskell-process-errors-warnings session process response)
|
||||
(setq message-count (1+ message-count)))
|
||||
(haskell-process-set-response-cursor process cursor)
|
||||
(let ((msg (format "Complete: cabal %s (%s compiler messages)"
|
||||
(cl-caddr state)
|
||||
message-count)))
|
||||
(haskell-interactive-mode-echo session msg)
|
||||
(when (= message-count 0)
|
||||
(haskell-interactive-mode-echo
|
||||
session
|
||||
"No compiler messages, dumping complete output:")
|
||||
(haskell-interactive-mode-echo session response))
|
||||
(haskell-mode-message-line msg)
|
||||
(when (and haskell-notify-p
|
||||
(fboundp 'notifications-notify))
|
||||
(notifications-notify
|
||||
:title (format "*%s*" (haskell-session-name (car state)))
|
||||
:body msg
|
||||
:app-name (cl-ecase (haskell-process-type)
|
||||
('ghci haskell-process-path-cabal)
|
||||
('cabal-repl haskell-process-path-cabal)
|
||||
('cabal-ghci haskell-process-path-cabal)
|
||||
('cabal-dev haskell-process-path-cabal-dev))
|
||||
:app-icon haskell-process-logo)))))))))
|
||||
|
||||
(defun haskell-process-echo-load-message (process buffer echo-in-repl th)
|
||||
"Echo a load message."
|
||||
(let ((session (haskell-process-session process))
|
||||
(module-name (match-string 3 buffer))
|
||||
(file-name (match-string 4 buffer)))
|
||||
(haskell-interactive-show-load-message
|
||||
session
|
||||
'compiling
|
||||
module-name
|
||||
(haskell-session-strip-dir session file-name)
|
||||
echo-in-repl
|
||||
th)))
|
||||
|
||||
(defun haskell-process-extract-modules (buffer)
|
||||
"Extract the modules from the process buffer."
|
||||
(let* ((modules-string (match-string 1 buffer))
|
||||
(modules (split-string modules-string ", ")))
|
||||
(cons modules modules-string)))
|
||||
|
||||
(defun haskell-process-errors-warnings (session process buffer &optional return-only)
|
||||
"Trigger handling type errors or warnings. Either prints the
|
||||
messages in the interactive buffer or if CONT is specified,
|
||||
passes the error onto that."
|
||||
(cond
|
||||
((haskell-process-consume
|
||||
process
|
||||
"\\(Module imports form a cycle:[ \n]+module [^ ]+ ([^)]+)[[:unibyte:][:nonascii:]]+?\\)\nFailed")
|
||||
(let ((err (match-string 1 buffer)))
|
||||
(if (string-match "module [`'‘‛]\\([^ ]+\\)['’`] (\\([^)]+\\))" err)
|
||||
(let* ((default-directory (haskell-session-current-dir session))
|
||||
(module (match-string 1 err))
|
||||
(file (match-string 2 err))
|
||||
(relative-file-name (file-relative-name file)))
|
||||
(unless return-only
|
||||
(haskell-interactive-show-load-message
|
||||
session
|
||||
'import-cycle
|
||||
module
|
||||
relative-file-name
|
||||
nil
|
||||
nil)
|
||||
(haskell-interactive-mode-compile-error
|
||||
session
|
||||
(format "%s:1:0: %s"
|
||||
relative-file-name
|
||||
err)))
|
||||
(list :file file :line 1 :col 0 :msg err :type 'error))
|
||||
t)))
|
||||
((haskell-process-consume
|
||||
process
|
||||
(concat "[\r\n]\\([A-Z]?:?[^ \r\n:][^:\n\r]+\\):\\([0-9()-:]+\\):"
|
||||
"[ \n\r]+\\([[:unibyte:][:nonascii:]]+?\\)\n[^ ]"))
|
||||
(haskell-process-set-response-cursor process
|
||||
(- (haskell-process-response-cursor process) 1))
|
||||
(let* ((buffer (haskell-process-response process))
|
||||
(file (match-string 1 buffer))
|
||||
(location (match-string 2 buffer))
|
||||
(error-msg (match-string 3 buffer))
|
||||
(warning (string-match "^Warning:" error-msg))
|
||||
(splice (string-match "^Splicing " error-msg))
|
||||
(final-msg (format "%s:%s: %s"
|
||||
(haskell-session-strip-dir session file)
|
||||
location
|
||||
error-msg)))
|
||||
(if return-only
|
||||
(let* ((location (haskell-process-parse-error (concat file ":" location ": x")))
|
||||
(file (plist-get location :file))
|
||||
(line (plist-get location :line))
|
||||
(col1 (plist-get location :col)))
|
||||
(list :file file :line line :col col1 :msg error-msg :type (if warning 'warning 'error)))
|
||||
(progn (funcall (cond (warning
|
||||
'haskell-interactive-mode-compile-warning)
|
||||
(splice
|
||||
'haskell-interactive-mode-compile-splice)
|
||||
(t 'haskell-interactive-mode-compile-error))
|
||||
session final-msg)
|
||||
(unless warning
|
||||
(haskell-mode-message-line final-msg))
|
||||
(haskell-process-trigger-suggestions
|
||||
session
|
||||
error-msg
|
||||
file
|
||||
(plist-get (haskell-process-parse-error final-msg) :line))
|
||||
t))))))
|
||||
|
||||
(defun haskell-interactive-show-load-message (session type module-name file-name echo th)
|
||||
"Show the '(Compiling|Loading) X' message."
|
||||
(let ((msg (concat
|
||||
(cl-ecase type
|
||||
('compiling
|
||||
(if haskell-interactive-mode-include-file-name
|
||||
(format "Compiling: %s (%s)" module-name file-name)
|
||||
(format "Compiling: %s" module-name)))
|
||||
('loading (format "Loading: %s" module-name))
|
||||
('import-cycle (format "Module has an import cycle: %s" module-name)))
|
||||
(if th " [TH]" ""))))
|
||||
(haskell-mode-message-line msg)
|
||||
(when haskell-interactive-mode-delete-superseded-errors
|
||||
(haskell-interactive-mode-delete-compile-messages session file-name))
|
||||
(when echo
|
||||
(haskell-interactive-mode-echo session msg))))
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-process-reload-devel-main ()
|
||||
"Reload the module `DevelMain' and then run
|
||||
`DevelMain.update'. This is for doing live update of the code of
|
||||
servers or GUI applications. Put your development version of the
|
||||
program in `DevelMain', and define `update' to auto-start the
|
||||
program on a new thread, and use the `foreign-store' package to
|
||||
access the running context across :load/:reloads in GHCi."
|
||||
(interactive)
|
||||
(with-current-buffer (or (get-buffer "DevelMain.hs")
|
||||
(if (y-or-n-p "You need to open a buffer named DevelMain.hs. Find now?")
|
||||
(ido-find-file)
|
||||
(error "No DevelMain.hs buffer.")))
|
||||
(let ((session (haskell-interactive-session)))
|
||||
(let ((process (haskell-interactive-process)))
|
||||
(haskell-process-queue-command
|
||||
process
|
||||
(make-haskell-command
|
||||
:state (list :session session
|
||||
:process process
|
||||
:buffer (current-buffer))
|
||||
:go (lambda (state)
|
||||
(haskell-process-send-string (plist-get state ':process)
|
||||
":l DevelMain"))
|
||||
:live (lambda (state buffer)
|
||||
(haskell-process-live-build (plist-get state ':process)
|
||||
buffer
|
||||
nil))
|
||||
:complete (lambda (state response)
|
||||
(haskell-process-load-complete
|
||||
(plist-get state ':session)
|
||||
(plist-get state ':process)
|
||||
response
|
||||
nil
|
||||
(plist-get state ':buffer)
|
||||
(lambda (ok)
|
||||
(when ok
|
||||
(haskell-process-queue-without-filters
|
||||
(haskell-interactive-process)
|
||||
"DevelMain.update")
|
||||
(message "DevelMain updated.")))))))))))
|
||||
|
||||
(provide 'haskell-load)
|
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-load.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-load.elc
Normal file
Binary file not shown.
158
.emacs.d/elpa/haskell-mode-13.12/haskell-menu.el
Normal file
158
.emacs.d/elpa/haskell-mode-13.12/haskell-menu.el
Normal file
@@ -0,0 +1,158 @@
|
||||
;;; haskell-menu.el --- A Haskell sessions menu
|
||||
|
||||
;; Copyright (C) 2013 Chris Done
|
||||
|
||||
;; Author: Chris Done <chrisdone@gmail.com>
|
||||
|
||||
;; 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 GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
;; Boston, MA 02110-1301, USA.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;;; Todo:
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'cl-lib)
|
||||
(require 'haskell-compat)
|
||||
(require 'haskell-session)
|
||||
(require 'haskell-process)
|
||||
(require 'haskell-interactive-mode)
|
||||
|
||||
(defcustom haskell-menu-buffer-name "*haskell-menu*"
|
||||
"The name of the Haskell session menu buffer"
|
||||
:group 'haskell-interactive
|
||||
:type 'string)
|
||||
|
||||
;;;###autoload
|
||||
(defun haskell-menu ()
|
||||
"Launch the Haskell sessions menu."
|
||||
(interactive)
|
||||
(or (get-buffer haskell-menu-buffer-name)
|
||||
(with-current-buffer (get-buffer-create haskell-menu-buffer-name)
|
||||
(haskell-menu-mode)))
|
||||
(switch-to-buffer-other-window (get-buffer haskell-menu-buffer-name))
|
||||
(haskell-menu-revert-function nil nil))
|
||||
|
||||
(define-derived-mode haskell-menu-mode special-mode "Haskell Session Menu"
|
||||
"Major mode for managing Haskell sessions.
|
||||
Each line describes one session.
|
||||
Letters do not insert themselves; instead, they are commands."
|
||||
(setq buffer-read-only t)
|
||||
(set (make-local-variable 'revert-buffer-function)
|
||||
'haskell-menu-revert-function)
|
||||
(setq truncate-lines t)
|
||||
(haskell-menu-revert-function nil t))
|
||||
|
||||
(suppress-keymap haskell-menu-mode-map t)
|
||||
(define-key haskell-menu-mode-map (kbd "n") 'next-line)
|
||||
(define-key haskell-menu-mode-map (kbd "p") 'previous-line)
|
||||
(define-key haskell-menu-mode-map (kbd "RET") 'haskell-menu-mode-ret)
|
||||
|
||||
(defun haskell-menu-revert-function (arg1 arg2)
|
||||
"Function to refresh the display."
|
||||
(let ((buffer-read-only nil)
|
||||
(orig-line (line-number-at-pos))
|
||||
(orig-col (current-column)))
|
||||
(or (eq buffer-undo-list t)
|
||||
(setq buffer-undo-list nil))
|
||||
(erase-buffer)
|
||||
(haskell-menu-insert-menu)
|
||||
(goto-char (point-min))
|
||||
(forward-line (1- orig-line))
|
||||
(forward-char orig-col)))
|
||||
|
||||
(defun haskell-menu-insert-menu ()
|
||||
"Insert the Haskell sessions menu to the current buffer."
|
||||
(if (null haskell-sessions)
|
||||
(insert "No Haskell sessions.")
|
||||
(haskell-menu-tabulate
|
||||
(list "Name" "PID" "Time" "RSS" "Cabal directory" "Working directory" "Command")
|
||||
(mapcar (lambda (session)
|
||||
(let ((process (haskell-process-process (haskell-session-process session))))
|
||||
(cond
|
||||
(process
|
||||
(let ((id (process-id process)))
|
||||
(list (propertize (haskell-session-name session) 'face 'buffer-menu-buffer)
|
||||
(if (process-live-p process) (number-to-string id) "-")
|
||||
(if (process-live-p process)
|
||||
(format-time-string "%H:%M:%S"
|
||||
(encode-time (cl-caddr (assoc 'etime (process-attributes id)))
|
||||
0 0 0 0 0))
|
||||
"-")
|
||||
(if (process-live-p process)
|
||||
(concat (number-to-string (/ (cdr (assoc 'rss (process-attributes id)))
|
||||
1024))
|
||||
"MB")
|
||||
"-")
|
||||
(haskell-session-cabal-dir session)
|
||||
(haskell-session-current-dir session)
|
||||
(mapconcat 'identity (process-command process) " "))))
|
||||
(t (list (propertize (haskell-session-name session) 'face 'buffer-menu-buffer)
|
||||
"—"
|
||||
"—"
|
||||
"—"
|
||||
(haskell-session-cabal-dir session)
|
||||
(haskell-session-current-dir session))))))
|
||||
haskell-sessions))))
|
||||
|
||||
(defun haskell-menu-tabulate (headings rows)
|
||||
"Prints a list of lists as a formatted table to the current buffer."
|
||||
(let* ((columns (length headings))
|
||||
(widths (make-list columns 0)))
|
||||
;; Calculate column widths. This is kind of hideous.
|
||||
(dolist (row rows)
|
||||
(setq widths
|
||||
(let ((list (list)))
|
||||
(dotimes (i columns)
|
||||
(setq list (cons (max (nth i widths)
|
||||
(1+ (length (nth i row)))
|
||||
(1+ (length (nth i headings))))
|
||||
list)))
|
||||
(reverse list))))
|
||||
;; Print headings.
|
||||
(let ((heading (propertize " " 'display '(space :align-to 0))))
|
||||
(dotimes (i columns)
|
||||
(setq heading (concat heading
|
||||
(format (concat "%-" (number-to-string (nth i widths)) "s")
|
||||
(nth i headings)))))
|
||||
(setq header-line-format heading))
|
||||
;; Print tabulated rows.
|
||||
(dolist (row rows)
|
||||
(dotimes (i columns)
|
||||
(insert (format (concat "%-" (number-to-string (nth i widths)) "s")
|
||||
(nth i row))))
|
||||
(insert "\n"))))
|
||||
|
||||
(defun haskell-menu-mode-ret ()
|
||||
"Handle RET key."
|
||||
(interactive)
|
||||
(let* ((name (save-excursion
|
||||
(goto-char (line-beginning-position))
|
||||
(buffer-substring-no-properties (point)
|
||||
(progn (search-forward " ")
|
||||
(forward-char -1)
|
||||
(point)))))
|
||||
(session (car (cl-remove-if-not (lambda (session)
|
||||
(string= (haskell-session-name session)
|
||||
name))
|
||||
haskell-sessions))))
|
||||
(switch-to-buffer (haskell-session-interactive-buffer session))))
|
||||
|
||||
(provide 'haskell-menu)
|
||||
|
||||
;;; haskell-menu.el ends here
|
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-menu.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-menu.elc
Normal file
Binary file not shown.
953
.emacs.d/elpa/haskell-mode-13.12/haskell-mode-autoloads.el
Normal file
953
.emacs.d/elpa/haskell-mode-13.12/haskell-mode-autoloads.el
Normal file
@@ -0,0 +1,953 @@
|
||||
;;; haskell-mode-autoloads.el --- automatically extracted autoloads
|
||||
;;
|
||||
;;; Code:
|
||||
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
|
||||
|
||||
;;;### (autoloads nil "ghc-core" "ghc-core.el" (21860 25846 0 0))
|
||||
;;; Generated autoloads from ghc-core.el
|
||||
|
||||
(autoload 'ghc-core-create-core "ghc-core" "\
|
||||
Compile and load the current buffer as tidy core.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.hcr\\'" . ghc-core-mode))
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.dump-simpl\\'" . ghc-core-mode))
|
||||
|
||||
(autoload 'ghc-core-mode "ghc-core" "\
|
||||
Major mode for GHC Core files.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "ghci-script-mode" "ghci-script-mode.el" (21860
|
||||
;;;;;; 25846 0 0))
|
||||
;;; Generated autoloads from ghci-script-mode.el
|
||||
|
||||
(autoload 'ghci-script-mode "ghci-script-mode" "\
|
||||
Major mode for working with .ghci files.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.ghci\\'" . ghci-script-mode))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell" "haskell.el" (21860 25846 0 0))
|
||||
;;; Generated autoloads from haskell.el
|
||||
|
||||
(autoload 'interactive-haskell-mode "haskell" "\
|
||||
Minor mode for enabling haskell-process interaction.
|
||||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
(autoload 'haskell-interactive-mode-return "haskell" "\
|
||||
Handle the return key.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-session-kill "haskell" "\
|
||||
Kill the session process and buffer, delete the session.
|
||||
0. Prompt to kill all associated buffers.
|
||||
1. Kill the process.
|
||||
2. Kill the interactive buffer.
|
||||
3. Walk through all the related buffers and set their haskell-session to nil.
|
||||
4. Remove the session from the sessions list.
|
||||
|
||||
\(fn &optional LEAVE-INTERACTIVE-BUFFER)" t nil)
|
||||
|
||||
(autoload 'haskell-interactive-kill "haskell" "\
|
||||
Kill the buffer and (maybe) the session.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-session "haskell" "\
|
||||
Get the Haskell session, prompt if there isn't one or fail.
|
||||
|
||||
\(fn)" nil nil)
|
||||
|
||||
(autoload 'haskell-interactive-switch "haskell" "\
|
||||
Switch to the interactive mode for this session.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-session-change "haskell" "\
|
||||
Change the session for the current buffer.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-kill-session-process "haskell" "\
|
||||
Kill the process.
|
||||
|
||||
\(fn &optional SESSION)" t nil)
|
||||
|
||||
(autoload 'haskell-interactive-mode-visit-error "haskell" "\
|
||||
Visit the buffer of the current (or last) error message.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-mode-contextual-space "haskell" "\
|
||||
Contextually do clever stuff when hitting space.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-mode-jump-to-tag "haskell" "\
|
||||
Jump to the tag of the given identifier.
|
||||
|
||||
\(fn &optional NEXT-P)" t nil)
|
||||
|
||||
(autoload 'haskell-mode-after-save-handler "haskell" "\
|
||||
Function that will be called after buffer's saving.
|
||||
|
||||
\(fn)" nil nil)
|
||||
|
||||
(autoload 'haskell-mode-tag-find "haskell" "\
|
||||
The tag find function, specific for the particular session.
|
||||
|
||||
\(fn &optional NEXT-P)" t nil)
|
||||
|
||||
(autoload 'haskell-interactive-bring "haskell" "\
|
||||
Bring up the interactive mode for this session.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-process-load-file "haskell" "\
|
||||
Load the current buffer file.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-process-reload-file "haskell" "\
|
||||
Re-load the current buffer file.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-process-load-or-reload "haskell" "\
|
||||
Load or reload. Universal argument toggles which.
|
||||
|
||||
\(fn &optional TOGGLE)" t nil)
|
||||
|
||||
(autoload 'haskell-process-cabal-build "haskell" "\
|
||||
Build the Cabal project.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-process-cabal "haskell" "\
|
||||
Prompts for a Cabal command to run.
|
||||
|
||||
\(fn P)" t nil)
|
||||
|
||||
(autoload 'haskell-process-minimal-imports "haskell" "\
|
||||
Dump minimal imports.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-align-imports" "haskell-align-imports.el"
|
||||
;;;;;; (21860 25846 0 0))
|
||||
;;; Generated autoloads from haskell-align-imports.el
|
||||
|
||||
(autoload 'haskell-align-imports "haskell-align-imports" "\
|
||||
Align all the imports in the buffer.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-c" "haskell-c.el" (21860 25846 0 0))
|
||||
;;; Generated autoloads from haskell-c.el
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.hsc\\'" . haskell-c-mode))
|
||||
|
||||
(autoload 'haskell-c-mode "haskell-c" "\
|
||||
Major mode for Haskell FFI files.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-cabal" "haskell-cabal.el" (21860 25846
|
||||
;;;;;; 0 0))
|
||||
;;; Generated autoloads from haskell-cabal.el
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.cabal\\'" . haskell-cabal-mode))
|
||||
|
||||
(autoload 'haskell-cabal-mode "haskell-cabal" "\
|
||||
Major mode for Cabal package description files.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-guess-setting "haskell-cabal" "\
|
||||
Guess the specified setting of this project.
|
||||
If there is no valid .cabal file to get the setting from (or
|
||||
there is no corresponding setting with that name in the .cabal
|
||||
file), then this function returns nil.
|
||||
|
||||
\(fn NAME)" t nil)
|
||||
|
||||
(autoload 'haskell-cabal-get-dir "haskell-cabal" "\
|
||||
Get the Cabal dir for a new project. Various ways of figuring this out,
|
||||
and indeed just prompting the user. Do them all.
|
||||
|
||||
\(fn)" nil nil)
|
||||
|
||||
(autoload 'haskell-cabal-visit-file "haskell-cabal" "\
|
||||
Locate and visit package description file for file visited by current buffer.
|
||||
This uses `haskell-cabal-find-file' to locate the closest
|
||||
\".cabal\" file and open it. This command assumes a common Cabal
|
||||
project structure where the \".cabal\" file is in the top-folder
|
||||
of the project, and all files related to the project are in or
|
||||
below the top-folder. If called with non-nil prefix argument
|
||||
OTHER-WINDOW use `find-file-other-window'.
|
||||
|
||||
\(fn OTHER-WINDOW)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-commands" "haskell-commands.el" (21860
|
||||
;;;;;; 25846 0 0))
|
||||
;;; Generated autoloads from haskell-commands.el
|
||||
|
||||
(autoload 'haskell-process-restart "haskell-commands" "\
|
||||
Restart the inferior Haskell process.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-process-clear "haskell-commands" "\
|
||||
Clear the current process.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-process-interrupt "haskell-commands" "\
|
||||
Interrupt the process (SIGINT).
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-process-touch-buffer "haskell-commands" "\
|
||||
Updates mtime on the file for BUFFER by queing a touch on
|
||||
PROCESS.
|
||||
|
||||
\(fn PROCESS BUFFER)" t nil)
|
||||
|
||||
(autoload 'haskell-describe "haskell-commands" "\
|
||||
Describe the given identifier.
|
||||
|
||||
\(fn IDENT)" t nil)
|
||||
|
||||
(autoload 'haskell-rgrep "haskell-commands" "\
|
||||
Grep the effective project for the symbol at point. Very
|
||||
useful for codebase navigation. Prompts for an arbitrary regexp
|
||||
given a prefix arg.
|
||||
|
||||
\(fn &optional PROMPT)" t nil)
|
||||
|
||||
(autoload 'haskell-process-do-info "haskell-commands" "\
|
||||
Print info on the identifier at point.
|
||||
If PROMPT-VALUE is non-nil, request identifier via mini-buffer.
|
||||
|
||||
\(fn &optional PROMPT-VALUE)" t nil)
|
||||
|
||||
(autoload 'haskell-process-do-type "haskell-commands" "\
|
||||
Print the type of the given expression.
|
||||
|
||||
\(fn &optional INSERT-VALUE)" t nil)
|
||||
|
||||
(autoload 'haskell-mode-jump-to-def-or-tag "haskell-commands" "\
|
||||
Jump to the definition (by consulting GHCi), or (fallback)
|
||||
jump to the tag.
|
||||
|
||||
Remember: If GHCi is busy doing something, this will delay, but
|
||||
it will always be accurate, in contrast to tags, which always
|
||||
work but are not always accurate.
|
||||
If the definition or tag is found, the location from which you jumped
|
||||
will be pushed onto `xref--marker-ring', so you can return to that
|
||||
position with `xref-pop-marker-stack'.
|
||||
|
||||
\(fn &optional NEXT-P)" t nil)
|
||||
|
||||
(autoload 'haskell-mode-goto-loc "haskell-commands" "\
|
||||
Go to the location of the thing at point. Requires the :loc-at
|
||||
command from GHCi.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-mode-jump-to-def "haskell-commands" "\
|
||||
Jump to definition of identifier at point.
|
||||
|
||||
\(fn IDENT)" t nil)
|
||||
|
||||
(autoload 'haskell-process-cd "haskell-commands" "\
|
||||
Change directory.
|
||||
|
||||
\(fn &optional NOT-INTERACTIVE)" t nil)
|
||||
|
||||
(autoload 'haskell-process-cabal-macros "haskell-commands" "\
|
||||
Send the cabal macros string.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-mode-show-type-at "haskell-commands" "\
|
||||
Show the type of the thing at point.
|
||||
|
||||
\(fn &optional INSERT-VALUE)" t nil)
|
||||
|
||||
(autoload 'haskell-process-generate-tags "haskell-commands" "\
|
||||
Regenerate the TAGS table.
|
||||
|
||||
\(fn &optional AND-THEN-FIND-THIS-TAG)" t nil)
|
||||
|
||||
(autoload 'haskell-process-unignore "haskell-commands" "\
|
||||
Unignore any files that were specified as being ignored by the
|
||||
inferior GHCi process.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-session-change-target "haskell-commands" "\
|
||||
Set the build target for cabal repl
|
||||
|
||||
\(fn TARGET)" t nil)
|
||||
|
||||
(autoload 'haskell-mode-stylish-buffer "haskell-commands" "\
|
||||
Apply stylish-haskell to the current buffer.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-mode-find-uses "haskell-commands" "\
|
||||
Find uses of the identifier at point, highlight them all.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-compile" "haskell-compile.el" (21860
|
||||
;;;;;; 25846 0 0))
|
||||
;;; Generated autoloads from haskell-compile.el
|
||||
|
||||
(autoload 'haskell-compile "haskell-compile" "\
|
||||
Compile the Haskell program including the current buffer.
|
||||
Tries to locate the next cabal description in current or parent
|
||||
folders via `haskell-cabal-find-dir' and if found, invoke
|
||||
`haskell-compile-cabal-build-command' from the cabal package root
|
||||
folder. If no cabal package could be detected,
|
||||
`haskell-compile-command' is used instead.
|
||||
|
||||
If prefix argument EDIT-COMMAND is non-nil (and not a negative
|
||||
prefix `-'), `haskell-compile' prompts for custom compile
|
||||
command.
|
||||
|
||||
If EDIT-COMMAND contains the negative prefix argument `-',
|
||||
`haskell-compile' calls the alternative command defined in
|
||||
`haskell-compile-cabal-build-alt-command' if a cabal package was
|
||||
detected.
|
||||
|
||||
`haskell-compile' uses `haskell-compilation-mode' which is
|
||||
derived from `compilation-mode'. See Info
|
||||
node `(haskell-mode)compilation' for more details.
|
||||
|
||||
\(fn &optional EDIT-COMMAND)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-customize" "haskell-customize.el"
|
||||
;;;;;; (21860 25846 0 0))
|
||||
;;; Generated autoloads from haskell-customize.el
|
||||
|
||||
(autoload 'haskell-customize "haskell-customize" "\
|
||||
Browse the haskell customize sub-tree.
|
||||
This calls 'customize-browse' with haskell as argument and makes
|
||||
sure all haskell customize definitions have been loaded.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-decl-scan" "haskell-decl-scan.el"
|
||||
;;;;;; (21860 25846 0 0))
|
||||
;;; Generated autoloads from haskell-decl-scan.el
|
||||
|
||||
(autoload 'haskell-ds-create-imenu-index "haskell-decl-scan" "\
|
||||
Function for finding `imenu' declarations in Haskell mode.
|
||||
Finds all declarations (classes, variables, imports, instances and
|
||||
datatypes) in a Haskell file for the `imenu' package.
|
||||
|
||||
\(fn)" nil nil)
|
||||
|
||||
(autoload 'turn-on-haskell-decl-scan "haskell-decl-scan" "\
|
||||
Unconditionally activate `haskell-decl-scan-mode'.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-decl-scan-mode "haskell-decl-scan" "\
|
||||
Toggle Haskell declaration scanning minor mode on or off.
|
||||
With a prefix argument ARG, enable minor mode if ARG is
|
||||
positive, and disable it otherwise. If called from Lisp, enable
|
||||
the mode if ARG is omitted or nil, and toggle it if ARG is `toggle'.
|
||||
|
||||
See also info node `(haskell-mode)haskell-decl-scan-mode' for
|
||||
more details about this minor mode.
|
||||
|
||||
Top-level declarations are scanned and listed in the menu item
|
||||
\"Declarations\" (if enabled via option
|
||||
`haskell-decl-scan-add-to-menubar'). Selecting an item from this
|
||||
menu will take point to the start of the declaration.
|
||||
|
||||
\\[beginning-of-defun] and \\[end-of-defun] move forward and backward to the start of a declaration.
|
||||
|
||||
This may link with `haskell-doc-mode'.
|
||||
|
||||
For non-literate and LaTeX-style literate scripts, we assume the
|
||||
common convention that top-level declarations start at the first
|
||||
column. For Bird-style literate scripts, we assume the common
|
||||
convention that top-level declarations start at the third column,
|
||||
ie. after \"> \".
|
||||
|
||||
Anything in `font-lock-comment-face' is not considered for a
|
||||
declaration. Therefore, using Haskell font locking with comments
|
||||
coloured in `font-lock-comment-face' improves declaration scanning.
|
||||
|
||||
Literate Haskell scripts are supported: If the value of
|
||||
`haskell-literate' (set automatically by `literate-haskell-mode')
|
||||
is `bird', a Bird-style literate script is assumed. If it is nil
|
||||
or `tex', a non-literate or LaTeX-style literate script is
|
||||
assumed, respectively.
|
||||
|
||||
Invokes `haskell-decl-scan-mode-hook' on activation.
|
||||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-doc" "haskell-doc.el" (21860 25846
|
||||
;;;;;; 0 0))
|
||||
;;; Generated autoloads from haskell-doc.el
|
||||
|
||||
(autoload 'haskell-doc-mode "haskell-doc" "\
|
||||
Enter `haskell-doc-mode' for showing fct types in the echo area.
|
||||
See variable docstring.
|
||||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
(defalias 'turn-on-haskell-doc-mode 'haskell-doc-mode)
|
||||
|
||||
(defalias 'turn-on-haskell-doc 'haskell-doc-mode)
|
||||
|
||||
(autoload 'haskell-doc-current-info "haskell-doc" "\
|
||||
Return the info about symbol at point.
|
||||
Meant for `eldoc-documentation-function'.
|
||||
|
||||
\(fn)" nil nil)
|
||||
|
||||
(autoload 'haskell-doc-show-type "haskell-doc" "\
|
||||
Show the type of the function near point.
|
||||
For the function under point, show the type in the echo area.
|
||||
This information is extracted from the `haskell-doc-prelude-types' alist
|
||||
of prelude functions and their types, or from the local functions in the
|
||||
current buffer.
|
||||
|
||||
\(fn &optional SYM)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-font-lock" "haskell-font-lock.el"
|
||||
;;;;;; (21860 25846 0 0))
|
||||
;;; Generated autoloads from haskell-font-lock.el
|
||||
|
||||
(autoload 'haskell-font-lock-choose-keywords "haskell-font-lock" "\
|
||||
|
||||
|
||||
\(fn)" nil nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-indent" "haskell-indent.el" (21860
|
||||
;;;;;; 25846 0 0))
|
||||
;;; Generated autoloads from haskell-indent.el
|
||||
|
||||
(autoload 'turn-on-haskell-indent "haskell-indent" "\
|
||||
Turn on ``intelligent'' Haskell indentation mode.
|
||||
|
||||
\(fn)" nil nil)
|
||||
|
||||
(autoload 'haskell-indent-mode "haskell-indent" "\
|
||||
``Intelligent'' Haskell indentation mode.
|
||||
This deals with the layout rule of Haskell.
|
||||
\\[haskell-indent-cycle] starts the cycle which proposes new
|
||||
possibilities as long as the TAB key is pressed. Any other key
|
||||
or mouse click terminates the cycle and is interpreted except for
|
||||
RET which merely exits the cycle.
|
||||
Other special keys are:
|
||||
\\[haskell-indent-insert-equal]
|
||||
inserts an =
|
||||
\\[haskell-indent-insert-guard]
|
||||
inserts an |
|
||||
\\[haskell-indent-insert-otherwise]
|
||||
inserts an | otherwise =
|
||||
these functions also align the guards and rhs of the current definition
|
||||
\\[haskell-indent-insert-where]
|
||||
inserts a where keyword
|
||||
\\[haskell-indent-align-guards-and-rhs]
|
||||
aligns the guards and rhs of the region
|
||||
\\[haskell-indent-put-region-in-literate]
|
||||
makes the region a piece of literate code in a literate script
|
||||
|
||||
Invokes `haskell-indent-hook' if not nil.
|
||||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-indentation" "haskell-indentation.el"
|
||||
;;;;;; (21860 25846 0 0))
|
||||
;;; Generated autoloads from haskell-indentation.el
|
||||
|
||||
(autoload 'haskell-indentation-mode "haskell-indentation" "\
|
||||
Haskell indentation mode that deals with the layout rule.
|
||||
It rebinds RET, DEL and BACKSPACE, so that indentations can be
|
||||
set and deleted as if they were real tabs. It supports
|
||||
autofill-mode.
|
||||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
(autoload 'turn-on-haskell-indentation "haskell-indentation" "\
|
||||
Turn on the haskell-indentation minor mode.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-interactive-mode" "haskell-interactive-mode.el"
|
||||
;;;;;; (21860 25846 0 0))
|
||||
;;; Generated autoloads from haskell-interactive-mode.el
|
||||
|
||||
(autoload 'haskell-interactive-mode-reset-error "haskell-interactive-mode" "\
|
||||
Reset the error cursor position.
|
||||
|
||||
\(fn SESSION)" t nil)
|
||||
|
||||
(autoload 'haskell-interactive-mode-echo "haskell-interactive-mode" "\
|
||||
Echo a read only piece of text before the prompt.
|
||||
|
||||
\(fn SESSION MESSAGE &optional MODE)" nil nil)
|
||||
|
||||
(autoload 'haskell-process-do-simple-echo "haskell-interactive-mode" "\
|
||||
Send LINE to the GHCi process and echo the result in some
|
||||
fashion, such as printing in the minibuffer, or using
|
||||
haskell-present, depending on configuration.
|
||||
|
||||
\(fn LINE &optional MODE)" nil nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-load" "haskell-load.el" (21860 25846
|
||||
;;;;;; 0 0))
|
||||
;;; Generated autoloads from haskell-load.el
|
||||
|
||||
(autoload 'haskell-process-reload-devel-main "haskell-load" "\
|
||||
Reload the module `DevelMain' and then run
|
||||
`DevelMain.update'. This is for doing live update of the code of
|
||||
servers or GUI applications. Put your development version of the
|
||||
program in `DevelMain', and define `update' to auto-start the
|
||||
program on a new thread, and use the `foreign-store' package to
|
||||
access the running context across :load/:reloads in GHCi.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-menu" "haskell-menu.el" (21860 25846
|
||||
;;;;;; 0 0))
|
||||
;;; Generated autoloads from haskell-menu.el
|
||||
|
||||
(autoload 'haskell-menu "haskell-menu" "\
|
||||
Launch the Haskell sessions menu.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-mode" "haskell-mode.el" (21860 25846
|
||||
;;;;;; 0 0))
|
||||
;;; Generated autoloads from haskell-mode.el
|
||||
|
||||
(autoload 'haskell-version "haskell-mode" "\
|
||||
Show the `haskell-mode` version in the echo area.
|
||||
With prefix argument HERE, insert it at point.
|
||||
When FULL is non-nil, use a verbose version string.
|
||||
When MESSAGE is non-nil, display a message with the version.
|
||||
|
||||
\(fn &optional HERE)" t nil)
|
||||
|
||||
(autoload 'haskell-mode-view-news "haskell-mode" "\
|
||||
Display information on recent changes to haskell-mode.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(defvar haskell-mode-map (let ((map (make-sparse-keymap))) (define-key map (kbd "C-c C-.") 'haskell-mode-format-imports) (define-key map [remap delete-indentation] 'haskell-delete-indentation) (define-key map (kbd "C-c C-l") 'haskell-mode-enable-process-minor-mode) (define-key map (kbd "C-c C-b") 'haskell-mode-enable-process-minor-mode) (define-key map (kbd "C-c C-v") 'haskell-mode-enable-process-minor-mode) (define-key map (kbd "C-c C-t") 'haskell-mode-enable-process-minor-mode) (define-key map (kbd "C-c C-i") 'haskell-mode-enable-process-minor-mode) map) "\
|
||||
Keymap used in Haskell mode.")
|
||||
|
||||
(autoload 'haskell-mode "haskell-mode" "\
|
||||
Major mode for editing Haskell programs.
|
||||
|
||||
See also Info node `(haskell-mode)Getting Started' for more
|
||||
information about this mode.
|
||||
|
||||
\\<haskell-mode-map>
|
||||
Literate scripts are supported via `literate-haskell-mode'.
|
||||
The variable `haskell-literate' indicates the style of the script in the
|
||||
current buffer. See the documentation on this variable for more details.
|
||||
|
||||
Use `haskell-version' to find out what version of Haskell mode you are
|
||||
currently using.
|
||||
|
||||
Additional Haskell mode modules can be hooked in via `haskell-mode-hook';
|
||||
see documentation for that variable for more details.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'literate-haskell-mode "haskell-mode" "\
|
||||
As `haskell-mode' but for literate scripts.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.[gh]s\\'" . haskell-mode))
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.l[gh]s\\'" . literate-haskell-mode))
|
||||
|
||||
(add-to-list 'interpreter-mode-alist '("runghc" . haskell-mode))
|
||||
|
||||
(add-to-list 'interpreter-mode-alist '("runhaskell" . haskell-mode))
|
||||
|
||||
(add-to-list 'completion-ignored-extensions ".hi")
|
||||
|
||||
(autoload 'haskell-hoogle "haskell-mode" "\
|
||||
Do a Hoogle search for QUERY.
|
||||
When `haskell-hoogle-command' is non-nil, this command runs
|
||||
that. Otherwise, it opens a hoogle search result in the browser.
|
||||
|
||||
If prefix argument INFO is given, then `haskell-hoogle-command'
|
||||
is asked to show extra info for the items matching QUERY..
|
||||
|
||||
\(fn QUERY &optional INFO)" t nil)
|
||||
|
||||
(defalias 'hoogle 'haskell-hoogle)
|
||||
|
||||
(autoload 'hoogle-lookup-from-local "haskell-mode" "\
|
||||
Lookup by local hoogle.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-hayoo "haskell-mode" "\
|
||||
Do a Hayoo search for QUERY.
|
||||
|
||||
\(fn QUERY)" t nil)
|
||||
|
||||
(defalias 'hayoo 'haskell-hayoo)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-modules" "haskell-modules.el" (21860
|
||||
;;;;;; 25846 0 0))
|
||||
;;; Generated autoloads from haskell-modules.el
|
||||
|
||||
(autoload 'haskell-session-installed-modules "haskell-modules" "\
|
||||
Get the modules installed in the current package set.
|
||||
If DONTCREATE is non-nil don't create a new session.
|
||||
|
||||
\(fn SESSION &optional DONTCREATE)" nil nil)
|
||||
|
||||
(autoload 'haskell-session-all-modules "haskell-modules" "\
|
||||
Get all modules -- installed or in the current project.
|
||||
If DONTCREATE is non-nil don't create a new session.
|
||||
|
||||
\(fn SESSION &optional DONTCREATE)" nil nil)
|
||||
|
||||
(autoload 'haskell-session-project-modules "haskell-modules" "\
|
||||
Get the modules of the current project.
|
||||
If DONTCREATE is non-nil don't create a new session.
|
||||
|
||||
\(fn SESSION &optional DONTCREATE)" nil nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-move-nested" "haskell-move-nested.el"
|
||||
;;;;;; (21860 25846 0 0))
|
||||
;;; Generated autoloads from haskell-move-nested.el
|
||||
|
||||
(autoload 'haskell-move-nested "haskell-move-nested" "\
|
||||
Shift the nested off-side-rule block adjacent to point by COLS columns to the right.
|
||||
|
||||
In Transient Mark mode, if the mark is active, operate on the contents
|
||||
of the region instead.
|
||||
|
||||
\(fn COLS)" nil nil)
|
||||
|
||||
(autoload 'haskell-move-nested-right "haskell-move-nested" "\
|
||||
Increase indentation of the following off-side-rule block adjacent to point.
|
||||
|
||||
Use a numeric prefix argument to indicate amount of indentation to apply.
|
||||
|
||||
In Transient Mark mode, if the mark is active, operate on the contents
|
||||
of the region instead.
|
||||
|
||||
\(fn COLS)" t nil)
|
||||
|
||||
(autoload 'haskell-move-nested-left "haskell-move-nested" "\
|
||||
Decrease indentation of the following off-side-rule block adjacent to point.
|
||||
|
||||
Use a numeric prefix argument to indicate amount of indentation to apply.
|
||||
|
||||
In Transient Mark mode, if the mark is active, operate on the contents
|
||||
of the region instead.
|
||||
|
||||
\(fn COLS)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-navigate-imports" "haskell-navigate-imports.el"
|
||||
;;;;;; (21860 25846 0 0))
|
||||
;;; Generated autoloads from haskell-navigate-imports.el
|
||||
|
||||
(autoload 'haskell-navigate-imports "haskell-navigate-imports" "\
|
||||
Cycle the Haskell import lines or return to point (with prefix arg).
|
||||
|
||||
\(fn &optional RETURN)" t nil)
|
||||
|
||||
(autoload 'haskell-navigate-imports-go "haskell-navigate-imports" "\
|
||||
Go to the first line of a list of consequtive import lines. Cycles.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'haskell-navigate-imports-return "haskell-navigate-imports" "\
|
||||
Return to the non-import point we were at before going to the module list.
|
||||
If we were originally at an import list, we can just cycle through easily.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-session" "haskell-session.el" (21860
|
||||
;;;;;; 25846 0 0))
|
||||
;;; Generated autoloads from haskell-session.el
|
||||
|
||||
(autoload 'haskell-session-maybe "haskell-session" "\
|
||||
Maybe get the Haskell session, return nil if there isn't one.
|
||||
|
||||
\(fn)" nil nil)
|
||||
|
||||
(autoload 'haskell-session-process "haskell-session" "\
|
||||
Get the session process.
|
||||
|
||||
\(fn S)" nil nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-show" "haskell-show.el" (21860 25846
|
||||
;;;;;; 0 0))
|
||||
;;; Generated autoloads from haskell-show.el
|
||||
|
||||
(autoload 'haskell-show-replace "haskell-show" "\
|
||||
Replace the given region containing a Show value with a pretty
|
||||
printed collapsible version.
|
||||
|
||||
\(fn START END)" nil nil)
|
||||
|
||||
(autoload 'haskell-show-parse-and-insert "haskell-show" "\
|
||||
Parse a `string' containing a Show instance value and insert
|
||||
it pretty printed into the current buffer.
|
||||
|
||||
\(fn GIVEN)" nil nil)
|
||||
|
||||
(autoload 'haskell-show-parse "haskell-show" "\
|
||||
Parse the given input into a tree.
|
||||
|
||||
\(fn GIVEN)" nil nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-simple-indent" "haskell-simple-indent.el"
|
||||
;;;;;; (21860 25846 0 0))
|
||||
;;; Generated autoloads from haskell-simple-indent.el
|
||||
|
||||
(autoload 'haskell-simple-indent-mode "haskell-simple-indent" "\
|
||||
Simple Haskell indentation mode that uses simple heuristic.
|
||||
In this minor mode, `indent-for-tab-command' (bound to <tab> by
|
||||
default) will move the cursor to the next indent point in the
|
||||
previous nonblank line, whereas `haskell-simple-indent-backtab'
|
||||
\(bound to <backtab> by default) will move the cursor the
|
||||
previous indent point. An indent point is a non-whitespace
|
||||
character following whitespace.
|
||||
|
||||
Runs `haskell-simple-indent-hook' on activation.
|
||||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
(autoload 'turn-on-haskell-simple-indent "haskell-simple-indent" "\
|
||||
Turn on function `haskell-simple-indent-mode'.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-sort-imports" "haskell-sort-imports.el"
|
||||
;;;;;; (21860 25846 0 0))
|
||||
;;; Generated autoloads from haskell-sort-imports.el
|
||||
|
||||
(autoload 'haskell-sort-imports "haskell-sort-imports" "\
|
||||
Sort the import list at point. It sorts the current group
|
||||
i.e. an import list separated by blank lines on either side.
|
||||
|
||||
If the region is active, it will restrict the imports to sort
|
||||
within that region.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-string" "haskell-string.el" (21860
|
||||
;;;;;; 25846 0 0))
|
||||
;;; Generated autoloads from haskell-string.el
|
||||
|
||||
(autoload 'haskell-trim "haskell-string" "\
|
||||
|
||||
|
||||
\(fn STRING)" nil nil)
|
||||
|
||||
(autoload 'haskell-string-take "haskell-string" "\
|
||||
Take n chars from string.
|
||||
|
||||
\(fn STRING N)" nil nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-unicode-input-method" "haskell-unicode-input-method.el"
|
||||
;;;;;; (21860 25846 0 0))
|
||||
;;; Generated autoloads from haskell-unicode-input-method.el
|
||||
|
||||
(autoload 'turn-on-haskell-unicode-input-method "haskell-unicode-input-method" "\
|
||||
Set input method `haskell-unicode'.
|
||||
See Info node `Unicode(haskell-mode)' for more details.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "haskell-yas" "haskell-yas.el" (21860 25846
|
||||
;;;;;; 0 0))
|
||||
;;; Generated autoloads from haskell-yas.el
|
||||
|
||||
(autoload 'haskell-yas-complete "haskell-yas" "\
|
||||
|
||||
|
||||
\(fn &rest ARGS)" nil nil)
|
||||
|
||||
(autoload 'haskell-snippets-initialize "haskell-yas" "\
|
||||
Register haskell snippets with yasnippet.
|
||||
|
||||
\(fn)" nil nil)
|
||||
|
||||
(eval-after-load 'yasnippet '(haskell-snippets-initialize))
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "highlight-uses-mode" "highlight-uses-mode.el"
|
||||
;;;;;; (21860 25846 0 0))
|
||||
;;; Generated autoloads from highlight-uses-mode.el
|
||||
|
||||
(autoload 'highlight-uses-mode "highlight-uses-mode" "\
|
||||
Minor mode for highlighting and jumping between uses.
|
||||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "inf-haskell" "inf-haskell.el" (21860 25846
|
||||
;;;;;; 0 0))
|
||||
;;; Generated autoloads from inf-haskell.el
|
||||
|
||||
(defalias 'run-haskell 'switch-to-haskell)
|
||||
|
||||
(autoload 'switch-to-haskell "inf-haskell" "\
|
||||
Show the inferior-haskell buffer. Start the process if needed.
|
||||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
(autoload 'inferior-haskell-load-file "inf-haskell" "\
|
||||
Pass the current buffer's file to the inferior haskell process.
|
||||
If prefix arg \\[universal-argument] is given, just reload the previous file.
|
||||
|
||||
\(fn &optional RELOAD)" t nil)
|
||||
|
||||
(autoload 'inferior-haskell-load-and-run "inf-haskell" "\
|
||||
Pass the current buffer's file to haskell and then run a COMMAND.
|
||||
|
||||
\(fn COMMAND)" t nil)
|
||||
|
||||
(autoload 'inferior-haskell-send-decl "inf-haskell" "\
|
||||
Send current declaration to inferior-haskell process.
|
||||
|
||||
\(fn)" t nil)
|
||||
|
||||
(autoload 'inferior-haskell-type "inf-haskell" "\
|
||||
Query the haskell process for the type of the given expression.
|
||||
If optional argument `insert-value' is non-nil, insert the type above point
|
||||
in the buffer. This can be done interactively with the \\[universal-argument] prefix.
|
||||
The returned info is cached for reuse by `haskell-doc-mode'.
|
||||
|
||||
\(fn EXPR &optional INSERT-VALUE)" t nil)
|
||||
|
||||
(autoload 'inferior-haskell-kind "inf-haskell" "\
|
||||
Query the haskell process for the kind of the given expression.
|
||||
|
||||
\(fn TYPE)" t nil)
|
||||
|
||||
(autoload 'inferior-haskell-info "inf-haskell" "\
|
||||
Query the haskell process for the info of the given expression.
|
||||
|
||||
\(fn SYM)" t nil)
|
||||
|
||||
(autoload 'inferior-haskell-find-definition "inf-haskell" "\
|
||||
Attempt to locate and jump to the definition of the given expression.
|
||||
|
||||
\(fn SYM)" t nil)
|
||||
|
||||
(autoload 'inferior-haskell-find-haddock "inf-haskell" "\
|
||||
Find and open the Haddock documentation of SYM.
|
||||
Make sure to load the file into GHCi or Hugs first by using C-c C-l.
|
||||
Only works for functions in a package installed with ghc-pkg, or
|
||||
whatever the value of `haskell-package-manager-name' is.
|
||||
|
||||
This function needs to find which package a given module belongs
|
||||
to. In order to do this, it computes a module-to-package lookup
|
||||
alist, which is expensive to compute (it takes upwards of five
|
||||
seconds with more than about thirty installed packages). As a
|
||||
result, we cache it across sessions using the cache file
|
||||
referenced by `inferior-haskell-module-alist-file'. We test to
|
||||
see if this is newer than `haskell-package-conf-file' every time
|
||||
we load it.
|
||||
|
||||
\(fn SYM)" t nil)
|
||||
|
||||
(autoload 'inf-haskell-mode "inf-haskell" "\
|
||||
Minor mode for enabling inf-haskell process interaction.
|
||||
|
||||
\(fn &optional ARG)" t nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil nil ("haskell-bot.el" "haskell-checkers.el"
|
||||
;;;;;; "haskell-collapse.el" "haskell-compat.el" "haskell-complete-module.el"
|
||||
;;;;;; "haskell-debug.el" "haskell-mode-pkg.el" "haskell-package.el"
|
||||
;;;;;; "haskell-presentation-mode.el" "haskell-process.el" "haskell-repl.el"
|
||||
;;;;;; "haskell-sandbox.el" "haskell-str.el" "haskell-utils.el"
|
||||
;;;;;; "w3m-haddock.el") (21860 25846 417005 0))
|
||||
|
||||
;;;***
|
||||
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; End:
|
||||
;;; haskell-mode-autoloads.el ends here
|
11
.emacs.d/elpa/haskell-mode-13.12/haskell-mode-autoloads.el~
Normal file
11
.emacs.d/elpa/haskell-mode-13.12/haskell-mode-autoloads.el~
Normal file
@@ -0,0 +1,11 @@
|
||||
;;; haskell-mode-autoloads.el --- automatically extracted autoloads
|
||||
;;
|
||||
;;; Code:
|
||||
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
|
||||
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
;; no-byte-compile: t
|
||||
;; no-update-autoloads: t
|
||||
;; End:
|
||||
;;; haskell-mode-autoloads.el ends here
|
5
.emacs.d/elpa/haskell-mode-13.12/haskell-mode-pkg.el
Normal file
5
.emacs.d/elpa/haskell-mode-13.12/haskell-mode-pkg.el
Normal file
@@ -0,0 +1,5 @@
|
||||
(define-package "haskell-mode" "13.12" "A Haskell editing mode"
|
||||
'((cl-lib "0.5")))
|
||||
;; Local Variables:
|
||||
;; no-byte-compile: t
|
||||
;; End:
|
1029
.emacs.d/elpa/haskell-mode-13.12/haskell-mode.el
Normal file
1029
.emacs.d/elpa/haskell-mode-13.12/haskell-mode.el
Normal file
File diff suppressed because it is too large
Load Diff
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-mode.elc
Normal file
BIN
.emacs.d/elpa/haskell-mode-13.12/haskell-mode.elc
Normal file
Binary file not shown.
621
.emacs.d/elpa/haskell-mode-13.12/haskell-mode.info
Normal file
621
.emacs.d/elpa/haskell-mode-13.12/haskell-mode.info
Normal file
@@ -0,0 +1,621 @@
|
||||
This is haskell-mode.info, produced by makeinfo version 5.2 from
|
||||
haskell-mode.texi.
|
||||
|
||||
This manual is for Haskell mode, version @GIT_VERSION@
|
||||
|
||||
Copyright © 2013 Haskell Mode contributors.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this
|
||||
document under the terms of the GNU Free Documentation License
|
||||
(http://www.gnu.org/licenses/fdl.html), 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.
|
||||
INFO-DIR-SECTION Emacs
|
||||
START-INFO-DIR-ENTRY
|
||||
* Haskell Mode: (haskell-mode). Haskell Development Environment for Emacs(en)
|
||||
END-INFO-DIR-ENTRY
|
||||
|
||||
|
||||
File: haskell-mode.info, Node: Top, Next: Introduction, Up: (dir)
|
||||
|
||||
Haskell Mode
|
||||
************
|
||||
|
||||
Haskell Mode is an Haskell development Environment for GNU Emacs version
|
||||
23 or later. It provides syntax-based indentation, font locking,
|
||||
editing cabal files, and supports running an inferior Haskell
|
||||
interpreter (e.g. GHCi).
|
||||
|
||||
* Menu:
|
||||
|
||||
* Introduction::
|
||||
* Getting Help and Reporting Bugs::
|
||||
* Getting Started::
|
||||
* Editing Haskell Code::
|
||||
* Unicode support::
|
||||
* Indentation::
|
||||
* haskell-decl-scan-mode::
|
||||
* Compilation::
|
||||
* inferior-haskell-mode::
|
||||
* haskell-interactive-mode::
|
||||
* haskell-cabal-mode::
|
||||
* Concept index::
|
||||
* Function index::
|
||||
* Variable index::
|
||||
|
||||
|
||||
File: haskell-mode.info, Node: Introduction, Next: Getting Help and Reporting Bugs, Prev: Top, Up: Top
|
||||
|
||||
1 Introduction
|
||||
**************
|
||||
|
||||
"Haskell Mode" is a major mode providing a convenient environment for
|
||||
editing Haskell (http://www.haskell.org) programs.
|
||||
|
||||
Some of its major features are:
|
||||
|
||||
• Syntax highlighting (font lock),
|
||||
• automatic indentation,
|
||||
• on-the-fly documentation,
|
||||
• interaction with inferior GHCi/Hugs instance, and
|
||||
• scanning declarations and placing them in a menu.
|
||||
|
||||
|
||||
File: haskell-mode.info, Node: Getting Help and Reporting Bugs, Next: Getting Started, Prev: Introduction, Up: Top
|
||||
|
||||
2 Getting Help and Reporting Bugs
|
||||
*********************************
|
||||
|
||||
This Info manual is work in progress and incomplete. However, you can
|
||||
find more information at these locations in the meantime:
|
||||
|
||||
• Haskell Mode’s GitHub Home
|
||||
(https://github.com/haskell/haskell-mode)
|
||||
• Haskell Wiki Emacs Page
|
||||
(http://www.haskell.org/haskellwiki/Haskell_mode_for_Emacs)
|
||||
|
||||
If you have any questions or like to discuss something regarding
|
||||
Haskell Mode, please consider sending an email to the Haskellmode-emacs
|
||||
mailing list
|
||||
(http://projects.haskell.org/cgi-bin/mailman/listinfo/haskellmode-emacs).
|
||||
The mailing list is also available on Gmane (http://gmane.org/) via the
|
||||
gmane.comp.lang.haskell.emacs
|
||||
(http://dir.gmane.org/gmane.comp.lang.haskell.emacs) newsgroup.
|
||||
|
||||
If you have discovered a bug or wish to request a new feature, you
|
||||
can file a new issue
|
||||
(https://github.com/haskell/haskell-mode/issues/new) with Haskell Mode’s
|
||||
issue tracker. When filing a bug, please state your currently used
|
||||
software version (‘M-x haskell-version’, ‘M-x version’) and what steps
|
||||
to perform in order to reproduce the bug you’re experiencing. Finally,
|
||||
if you happen to be proficient in *note Emacs Lisp: (elisp)Top. you are
|
||||
welcome to submit patches via GitHub Pull Requests
|
||||
(https://help.github.com/articles/using-pull-requests).
|
||||
|
||||
|
||||
File: haskell-mode.info, Node: Getting Started, Next: Editing Haskell Code, Prev: Getting Help and Reporting Bugs, Up: Top
|
||||
|
||||
3 Getting Started
|
||||
*****************
|
||||
|
||||
If you are reading this, you have most likely already managed to install
|
||||
Haskell Mode in one way or another. However, just for the record, the
|
||||
officially recommended way is to install Haskell Mode via the Marmalade
|
||||
package archive (http://marmalade-repo.org/packages/haskell-mode) which
|
||||
contains the latest stable release of Haskell Mode.
|
||||
|
||||
Most of Haskell Mode’s settings are configurable via customizable
|
||||
variables (*note (emacs)Easy Customization::, for details). You can use
|
||||
‘M-x haskell-customize’ to browse the ‘haskell’ customization sub-tree.
|
||||
|
||||
One of the important setting you should customize is the
|
||||
‘haskell-mode-hook’ variable (*note (emacs)Hooks::) which gets run right
|
||||
after the ‘haskell-mode’ major mode is initialized for a buffer. You
|
||||
can customize ‘haskell-mode-hook’ by ‘M-x customize-variable <RET>
|
||||
haskell-mode-hook’. It’s highly recommended you set up indentation to
|
||||
match your preferences; *Note Indentation::, for more details about the
|
||||
indentation modes included with Haskell Mode.
|
||||
|
||||
|
||||
File: haskell-mode.info, Node: Editing Haskell Code, Next: Unicode support, Prev: Getting Started, Up: Top
|
||||
|
||||
4 Editing Haskell Code
|
||||
**********************
|
||||
|
||||
"Haskell Mode" is actually a collection of so-called major modes(1) one
|
||||
of which is called ‘haskell-mode’. To avoid confusion, when referring
|
||||
to this package the name “Haskell mode” is written in a normal font,
|
||||
whereas when referring the major mode of the same name ‘haskell-mode’
|
||||
written with a dash in-between in a typewriter font is used.
|
||||
|
||||
As one might guess, ‘haskell-mode’ is the (programming language(2))
|
||||
major mode for editing (non-literate) Haskell source code.
|
||||
‘haskell-mode’ is associated with the file extensions listed below by
|
||||
default(3).
|
||||
|
||||
‘.hs’
|
||||
official file extension for (non-literate) Haskell 98/2010 files
|
||||
‘.hsc’
|
||||
“almost-Haskell” input file for the hsc2hs
|
||||
(http://www.haskell.org/ghc/docs/latest/html/users_guide/hsc2hs.html)
|
||||
pre-processor
|
||||
‘.cpphs’
|
||||
input file for the cpphs (http://projects.haskell.org/cpphs/)
|
||||
pre-processor
|
||||
|
||||
The major mode ‘literate-haskell-mode’ (which is derived from
|
||||
‘haskell-mode’ and thus transitively from ‘prog-mode’) provides support
|
||||
for literate Haskell programs
|
||||
(http://www.haskell.org/haskellwiki/Literate_programming) and is
|
||||
associated with the ‘.lhs’ file extension by default.
|
||||
|
||||
‘literate-haskell-mode’ supports Bird-style as well as TeX-style
|
||||
literate Haskell files. The currently detected literate Haskell variant
|
||||
is shown in the mode line (*note (emacs)Mode Line::) as either
|
||||
‘LitHaskell/bird’ or ‘LitHaskell/tex’.
|
||||
|
||||
4.1 Font Lock Support
|
||||
=====================
|
||||
|
||||
‘haskell-mode’ supports "syntax highlighting" via Emacs’ Font Lock minor
|
||||
mode which should be enabled by default in current Emacsen. *Note
|
||||
(emacs)Font Lock::, for more information on how to control
|
||||
‘font-lock-mode’.
|
||||
|
||||
---------- Footnotes ----------
|
||||
|
||||
(1) for more information about the concept of "major modes" *note
|
||||
(emacs)Major Modes::
|
||||
|
||||
(2) ‘haskell-mode’ is derived from ‘prog-mode’
|
||||
|
||||
(3) for more information about file associations, *note
|
||||
(emacs)Choosing Modes::
|
||||
|
||||
|
||||
File: haskell-mode.info, Node: Unicode support, Next: Indentation, Prev: Editing Haskell Code, Up: Top
|
||||
|
||||
5 Unicode support
|
||||
*****************
|
||||
|
||||
See the Haskell Wiki’s entry on Unicode Symbols
|
||||
(http://www.haskell.org/haskellwiki/Unicode-symbols) for general
|
||||
information about Unicode support in Haskell.
|
||||
|
||||
As Emacs supports editing files containing Unicode out of the box, so
|
||||
does Haskell Mode. As an add-on, Haskell Mode includes the
|
||||
‘haskell-unicode’ input method which allows you to easily type a number
|
||||
of Unicode symbols that are useful when writing Haskell code; *Note
|
||||
(emacs)Input Methods::, for more details.
|
||||
|
||||
To automatically enable the ‘haskell-unicode’ input method in
|
||||
haskell-mode buffers use ‘M-x customize-variable <RET>
|
||||
haskell-mode-hook’ or put the following code in your ‘.emacs’ file:
|
||||
|
||||
(add-hook 'haskell-mode-hook 'turn-on-haskell-unicode-input-method)
|
||||
|
||||
To temporarily enable this input method for a single buffer you can use
|
||||
‘M-x turn-on-haskell-unicode-input-method’.
|
||||
|
||||
When the ‘haskell-unicode’ input method is active, you can simply
|
||||
type ‘->’ and it is immediately replaced with ‘→’. Use ‘C-\’ to toggle
|
||||
the input method. To see a table of all key sequences use ‘M-x
|
||||
describe-input-method <RET> haskell-unicode’. A sequence like ‘<=’ is
|
||||
ambiguous and can mean either ‘⇐’ or ‘≤’. Typing it presents you with a
|
||||
choice. Type ‘1’ or ‘2’ to select an option or keep typing to use the
|
||||
default option.
|
||||
|
||||
If you don’t like the highlighting of partially matching tokens you
|
||||
can turn it off by setting ‘input-method-highlight-flag’ to ‘nil’ via
|
||||
‘M-x customize-variable’.
|
||||
|
||||
|
||||
File: haskell-mode.info, Node: Indentation, Next: haskell-decl-scan-mode, Prev: Unicode support, Up: Top
|
||||
|
||||
6 Indentation
|
||||
*************
|
||||
|
||||
For general information about indentation support in GNU Emacs, *note
|
||||
(emacs)Indentation::.
|
||||
|
||||
In Haskell, code indentation has semantic meaning as it defines the
|
||||
block structure(1).
|
||||
|
||||
As GNU Emacs’ default indentation function (i.e. ‘indent-relative’)
|
||||
is not designed for use with Haskell’s layout rule, Haskell mode
|
||||
includes three different indentation minor modes with different
|
||||
trade-offs:
|
||||
|
||||
‘turn-on-haskell-simple-indent’
|
||||
|
||||
A very simple indentation scheme; In this scheme, <TAB> will now
|
||||
move the cursor to the next indent point in the previous non-blank
|
||||
line. An indent point is a non-whitespace character following
|
||||
whitespace.
|
||||
|
||||
‘turn-on-haskell-indent’
|
||||
|
||||
Intelligent semi-automatic indentation for Haskell’s layout rule.
|
||||
The basic idea is to have <TAB> cycle through possibilities
|
||||
indentation points based on some clever heuristics.
|
||||
|
||||
The rationale and the implementation principles are described in
|
||||
more detail in the article ‘Dynamic tabbing for automatic
|
||||
indentation with the layout rule’ published in the Journal of
|
||||
Functional Programming 8.5 (1998).
|
||||
|
||||
‘turn-on-haskell-indentation’
|
||||
|
||||
Improved variation of ‘turn-on-haskell-indent’ indentation mode.
|
||||
Rebinds <RET> and <DEL>, so that indentations can be set and
|
||||
deleted as if they were real tabs.
|
||||
|
||||
To enable one of these three mutually exclusive indentation schemes,
|
||||
you just need call one (and only one!) of the ‘turn-on-*’ commands
|
||||
while in the buffer you want the indentation scheme to be activated for.
|
||||
|
||||
The recommended way is to add one of ‘turn-on-*’ commands to
|
||||
‘haskell-mode-hook’. This can be done either by using ‘M-x
|
||||
customize-variable <RET> haskell-mode-hook’ which provides a convenient
|
||||
user interface or by adding _one_ of the following three lines to your
|
||||
‘.emacs’ file:
|
||||
|
||||
(add-hook 'haskell-mode-hook 'turn-on-haskell-simple-indent)
|
||||
(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
|
||||
(add-hook 'haskell-mode-hook 'turn-on-haskell-indentation)
|
||||
|
||||
6.1 Interactive Block Indentation
|
||||
=================================
|
||||
|
||||
By inserting the key bindings for ‘C-,’ and ‘C-.’ (these bindings are
|
||||
convenient on keyboard layouts where <,> and <.> are adjacent keys) as
|
||||
shown below you can interactively de/indent either the following nested
|
||||
block or, if a region is active while in Transient Mark Mode (*note
|
||||
(emacs)Disabled Transient Mark::), de/indent the active region.
|
||||
|
||||
By using a numeric prefix argument (*note (elisp)Prefix Command
|
||||
Arguments::) you can modify the shift-amount; for instance, ‘C-u C-,’
|
||||
increases indentation by 4 characters at once.
|
||||
|
||||
(eval-after-load "haskell-mode"
|
||||
'(progn
|
||||
(define-key haskell-mode-map (kbd "C-,") 'haskell-move-nested-left)
|
||||
(define-key haskell-mode-map (kbd "C-.") 'haskell-move-nested-right)))
|
||||
|
||||
6.2 Rectangle Commands
|
||||
======================
|
||||
|
||||
GNU Emacs provides so-called "rectangle commands" which operate on
|
||||
rectangular areas of text, which are particularly useful for languages
|
||||
with a layout rule such as Haskell. *Note (emacs)Rectangles::, to learn
|
||||
more about rectangle commands.
|
||||
|
||||
Moreover, CUA mode (*note (emacs)CUA Bindings::) provides enhanced
|
||||
rectangle support with visible rectangle highlighting. When CUA mode is
|
||||
active, you can initiate a rectangle selection by ‘C-RET’ and extend it
|
||||
simply by movement commands. You don’t have to enable full CUA mode to
|
||||
benefit from these enhanced rectangle commands; you can activate CUA
|
||||
selection mode (without redefining ‘C-x’,‘C-c’,‘C-v’, and ‘C-z’) by
|
||||
calling ‘M-x cua-selection-mode’ (or adding ‘(cua-selection-mode nil)’
|
||||
to your ‘haskell-mode-hook’).
|
||||
|
||||
---------- Footnotes ----------
|
||||
|
||||
(1) Haskell also supports braces and semicolons notation for
|
||||
conveying the block structure. However, most Haskell programs written
|
||||
by humans use indentation for block structuring.
|
||||
|
||||
|
||||
File: haskell-mode.info, Node: haskell-decl-scan-mode, Next: Compilation, Prev: Indentation, Up: Top
|
||||
|
||||
7 ‘haskell-decl-scan-mode’
|
||||
**************************
|
||||
|
||||
‘haskell-decl-scan-mode’ is a minor mode which performs declaration
|
||||
scanning and provides ‘M-x imenu’ support (*note (emacs)Imenu:: for more
|
||||
information).
|
||||
|
||||
For non-literate and TeX-style literate scripts, the common
|
||||
convention that top-level declarations start at the first column is
|
||||
assumed. For Bird-style literate scripts, the common convention that
|
||||
top-level declarations start at the third column, ie. after ‘> ’, is
|
||||
assumed.
|
||||
|
||||
When ‘haskell-decl-scan-mode’ is active, the standard Emacs top-level
|
||||
definition movement commands (*note (emacs)Moving by Defuns::) are
|
||||
enabled to operate on Haskell declarations:
|
||||
|
||||
‘C-M-a’
|
||||
Move to beginning of current or preceding declaration
|
||||
(‘beginning-of-defun’).
|
||||
|
||||
‘C-M-e’
|
||||
Move to end of current or following declaration (‘end-of-defun’).
|
||||
|
||||
‘C-M-h’
|
||||
Select whole current or following declaration (‘mark-defun’).
|
||||
|
||||
Moreover, if enabled via the option
|
||||
‘haskell-decl-scan-add-to-menubar’, a menu item “Declarations” is added
|
||||
to the menu bar listing the scanned declarations and allowing to jump to
|
||||
declarations in the source buffer.
|
||||
|
||||
It’s recommended to have font lock mode enabled (*note (emacs)Font
|
||||
Lock::) as ‘haskell-decl-scan-mode’ ignores text highlighted with
|
||||
‘font-lock-comment-face’.
|
||||
|
||||
As usual, in order to activate ‘haskell-decl-scan-mode’ automatically
|
||||
for Haskell buffers, add ‘turn-on-haskell-decl-scan’ to
|
||||
‘haskell-mode-hook’:
|
||||
|
||||
(add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan)
|
||||
|
||||
‘haskell-decl-scan-mode’ enables the use of features that build upon
|
||||
‘imenu’ support such as Speedbar Frames (*note (emacs)Speedbar::) or the
|
||||
global “Which Function” minor mode (*note (emacs)Which Function::).
|
||||
|
||||
In order to enable ‘which-function-mode’ for Haskell buffers you need
|
||||
to add the following to your Emacs initialization:
|
||||
|
||||
(eval-after-load "which-func"
|
||||
'(add-to-list 'which-func-modes 'haskell-mode))
|
||||
|
||||
|
||||
File: haskell-mode.info, Node: Compilation, Next: inferior-haskell-mode, Prev: haskell-decl-scan-mode, Up: Top
|
||||
|
||||
8 Compilation
|
||||
*************
|
||||
|
||||
Haskell mode comes equipped with a specialized "Compilation mode"
|
||||
tailored to GHC’s compiler messages with optional support for Cabal
|
||||
projects. *Note (emacs)Compilation Mode::, for more information about
|
||||
the basic commands provided by the Compilation mode which are available
|
||||
in the Haskell compilation sub-mode as well. The additional features
|
||||
provided compared to Emacs’ basic Compilation mode are:
|
||||
|
||||
• DWIM-style auto-detection of compile command (including support for
|
||||
CABAL projects)
|
||||
• Support for GHC’s compile messages and recognizing error, warning
|
||||
and info source locations (including ‘-ferror-spans’ syntax)
|
||||
• Support for filtering out GHC’s uninteresting ‘Loading package...’
|
||||
linker messages
|
||||
|
||||
In order to use it, invoke the ‘haskell-compile’ command instead of
|
||||
‘compile’ as you would for the ordinary Compilation mode. It’s
|
||||
recommended to bind ‘haskell-compile’ to a convenient key binding. For
|
||||
instance, you can add the following to your Emacs initialization to bind
|
||||
‘haskell-compile’ to ‘C-c C-c’.
|
||||
|
||||
(eval-after-load "haskell-mode"
|
||||
'(define-key haskell-mode-map (kbd "C-c C-c") 'haskell-compile))
|
||||
|
||||
(eval-after-load "haskell-cabal"
|
||||
'(define-key haskell-cabal-mode-map (kbd "C-c C-c") 'haskell-compile))
|
||||
|
||||
The following description assumes that ‘haskell-compile’ has been bound
|
||||
to ‘C-c C-c’.
|
||||
|
||||
When invoked, ‘haskell-compile’ tries to guess how to compile the
|
||||
Haskell program your currently visited buffer belongs to, by searching
|
||||
for a ‘.cabal’ file in the current of enclosing parent folders. If a
|
||||
‘.cabal’ file was found, the command defined in the
|
||||
‘haskell-compile-cabal-build-command’ option is used. Moreover, when
|
||||
requesting to compile a ‘.cabal’-file is detected and a negative prefix
|
||||
argument (e.g. ‘C-- C-c C-c’) was given, the alternative
|
||||
‘haskell-compile-cabal-build-command-alt’ is invoked. By default,
|
||||
‘haskell-compile-cabal-build-command-alt’ contains a ‘cabal clean -s’
|
||||
command in order to force a full rebuild.
|
||||
|
||||
Otherwise if no ‘.cabal’ could be found, a single-module compilation
|
||||
is assumed and ‘haskell-compile-command’ is used (_if_ the currently
|
||||
visited buffer contains Haskell source code).
|
||||
|
||||
You can also inspect and modify the compile command to be invoked
|
||||
temporarily by invoking ‘haskell-compile’ with a prefix argument (e.g.
|
||||
‘C-u C-c C-c’). If later-on you want to recompile using the same
|
||||
customized compile command, invoke ‘recompile’ (bound to ‘g’) inside the
|
||||
‘*haskell-compilation*’ buffer.
|
||||
|
||||
|
||||
File: haskell-mode.info, Node: inferior-haskell-mode, Next: haskell-interactive-mode, Prev: Compilation, Up: Top
|
||||
|
||||
9 ‘inferior-haskell-mode’
|
||||
*************************
|
||||
|
||||
The major mode ‘inferior-haskell-mode’ provides support for interacting
|
||||
with an inferior Haskell process based on ‘comint-mode’.
|
||||
|
||||
By default the ‘haskell-mode-map’ keymap is setup to use this mode:
|
||||
|
||||
‘C-c C-z’
|
||||
is bound to ‘switch-to-haskell’
|
||||
‘C-c C-b’
|
||||
is bound to ‘switch-to-haskell’
|
||||
‘C-c C-l’
|
||||
is bound to ‘inferior-haskell-load-file’
|
||||
‘C-c C-t’
|
||||
is bound to ‘inferior-haskell-type’
|
||||
‘C-c C-i’
|
||||
is bound to ‘inferior-haskell-info’
|
||||
|
||||
The Haskell interpreter used by the inferior Haskell mode is
|
||||
auto-detected by default, but is customizable via the
|
||||
‘haskell-program-name’ variable.
|
||||
|
||||
Currently, GHCi and Hugs are support as Haskell interpreter.
|
||||
|
||||
TODO/WRITEME
|
||||
|
||||
|
||||
File: haskell-mode.info, Node: haskell-interactive-mode, Next: haskell-cabal-mode, Prev: inferior-haskell-mode, Up: Top
|
||||
|
||||
10 ‘haskell-interactive-mode’
|
||||
*****************************
|
||||
|
||||
An alternative mode providing a REPL (read–eval–print loop) via GHCi
|
||||
sessions is called ‘haskell-interactive-mode’, which effectively
|
||||
replaces ‘inferior-haskell-mode’, but comes with a different set of
|
||||
features:
|
||||
|
||||
• Separate sessions per Cabal project ‘haskell-session.el’.
|
||||
• A new inferior Haskell process handling code ‘haskell-process.el’.
|
||||
• New REPL implementation similiar to SLIME/IELM
|
||||
‘haskell-interactive-mode.el’.
|
||||
|
||||
In order to use ‘haskell-interactive-mode’ instead of the default
|
||||
‘inferior-haskell-mode’, you need to replace some of the default
|
||||
keybindings in the ‘haskell-mode-map’ keymap with the respective
|
||||
‘haskell-interactive-mode’ counterparts:
|
||||
|
||||
(eval-after-load "haskell-mode"
|
||||
'(progn
|
||||
(define-key haskell-mode-map (kbd "C-x C-d") nil)
|
||||
(define-key haskell-mode-map (kbd "C-c C-z") 'haskell-interactive-switch)
|
||||
(define-key haskell-mode-map (kbd "C-c C-l") 'haskell-process-load-file)
|
||||
(define-key haskell-mode-map (kbd "C-c C-b") 'haskell-interactive-switch)
|
||||
(define-key haskell-mode-map (kbd "C-c C-t") 'haskell-process-do-type)
|
||||
(define-key haskell-mode-map (kbd "C-c C-i") 'haskell-process-do-info)
|
||||
(define-key haskell-mode-map (kbd "C-c M-.") nil)
|
||||
(define-key haskell-mode-map (kbd "C-c C-d") nil)))
|
||||
|
||||
With ‘haskell-interactive-mode’, each Haskell source buffer is
|
||||
associated with at most one GHCi session, so when you call
|
||||
‘haskell-process-load-file’ for a Haskell source buffer which has no
|
||||
session associated yet, you’re asked which GHCi session to create or
|
||||
associate with.
|
||||
|
||||
TODO/WRITEME
|
||||
|
||||
|
||||
File: haskell-mode.info, Node: haskell-cabal-mode, Next: Concept index, Prev: haskell-interactive-mode, Up: Top
|
||||
|
||||
11 ‘haskell-cabal-mode’
|
||||
***********************
|
||||
|
||||
‘haskell-cabal-mode’ is a major mode for editing Cabal package
|
||||
description files
|
||||
(http://www.haskell.org/cabal/users-guide/developing-packages.html) and
|
||||
is automatically associated with files having a ‘.cabal’ extension.
|
||||
|
||||
For quickly locating and jumping to the nearest ‘.cabal’ file from a
|
||||
Haskell source buffer, you can use ‘M-x haskell-cabal-visit-file’; with
|
||||
a prefix argument (i.e. ‘C-u’) ‘find-file-other-window’ is used to
|
||||
visit the ‘.cabal’ file. If you wish, you can bind
|
||||
‘haskell-cabal-visit-file’ to a convenient key sequence, e.g.
|
||||
|
||||
(eval-after-load "haskell-mode"
|
||||
(define-key haskell-mode-map (kbd "C-c v c") 'haskell-cabal-visit-file))
|
||||
|
||||
TODO/WRITEME
|
||||
|
||||
|
||||
File: haskell-mode.info, Node: Concept index, Next: Function index, Prev: haskell-cabal-mode, Up: Top
|
||||
|
||||
Concept index
|
||||
*************
|
||||
|
||||
|