[NEW] Configurized 'emacs.d'

This commit is contained in:
Sami Samhuri 2009-11-10 22:26:19 -08:00
parent be7f2e3860
commit 1e3e162302
208 changed files with 51627 additions and 0 deletions

1168
emacs.d/TUTORIAL Normal file

File diff suppressed because it is too large Load diff

639
emacs.d/ansi-color.el Normal file
View file

@ -0,0 +1,639 @@
;;; ansi-color.el --- translate ANSI escape sequences into faces
;; Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
;; Author: Alex Schroeder <alex@gnu.org>
;; Maintainer: Alex Schroeder <alex@gnu.org>
;; Version: 3.4.5
;; Keywords: comm processes terminals services
;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?AnsiColor
;; This file is part of GNU Emacs.
;; GNU Emacs is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by the
;; Free Software Foundation; either version 2, or (at your option) any
;; later version.
;;
;; GNU Emacs is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;; This file provides a function that takes a string or a region
;; containing Select Graphic Rendition (SGR) control sequences (formerly
;; known as ANSI escape sequences) and tries to translate these into
;; faces.
;;
;; This allows you to run ls --color=yes in shell-mode. In order to
;; test this, proceed as follows:
;;
;; 1. start a shell: M-x shell
;; 2. load this file: M-x load-library RET ansi-color RET
;; 3. activate ansi-color: M-x ansi-color-for-comint-mode-on
;; 4. test ls --color=yes in the *shell* buffer
;;
;; Note that starting your shell from within Emacs might set the TERM
;; environment variable. The new setting might disable the output of
;; SGR control sequences. Using ls --color=yes forces ls to produce
;; these.
;;
;; If you decide you like this, add the following to your .emacs file:
;;
;; (autoload 'ansi-color-for-comint-mode-on "ansi-color" nil t)
;; (add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)
;;
;; SGR control sequences are defined in section 3.8.117 of the ECMA-48
;; standard (identical to ISO/IEC 6429), which is freely available as a
;; PDF file <URL:http://www.ecma.ch/ecma1/STAND/ECMA-048.HTM>. The
;; "Graphic Rendition Combination Mode (GRCM)" implemented is
;; "cumulative mode" as defined in section 7.2.8. Cumulative mode means
;; that whenever possible, SGR control sequences are combined (ie. blue
;; and bold).
;; The basic functions are:
;;
;; `ansi-color-apply' to colorize a string containing SGR control
;; sequences.
;;
;; `ansi-color-filter-apply' to filter SGR control sequences from a
;; string.
;;
;; `ansi-color-apply-on-region' to colorize a region containing SGR
;; control sequences.
;;
;; `ansi-color-filter-region' to filter SGR control sequences from a
;; region.
;;; Bugs
;; Doesn't seem to work with older Emacs versions such as 20.2.
;;; Thanks
;; Georges Brun-Cottan <gbruncot@emc.com> for improving ansi-color.el
;; substantially by adding the code needed to cope with arbitrary chunks
;; of output and the filter functions.
;;
;; Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk> for pointing me to ECMA-48.
;;
;; Stefan Monnier <foo@acm.com> explaing obscure font-lock stuff and
;; code suggestions.
;;; Code:
;; Customization
(defgroup ansi-colors nil
"Translating SGR control sequences to faces.
This translation effectively colorizes strings and regions based upon
SGR control sequences embedded in the text. SGR (Select Graphic
Rendition) control sequences are defined in section 3.8.117 of the
ECMA-48 standard \(identical to ISO/IEC 6429), which is freely available
as a PDF file <URL:http://www.ecma.ch/ecma1/STAND/ECMA-048.HTM>."
:version "21.1"
:group 'processes)
(defcustom ansi-color-faces-vector
[default bold default italic underline bold bold-italic modeline]
"Faces used for SGR control sequences determining a face.
This vector holds the faces used for SGR control sequence parameters 0
to 7.
Parameter Description Face used by default
0 default default
1 bold bold
2 faint default
3 italic italic
4 underlined underline
5 slowly blinking bold
6 rapidly blinking bold-italic
7 negative image modeline
Note that the symbol `default' is special: It will not be combined
with the current face.
This vector is used by `ansi-color-make-color-map' to create a color
map. This color map is stored in the variable `ansi-color-map'."
:type '(vector face face face face face face face face)
:set 'ansi-color-map-update
:initialize 'custom-initialize-default
:group 'ansi-colors)
(defcustom ansi-color-names-vector
["black" "red" "green" "yellow" "blue" "magenta" "cyan" "white"]
"Colors used for SGR control sequences determining a color.
This vector holds the colors used for SGR control sequences parameters
30 to 37 \(foreground colors) and 40 to 47 (background colors).
Parameter Color
30 40 black
31 41 red
32 42 green
33 43 yellow
34 44 blue
35 45 magenta
36 46 cyan
37 47 white
This vector is used by `ansi-color-make-color-map' to create a color
map. This color map is stored in the variable `ansi-color-map'."
:type '(vector string string string string string string string string)
:set 'ansi-color-map-update
:initialize 'custom-initialize-default
:group 'ansi-colors)
(defconst ansi-color-regexp "\033\\[\\([0-9;]*\\)m"
"Regexp that matches SGR control sequences.")
(defconst ansi-color-parameter-regexp "\\([0-9]*\\)[m;]"
"Regexp that matches SGR control sequence parameters.")
;; Convenience functions for comint modes (eg. shell-mode)
(defcustom ansi-color-for-comint-mode nil
"Determines what to do with comint output.
If nil, do nothing.
If the symbol `filter', then filter all SGR control sequences.
If anything else (such as t), then translate SGR control sequences
into text-properties.
In order for this to have any effect, `ansi-color-process-output' must
be in `comint-output-filter-functions'.
This can be used to enable colorized ls --color=yes output
in shell buffers. You set this variable by calling one of:
\\[ansi-color-for-comint-mode-on]
\\[ansi-color-for-comint-mode-off]
\\[ansi-color-for-comint-mode-filter]"
:type '(choice (const :tag "Do nothing" nil)
(const :tag "Filter" filter)
(const :tag "Translate" t))
:group 'ansi-colors)
;;;###autoload
(defun ansi-color-for-comint-mode-on ()
"Set `ansi-color-for-comint-mode' to t."
(interactive)
(setq ansi-color-for-comint-mode t))
(defun ansi-color-for-comint-mode-off ()
"Set `ansi-color-for-comint-mode' to nil."
(interactive)
(setq ansi-color-for-comint-mode nil))
(defun ansi-color-for-comint-mode-filter ()
"Set `ansi-color-for-comint-mode' to symbol `filter'."
(interactive)
(setq ansi-color-for-comint-mode 'filter))
;;;###autoload
(defun ansi-color-process-output (string)
"Maybe translate SGR control sequences of comint output into text-properties.
Depending on variable `ansi-color-for-comint-mode' the comint output is
either not processed, SGR control sequences are filtered using
`ansi-color-filter-region', or SGR control sequences are translated into
text-properties using `ansi-color-apply-on-region'.
The comint output is assumed to lie between the marker
`comint-last-output-start' and the process-mark.
This is a good function to put in `comint-output-filter-functions'."
(let ((start-marker (or comint-last-output-start
(point-min-marker)))
(end-marker (process-mark (get-buffer-process (current-buffer)))))
(cond ((eq ansi-color-for-comint-mode nil))
((eq ansi-color-for-comint-mode 'filter)
(ansi-color-filter-region start-marker end-marker))
(t
(ansi-color-apply-on-region start-marker end-marker)))))
(add-hook 'comint-output-filter-functions
'ansi-color-process-output)
;; Alternative font-lock-unfontify-region-function for Emacs only
(eval-when-compile
;; We use this to preserve or protect things when modifying text
;; properties. Stolen from lazy-lock and font-lock. Ugly!!!
;; Probably most of this is not needed?
(defmacro save-buffer-state (varlist &rest body)
"Bind variables according to VARLIST and eval BODY restoring buffer state."
(` (let* ((,@ (append varlist
'((modified (buffer-modified-p)) (buffer-undo-list t)
(inhibit-read-only t) (inhibit-point-motion-hooks t)
before-change-functions after-change-functions
deactivate-mark buffer-file-name buffer-file-truename))))
(,@ body)
(when (and (not modified) (buffer-modified-p))
(set-buffer-modified-p nil)))))
(put 'save-buffer-state 'lisp-indent-function 1))
(defun ansi-color-unfontify-region (beg end &rest xemacs-stuff)
"Replacement function for `font-lock-default-unfontify-region'.
As text-properties are implemented using extents in XEmacs, this
function is probably not needed. In Emacs, however, things are a bit
different: When font-lock is active in a buffer, you cannot simply add
face text-properties to the buffer. Font-lock will remove the face
text-property using `font-lock-unfontify-region-function'. If you want
to insert the strings returned by `ansi-color-apply' into such buffers,
you must set `font-lock-unfontify-region-function' to
`ansi-color-unfontify-region'. This function will not remove all face
text-properties unconditionally. It will keep the face text-properties
if the property `ansi-color' is set.
The region from BEG to END is unfontified. XEMACS-STUFF is ignored.
A possible way to install this would be:
\(add-hook 'font-lock-mode-hook
\(function (lambda ()
\(setq font-lock-unfontify-region-function
'ansi-color-unfontify-region))))"
;; save-buffer-state is a macro in font-lock.el!
(save-buffer-state nil
(when (boundp 'font-lock-syntactic-keywords)
(remove-text-properties beg end '(syntax-table nil)))
;; instead of just using (remove-text-properties beg end '(face
;; nil)), we find regions with a non-nil face test-property, skip
;; positions with the ansi-color property set, and remove the
;; remaining face test-properties.
(while (setq beg (text-property-not-all beg end 'face nil))
(setq beg (or (text-property-not-all beg end 'ansi-color t) end))
(when (get-text-property beg 'face)
(let ((end-face (or (text-property-any beg end 'face nil)
end)))
(remove-text-properties beg end-face '(face nil))
(setq beg end-face))))))
;; Working with strings
(defvar ansi-color-context nil
"Context saved between two calls to `ansi-color-apply'.
This is a list of the form (FACES FRAGMENT) or nil. FACES is a list of
faces the last call to `ansi-color-apply' ended with, and FRAGMENT is a
string starting with an escape sequence, possibly the start of a new
escape sequence.")
(make-variable-buffer-local 'ansi-color-context)
(defun ansi-color-filter-apply (string)
"Filter out all SGR control sequences from STRING.
Every call to this function will set and use the buffer-local variable
`ansi-color-context' to save partial escape sequences. This information
will be used for the next call to `ansi-color-apply'. Set
`ansi-color-context' to nil if you don't want this.
This function can be added to `comint-preoutput-filter-functions'."
(let ((start 0) end result)
;; if context was saved and is a string, prepend it
(if (cadr ansi-color-context)
(setq string (concat (cadr ansi-color-context) string)
ansi-color-context nil))
;; find the next escape sequence
(while (setq end (string-match ansi-color-regexp string start))
(setq result (concat result (substring string start end))
start (match-end 0)))
;; save context, add the remainder of the string to the result
(let (fragment)
(if (string-match "\033" string start)
(let ((pos (match-beginning 0)))
(setq fragment (substring string pos)
result (concat result (substring string start pos))))
(setq result (concat result (substring string start))))
(if fragment
(setq ansi-color-context (list nil fragment))
(setq ansi-color-context nil)))
result))
(defun ansi-color-apply (string)
"Translates SGR control sequences into text-properties.
Applies SGR control sequences setting foreground and background colors
to STRING using text-properties and returns the result. The colors used
are given in `ansi-color-faces-vector' and `ansi-color-names-vector'.
See function `ansi-color-apply-sequence' for details.
Every call to this function will set and use the buffer-local variable
`ansi-color-context' to save partial escape sequences and current face.
This information will be used for the next call to `ansi-color-apply'.
Set `ansi-color-context' to nil if you don't want this.
This function can be added to `comint-preoutput-filter-functions'.
You cannot insert the strings returned into buffers using font-lock.
See `ansi-color-unfontify-region' for a way around this."
(let ((face (car ansi-color-context))
(start 0) end escape-sequence result)
;; if context was saved and is a string, prepend it
(if (cadr ansi-color-context)
(setq string (concat (cadr ansi-color-context) string)
ansi-color-context nil))
;; find the next escape sequence
(while (setq end (string-match ansi-color-regexp string start))
;; store escape sequence
(setq escape-sequence (match-string 1 string))
;; colorize the old block from start to end using old face
(when face
(put-text-property start end 'ansi-color t string)
(put-text-property start end 'face face string))
(setq result (concat result (substring string start end))
start (match-end 0))
;; create new face by applying all the parameters in the escape
;; sequence
(setq face (ansi-color-apply-sequence escape-sequence face ansi-color-context)))
;; if the rest of the string should have a face, put it there
(when face
(put-text-property start (length string) 'ansi-color t string)
(put-text-property start (length string) 'face face string))
;; save context, add the remainder of the string to the result
(let (fragment)
(if (string-match "\033" string start)
(let ((pos (match-beginning 0)))
(setq fragment (substring string pos)
result (concat result (substring string start pos))))
(setq result (concat result (substring string start))))
(if (or face fragment)
(setq ansi-color-context (list face fragment))
(setq ansi-color-context nil)))
result))
;; Working with regions
(defvar ansi-color-context-region nil
"Context saved between two calls to `ansi-color-apply-on-region'.
This is a list of the form (FACES MARKER) or nil. FACES is a list of
faces the last call to `ansi-color-apply-on-region' ended with, and
MARKER is a buffer position within an escape sequence or the last
position processed.")
(make-variable-buffer-local 'ansi-color-context-region)
(defun ansi-color-filter-region (begin end)
"Filter out all SGR control sequences from region BEGIN to END.
Every call to this function will set and use the buffer-local variable
`ansi-color-context-region' to save position. This information will be
used for the next call to `ansi-color-apply-on-region'. Specifically,
it will override BEGIN, the start of the region. Set
`ansi-color-context-region' to nil if you don't want this."
(let ((end-marker (copy-marker end))
(start (or (cadr ansi-color-context-region) begin)))
(save-excursion
(goto-char start)
;; find the next escape sequence
(while (re-search-forward ansi-color-regexp end-marker t)
;; delete the escape sequence
(replace-match ""))
;; save context, add the remainder of the string to the result
(if (re-search-forward "\033" end-marker t)
(setq ansi-color-context-region (list nil (match-beginning 0)))
(setq ansi-color-context-region nil)))))
(defun ansi-color-apply-on-region (begin end)
"Translates SGR control sequences into overlays or extents.
Applies SGR control sequences setting foreground and background colors
to text in region between BEGIN and END using extents or overlays.
Emacs will use overlays, XEmacs will use extents. The colors used are
given in `ansi-color-faces-vector' and `ansi-color-names-vector'. See
function `ansi-color-apply-sequence' for details.
Every call to this function will set and use the buffer-local variable
`ansi-color-context-region' to save position and current face. This
information will be used for the next call to
`ansi-color-apply-on-region'. Specifically, it will override BEGIN, the
start of the region and set the face with which to start. Set
`ansi-color-context-region' to nil if you don't want this."
(let ((face (car ansi-color-context-region))
(start-marker (or (cadr ansi-color-context-region)
(copy-marker begin)))
(end-marker (copy-marker end))
escape-sequence)
(save-excursion
(goto-char start-marker)
;; find the next escape sequence
(while (re-search-forward ansi-color-regexp end-marker t)
;; colorize the old block from start to end using old face
(when face
(ansi-color-set-extent-face
(ansi-color-make-extent start-marker (match-beginning 0))
face))
;; store escape sequence and new start position
(setq escape-sequence (match-string 1)
start-marker (copy-marker (match-end 0)))
;; delete the escape sequence
(replace-match "")
;; create new face by applying all the parameters in the escape
;; sequence
(setq face (ansi-color-apply-sequence escape-sequence face ansi-color-context-region)))
;; search for the possible start of a new escape sequence
(if (re-search-forward "\033" end-marker t)
(progn
;; if the rest of the region should have a face, put it there
(when face
(ansi-color-set-extent-face
(ansi-color-make-extent start-marker (point))
face))
;; save face and point
(setq ansi-color-context-region
(list face (copy-marker (match-beginning 0)))))
;; if the rest of the region should have a face, put it there
(if face
(progn
(ansi-color-set-extent-face
(ansi-color-make-extent start-marker end-marker)
face)
(setq ansi-color-context-region (list face)))
;; reset context
(setq ansi-color-context-region nil))))))
;; This function helps you look for overlapping overlays. This is
;; usefull in comint-buffers. Overlapping overlays should not happen!
;; A possible cause for bugs are the markers. If you create an overlay
;; up to the end of the region, then that end might coincide with the
;; process-mark. As text is added BEFORE the process-mark, the overlay
;; will keep growing. Therefore, as more overlays are created later on,
;; there will be TWO OR MORE overlays covering the buffer at that point.
;; This function helps you check your buffer for these situations.
; (defun ansi-color-debug-overlays ()
; (interactive)
; (let ((pos (point-min)))
; (while (< pos (point-max))
; (if (<= 2 (length (overlays-at pos)))
; (progn
; (goto-char pos)
; (error "%d overlays at %d" (length (overlays-at pos)) pos))
; (let (message-log-max)
; (message "Reached %d." pos)))
; (setq pos (next-overlay-change pos)))))
;; Emacs/XEmacs compatibility layer
(defun ansi-color-make-face (property color)
"Return a face with PROPERTY set to COLOR.
PROPERTY can be either symbol `foreground' or symbol `background'.
For Emacs, we just return the cons cell \(PROPERTY . COLOR).
For XEmacs, we create a temporary face and return it."
(if (featurep 'xemacs)
(let ((face (make-face (intern (concat color "-" (symbol-name property)))
"Temporary face created by ansi-color."
t)))
(set-face-property face property color)
face)
(cond ((eq property 'foreground)
(cons 'foreground-color color))
((eq property 'background)
(cons 'background-color color))
(t
(cons property color)))))
(defun ansi-color-make-extent (from to &optional object)
"Make an extent for the range [FROM, TO) in OBJECT.
OBJECT defaults to the current buffer. XEmacs uses `make-extent', Emacs
uses `make-overlay'. XEmacs can use a buffer or a string for OBJECT,
Emacs requires OBJECT to be a buffer."
(if (functionp 'make-extent)
(make-extent from to object)
;; In Emacs, the overlay might end at the process-mark in comint
;; buffers. In that case, new text will be inserted before the
;; process-mark, ie. inside the overlay (using insert-before-marks).
;; In order to avoid this, we use the `insert-behind-hooks' overlay
;; property to make sure it works.
(let ((overlay (make-overlay from to object)))
(overlay-put overlay 'modification-hooks '(ansi-color-freeze-overlay))
overlay)))
(defun ansi-color-freeze-overlay (overlay is-after begin end &optional len)
"Prevent OVERLAY from being extended.
This function can be used for the `modification-hooks' overlay
property."
;; if stuff was inserted at the end of the overlay
(when (and is-after
(= 0 len)
(= end (overlay-end overlay)))
;; reset the end of the overlay
(move-overlay overlay (overlay-start overlay) begin)))
(defun ansi-color-set-extent-face (extent face)
"Set the `face' property of EXTENT to FACE.
XEmacs uses `set-extent-face', Emacs uses `overlay-put'."
(if (functionp 'set-extent-face)
(set-extent-face extent face)
(overlay-put extent 'face face)))
;; Helper functions
(defun ansi-color-apply-sequence (escape-sequence faces &optional context)
"Apply ESCAPE-SEQUENCE to FACES and return the new list of faces.
ESCAPE-SEQUENCE is an escape sequence and specifies a list of new
faces. If any of the new faces is the default face, then the list of
faces is reset.
The optional argument CONTEXT is a cons-cell with the current
context. This is either the value of `ansi-color-context' or
`ansi-color-context-region'. Both have the current face in
the CAR. When the escape sequence specifies that the face must
be reset to default, then the face in the context must be reset
as well."
(let ((ansi-color-r "[0-9][0-9]?")
(i 0)
face)
(while (string-match ansi-color-r escape-sequence i)
(setq i (match-end 0)
face (ansi-color-get-face-1
(string-to-int (match-string 0 escape-sequence) 10)))
(cond ((not face))
((eq face 'default)
(setq faces nil)
(when context
(setcar context nil)))
(t
;; Prepend the new face to the list of faces. Prepending
;; is important when faces conflict, ie. both specify a
;; foreground color.
(setq faces (cons face faces))))))
faces)
(defun ansi-color-make-color-map ()
"Creates a vector of face definitions and returns it.
The index into the vector is an ANSI code. See the documentation of
`ansi-color-map' for an example.
The face definitions are based upon the variables
`ansi-color-faces-vector' and `ansi-color-names-vector'."
(let ((ansi-color-map (make-vector 50 nil))
(index 0))
;; miscellaneous attributes
(mapcar
(function (lambda (e)
(aset ansi-color-map index e)
(setq index (1+ index)) ))
ansi-color-faces-vector)
;; foreground attributes
(setq index 30)
(mapcar
(function (lambda (e)
(aset ansi-color-map index
(ansi-color-make-face 'foreground e))
(setq index (1+ index)) ))
ansi-color-names-vector)
;; background attributes
(setq index 40)
(mapcar
(function (lambda (e)
(aset ansi-color-map index
(ansi-color-make-face 'background e))
(setq index (1+ index)) ))
ansi-color-names-vector)
ansi-color-map))
(defvar ansi-color-map (ansi-color-make-color-map)
"A brand new color map suitable for `ansi-color-get-face'.
The value of this variable is usually constructed by
`ansi-color-make-color-map'. The values in the array are such that the
numbers included in an SGR control sequences point to the correct
foreground or background colors.
Example: The sequence \033[34m specifies a blue foreground. Therefore:
(aref ansi-color-map 34)
=> \(foreground-color . \"blue\")")
(defun ansi-color-map-update (symbol value)
"Update `ansi-color-map'.
Whenever the vectors used to construct `ansi-color-map' are changed,
this function is called. Therefore this function is listed as the :set
property of `ansi-color-faces-vector' and `ansi-color-names-vector'."
(set-default symbol value)
(setq ansi-color-map (ansi-color-make-color-map)))
(defun ansi-color-get-face-1 (ansi-code)
"Get face definition from `ansi-color-map'.
ANSI-CODE is used as an index into the vector."
(condition-case nil
(aref ansi-color-map ansi-code)
('args-out-of-range nil)))
(provide 'ansi-color)
;;; ansi-color.el ends here

View file

@ -0,0 +1,38 @@
/Users/sjs/Projects/stack/integer.c
/Users/sjs/Projects/stack/#integer.c#
/Users/sjs/Projects/stack/float.c
/Users/sjs/Projects/stack/#float.c#
/Users/sjs/Projects/stack/common.c
/Users/sjs/Projects/stack/#common.c#
/Users/sjs/Projects/stack/number.c
/Users/sjs/Projects/stack/#number.c#
/Users/sjs/Projects/stack/number.h
/Users/sjs/Projects/stack/#number.h#
/Users/sjs/Projects/stack/float.h
/Users/sjs/Projects/stack/#float.h#
/Users/sjs/Projects/stack/common.h
/Users/sjs/Projects/stack/#common.h#
/Users/sjs/Projects/stack/TODO
/Users/sjs/Projects/stack/#TODO#
/Users/sjs/Projects/stack/integer.h
/Users/sjs/Projects/stack/#integer.h#
/Users/sjs/Projects/stack/types.h
/Users/sjs/Projects/stack/#types.h#
/Users/sjs/Projects/stack/vm/vm.c
/Users/sjs/Projects/stack/vm/#vm.c#
/Users/sjs/Projects/stack/vm/test_vm.c
/Users/sjs/Projects/stack/vm/#test_vm.c#
/Users/sjs/Projects/stack/Makefile
/Users/sjs/Projects/stack/#Makefile#
/Users/sjs/Projects/stack/types.c
/Users/sjs/Projects/stack/#types.c#
/Users/sjs/Projects/stack/class.h
/Users/sjs/Projects/stack/#class.h#
/Users/sjs/Projects/stack/class.c
/Users/sjs/Projects/stack/#class.c#
/Users/sjs/Projects/stack/string.c
/Users/sjs/Projects/stack/#string.c#
/Users/sjs/Projects/stack/string.h
/Users/sjs/Projects/stack/#string.h#
/Users/sjs/Projects/stack/config.h
/Users/sjs/Projects/stack/#config.h#

View file

@ -0,0 +1,70 @@
/Users/sjs/Projects/stack/sequence.c
/Users/sjs/Projects/stack/#sequence.c#
/Users/sjs/Projects/stack/float.c
/Users/sjs/Projects/stack/#float.c#
/Users/sjs/Projects/stack/number.c
/Users/sjs/Projects/stack/#number.c#
/Users/sjs/Projects/stack/common.h
/Users/sjs/Projects/stack/#common.h#
/Users/sjs/Projects/stack/integer.c
/Users/sjs/Projects/stack/#integer.c#
/Users/sjs/Projects/stack/types.h
/Users/sjs/Projects/stack/#types.h#
/Users/sjs/Projects/stack/sequence.h
/Users/sjs/Projects/stack/#sequence.h#
/Users/sjs/Projects/stack/class.c
/Users/sjs/Projects/stack/#class.c#
/Users/sjs/Projects/stack/class.h
/Users/sjs/Projects/stack/#class.h#
/Users/sjs/Projects/stack/Makefile
/Users/sjs/Projects/stack/#Makefile#
/Users/sjs/Projects/stack/test.c
/Users/sjs/Projects/stack/#test.c#
/Users/sjs/Projects/stack/object.c
/Users/sjs/Projects/stack/#object.c#
/Users/sjs/Projects/stack/nil.c
/Users/sjs/Projects/stack/#nil.c#
/Users/sjs/Projects/stack/string.c
/Users/sjs/Projects/stack/#string.c#
/Users/sjs/Projects/stack/boolean.c
/Users/sjs/Projects/stack/#boolean.c#
/Users/sjs/Projects/stack/array.c
/Users/sjs/Projects/stack/#array.c#
/Users/sjs/Projects/stack/number.h
/Users/sjs/Projects/stack/#number.h#
/Users/sjs/Projects/stack/common.c
/Users/sjs/Projects/stack/#common.c#
/Users/sjs/Projects/stack/nil.h
/Users/sjs/Projects/stack/#nil.h#
/Users/sjs/Projects/stack/types.c
/Users/sjs/Projects/stack/#types.c#
/Users/sjs/Projects/stack/float.h
/Users/sjs/Projects/stack/#float.h#
/Users/sjs/Projects/stack/integer.h
/Users/sjs/Projects/stack/#integer.h#
/Users/sjs/Projects/stack/string.h
/Users/sjs/Projects/stack/#string.h#
/Users/sjs/Projects/stack/object.h
/Users/sjs/Projects/stack/#object.h#
/Users/sjs/Projects/stack/array.h
/Users/sjs/Projects/stack/#array.h#
/Users/sjs/Projects/stack/boolean.h
/Users/sjs/Projects/stack/#boolean.h#
/Users/sjs/Projects/stack/test.h
/Users/sjs/Projects/stack/#test.h#
/Users/sjs/Projects/stack/vm/vm.c
/Users/sjs/Projects/stack/vm/#vm.c#
/Users/sjs/Projects/stack/vm/stack.h
/Users/sjs/Projects/stack/vm/#stack.h#
/Users/sjs/Projects/stack/vm/vm.h
/Users/sjs/Projects/stack/vm/#vm.h#
/Users/sjs/Projects/stack/st.c
/Users/sjs/Projects/stack/#st.c#
/Users/sjs/Projects/stack/st.h
/Users/sjs/Projects/stack/#st.h#
/Users/sjs/Projects/stack/error.h
/Users/sjs/Projects/stack/#error.h#
/Users/sjs/Projects/stack/TODO
/Users/sjs/Projects/stack/#TODO#
/Users/sjs/.emacs
/Users/sjs/#.emacs#

View file

@ -0,0 +1,20 @@
/Users/sjs/Projects/stack/common.h
/Users/sjs/Projects/stack/#common.h#
/Users/sjs/Projects/stack/types.h
/Users/sjs/Projects/stack/#types.h#
/Users/sjs/Projects/stack/types.c
/Users/sjs/Projects/stack/#types.c#
/Users/sjs/Projects/stack/fixnum.h
/Users/sjs/Projects/stack/#fixnum.h#
/Users/sjs/Projects/stack/test.c
/Users/sjs/Projects/stack/#test.c#
/Users/sjs/Projects/stack/vm/vm.c
/Users/sjs/Projects/stack/vm/#vm.c#
/Users/sjs/Projects/stack/vm/vm.h
/Users/sjs/Projects/stack/vm/#vm.h#
/Users/sjs/Projects/stack/vm/stack.h
/Users/sjs/Projects/stack/vm/#stack.h#
/Users/sjs/Projects/stack/vm/stack.c
/Users/sjs/Projects/stack/vm/#stack.c#
/Users/sjs/Projects/stack/TODO
/Users/sjs/Projects/stack/#TODO#

View file

@ -0,0 +1,14 @@
/Users/sjs/Projects/stack/kiss/test.c
/Users/sjs/Projects/stack/kiss/#test.c#
/Users/sjs/Projects/stack/kiss/lexer.c
/Users/sjs/Projects/stack/kiss/#lexer.c#
/Users/sjs/Projects/stack/kiss/lexer.h
/Users/sjs/Projects/stack/kiss/#lexer.h#
/Users/sjs/Projects/stack/kiss/Makefile
/Users/sjs/Projects/stack/kiss/#Makefile#
/Users/sjs/.emacs
/Users/sjs/#.emacs#
/Users/sjs/Projects/stack/kiss/parser.c
/Users/sjs/Projects/stack/kiss/#parser.c#
/Users/sjs/Projects/stack/kiss/parser.h
/Users/sjs/Projects/stack/kiss/#parser.h#

View file

@ -0,0 +1,34 @@
/home/sjs/.emacs
/home/sjs/#.emacs#
/home/sjs/projects/balltrek/doc/TODO
/home/sjs/projects/balltrek/doc/#TODO#
/home/sjs/projects/balltrek/test/unit/customer_test.rb
/home/sjs/projects/balltrek/test/unit/#customer_test.rb#
/home/sjs/projects/balltrek/test/unit/purchase_test.rb
/home/sjs/projects/balltrek/test/unit/#purchase_test.rb#
/home/sjs/projects/balltrek/test/unit/cart_test.rb
/home/sjs/projects/balltrek/test/unit/#cart_test.rb#
/home/sjs/projects/balltrek/app/models/cart.rb
/home/sjs/projects/balltrek/app/models/#cart.rb#
/home/sjs/projects/balltrek/app/models/reservation.rb
/home/sjs/projects/balltrek/app/models/#reservation.rb#
/home/sjs/projects/balltrek/test/unit/reservation_test.rb
/home/sjs/projects/balltrek/test/unit/#reservation_test.rb#
/home/sjs/projects/balltrek/test/unit/item_test.rb
/home/sjs/projects/balltrek/test/unit/#item_test.rb#
/home/sjs/projects/balltrek/app/models/item.rb
/home/sjs/projects/balltrek/app/models/#item.rb#
/home/sjs/projects/balltrek/test/test_helper.rb
/home/sjs/projects/balltrek/test/#test_helper.rb#
/home/sjs/projects/balltrek/app/models/customer.rb
/home/sjs/projects/balltrek/app/models/#customer.rb#
/home/sjs/projects/balltrek/test/functional/admin/users_controller_test.rb
/home/sjs/projects/balltrek/test/functional/admin/#users_controller_test.rb#
/home/sjs/projects/balltrek/app/models/account_type.rb
/home/sjs/projects/balltrek/app/models/#account_type.rb#
/home/sjs/projects/balltrek/app/controllers/customers_controller.rb
/home/sjs/projects/balltrek/app/controllers/#customers_controller.rb#
/home/sjs/projects/balltrek/app/controllers/creditcard_controller.rb
/home/sjs/projects/balltrek/app/controllers/#creditcard_controller.rb#
/home/sjs/projects/balltrek/test/functional/customers_controller_test.rb
/home/sjs/projects/balltrek/test/functional/#customers_controller_test.rb#

View file

@ -0,0 +1,8 @@
/Users/sjs/count.rb
/Users/sjs/#count.rb#
/Users/sjs/count.sh
/Users/sjs/#count.sh#
/Users/sjs/Projects/c/itoa.c
/Users/sjs/Projects/c/#itoa.c#
/Users/sjs/Projects/c/expand.c
/Users/sjs/Projects/c/#expand.c#

View file

@ -0,0 +1,4 @@
/home/sjs/projects/crescendo/IDEAS
/home/sjs/projects/crescendo/#IDEAS#
/home/sjs/.emacs
/home/sjs/#.emacs#

View file

@ -0,0 +1,2 @@
/Users/sjs/Projects/bjs/js.lex
/Users/sjs/Projects/bjs/#js.lex#

View file

@ -0,0 +1,178 @@
/home/sjs/projects/balltrek/app/views/customers/show.rhtml
/home/sjs/projects/balltrek/app/views/customers/#show.rhtml#
/home/sjs/projects/balltrek/app/models/fund_source.rb
/home/sjs/projects/balltrek/app/models/#fund_source.rb#
/home/sjs/projects/balltrek/doc/TODO
/home/sjs/projects/balltrek/doc/#TODO#
/home/sjs/projects/balltrek/app/controllers/customers_controller.rb
/home/sjs/projects/balltrek/app/controllers/#customers_controller.rb#
/home/sjs/projects/balltrek/app/helpers/customers_helper.rb
/home/sjs/projects/balltrek/app/helpers/#customers_helper.rb#
/home/sjs/projects/balltrek/app/models/paypal.rb
/home/sjs/projects/balltrek/app/models/#paypal.rb#
/home/sjs/projects/balltrek/app/models/credit_card.rb
/home/sjs/projects/balltrek/app/models/#credit_card.rb#
/home/sjs/projects/balltrek/app/models/customer.rb
/home/sjs/projects/balltrek/app/models/#customer.rb#
/home/sjs/projects/balltrek/lib/balltrek.rb
/home/sjs/projects/balltrek/lib/#balltrek.rb#
/home/sjs/projects/balltrek/app/helpers/application_helper.rb
/home/sjs/projects/balltrek/app/helpers/#application_helper.rb#
/home/sjs/projects/balltrek/config/environment.rb
/home/sjs/projects/balltrek/config/#environment.rb#
/home/sjs/projects/balltrek/config/environments/development.rb
/home/sjs/projects/balltrek/config/environments/#development.rb#
/home/sjs/code/ruby/lisp.rb
/home/sjs/code/ruby/#lisp.rb#
/home/sjs/projects/balltrek/config/environments/production.rb
/home/sjs/projects/balltrek/config/environments/#production.rb#
/home/sjs/projects/balltrek/config/environments/test.rb
/home/sjs/projects/balltrek/config/environments/#test.rb#
/home/sjs/code/factorial.txt
/home/sjs/code/#factorial.txt#
/home/sjs/projects/elschemo/sandbox.scm
/home/sjs/projects/elschemo/#sandbox.scm#
/home/sjs/projects/elschemo/stdlib.scm
/home/sjs/projects/elschemo/#stdlib.scm#
/home/sjs/.gtkrc-2.0
/home/sjs/#.gtkrc-2.0#
/home/sjs/code/haskell/factorial.hs
/home/sjs/code/haskell/#factorial.hs#
/home/sjs/.emacs
/home/sjs/#.emacs#
/home/sjs/config/fluxbox/keys
/home/sjs/config/fluxbox/#keys#
/home/sjs/projects/balltrek/app/models/prize.rb
/home/sjs/projects/balltrek/app/models/#prize.rb#
/home/sjs/projects/balltrek/app/models/draw.rb
/home/sjs/projects/balltrek/app/models/#draw.rb#
/home/sjs/projects/balltrek/test/unit/prize_test.rb
/home/sjs/projects/balltrek/test/unit/#prize_test.rb#
/home/sjs/projects/balltrek/app/models/likely_result.rb
/home/sjs/projects/balltrek/app/models/#likely_result.rb#
/home/sjs/projects/balltrek/test/unit/likely_result_test.rb
/home/sjs/projects/balltrek/test/unit/#likely_result_test.rb#
/home/sjs/projects/balltrek/db/migrate/015_create_fund_sources.rb
/home/sjs/projects/balltrek/db/migrate/#015_create_fund_sources.rb#
/home/sjs/projects/balltrek/app/views/customers/winners.rhtml
/home/sjs/projects/balltrek/app/views/customers/#winners.rhtml#
/home/sjs/projects/balltrek/app/controllers/purchase_controller.rb
/home/sjs/projects/balltrek/app/controllers/#purchase_controller.rb#
/home/sjs/projects/balltrek/app/models/cart.rb
/home/sjs/projects/balltrek/app/models/#cart.rb#
/home/sjs/projects/balltrek/app/views/customers/_form.rhtml
/home/sjs/projects/balltrek/app/views/customers/#_form.rhtml#
/home/sjs/projects/balltrek/app/views/customers/edit.rhtml
/home/sjs/projects/balltrek/app/views/customers/#edit.rhtml#
/home/sjs/projects/balltrek/app/controllers/payments_controller.rb
/home/sjs/projects/balltrek/app/controllers/#payments_controller.rb#
/home/sjs/projects/balltrek/app/views/admin/cardtypes/index.rhtml
/home/sjs/projects/balltrek/app/views/admin/cardtypes/#index.rhtml#
/home/sjs/projects/balltrek/app/views/admin/cardtypes/create.rjs
/home/sjs/projects/balltrek/app/views/admin/cardtypes/#create.rjs#
/home/sjs/projects/balltrek/app/controllers/admin/paymentmethods_controller.rb
/home/sjs/projects/balltrek/app/controllers/admin/#paymentmethods_controller.rb#
/home/sjs/projects/balltrek/app/models/payment_method.rb
/home/sjs/projects/balltrek/app/models/#payment_method.rb#
/home/sjs/projects/balltrek/app/views/admin/paymentmethods/index.rhtml
/home/sjs/projects/balltrek/app/views/admin/paymentmethods/#index.rhtml#
/home/sjs/projects/balltrek/app/views/admin/paymentmethods/create.rjs
/home/sjs/projects/balltrek/app/views/admin/paymentmethods/#create.rjs#
/home/sjs/projects/balltrek/app/views/admin/paymentmethods/_payment_methods.rhtml
/home/sjs/projects/balltrek/app/views/admin/paymentmethods/#_payment_methods.rhtml#
/home/sjs/projects/balltrek/app/views/admin/paymentmethods/_payment_method.rhtml
/home/sjs/projects/balltrek/app/views/admin/paymentmethods/#_payment_method.rhtml#
/home/sjs/projects/balltrek/db/migrate/001_create_tables.rb
/home/sjs/projects/balltrek/db/migrate/#001_create_tables.rb#
/home/sjs/projects/balltrek/app/views/admin/lotteries/_prize.rhtml
/home/sjs/projects/balltrek/app/views/admin/lotteries/#_prize.rhtml#
/home/sjs/projects/balltrek/app/views/admin/lotteries/show.rhtml
/home/sjs/projects/balltrek/app/views/admin/lotteries/#show.rhtml#
/home/sjs/projects/balltrek/app/views/admin/prizes/_form.rhtml
/home/sjs/projects/balltrek/app/views/admin/prizes/#_form.rhtml#
/home/sjs/projects/balltrek/app/views/admin/prizes/new.rhtml
/home/sjs/projects/balltrek/app/views/admin/prizes/#new.rhtml#
/home/sjs/projects/balltrek/app/controllers/admin/prizes_controller.rb
/home/sjs/projects/balltrek/app/controllers/admin/#prizes_controller.rb#
/home/sjs/projects/balltrek/app/helpers/admin/lotteries_helper.rb
/home/sjs/projects/balltrek/app/helpers/admin/#lotteries_helper.rb#
/home/sjs/projects/balltrek/app/helpers/lottery_helper.rb
/home/sjs/projects/balltrek/app/helpers/#lottery_helper.rb#
/home/sjs/projects/balltrek/app/views/admin/lotteries/_form.rhtml
/home/sjs/projects/balltrek/app/views/admin/lotteries/#_form.rhtml#
/home/sjs/projects/balltrek/app/controllers/admin/lotteries_controller.rb
/home/sjs/projects/balltrek/app/controllers/admin/#lotteries_controller.rb#
/home/sjs/projects/balltrek/app/controllers/lottery_controller.rb
/home/sjs/projects/balltrek/app/controllers/#lottery_controller.rb#
/home/sjs/projects/balltrek/db/migrate/011_remove_p7_from_number_sets.rb
/home/sjs/projects/balltrek/db/migrate/#011_remove_p7_from_number_sets.rb#
/home/sjs/projects/balltrek/test/functional/customers_controller_test.rb
/home/sjs/projects/balltrek/test/functional/#customers_controller_test.rb#
/home/sjs/projects/balltrek/test/unit/payment_method_test.rb
/home/sjs/projects/balltrek/test/unit/#payment_method_test.rb#
/home/sjs/projects/balltrek/test/fixtures/payment_methods.yml
/home/sjs/projects/balltrek/test/fixtures/#payment_methods.yml#
/home/sjs/projects/balltrek/app/views/customers/_fund_sources.rhtml
/home/sjs/projects/balltrek/app/views/customers/#_fund_sources.rhtml#
/home/sjs/projects/balltrek/app/views/customers/_creditcard.rhtml
/home/sjs/projects/balltrek/app/views/customers/#_creditcard.rhtml#
/home/sjs/projects/balltrek/app/views/layouts/standard.rhtml
/home/sjs/projects/balltrek/app/views/layouts/#standard.rhtml#
/home/sjs/projects/balltrek/app/views/creditcard/set_default.rjs
/home/sjs/projects/balltrek/app/views/creditcard/#set_default.rjs#
/home/sjs/projects/balltrek/app/views/fund_sources/_paypal.rhtml
/home/sjs/projects/balltrek/app/views/fund_sources/#_paypal.rhtml#
/home/sjs/projects/balltrek/app/views/fund_sources/_credit_card.rhtml
/home/sjs/projects/balltrek/app/views/fund_sources/#_credit_card.rhtml#
/home/sjs/projects/balltrek/app/views/creditcard/app/views/creditcard/remove.rjs
/home/sjs/projects/balltrek/app/views/creditcard/app/views/creditcard/#remove.rjs#
/home/sjs/projects/balltrek/app/views/creditcard/_credit_card_form.rhtml
/home/sjs/projects/balltrek/app/views/creditcard/#_credit_card_form.rhtml#
/home/sjs/projects/balltrek/public/stylesheets/smooth.css
/home/sjs/projects/balltrek/public/stylesheets/#smooth.css#
/home/sjs/projects/balltrek/test/unit/customer_test.rb
/home/sjs/projects/balltrek/test/unit/#customer_test.rb#
/home/sjs/projects/balltrek/app/controllers/application.rb
/home/sjs/projects/balltrek/app/controllers/#application.rb#
/home/sjs/projects/balltrek/lib/authentication.rb
/home/sjs/projects/balltrek/lib/#authentication.rb#
/home/sjs/projects/balltrek/test/fixtures/customers.yml
/home/sjs/projects/balltrek/test/fixtures/#customers.yml#
/home/sjs/projects/balltrek/app/controllers/admin/customers_controller.rb
/home/sjs/projects/balltrek/app/controllers/admin/#customers_controller.rb#
/home/sjs/projects/balltrek/app/views/admin/_menu.rhtml
/home/sjs/projects/balltrek/app/views/admin/#_menu.rhtml#
/home/sjs/projects/balltrek/app/models/user.rb
/home/sjs/projects/balltrek/app/models/#user.rb#
/home/sjs/projects/balltrek/app/models/reservation.rb
/home/sjs/projects/balltrek/app/models/#reservation.rb#
/home/sjs/projects/balltrek/app/models/purchase.rb
/home/sjs/projects/balltrek/app/models/#purchase.rb#
/home/sjs/projects/balltrek/app/models/payment.rb
/home/sjs/projects/balltrek/app/models/#payment.rb#
/home/sjs/projects/balltrek/app/models/lottery.rb
/home/sjs/projects/balltrek/app/models/#lottery.rb#
/home/sjs/projects/balltrek/app/models/item.rb
/home/sjs/projects/balltrek/app/models/#item.rb#
/home/sjs/projects/balltrek/db/schema.rb
/home/sjs/projects/balltrek/db/#schema.rb#
/home/sjs/projects/balltrek/test/unit/payment_test.rb
/home/sjs/projects/balltrek/test/unit/#payment_test.rb#
/home/sjs/projects/balltrek/test/unit/credit_card_test.rb
/home/sjs/projects/balltrek/test/unit/#credit_card_test.rb#
/home/sjs/projects/balltrek/test/unit/paypal_test.rb
/home/sjs/projects/balltrek/test/unit/#paypal_test.rb#
/home/sjs/projects/balltrek/test/unit/fund_source_test.rb
/home/sjs/projects/balltrek/test/unit/#fund_source_test.rb#
/home/sjs/projects/balltrek/test/fixtures/paypals.yml
/home/sjs/projects/balltrek/test/fixtures/#paypals.yml#
/home/sjs/projects/balltrek/test/fixtures/credit_cards.yml
/home/sjs/projects/balltrek/test/fixtures/#credit_cards.yml#
/home/sjs/projects/balltrek/test/fixtures/fund_sources.yml
/home/sjs/projects/balltrek/test/fixtures/#fund_sources.yml#
/home/sjs/projects/balltrek/app/views/customers/signup.rhtml
/home/sjs/projects/balltrek/app/views/customers/#signup.rhtml#
/home/sjs/projects/balltrek/test/fixtures/account_types.yml
/home/sjs/projects/balltrek/test/fixtures/#account_types.yml#
/home/sjs/projects/balltrek/TAGS
/home/sjs/projects/balltrek/#TAGS#

File diff suppressed because it is too large Load diff

Binary file not shown.

137
emacs.d/find-recursive.el Normal file
View file

@ -0,0 +1,137 @@
;; find-recursive.el -- Find files recursively into a directory
;;
;; Copyright (C) 2001 Ovidiu Predescu
;;
;; Author: Ovidiu Predescu <ovidiu@cup.hp.com>
;; Date: March 26, 2001
;;
;; 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, write to the Free Software
;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
;;
;; Setup: put this file in your Lisp path and add the following line in
;; your .emacs:
;;
;; (require 'find-recursive)
;;
(require 'cl)
(defcustom find-recursive-exclude-files '(".*.class$" ".*~$" ".*.elc$")
"List of regular expressions of files to be excluded when recursively searching for files."
:type '(repeat (string :tag "File regexp")))
(defun find-file-recursively (file-regexp directory)
(interactive "sFile name to search for recursively: \nDIn directory: ")
(let ((directory (if (equal (substring directory -1) "/")
directory
(concat directory "/")))
(matches
(find-recursive-filter-out
find-recursive-exclude-files
(find-recursive-directory-relative-files directory "" file-regexp))))
(cond ((eq (length matches) 0) (message "No file(s) found!"))
((eq (length matches) 1)
(find-file (concat directory (car matches))))
(t
(run-with-timer 0.001 nil
(lambda ()
(dispatch-event
(make-event 'key-press '(key tab)))))
(let ((file (completing-read "Choose file: "
(mapcar 'list matches)
nil t)))
(if (or (eq file nil) (equal file ""))
(message "No file selected.")
(find-file (concat directory file))))))))
(defun find-recursive-directory-relative-files (directory
relative-directory
file-regexp)
(let* ((full-dir (concat directory "/" relative-directory))
(matches
(mapcar
(function (lambda (x)
(concat relative-directory x)))
(find-recursive-filter-out '(nil)
(directory-files full-dir nil
file-regexp nil t))))
(inner
(mapcar
(function
(lambda (dir)
(find-recursive-directory-relative-files directory
(concat relative-directory
dir "/")
file-regexp)))
(find-recursive-filter-out '(nil "\\." "\\.\\.")
(directory-files full-dir nil ".*"
nil 'directories)))))
(mapcar (function (lambda (dir) (setq matches (append matches dir))))
inner)
matches))
(defun find-recursive-filter-out (remove-list list)
"Remove all the elements in *remove-list* from *list*"
(if (eq list nil)
nil
(let ((elem (car list))
(rest (cdr list)))
(if (some
(lambda (regexp)
(if (or (eq elem nil) (eq regexp nil))
nil
(not (eq (string-match regexp elem) nil))))
remove-list)
(find-recursive-filter-out remove-list rest)
(cons elem (find-recursive-filter-out remove-list rest))))))
(defvar find-recursive-running-xemacs (string-match "XEmacs\\|Lucid" emacs-version))
(if find-recursive-running-xemacs
nil
(defadvice directory-files (after
directory-files-xemacs
(dirname &optional full match nosort files-only)
activate)
"Add an additional argument, FILES-ONLY to the list of arguments
for GNU Emacs. If the symbol is t, then only the files in the
directory will be returned. If FILES-ONLY is nil, then both files and
directories are selected. If FILES-ONLY is not nil and not t, then
only sundirectories are returned."
(setq ad-return-value
(cond ((null files-only) ad-return-value)
((eq files-only t)
(find-recursive-remove-if (lambda (f)
(file-directory-p
(concat dirname "/" f)))
ad-return-value))
(t
(find-recursive-remove-if (lambda (f)
(not (file-directory-p
(concat dirname "/" f))))
ad-return-value)))))
(defun find-recursive-remove-if (func list)
"Removes all elements satisfying FUNC from LIST."
(let ((result nil))
(while list
(if (not (funcall func (car list)))
(setq result (cons (car list) result)))
(setq list (cdr list)))
(nreverse result))))
(global-set-key [(control x) (meta f)] 'find-file-recursively)
(provide 'find-recursive)

View file

@ -0,0 +1 @@
00666 Tue Jun 19 18:22:15 2007 <sjs@tuono.exile.net>

541
emacs.d/haskell/ChangeLog Normal file
View file

@ -0,0 +1,541 @@
2007-02-14 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-cabal.el: New file.
* haskell-indent.el (haskell-indent-look-past-empty-line): Typo.
* inf-haskell.el (with-selected-window): Define while compiling.
2007-02-10 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-font-lock.el (haskell-font-lock-keywords-create):
Remove qualified and hiding from the reserved identifiers.
Add a special rule for import statements.
* haskell-doc.el (haskell-doc-get-current-word): Remove.
Change all refs to it, to use haskell-ident-at-point instead.
* inf-haskell.el (inferior-haskell-info-xref-re): New cst.
(inferior-haskell-error-regexp-alist): Use it to highlight xref info.
(inferior-haskell-type, inferior-haskell-info)
(inferior-haskell-find-definition): New funs.
Contributed by Matthew Danish <mrd@cs.cmu.edu>.
* haskell-mode.el (haskell-ident-at-point): New fun.
Copy of haskell-doc-get-current-word.
(haskell-mode-map): Add bindings for inferior-haskell-(type|info|find).
2007-02-09 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-indent.el (haskell-indent-back-to-indentation): Simplify.
(haskell-indent-look-past-empty-line): New var.
(haskell-indent-start-of-def): Use it.
* fontlock.hs: Add test case.
* haskell-font-lock.el (haskell-font-lock-version): Remove.
* haskell-doc.el (haskell-doc-version): Remove.
(haskell-doc-get-current-word): Correctly distinguish
variable identifiers and infix identifiers.
(haskell-doc-rescan-files): Avoid switch-to-buffer.
(haskell-doc-imported-list): Operate on current buffer.
(haskell-doc-make-global-fct-index): Adjust call.
2006-11-20 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-doc.el (haskell-doc-mode-print-current-symbol-info):
Fix thinko.
2006-10-19 Stefan Monnier <monnier@iro.umontreal.ca>
* inf-haskell.el (inferior-haskell-load-file): Simplify and make more
robust at the same time.
* haskell-doc.el: Drop p-c-idle-h in favor of run-with-idle-timer.
(haskell-doc-timer, haskell-doc-buffers): New vars.
(haskell-doc-mode): Use them.
(haskell-doc-check-active): Update the check.
(haskell-doc-mode-print-current-symbol-info): Don't sit-for unless it's
really needed. Remove the interactive spec.
2006-09-25 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-mode.el (haskell-mode-menu): Fix typo.
2006-09-20 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-font-lock.el (haskell-font-lock-keywords-create): Use a more
precise test for literate haskell highlighting.
* haskell-mode.el (haskell-mode-menu): New menu.
(haskell-mode): Use new name `eldoc-documentation-function'.
2006-05-18 Stefan Monnier <monnier@iro.umontreal.ca>
* inf-haskell.el (inferior-haskell-wait-for-prompt): New fun, extracted
from inferior-haskell-send-command.
(inferior-haskell-send-command): Use it.
(inferior-haskell-wait-and-jump): New custom var.
(inferior-haskell-load-file): Use it.
2006-05-17 Stefan Monnier <monnier@iro.umontreal.ca>
* inf-haskell.el (inferior-haskell-mode): Use shell-dirtrack-mode
if possible.
* haskell-hugs.el (haskell-hugs-start-process):
* haskell-ghci.el (haskell-ghci-start-process):
Use comint-input-filter-functions rather than the outdated
comint-input-sentinel. Reported by Jerry James <james@xemacs.org>.
2005-12-09 Stefan Monnier <monnier@iro.umontreal.ca>
* indent.hs: Add some erroneous cases.
* haskell-font-lock.el (haskell-font-lock-keywords-create):
Minor regexp fiddling.
2005-11-23 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-indent.el (haskell-indent-next-symbol): Simplify.
(haskell-indent-comment): Rename from haskell-indent-inside-comment.
(haskell-indent-skip-lexeme-forward)
(haskell-indent-offset-after-info, haskell-indent-hanging-p): New funs.
(haskell-indent-inhibit-after-offset, haskell-indent-dont-hang):
New variables.
(haskell-indent-closing-keyword, haskell-indent-after-keyword-column)
(haskell-indent-inside-paren): New functions, extracted
from haskell-indent-indentation-info. Use the above new functions.
(haskell-indent-indentation-info): Use them.
(haskell-indent-after-keywords): Add data for ( and {.
* haskell-font-lock.el (haskell-font-lock-keywords-create): `as' is not
a reserved keyword, apparently, and is used as var name.
2005-11-21 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-*.el (turn-(on|off)-*): Make non-interactive.
* haskell-decl-scan.el (haskell-decl-scan-mode): New minor mode.
(turn-on-haskell-decl-scan): Use it.
* haskell-doc.el (haskell-doc-extract-types): Get labelled data working.
(haskell-doc-prelude-types): Update via auto-generation.
* haskell-doc.el (haskell-doc-extract-types): Get it partly working.
(haskell-doc-fetch-lib-urls): Don't use a literal if we apply
`nreverse' on it later on.
(haskell-doc-prelude-types): Update some parts by auto-generation.
(haskell-doc-grab, haskell-doc-string-nub-ws): Simplify.
* haskell-doc.el (haskell-doc-maintainer, haskell-doc-varlist)
(haskell-doc-submit-bug-report, haskell-doc-ftp-site)
(haskell-doc-visit-home): Remove.
(haskell-doc-reserved-ids, haskell-doc-fetch-lib-urls)
(haskell-doc-extract-and-insert-types): New funs.
(haskell-doc-reserved-ids): Fix type of `map'.
2005-11-20 Stefan Monnier <monnier@iro.umontreal.ca>
* inf-haskell.el (inferior-haskell-load-file): Fix the
compilation-parsing-end fiddling so it doesn't get moved inadvertently.
* haskell-font-lock.el (haskell-font-lock-symbols-alist): Some XEmacs
versions define make-char but not charsetp.
(haskell-font-lock-symbols-keywords): Add a `keep' arg so
de-highlighting in strings works correctly even in Emacs-21.
* haskell-doc.el: Add coding cookie.
2005-11-14 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-decl-scan.el (haskell-ds-get-variable): Massage.
(haskell-ds-move-to-decl, haskell-ds-generic-find-next-decl):
Use with-syntax-table.
2005-11-14 Dave Love <fx@gnu.org>
* haskell-decl-scan.el: Docstring fixes.
(haskell-ds-keys): Delete.
(turn-on-haskell-decl-scan): Inline it here.
Use beginning-of-defun-function if available.
* haskell-font-lock.el (haskell-font-lock-keywords-create): Add pattern
for numbers and strings for arguments to toplevel declarations.
2005-11-14 Stefan Monnier <monnier@iro.umontreal.ca>
* inf-haskell.el (inferior-haskell-error-regexp-alist): Fix GHCi
regexp, add support for warnings.
2005-11-11 Stefan Monnier <monnier@iro.umontreal.ca>
* Makefile (dist): Remove profile file and avoid ztar.
* inf-haskell.el (inferior-haskell-command): Provide a default.
(with-selected-window): Define if necessary.
(inferior-haskell-load-file): Display the buffer.
* haskell-indent.el (haskell-indent-indentation-info): Typo.
* haskell-ghci.el (haskell-ghci-mode): Use define-derived-mode.
2005-11-07 Stefan Monnier <monnier@iro.umontreal.ca>
* Release version 2.1.
* haskell-indent.el (haskell-indent-inside-comment): Rename `start' arg
into `open' and add a new `start' arg.
(haskell-indent-after-keywords): Change defaults for `in'.
(haskell-indent-indentation-info): Fix confusion between pos and col.
(haskell-indent-mode): Autoload.
* haskell-indent.el (haskell-indent-find-matching-start):
Add `pred' and `start' arguments.
(haskell-indent-filter-let-no-in): New fun.
(haskell-indent-indentation-info): Use them to correctly match `let's
with `in's even when some of the `let's have no matching `in'.
2005-11-06 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-indent.el: Reduce the use of dyn-bound haskell-indent-info.
(haskell-indent-push-col): Don't duplicate info.
(haskell-indent-line-indentation): Handle let-in-do. Remove dead code.
(haskell-indent-inside-comment): Move rest of code from
haskell-indent-indentation-info.
* haskell-indent.el (haskell-literate): Declare.
(haskell-running-xemacs, event-basic-type, read-event): Remove.
(haskell-indent-get-beg-of-line, haskell-indent-get-end-of-line):
Remove. Use line-(beginning|end)-position instead.
(haskell-indent-mark-active): Move the xemacs test inside the defun.
(haskell-indent-info): Rename from indent-info. Update users.
(haskell-indent-bolp, haskell-indent-inside-comment):
Use line-beginning-position.
(haskell-indent-within-literate-code): Use `case'.
(haskell-indent-put-region-in-literate): Bind more comment-* vars.
(haskell-indent-virtual-indentation): Add the missing `start' arg.
(haskell-indent-mode): Move before first use.
(haskell-indent-stand-alone-mode): Use haskell-indent-mode.
Rename from haskell-stand-alone-indent-mode. Use define-derived-mode.
(hugs-mode-map, hugs-syntax-table):
Rename to haskell-stand-alone-indent-mode-(map|syntax-table).
* haskell-doc.el (haskell-doc-xemacs-p, haskell-doc-emacs-p)
(haskell-doc-message): Remove.
(haskell-doc-is-id-char-at): Remove.
(haskell-doc-get-current-word): Rewrite.
2005-11-04 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-indent.el (haskell-indent-indentation-info): Fix detection of
hanging let/if/case statements.
* haskell-mode.el (haskell-mode): Fix typo.
2005-11-04 Stefan Monnier <monnier@iro.umontreal.ca>
* inf-haskell.el (inferior-haskell-mode): Hide compilation bindings.
* haskell-indent.el (haskell-indent-after-keywords): New var.
(haskell-indent-virtual-indentation): New fun.
(haskell-indent-indentation-info): Use them to indent after keywords.
* haskell-simple-indent.el (haskell-simple-indent): Minor simplif.
(turn-on-haskell-simple-indent): Don't bind \t and \n.
* haskell-mode.el (haskell-vars, haskell-mode-generic): Remove.
(haskell-mode-hook): Rename from haskell-mode-hooks.
(haskell-mode): Use define-derived-mode. Inline haskell-mode-generic
and haskell-vars.
(literate-haskell-mode): Use define-derived-mode.
* fontlock.hs: Add some entries for infix declarations.
2005-10-12 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-indent.el (haskell-indent-start-keywords-re): Use regexp-opt.
(haskell-indent-type-at-point): Accept ' in identifiers.
(haskell-indent-find-case): Tell match-data to not generate markers.
(haskell-indent-line-indentation): Ignore off-side keywords in comments
and strings.
(haskell-indent-find-matching-start): Generalize.
Rename from haskell-indent-find-let.
(haskell-indent-indentation-info): Use it for of, then, and else.
2005-09-28 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-indent.el (haskell-indent-in-comment): Don't fail at EOB.
* haskell-font-lock.el (haskell-font-lock-symbols-alist): Add "not".
(haskell-font-lock-compose-symbol): Handle alphanum identifiers.
Fix incorrect handling of . when used for qualified names.
2005-09-26 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-font-lock.el (haskell-font-lock-symbols-alist): Prefer the
unicode version of lambda. Add two symbols from the Omega language and
from Paterson's arrow syntax.
2005-08-24 Steve Chamberlain <sac@pobox.com> (tiny patch)
* haskell-doc.el (haskell-doc-message): Paren typo.
2005-08-23 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-doc.el (haskell-doc-show-type): Assume that the availability
of display-message won't change at runtime.
* haskell-font-lock.el (haskell-font-lock-keywords-create): Try and
work around a bug that seems to be in Emacs-21.3 rather than in
haskell-font-lock.el. Reported by Steve Chamberlain <sac@pobox.com>.
2005-07-18 Stefan Monnier <monnier@iro.umontreal.ca>
* inf-haskell.el (haskell-program-name): Fix defcustom delcaration.
* haskell-doc.el (haskell-doc-message): Remove.
(haskell-doc-show-type): Inline it. Don't do anything for if there's
no doc to show.
2005-02-02 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-hugs.el (haskell-hugs-mode-map):
* haskell-ghci.el (haskell-ghci-mode-map): Remove.
2005-01-26 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-indent.el (haskell-indent-inside-comment): Don't assume that
column(pos+2) = column(pos)+2.
(haskell-indent-indentation-info): Fix indentation of , and ;.
Add arg `start'. Restrict choice of indentation for comments.
(haskell-indent-event-type): Remove.
(haskell-indent-last-info): New var.
(haskell-indent-cycle): Use it to store info from one invocation to
the next, so we can do cycling outside of the function.
Don't cycle directly any more. Instead, recognize repeated invocations
via last-command and friends.
Use indent-line-function rather than hardcoding indent-to-left-margin.
(haskell-indent-insert-where): Don't save excursion.
(haskell-indent-layout-indent-info): Minor simplifications.
(haskell-indent-line-indentation): Don't ignore code on a line
before a string.
* haskell-hugs.el (haskell-hugs-last-loaded-file): Remove.
(haskell-hugs-start-process): Fix misuse of make-variable-buffer-local.
(haskell-hugs-go): Quote file name. Simplify.
* haskell-ghci.el (haskell-ghci-last-loaded-file): Remove.
(haskell-ghci-start-process): Fix misuse of make-variable-buffer-local.
(haskell-ghci-go): Quote file name. Simplify.
* haskell-mode.el (haskell-version): Keep it up-to-date.
* inf-haskell.el (inferior-haskell-load-file): Quote file name.
2004-12-10 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-indent.el (haskell-indent-start-of-def): Only go backward.
(haskell-indent-in-string): Simplify.
(haskell-indent-in-comment): Simplify.
(haskell-indent-comment): Remove.
(haskell-indent-inside-comment): New fun.
(haskell-indent-indentation-info): Assume we're at the indentation.
Handle comments differently.
(haskell-indent-cycle): Go to indentation and then save excursion
around haskell-indent-indentation-info.
* haskell-doc.el (haskell-doc-minor-mode-string): Make it dynamic.
(haskell-doc-install-keymap): Remove conflicting C-c C-o binding.
(haskell-doc-mode): Make a nil arg turn the mode ON.
(turn-on-haskell-doc-mode): Make it an alias for haskell-doc-mode.
(haskell-doc-mode): Don't touch haskell-doc-minor-mode-string.
(haskell-doc-show-global-types): Don't touch
haskell-doc-minor-mode-string. Call haskell-doc-make-global-fct-index.
(haskell-doc-check-active): Fix message.
(define-key-after): Don't define.
(haskell-doc-install-keymap): Check existence of define-key-after.
* haskell-mode.el (haskell-literate-default): Fix custom type.
(haskell-vars): Ignore comments when doing C-M-f.
* indent.hs: More test cases.
* inf-haskell.el (haskell-program-name): Use ghci if hugs is absent.
(inferior-haskell-load-file): Reset compilation-parsing-end.
2004-11-25 Stefan Monnier <monnier@iro.umontreal.ca>
* Release version 2.0.
* .emacs: Remove.
* haskell-decl-scan.el (haskell-ds-imenu-label-cmp): Undo last
idiotic change.
* haskell-doc.el (haskell-doc-sym-doc): Make even the last char bold.
* haskell-mode.el (haskell-mode-map): Typo.
* inf-haskell.el (inferior-haskell-mode): Typo.
(inferior-haskell-wait-for-output): Remove.
(inferior-haskell-send-command): New function.
(inferior-haskell-load-file): Use it.
* index.html:
* installation-guide.html: Partial fixup.
2004-11-24 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-mode.el (turn-on-haskell-hugs, turn-on-haskell-ghci):
Mark them as obsolete.
(haskell-mode-map): Add bindings for the inferior-haskell commands.
* inf-haskell.el: New file.
* haskell-doc.el (haskell-doc-install-keymap): Don't blindly assume
there's a Hugs menu.
2004-11-22 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-indent.el (turn-on-haskell-indent, turn-off-haskell-indent):
Use C-c C-foo rather than C-c foo to follow coding conventions.
* haskell-font-lock.el (haskell-font-lock-symbols-alist): Add . = ○.
2004-10-25 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-indent.el (haskell-indent-indentation-info): Don't use layout
for paren-closing elements.
2004-10-20 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-indent.el (haskell-indent-indentation-info): Only use
the new `in' indentation rule if the `let' is on the left of the decl.
2004-10-19 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-indent.el (haskell-indent-find-let): New function.
(haskell-indent-indentation-info): Use it to indent `in'.
* haskell-font-lock.el (haskell-default-face): Add missing declaration.
* haskell-indent.el (haskell-indent-open-structure): Simplify.
(haskell-indent-contour-line): Work even when `start' is in the middle
of a line.
(haskell-indent-layout-indent-info): New fun extracted from
haskell-indent-indentation-info.
(haskell-indent-indentation-info): Use it as before. Use it also to
handle layout-within-open-structure.
2004-10-18 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-font-lock.el (haskell-font-lock-keywords-create):
Use explicit `symbol-value' to work around limitations in XEmacs's
implementation of font-lock.
(haskell-basic-syntactic-keywords): Fix up char-constants some more.
2004-10-14 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-doc.el (turn-off-haskell-doc-mode)
(haskell-doc-current-info): Don't autoload.
* haskell-decl-scan.el (haskell-ds-match-string):
Use match-string-no-properties if available.
(haskell-ds-syntax-table): Use haskell-mode-syntax-table.
(haskell-ds-imenu-label-cmp): Use car-less-than-car if available.
(haskell-ds-imenu): Remove obsolete incorrect code.
* haskell-mode.el: Set things up so that mode-hook functions are not
necessary, and generic functions can be used instead, like
global-font-lock-mode.
(haskell-enum-from-to): Remove.
(turn-on-haskell-font-lock): Make obsolete.
(haskell-running-xemacs): Remove.
(haskell-mode-syntax-table): Fiddle with non-ascii chars.
Fix up comment syntax in XEmacs.
(haskell-vars): Improve comment-start-skip.
Add comment-end-skip. Setup imenu, eldoc, and font-lock.
Tweak handling of tabs to be on the safe side.
(haskell-mode-hooks): Declare and mention some useful ideas.
(literate-haskell-mode): Simplify.
(haskell-comment-indent): Remove. The default works as well.
* haskell-font-lock.el: Remove level 1 fontification.
(haskell-font-lock-keywords-1, haskell-font-lock-keywords-2)
(bird-literate-haskell-font-lock-keywords-1)
(bird-literate-haskell-font-lock-keywords-2)
(latex-literate-haskell-font-lock-keywords-1)
(latex-literate-haskell-font-lock-keywords-2): Remove.
(bird-literate-haskell-font-lock-keywords)
(latex-literate-haskell-font-lock-keywords): Rename.
(haskell-font-lock-keywords-create): Remove `level' arg.
(haskell-fl-syntax): Remove. Assume the major modes sets it right.
(haskell-font-lock-choose-keywords)
(haskell-font-lock-choose-syntactic-keywords): New funs.
(haskell-font-lock-defaults-create): Use them.
(turn-off-haskell-font-lock, turn-on-haskell-font-lock): Simplify.
* haskell-hugs.el (haskell-hugs-mode): Use define-derived-mode.
(run-hugs): New alias.
(haskell-hugs-wait-for-output): Don't loop if the process is dead.
* haskell-font-lock.el (haskell-font-lock-compose-symbol): New fun.
(haskell-font-lock-symbols-keywords): Use it.
(haskell-string-char-face): Remove.
(haskell-font-lock-keywords-create): Hardcode font-lock-string-face.
(haskell-fl-syntax): Fix typos. Keep " as a string delimiter.
2004-10-13 Stefan Monnier <monnier@iro.umontreal.ca>
* haskell-doc.el (haskell-doc): New group.
(haskell-doc-show-reserved, haskell-doc-show-prelude)
(haskell-doc-show-strategy, haskell-doc-show-user-defined)
(haskell-doc-chop-off-context, haskell-doc-chop-off-fctname):
Make them custom vars.
(haskell-doc-keymap): Declare and fill it right there.
(haskell-doc-mode): Simplify.
(haskell-doc-toggle-var): Make it into what it was supposed to be.
(haskell-doc-mode-print-current-symbol-info): Simplify.
(haskell-doc-current-info): New autoloaded function.
(haskell-doc-sym-doc): New fun extracted from haskell-doc-show-type.
(haskell-doc-show-type): Use it.
(haskell-doc-wrapped-type-p): Remove unused var `lim'.
(haskell-doc-forward-sexp-safe, haskell-doc-current-symbol):
Remove. Unused.
(haskell-doc-visit-home): Don't require ange-ftp, it's autoloaded.
(haskell-doc-install-keymap): Simplify.
* haskell-decl-scan.el (literate-haskell-ds-create-imenu-index)
(haskell-ds-generic-create-imenu-index): Remove.
(haskell-ds-bird-p): New function.
(haskell-ds-backward-decl, haskell-ds-forward-decl): Use it.
(haskell-ds-create-imenu-index): Use it to make it generic.
(haskell-ds-imenu): Remove now-unused arg.
(turn-on-haskell-decl-scan): Fix up call to haskell-ds-imenu.
(haskell-ds-running-xemacs): Remove.
(haskell-ds-func-menu-next): Make generic.
(literate-haskell-ds-func-menu-next): Delete.
(haskell-ds-func-menu): Remove unused arg.
(turn-on-haskell-decl-scan): Simplify.
* haskell-indent.el: Don't load CL at runtime.
(haskell-indent-start-of-def, haskell-indent-type-at-point):
Don't hardcode point-min == 1.
(indent-info): Declare it.
(haskell-indent-empty, haskell-indent-ident, haskell-indent-other)
(haskell-indent-line-indentation): Use `string'.
(haskell-indent-valdef-indentation): Fix `case' arms syntax.
(haskell-indent-indentation-info): Remove unused var `pt'.
(haskell-indent-align-def): Remove unused var `defpos'.
(turn-on-haskell-indent): Don't bind TAB.
(turn-off-haskell-indent): Don't unbind TAB and DEL.
(hugs-syntax-table): Use the `n' for nested comments.
(haskell-stand-alone-indent-mode): Fix `comment-end'.
;; Local Variables:
;; coding: utf-8
;; End:
# arch-tag: a2606dc4-fab7-4b2f-bbe9-0a51db643511

54
emacs.d/haskell/Makefile Normal file
View file

@ -0,0 +1,54 @@
EMACS = emacs
ELFILES = \
haskell-font-lock.el \
haskell-mode.el \
haskell-doc.el \
haskell-decl-scan.el \
inf-haskell.el \
haskell-indent.el
ELCFILES = $(ELFILES:.el=.elc)
# AUTOLOADS = $(PACKAGE)-startup.el
AUTOLOADS = haskell-site-file.el
%.elc: %.el
$(EMACS) --batch --eval '(setq load-path (cons "." load-path))' \
-f batch-byte-compile $<
all: $(ELCFILES) $(AUTOLOADS)
info:
# No Texinfo file, sorry.
######################################################################
### don't look below ###
######################################################################
PACKAGE=haskell-mode
$(AUTOLOADS): $(ELFILES)
[ -f $@ ] || echo ' ' >$@
$(EMACS) --batch --eval '(setq generated-autoload-file "'`pwd`'/$@")' -f batch-update-autoloads "."
##
TAG = $(shell echo v$(VERSION) | tr '.' '_')
ftpdir=/u/monnier/html/elisp/
cvsmodule=$(shell cat CVS/Repository)
cvsroot=$(shell cat CVS/Root)
dist:
cvs tag -F $(TAG) &&\
cd $(TMP) &&\
unset CVSREAD; cvs -d $(cvsroot) export -kv -r $(TAG) -d $(PACKAGE)-$(VERSION) $(cvsmodule) &&\
cd $(PACKAGE)-$(VERSION) &&\
make info $(AUTOLOADS) &&\
rm -f gmon.out;\
cd .. &&\
tar zcf $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE)-$(VERSION) &&\
rm -rf $(PACKAGE)-$(VERSION)
mv $(TMP)/$(PACKAGE)-$(VERSION).tar.gz $(ftpdir)/
ln -sf $(PACKAGE)-$(VERSION).tar.gz $(ftpdir)/$(PACKAGE).tar.gz
# arch-tag: 1ab314c8-3821-44fb-b533-dd58f5d75ba4

54
emacs.d/haskell/NEWS Normal file
View file

@ -0,0 +1,54 @@
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>.
# arch-tag: e50204f2-98e4-438a-bcd1-a49afde5efa5

83
emacs.d/haskell/README Normal file
View file

@ -0,0 +1,83 @@
Haskell Mode for Emacs
----------------------
Version number: v2_3.
This is the Haskell mode package for Emacs. Its use should be mostly
self-explanatory if you're accustomed to Emacs.
When Emacs is started up, it normally runs a file called ~/.emacs located in
your home directory. This file should contain all of your personal
customisations written as a series of Elisp commands. In order to install
the Haskell mode, you have to tell Emacs where to find it. This is done by
adding some commands to the init file.
Installation
------------
- If you are using XEmacs, the haskell-mode package may be available for
installation through the XEmacs package UI.
- If you are using Debian, you may be able to install the package
haskell-mode with a command like "apt-get install haskell-mode".
Otherwise:
- Download and unpack the basic mode and modules into a suitable directory,
e.g. ~/lib/emacs/haskell-mode/ where ~ stands for your home directory.
- Assuming you have placed the basic mode haskell-mode.el and the modules
you want to use in the directory ~/lib/emacs/haskell-mode/, add the
following command to your init file (~/.emacs):
(load "~/lib/emacs/haskell-mode/haskell-site-file")
adding the following lines according to which modules you want to use:
(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
;;(add-hook 'haskell-mode-hook 'turn-on-haskell-simple-indent)
Note that the two indentation modules are mutually exclusive - add at
most one. Note that the line of code for simple indentation is commented
out (using a preceeding ;) in preference for the more advanced
indentation module. Installation is now complete!
The other modules are automatically loaded when needed in the following way:
- Font locking: just turn it on via `global-font-lock-mode' or do
(add-hook 'haskell-mode-hook 'font-lock-mode)
- Declaration scanning: just use M-x imenu or bind `imenu' to a key. E.g.
(global-set-key [(control meta down-mouse-3)] 'imenu) or you can also add
it to the menubar with (add-hook 'haskell-mode-hook 'imenu-add-menubar-index)
- Interaction with inferior Haskell interpreter: just hit C-c C-z or C-c C-l.
Customization
-------------
Most customizations are on the functionality of a particular module.
See the documentation of that module for information on its
customisation.
Known problems
--------------
It seems that some version of XEmacs come without the fsf-compat package
(which provides functions such as `line-end-position') and it seems that
even if your XEmacs does have the fsf-compat package installed it does not
autoload its part. Thus you may have to install the fsf-compat package and
add (require 'goto-addr) in your .emacs.
Support
-------
Any problems, do mail me <monnier@iro.umontreal.ca> and I will try my best
to help you!
<!-- arch-tag: 25fc8494-611d-459f-9919-579c97f6313e -->

View file

@ -0,0 +1,49 @@
-- Comments are coloured brightly and stand out clearly.
import qualified Foo as F hiding (toto)
import qualified Foo hiding (toto)
import qualified Foo as F (toto)
import Foo as F hiding (toto)
import Foo hiding (toto)
import Foo as F (toto)
hiding = 1
qualified = 3
as = 2
repeat :: a -> [a]
repeat xs = xs where xs = x:xs -- Keywords are also bright.
head :: [a] -> a
head (x:_) = x
head [] = error "PreludeList.head: empty list" -- Strings are coloured softly.
data Maybe a = Nothing | Just a -- Type constructors, data
deriving (Eq, Ord, Read, Show) -- constructors, class names
-- and module names are coloured
-- closer to ordinary code.
recognize +++ infix :: Operator Declarations
as `well` as = This Form
(+) and this one = as well
instance Show Toto where
fun1 arg1 = foo -- FIXME: `fun1' should be highlighted.
constStr = "hello \
\asdgfasgf\
\asf"
{-
map :: (a -> b) -> [a] -> [b] -- Commenting out large sections of
map f [] = [] -- code can be misleading. Coloured
map f (x:xs) = f x : map f xs -- comments reveal unused definitions.
-}
-- Note: the least significant bit is the first element of the list
bdigits :: Int -> [Int]
bdigits 0 = [0]
bdigits 1 = [1]
bdigits n | n>1 = n `mod` 2 :
-- arch-tag: a0d08cc2-4a81-4139-93bc-b3c6be0b5fb2

View file

@ -0,0 +1,106 @@
;;; haskell-cabal.el --- Support for Cabal packages
;; Copyright (C) 2007 Stefan Monnier
;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
;; 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 2, 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:
;; (defun haskell-cabal-extract-fields-from-doc ()
;; (require 'xml)
;; (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))
(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)))
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?
'(("^--.*" . font-lock-comment-face)
("^\\([^ :]+\\):" (1 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))
;;;###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))
(provide 'haskell-cabal)
;; arch-tag: d455f920-5e4d-42b6-a2c7-4a7e84a05c29
;;; haskell-cabal.el ends here

View file

@ -0,0 +1,695 @@
;;; haskell-decl-scan.el --- Declaration scanning module for Haskell Mode
;; Copyright (C) 2004, 2005 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 2, 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:
;;
;; 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:
;;
;; None available so far.
;;
;;
;; 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, and `func-menu' under XEmacs.
;;
;; 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.)
;;
;; . Inconsistency: we define the start of a declaration in `imenu' as
;; the start of the line the declaration starts on, but in
;; `func-menu' as the start of the name that the declaration is
;; given (eg. "class Eq a => Ord a ..." starts at "class" in `imenu'
;; but at "Ord" in `func-menu'). This avoids rescanning of the
;; buffer by the goto functions of `func-menu' but allows `imenu' to
;; have the better definition of the start of the declaration (IMO).
;;
;; . `func-menu' cannot cope well with spaces in declaration names.
;; This is unavoidable in "instance Eq Int" (changing the spaces to
;; underscores would cause rescans of the buffer). Note though that
;; `fume-prompt-function-goto' (usually bound to "C-c g") does cope
;; with spaces okay.
;;
;; . Would like to extend the goto functions given by `func-menu'
;; under XEmacs to Emacs. Would have to implement these
;; ourselves as `imenu' does not provide them.
;;
;; . `func-menu' uses its own syntax table when grabbing a declaration
;; name to lookup (why doesn't it use the syntax table of the
;; buffer?) so some declaration names will not be grabbed correctly,
;; eg. "fib'" will be grabbed as "fib" since "'" is not a word or
;; symbol constituent under the syntax table `func-menu' uses.
;; 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 'haskell-mode)
(defconst haskell-decl-scan-version "1.11"
"Version number of haskell-decl-scan.")
(defun haskell-decl-scan-version ()
"Echo the current version of haskell-decl-scan in the minibuffer."
(interactive)
(message "Using haskell-decl-scan version %s" haskell-decl-scan-version))
;;###autoload
;; As `cl' defines macros that `imenu' uses, we must require them at
;; compile time.
(eval-when-compile
(require 'cl)
(condition-case nil
(require 'imenu)
(error nil)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; General declaration scanning functions.
(defalias 'haskell-ds-match-string
(if (fboundp 'match-string-no-properties)
'match-string-no-properties
(lambda (num)
"As `match-string' except that the string is stripped of properties."
(format "%s" (match-string num)))))
(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_+\\))") (haskell-ds-match-string 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 (haskell-ds-match-string 2)))
;; Weed out `::', `=' and `|' from potential infix
;; symbolic variable.
(if (member match2 '("::" "=" "|"))
;; Variable identifier.
(haskell-ds-match-string 1)
(if (eq (aref match2 0) ?\`)
;; Infix variable identifier.
(haskell-ds-match-string 3)
;; Infix symbolic variable.
match2))))
;; Variable identifier.
(and (looking-at "\\sw+") (haskell-ds-match-string 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)))))
(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 (eq (get-text-property (point) 'face)
'font-lock-comment-face)))
(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 preceeding the current one.
(haskell-ds-move-to-start-regexp -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 1 start-decl-re))
;; If there is a variable, find the first
;; succeeding/preceeding declaration that does not type or
;; bind it. Check for reaching start/end of buffer.
(haskell-ds-move-to-start-regexp 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 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 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 point backward to the first character preceding the current
point 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 (progn (end-of-line) (point)))
(goto-char start)
(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 (haskell-ds-match-string 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 (haskell-ds-match-string 1))
(setq name-pos (match-beginning 1))
(setq type 'class))))
;; Import declaration.
((looking-at "import[ \t]+\\(qualified[ \t]+\\)?\\(\\sw+\\)")
(setq name (haskell-ds-match-string 2))
(setq name-pos (match-beginning 2))
(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 (format "%s"
(buffer-substring
(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'.
(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 (/ (point-max) 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) 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.
(alist (cond
((eq type 'variable) 'index-var-alist)
((eq type 'datatype) 'index-type-alist)
((eq type 'class) 'index-class-alist)
((eq type 'import) 'index-imp-alist)
((eq type 'instance) 'index-inst-alist))))
(set alist (cons (cons name start-pos) (eval alist))))))
;; Now sort all the lists, label them, and place them in one list.
(message "Sorting declarations in %s..." bufname)
(and index-type-alist
(push (cons "Datatypes"
(sort index-type-alist 'haskell-ds-imenu-label-cmp))
index-alist))
(and index-inst-alist
(push (cons "Instances"
(sort index-inst-alist 'haskell-ds-imenu-label-cmp))
index-alist))
(and index-imp-alist
(push (cons "Imports"
(sort index-imp-alist 'haskell-ds-imenu-label-cmp))
index-alist))
(and index-var-alist
(push (cons "Variables"
(sort index-var-alist 'haskell-ds-imenu-label-cmp))
index-alist))
(and index-class-alist
(push (cons "Classes"
(sort index-class-alist 'haskell-ds-imenu-label-cmp))
index-alist))
(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)
(if (fboundp 'imenu-add-to-menubar)
(imenu-add-to-menubar "Declarations")))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Declaration scanning via `func-menu'.
(defun haskell-ds-func-menu-next (buffer)
"Non-literate Haskell version of `haskell-ds-generic-func-menu-next'."
(haskell-ds-generic-func-menu-next (haskell-ds-bird-p) buffer))
(defun haskell-ds-generic-func-menu-next (bird-literate buffer)
"Return `(name . pos)' of next declaration."
(set-buffer buffer)
(let ((result (haskell-ds-generic-find-next-decl bird-literate)))
(if result
(let* ((name-posns (car result))
(name (car name-posns))
(posns (cdr name-posns))
(name-pos (cdr posns))
;;(type (cdr result))
)
(cons ;(concat
;; func-menu has problems with spaces, and adding a
;; qualifying keyword will not allow the "goto fn"
;; functions to work properly. Sigh.
;; (cond
;; ((eq type 'variable) "")
;; ((eq type 'datatype) "datatype ")
;; ((eq type 'class) "class ")
;; ((eq type 'import) "import ")
;; ((eq type 'instance) "instance "))
name;)
name-pos))
nil)))
(defvar haskell-ds-func-menu-regexp
(concat "^" haskell-ds-start-decl-re)
"Regexp to match the start of a possible declaration.")
(defvar literate-haskell-ds-func-menu-regexp
(concat "^" literate-haskell-ds-start-decl-re)
"As `haskell-ds-func-menu-regexp' but for Bird-style literate scripts.")
(defvar fume-menubar-menu-name)
(defvar fume-function-name-regexp-alist)
(defvar fume-find-function-name-method-alist)
(defun haskell-ds-func-menu ()
"Use `func-menu' to establish declaration scanning for Haskell scripts."
(require 'func-menu)
(set (make-local-variable 'fume-menubar-menu-name) "Declarations")
(set (make-local-variable 'fume-function-name-regexp-alist)
(if (haskell-ds-bird-p)
'((haskell-mode . literate-haskell-ds-func-menu-regexp))
'((haskell-mode . haskell-ds-func-menu-regexp))))
(set (make-local-variable 'fume-find-function-name-method-alist)
'((haskell-mode . haskell-ds-func-menu-next)))
(fume-add-menubar-entry)
(local-set-key "\C-cl" 'fume-list-functions)
(local-set-key "\C-cg" 'fume-prompt-function-goto)
(local-set-key [(meta button1)] 'fume-mouse-function-goto))
;; The main functions to turn on declaration scanning.
(defun turn-on-haskell-decl-scan ()
"Unconditionally activate `haskell-decl-scan-mode'."
(haskell-decl-scan-mode 1))
(defvar haskell-decl-scan-mode nil)
(make-variable-buffer-local 'haskell-decl-scan-mode)
;;;###autoload
(defun haskell-decl-scan-mode (&optional arg)
"Minor mode for declaration scanning for Haskell mode.
Top-level declarations are scanned and listed in the menu item \"Declarations\".
Selecting an item from this menu will take point to the start of the
declaration.
\\[haskell-ds-forward-decl] and \\[haskell-ds-backward-decl] move forward and backward to the start of a declaration.
Under XEmacs, the following keys are also defined:
\\[fume-list-functions] lists the declarations of the current buffer,
\\[fume-prompt-function-goto] prompts for a declaration to move to, and
\\[fume-mouse-function-goto] moves to the declaration whose name is at point.
This may link with `haskell-doc' (only for Emacs currently).
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.
To turn on declaration scanning for all Haskell buffers, add this to
.emacs:
(add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan)
To turn declaration scanning on for the current buffer, call
`turn-on-haskell-decl-scan'.
Literate Haskell scripts are supported: If the value of
`haskell-literate' (automatically set by the Haskell mode of
Moss&Thorn) is 'bird, a Bird-style literate script is assumed. If it
is nil or 'latex, a non-literate or LaTeX-style literate script is
assumed, respectively.
Invokes `haskell-decl-scan-hook' if not nil.
Use `haskell-decl-scan-version' to find out what version this is."
(if (boundp 'beginning-of-defun-function)
(if haskell-decl-scan-mode
(progn
(set (make-local-variable 'beginning-of-defun-function)
'haskell-ds-backward-decl)
(set (make-local-variable 'end-of-defun-function)
'haskell-ds-forward-decl))
(kill-local-variable 'beginning-of-defun-function)
(kill-local-variable 'end-of-defun-function))
(local-set-key "\M-\C-e"
(if haskell-decl-scan-mode 'haskell-ds-forward-decl))
(local-set-key "\M-\C-a"
(if haskell-decl-scan-mode 'haskell-ds-backward-decl)))
(if haskell-decl-scan-mode
(if (fboundp 'imenu)
(haskell-ds-imenu)
(haskell-ds-func-menu))
;; How can we cleanly remove that menus?
(local-set-key [menu-bar index] nil))
(run-hooks 'haskell-decl-scan-mode-hook))
;; Provide ourselves:
(provide 'haskell-decl-scan)
;; arch-tag: f4335fd8-4b6c-472e-9899-004d47d94818
;;; haskell-decl-scan.el ends here

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,554 @@
;;; haskell-font-lock.el --- Font locking module for Haskell Mode
;; Copyright 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
;; Copyright 1997-1998 Graeme E Moss, and Tommy Thorn
;; Authors: 1997-1998 Graeme E Moss <gem@cs.york.ac.uk> and
;; 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 2, 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 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.
;;
;;
;; History:
;;
;; If you have any problems or suggestions, after consulting the list
;; below, email gem@cs.york.ac.uk and thorn@irisa.fr quoting the
;; version of the mode you are using, the version of Emacs you are
;; using, and a small example of the problem or suggestion. Note that
;; this module requires a reasonably recent version of Emacs. It
;; requires Emacs 21 to cope with Unicode characters and to do proper
;; syntactic fontification.
;;
;; 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.
;;
;; 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-'.
;;; Code:
(eval-when-compile
(require 'haskell-mode)
(require 'cl))
(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))))
;; 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 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))
(cons "." (decode-char 'ucs 9675))))))
;; Use new vars for the font-lock faces. The indirection allows people to
;; use different faces than in other modes, as before.
(defvar haskell-keyword-face 'font-lock-keyword-face)
(defvar haskell-constructor-face 'font-lock-type-face)
;; 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).
(defvar haskell-definition-face 'font-lock-function-name-face)
;; 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'.
(defvar haskell-operator-face 'font-lock-variable-name-face)
(defvar haskell-default-face nil)
(defvar haskell-literate-comment-face 'font-lock-doc-face
"Face with which to fontify literate comments.
Set to `default' to avoid fontification of them.")
(defconst haskell-emacs21-features (string-match "[[:alpha:]]" "x")
"Non-nil if we have regexp char classes.
Assume this means we have other useful features from Emacs 21.")
(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 '(?_ ?\\)))))
(if (or (memq (char-syntax (or (char-before start) ?\ )) syntaxes)
(memq (char-syntax (or (char-after end) ?\ )) syntaxes)
(memq (get-text-property start 'face)
'(font-lock-doc-face font-lock-string-face
font-lock-comment-face)))
;; 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 (cdr (assoc (match-string 0) alist)))))
;; 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 (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)))))))
;; 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.
;; (ISOsymbol "\241-\277\327\367")
(ISOlarge "\300-\326\330-\337")
(ISOsmall "\340-\366\370-\377")
(small
(if haskell-emacs21-features "[:lower:]" (concat "a-z" ISOsmall)))
(large
(if haskell-emacs21-features "[:upper:]" (concat "A-Z" ISOlarge)))
(alnum
(if haskell-emacs21-features "[:alnum:]" (concat small large "0-9")))
;; (symbol
;; (concat ASCsymbol ISOsymbol))
;; We allow _ as the first char to fit GHC
(varid (concat "\\b[" small "_][" alnum "'_]*\\b"))
(conid (concat "\\b[" large "][" 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\\|newtype\\|of\\|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-*\\("
;; A toplevel declaration can be followed by a definition
;; (=), a type (::), 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-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)
,@(unless haskell-emacs21-features ;Supports nested comments?
;; Expensive.
`((,string-and-char 1 font-lock-string-face)))
;; This was originally at the very end (and needs to be after
;; all the comment/string/doc highlighting) but it seemed to
;; trigger a bug in Emacs-21.3 which caused the compositions to
;; be "randomly" dropped. Moving it earlier seemed to reduce
;; the occurrence of the bug.
,@(haskell-font-lock-symbols-keywords)
(,reservedid 1 (symbol-value 'haskell-keyword-face))
(,reservedsym 1 (symbol-value 'haskell-operator-face))
;; Special case for `as', `hiding', and `qualified', which are
;; keywords in import statements but are not otherwise reserved.
("\\<import[ \t]+\\(?:\\(qualified\\>\\)[ \t]*\\)?[^ \t\n()]+[ \t]*\\(?:\\(\\<as\\>\\)[ \t]*[^ \t\n()]+[ \t]*\\)?\\(\\<hiding\\>\\)?"
(1 (symbol-value 'haskell-keyword-face) nil lax)
(2 (symbol-value 'haskell-keyword-face) nil lax)
(3 (symbol-value 'haskell-keyword-face) nil lax))
;; Toplevel Declarations.
;; Place them *before* generic id-and-op highlighting.
(,topdecl-var (1 (symbol-value 'haskell-definition-face)))
(,topdecl-var2 (2 (symbol-value 'haskell-definition-face)))
(,topdecl-sym (2 (symbol-value 'haskell-definition-face)))
(,topdecl-sym2 (1 (symbol-value 'haskell-definition-face)))
;; These four are debatable...
("(\\(,*\\|->\\))" 0 (symbol-value 'haskell-constructor-face))
("\\[\\]" 0 (symbol-value 'haskell-constructor-face))
;; Expensive.
(,qvarid 0 haskell-default-face)
(,qconid 0 (symbol-value 'haskell-constructor-face))
(,(concat "\`" varid "\`") 0 (symbol-value 'haskell-operator-face))
;; Expensive.
(,conid 0 (symbol-value 'haskell-constructor-face))
;; Very expensive.
(,sym 0 (if (eq (char-after (match-beginning 0)) ?:)
haskell-constructor-face
haskell-operator-face))))
(unless (boundp 'font-lock-syntactic-keywords)
(case literate
(bird
(setq keywords
`(("^[^>\n].*$" 0 haskell-comment-face t)
,@keywords
("^>" 0 haskell-default-face t))))
(latex
(setq keywords
`((haskell-fl-latex-comments 0 'font-lock-comment-face t)
,@keywords)))))
keywords))
;; The next three aren't used in Emacs 21.
(defvar haskell-fl-latex-cache-pos nil
"Position of cache point used by `haskell-fl-latex-cache-in-comment'.
Should be at the start of a line.")
(defvar haskell-fl-latex-cache-in-comment nil
"If `haskell-fl-latex-cache-pos' is outside a
\\begin{code}..\\end{code} block (and therefore inside a comment),
this variable is set to t, otherwise nil.")
(defun haskell-fl-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-fl-latex-cache-pos))
;; If the start position is not cached, calculate the state
;; of the start.
(progn
(setq haskell-fl-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-fl-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-fl-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 (if (string-match "\\`-*\\'" (match-string 0))
;; Sequence of hyphens. Do nothing in
;; case of things like `{---'.
nil
"_"))))) ; 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))
(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)
(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.")
(defun haskell-font-lock-choose-keywords ()
(let ((literate (if (boundp 'haskell-literate) haskell-literate)))
(case literate
(bird haskell-font-lock-bird-literate-keywords)
(latex 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)))
(case literate
(bird haskell-bird-syntactic-keywords)
(latex 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))
;; Provide ourselves:
(provide 'haskell-font-lock)
;; arch-tag: 89fd122e-8378-4c7f-83a3-1f49a64e458d
;;; haskell-font-lock.el ends here

View file

@ -0,0 +1,332 @@
;;; haskell-ghci.el --- A GHCi interaction mode
;; Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
;; Copyright (C) 2001 Chris Webb
;; Copyright (C) 1998, 1999 Guy Lapalme
;; Keywords: inferior mode, GHCi 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 2, 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 GHCi
;; 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-ghci)
;;
;;
;; Customisation:
;;
;; The name of the GHCi interpreter is in haskell-ghci-program-name.
;;
;; Arguments can be sent to the GHCi interpreter when it is started by
;; setting haskell-ghci-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-ghci-hook' is invoked in the *ghci* buffer once GHCi is
;; started.
;;
;; All functions/variables start with `turn-{on,off}-haskell-ghci' or
;; `haskell-ghci-'.
;;; Code:
(defgroup haskell-ghci nil
"Major mode for interacting with an inferior GHCi session."
:group 'haskell
:prefix "haskell-ghci-")
(defun turn-on-haskell-ghci ()
"Turn on Haskell interaction mode with a GHCi interpreter running in an
another Emacs buffer named *ghci*.
Maps the following commands in the haskell keymap:
\\<haskell-mode-map>\\[haskell-ghci-start-process] to create the GHCi buffer and start a GHCi process in it.
\\[haskell-ghci-load-file] to save the current buffer and load it by sending the :load command to GHCi.
\\[haskell-ghci-reload-file] to send the :reload command to GHCi without saving the buffer.
\\[haskell-ghci-show-ghci-buffer] to show the GHCi buffer and go to it."
(local-set-key "\C-c\C-s" 'haskell-ghci-start-process)
(local-set-key "\C-c\C-l" 'haskell-ghci-load-file)
(local-set-key "\C-c\C-r" 'haskell-ghci-reload-file)
(local-set-key "\C-c\C-n" 'haskell-ghci-locate-next-error)
(local-set-key "\C-c\C-b" 'haskell-ghci-show-ghci-buffer))
(defun turn-off-haskell-ghci ()
"Turn off Haskell interaction mode with a GHCi interpreter within a buffer."
(local-unset-key "\C-c\C-s")
(local-unset-key "\C-c\C-l")
(local-unset-key "\C-c\C-r")
(local-unset-key "\C-c\C-b"))
(define-derived-mode haskell-ghci-mode comint-mode "Haskell GHCi"
"Major mode for interacting with an inferior GHCi session.
The commands available from within a Haskell script are:
\\<haskell-mode-map>\\[haskell-ghci-start-process] to create the GHCi buffer and start a GHCi process in it.
\\[haskell-ghci-load-file] to save the current buffer and load it by sending the :load command to GHCi.
\\[haskell-ghci-reload-file] to send the :reload command to GHCi without saving the buffer.
\\[haskell-ghci-show-ghci-buffer] to show the GHCi buffer and go to it.
\\<haskell-ghci-mode-map>Commands:
\\[comint-send-input] after end of GHCi output sends line as input to GHCi.
\\[comint-send-input] before end of GHCI output copies rest of line and sends it to GHCI as input.
\\[comint-kill-input] and \\[backward-kill-word] are kill commands, imitating normal Unix input editing.
\\[comint-interrupt-subjob] interrupts the comint or its current subjob if any.
\\[comint-stop-subjob] stops, likewise. \\[comint-quit-subjob] sends quit signal.")
;; GHCi interface:
(require 'comint)
(require 'shell)
(defvar haskell-ghci-process nil
"The active GHCi subprocess corresponding to current buffer.")
(defvar haskell-ghci-process-buffer nil
"*Buffer used for communication with GHCi subprocess for current buffer.")
(defcustom haskell-ghci-program-name "ghci"
"*The name of the GHCi interpreter program."
:type 'string
:group 'haskell-ghci)
(defcustom haskell-ghci-program-args nil
"*A list of string args to pass when starting the GHCi interpreter."
:type '(repeat string)
:group 'haskell-ghci)
(defvar haskell-ghci-load-end nil
"Position of the end of the last load command.")
(defvar haskell-ghci-error-pos nil
"Position of the end of the last load command.")
(defvar haskell-ghci-send-end nil
"Position of the end of the last send command.")
(defun haskell-ghci-start-process (arg)
"Start a GHCi process and invoke `haskell-ghci-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-ghci-program-args
(read-minibuffer (format "List of args for %s:"
haskell-ghci-program-name)
(prin1-to-string haskell-ghci-program-args))))
;; Start the GHCi process in a new comint buffer.
(message "Starting GHCi process `%s'." haskell-ghci-program-name)
(setq haskell-ghci-process-buffer
(apply 'make-comint
"ghci" haskell-ghci-program-name nil
haskell-ghci-program-args))
(setq haskell-ghci-process
(get-buffer-process haskell-ghci-process-buffer))
;; Select GHCi buffer temporarily.
(set-buffer haskell-ghci-process-buffer)
(haskell-ghci-mode)
(make-local-variable 'shell-cd-regexp)
(make-local-variable 'shell-dirtrackp)
;; Track directory changes using the `:cd' command.
(setq shell-cd-regexp ":cd")
(setq shell-dirtrackp t)
(add-hook 'comint-input-filter-functions 'shell-directory-tracker nil 'local)
;; GHCi prompt should be of the form `ModuleName> '.
(setq comint-prompt-regexp "^\\*?[A-Z][\\._a-zA-Z0-9]*\\( \\*?[A-Z][\\._a-zA-Z0-9]*\\)*> ")
;; History syntax of comint conflicts with Haskell, e.g. !!, so better
;; turn it off.
(setq comint-input-autoexpand nil)
(run-hooks 'haskell-ghci-hook)
;; Clear message area.
(message ""))
(defun haskell-ghci-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-ghci-process)))
(defun haskell-ghci-send (&rest string)
"Send `haskell-ghci-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-ghci-wait-for-output) ; wait for prompt
(goto-char (point-max)) ; position for this input
(apply 'insert string)
(comint-send-input)
(setq haskell-ghci-send-end (marker-position comint-last-input-end)))
(defun haskell-ghci-go (load-command cd)
"Save the current buffer and load its file into the GHCi process.
The first argument LOAD-COMMAND specifies how the file should be
loaded: as a new file (\":load \") or as a reload (\":reload \").
If the second argument CD is non-nil, change directory in the GHCi
process to the current buffer's directory before loading the file.
If the variable `haskell-ghci-command' is set then its value will be
sent to the GHCi process after the load command. This can be used for a
top-level expression to evaluate."
(hack-local-variables) ; in case they've changed
(save-buffer)
(let ((file (if (string-equal load-command ":load ")
(concat "\"" buffer-file-name "\"")
""))
(dir (expand-file-name default-directory))
(cmd (and (boundp 'haskell-ghci-command)
haskell-ghci-command
(if (stringp haskell-ghci-command)
haskell-ghci-command
(symbol-name haskell-ghci-command)))))
(if (and haskell-ghci-process-buffer
(eq (process-status haskell-ghci-process) 'run))
;; Ensure the GHCi buffer is selected.
(set-buffer haskell-ghci-process-buffer)
;; Start Haskell-GHCi process.
(haskell-ghci-start-process nil))
(if cd (haskell-ghci-send (concat ":cd " dir)))
;; Wait until output arrives and go to the last input.
(haskell-ghci-wait-for-output)
(haskell-ghci-send load-command file)
;; Error message search starts from last load command.
(setq haskell-ghci-load-end (marker-position comint-last-input-end))
(setq haskell-ghci-error-pos haskell-ghci-load-end)
(if cmd (haskell-ghci-send cmd))
;; Wait until output arrives and go to the last input.
(haskell-ghci-wait-for-output)))
(defun haskell-ghci-load-file (cd)
"Save a ghci buffer file and load its file.
If CD (prefix argument if interactive) is non-nil, change directory in
the GHCi process to the current buffer's directory before loading the
file. If there is an error, set the cursor at the error line otherwise
show the *ghci* buffer."
(interactive "P")
(haskell-ghci-gen-load-file ":load " cd))
(defun haskell-ghci-reload-file (cd)
"Save a ghci buffer file and load its file.
If CD (prefix argument if interactive) is non-nil, change the GHCi
process to the current buffer's directory before loading the file.
If there is an error, set the cursor at the error line otherwise show
the *ghci* buffer."
(interactive "P")
(haskell-ghci-gen-load-file ":reload " cd))
(defun haskell-ghci-gen-load-file (cmd cd)
"Save a ghci buffer file and load its file or reload depending on CMD.
If CD is non-nil, change the process to the current buffer's directory
before loading the file. If there is an error, set the cursor at the
error line otherwise show the *ghci* buffer."
;; Execute (re)load command.
(save-excursion (haskell-ghci-go cmd cd))
;; Show *ghci* buffer.
(pop-to-buffer haskell-ghci-process-buffer)
(goto-char haskell-ghci-load-end)
;; Did we finish loading without error?
(if (re-search-forward
"^Ok, modules loaded" nil t)
(progn (goto-char (point-max))
(recenter 2)
(message "There were no errors."))
;; Something went wrong. If possible, be helpful and pinpoint the
;; first error in the file whilst leaving the error visible in the
;; *ghci* buffer.
(goto-char haskell-ghci-load-end)
(haskell-ghci-locate-next-error)))
(defun haskell-ghci-locate-next-error ()
"Go to the next error shown in the *ghci* buffer."
(interactive)
(if (buffer-live-p haskell-ghci-process-buffer)
(progn (pop-to-buffer haskell-ghci-process-buffer)
(goto-char haskell-ghci-error-pos)
(if (re-search-forward
"^[^\/]*\\([^:\n]+\\):\\([0-9]+\\)" nil t)
(let ((efile (buffer-substring (match-beginning 1)
(match-end 1)))
(eline (string-to-int
(buffer-substring (match-beginning 2)
(match-end 2)))))
(recenter 2)
(setq haskell-ghci-error-pos (point))
(message "GHCi error on line %d of %s."
eline (file-name-nondirectory efile))
(if (file-exists-p efile)
(progn (find-file-other-window efile)
(goto-line eline)
(recenter))))
;; We got an error without a file and line number, so put the
;; point at end of the *ghci* buffer ready to deal with it.
(goto-char (point-max))
(recenter -2)
(message "No more errors found.")))
(message "No *ghci* buffer found.")))
(defun haskell-ghci-show-ghci-buffer ()
"Go to the *ghci* buffer."
(interactive)
(if (or (not haskell-ghci-process-buffer)
(not (buffer-live-p haskell-ghci-process-buffer)))
(haskell-ghci-start-process nil))
(pop-to-buffer haskell-ghci-process-buffer))
(provide 'haskell-ghci)
;; arch-tag: f0bade4b-288d-4329-9791-98c1e24167ac
;;; haskell-ghci.el ends here

View file

@ -0,0 +1,316 @@
;;; haskell-hugs.el --- simplistic interaction mode with a
;; Copyright 2004, 2005, 2006 Free Software Foundation, Inc.
;; Copyright 1998, 1999 Guy Lapalme
;; Hugs interpreter for Haskell developped by
;; The University of Nottingham and Yale University, 1994-1997.
;; Web: http://www.haskell.org/hugs.
;; In standard Emacs terminology, this would be called
;; inferior-hugs-mode
;; Keywords: Hugs inferior mode, Hugs interaction mode
;; URL: http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/CONTRIB/haskell-modes/emacs/haskell-hugs.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 2, 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 Hugs interpreter
;; The functions are adapted from the Hugs Mode developed by
;; Chris Van Humbeeck <chris.vanhumbeeck@cs.kuleuven.ac.be>
;; which used to be available at:
;; http://www-i2.informatik.rwth-aachen.de/Forschung/FP/Haskell/hugs-mode.el
;;
;; Installation:
;;
;; To use with the Haskell mode of
;; Moss&Thorn <http://www.haskell.org/haskell-mode>
;; add this to .emacs:
;;
;; (add-hook haskell-mode-hook 'turn-on-haskell-hugs)
;;
;; Customisation:
;; The name of the hugs interpreter is in variable
;; haskell-hugs-program-name
;; Arguments can be sent to the Hugs interpreter when it is called
;; by setting the value of the variable
;; haskell-hugs-program-args
;; which by default contains '("+.") so that the progress of the
;; interpreter is visible without any "^H" in the *hugs* Emacs buffer.
;;
;; This value can be interactively by calling C-cC-s with an
;; argument.
;;
;; If the command does not seem to respond, see the
;; content of the `comint-prompt-regexp' variable
;; to check that it waits for the appropriate Hugs prompt
;; the current value is appropriate for Hugs 1.3 and 1.4
;;
;;
;; `haskell-hugs-hook' is invoked in the *hugs* once it is started.
;;
;;; All functions/variables start with
;;; `(turn-(on/off)-)haskell-hugs' or `haskell-hugs-'.
(defgroup haskell-hugs nil
"Major mode for interacting with an inferior Hugs session."
:group 'haskell
:prefix "haskell-hugs-")
(defun turn-on-haskell-hugs ()
"Turn on Haskell interaction mode with a Hugs interpreter running in an
another Emacs buffer named *hugs*.
Maps the followind commands in the haskell keymap.
\\[haskell-hugs-load-file]
to save the current buffer and load it by sending the :load command
to Hugs.
\\[haskell-hugs-reload-file]
to send the :reload command to Hugs without saving the buffer.
\\[haskell-hugs-show-hugs-buffer]
to show the Hugs buffer and go to it."
(local-set-key "\C-c\C-s" 'haskell-hugs-start-process)
(local-set-key "\C-c\C-l" 'haskell-hugs-load-file)
(local-set-key "\C-c\C-r" 'haskell-hugs-reload-file)
(local-set-key "\C-c\C-b" 'haskell-hugs-show-hugs-buffer))
(defun turn-off-haskell-hugs ()
"Turn off Haskell interaction mode with a Hugs interpreter within a buffer."
(local-unset-key "\C-c\C-s")
(local-unset-key "\C-c\C-l")
(local-unset-key "\C-c\C-r")
(local-unset-key "\C-c\C-b"))
(define-derived-mode haskell-hugs-mode comint-mode "Haskell Hugs"
;; called by haskell-hugs-start-process,
;; itself called by haskell-hugs-load-file
;; only when the file is loaded the first time
"Major mode for interacting with an inferior Hugs session.
The commands available from within a Haskell script are:
\\<haskell-mode-map>\\[haskell-hugs-load-file]
to save the current buffer and load it by sending the :load command
to Hugs.
\\[haskell-hugs-reload-file]
to send the :reload command to Hugs without saving the buffer.
\\[haskell-hugs-show-hugs-buffer]
to show the Hugs buffer and go to it.
\\<haskell-hugs-mode-map>
Commands:
Return at end of buffer sends line as input.
Return not at end copies rest of line to end and sends it.
\\[comint-kill-input] and \\[backward-kill-word] are kill commands,
imitating normal Unix input editing.
\\[comint-interrupt-subjob] interrupts the comint or its current
subjob if any.
\\[comint-stop-subjob] stops, likewise.
\\[comint-quit-subjob] sends quit signal."
)
;; Hugs-interface
(require 'comint)
(require 'shell)
(defvar haskell-hugs-process nil
"The active Hugs subprocess corresponding to current buffer.")
(defvar haskell-hugs-process-buffer nil
"*Buffer used for communication with Hugs subprocess for current buffer.")
(defcustom haskell-hugs-program-name "hugs"
"*The name of the command to start the Hugs interpreter."
:type 'string
:group 'haskell-hugs)
(defcustom haskell-hugs-program-args '("+.")
"*A list of string args to send to the hugs process."
:type '(repeat string)
:group 'haskell-hugs)
(defvar haskell-hugs-load-end nil
"Position of the end of the last load command.")
(defvar haskell-hugs-send-end nil
"Position of the end of the last send command.")
(defalias 'run-hugs 'haskell-hugs-start-process)
(defun haskell-hugs-start-process (arg)
"Start a Hugs process and invokes `haskell-hugs-hook' if not nil.
Prompts for a list of args if called with an argument."
(interactive "P")
(message "Starting `hugs-process' %s" haskell-hugs-program-name)
(if arg
(setq haskell-hugs-program-args
(read-minibuffer "List of args for Hugs:"
(prin1-to-string haskell-hugs-program-args))))
(setq haskell-hugs-process-buffer
(apply 'make-comint
"hugs" haskell-hugs-program-name nil
haskell-hugs-program-args))
(setq haskell-hugs-process
(get-buffer-process haskell-hugs-process-buffer))
;; Select Hugs buffer temporarily
(set-buffer haskell-hugs-process-buffer)
(haskell-hugs-mode)
(make-local-variable 'shell-cd-regexp)
(make-local-variable 'shell-dirtrackp)
(setq shell-cd-regexp ":cd")
(setq shell-dirtrackp t)
(add-hook 'comint-input-filter-functions 'shell-directory-tracker nil 'local)
; ? or module name in Hugs 1.4
(setq comint-prompt-regexp "^\? \\|^[A-Z][_a-zA-Z0-9\.]*> ")
;; comint's history syntax conflicts with Hugs syntax, eg. !!
(setq comint-input-autoexpand nil)
(run-hooks 'haskell-hugs-hook)
(message "")
)
(defun haskell-hugs-wait-for-output ()
"Wait until output arrives and go to the last input."
(while (progn
(goto-char comint-last-input-end)
(and
(not (re-search-forward comint-prompt-regexp nil t))
(accept-process-output haskell-hugs-process)))))
(defun haskell-hugs-send (&rest string)
"Send `haskell-hugs-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."
;; Wait until output arrives and go to the last input.
(haskell-hugs-wait-for-output)
;; Position for this input.
(goto-char (point-max))
(apply 'insert string)
(comint-send-input)
(setq haskell-hugs-send-end (marker-position comint-last-input-end)))
(defun haskell-hugs-go (load-command cd)
"Save the current buffer and load its file into the Hugs process.
The first argument LOAD-COMMAND specifies how the file should be
loaded: as a new file (\":load \") or as a reload (\":reload \").
If the second argument CD is non-nil, change the Haskell-Hugs process to the
current buffer's directory before loading the file.
If the variable `haskell-hugs-command' is set then its value will be sent to
the Hugs process after the load command. This can be used for a
top-level expression to evaluate."
(hack-local-variables) ;; In case they've changed
(save-buffer)
(let ((file (if (string-equal load-command ":load ")
(concat "\"" buffer-file-name "\"")
""))
(dir (expand-file-name default-directory))
(cmd (and (boundp 'haskell-hugs-command)
haskell-hugs-command
(if (stringp haskell-hugs-command)
haskell-hugs-command
(symbol-name haskell-hugs-command)))))
(if (and haskell-hugs-process-buffer
(eq (process-status haskell-hugs-process) 'run))
;; Ensure the Hugs buffer is selected.
(set-buffer haskell-hugs-process-buffer)
;; Start Haskell-Hugs process.
(haskell-hugs-start-process nil))
(if cd (haskell-hugs-send (concat ":cd " dir)))
;; Wait until output arrives and go to the last input.
(haskell-hugs-wait-for-output)
(haskell-hugs-send load-command file)
;; Error message search starts from last load command.
(setq haskell-hugs-load-end (marker-position comint-last-input-end))
(if cmd (haskell-hugs-send cmd))
;; Wait until output arrives and go to the last input.
(haskell-hugs-wait-for-output)))
(defun haskell-hugs-load-file (cd)
"Save a hugs buffer file and load its file.
If CD (prefix argument if interactive) is non-nil, change the Hugs
process to the current buffer's directory before loading the file.
If there is an error, set the cursor at the error line otherwise show
the Hugs buffer."
(interactive "P")
(haskell-hugs-gen-load-file ":load " cd)
)
(defun haskell-hugs-reload-file (cd)
"Save a hugs buffer file and load its file.
If CD (prefix argument if interactive) is non-nil, change the Hugs
process to the current buffer's directory before loading the file.
If there is an error, set the cursor at the error line otherwise show
the Hugs buffer."
(interactive "P")
(haskell-hugs-gen-load-file ":reload " cd)
)
(defun haskell-hugs-gen-load-file (cmd cd)
"Save a hugs buffer file and load its file or reload depending on CMD.
If CD is non-nil, change the process to the current buffer's directory
before loading the file. If there is an error, set the cursor at the
error line otherwise show the Hugs buffer."
(save-excursion (haskell-hugs-go cmd cd))
;; Ensure the Hugs buffer is selected.
(set-buffer haskell-hugs-process-buffer)
;; Error message search starts from last load command.
(goto-char haskell-hugs-load-end)
(if (re-search-forward
"^ERROR \"\\([^ ]*\\)\"\\( (line \\([0-9]*\\))\\|\\)" nil t)
(let ((efile (buffer-substring (match-beginning 1)
(match-end 1)))
(eline (if (match-beginning 3)
(string-to-int (buffer-substring (match-beginning 3)
(match-end 3)))))
(emesg (buffer-substring (1+ (point))
(save-excursion (end-of-line) (point)))))
(pop-to-buffer haskell-hugs-process-buffer) ; show *hugs* buffer
(goto-char (point-max))
(recenter)
(message "Hugs error %s %s"
(file-name-nondirectory efile) emesg)
(if (file-exists-p efile)
(progn (find-file-other-window efile)
(if eline (goto-line eline))
(recenter)))
)
(pop-to-buffer haskell-hugs-process-buffer) ; show *hugs* buffer
(goto-char (point-max))
(message "There were no errors.")
(recenter 2) ; show only the end...
)
)
(defun haskell-hugs-show-hugs-buffer ()
"Goes to the Hugs buffer."
(interactive)
(if (or (not haskell-hugs-process-buffer)
(not (buffer-live-p haskell-hugs-process-buffer)))
(haskell-hugs-start-process nil))
(pop-to-buffer haskell-hugs-process-buffer)
)
(provide 'haskell-hugs)
;; arch-tag: c2a621e9-d743-4361-a459-983fbf1d4589
;;; haskell-hugs.el ends here

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,483 @@
;;; haskell-mode.el --- A Haskell editing mode -*-coding: iso-8859-1;-*-
;; Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc
;; Copyright (C) 1992, 1997-1998 Simon Marlow, Graeme E Moss, and Tommy Thorn
;; Authors: 1992 Simon Marlow
;; 1997-1998 Graeme E Moss <gem@cs.york.ac.uk> and
;; Tommy Thorn <thorn@irisa.fr>,
;; 2001-2002 Reuben Thomas (>=v1.4)
;; 2003 Dave Love <fx@gnu.org>
;; Keywords: faces files Haskell
;; Version: v2_3
;; URL: http://www.haskell.org/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 2, 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 provide a pleasant mode to browse and edit Haskell files, linking
;; into the following supported modules:
;;
;; `haskell-font-lock', Graeme E Moss and Tommy Thorn
;; Fontifies standard Haskell keywords, symbols, functions, etc.
;;
;; `haskell-decl-scan', Graeme E Moss
;; Scans top-level declarations, and places them in a menu.
;;
;; `haskell-doc', Hans-Wolfgang Loidl
;; Echoes types of functions or syntax of keywords when the cursor is idle.
;;
;; `haskell-indent', Guy Lapalme
;; Intelligent semi-automatic indentation.
;;
;; `haskell-simple-indent', Graeme E Moss and Heribert Schuetz
;; Simple indentation.
;;
;; `inf-haskell'
;; Interaction with an inferior Haskell process.
;; It replaces the previous two modules:
;; `haskell-hugs', Guy Lapalme
;; `haskell-ghci', Chris Web
;;
;;
;; This mode supports full Haskell 1.4 including literate scripts.
;; In some versions of (X)Emacs it may only support Latin-1, not Unicode.
;;
;; Installation:
;;
;; Put in your ~/.emacs:
;;
;; (setq auto-mode-alist
;; (append auto-mode-alist
;; '(("\\.[hg]s$" . haskell-mode)
;; ("\\.hi$" . haskell-mode)
;; ("\\.l[hg]s$" . literate-haskell-mode))))
;;
;; (autoload 'haskell-mode "haskell-mode"
;; "Major mode for editing Haskell scripts." t)
;; (autoload 'literate-haskell-mode "haskell-mode"
;; "Major mode for editing literate Haskell scripts." t)
;;
;; with `haskell-mode.el' accessible somewhere on the load-path.
;; To add a directory `~/lib/emacs' (for example) to the load-path,
;; add the following to .emacs:
;;
;; (setq load-path (cons "~/lib/emacs" load-path))
;;
;; To turn any of the supported modules on for all buffers, add the
;; appropriate line(s) to .emacs:
;;
;; (add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan)
;; (add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
;; (add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
;; (add-hook 'haskell-mode-hook 'turn-on-haskell-simple-indent)
;;
;; Make sure the module files are also on the load-path. Note that
;; the two indentation modules are mutually exclusive: Use only one.
;;
;;
;; Customisation:
;;
;; Set the value of `haskell-literate-default' to your preferred
;; literate style: 'bird or 'latex, within .emacs as follows:
;;
;; (setq haskell-literate-default 'latex)
;;
;; Also see the customisations of the modules.
;;
;;
;; History:
;;
;; This mode is based on an editing mode by Simon Marlow 11/1/92
;; and heavily modified by Graeme E Moss and Tommy Thorn 7/11/98.
;;
;; If you have any problems or suggestions specific to a supported
;; module, consult that module for a list of known bugs, and an
;; author to contact via email. For general problems or suggestions,
;; consult the list below, then email gem@cs.york.ac.uk and
;; thorn@irisa.fr quoting the version of the mode you are using, the
;; version of Emacs you are using, and a small example of the problem
;; or suggestion.
;;
;; Version 1.43:
;; Various tweaks to doc strings and customization support from
;; Ville Skyttä <scop@xemacs.org>.
;;
;; Version 1.42:
;; Added autoload for GHCi inferior mode (thanks to Scott
;; Williams for the bug report and fix).
;;
;; Version 1.41:
;; Improved packaging, and made a couple more variables
;; interactively settable.
;;
;; Version 1.4:
;; Added GHCi mode from Chris Webb, and tidied up a little.
;;
;; Version 1.3:
;; The literate or non-literate style of a buffer is now indicated
;; by just the variable haskell-literate: nil, 'bird, or 'latex.
;; For literate buffers with ambiguous style, the value of
;; haskell-literate-default is used.
;;
;; Version 1.2:
;; Separated off font locking, declaration scanning and simple
;; indentation, and made them separate modules. Modules can be
;; added easily now. Support for modules haskell-doc,
;; haskell-indent, and haskell-hugs. Literate and non-literate
;; modes integrated into one mode, and literate buffer indicated by
;; value of haskell-literate(-bird-style).
;;
;; Version 1.1:
;; Added support for declaration scanning under XEmacs via
;; func-menu. Moved operators to level two fontification.
;;
;; Version 1.0:
;; Added a nice indention support from Heribert Schuetz
;; <Heribert.Schuetz@informatik.uni-muenchen.de>:
;;
;; I have just hacked an Emacs Lisp function which you might prefer
;; to `indent-relative' in haskell-mode.el. See below. It is not
;; really Haskell-specific because it does not take into account
;; keywords like `do', `of', and `let' (where the layout rule
;; applies), but I already find it useful.
;;
;; Cleaned up the imenu support. Added support for literate scripts.
;;
;; Version 0.103 [HWL]:
;; From Hans Wolfgang Loidl <hwloidl@dcs.gla.ac.uk>:
;;
;; I (HWL) added imenu support by copying the appropriate functions
;; from hugs-mode. A menu-bar item "Declarations" is now added in
;; haskell mode. The new code, however, needs some clean-up.
;;
;; Version 0.102:
;;
;; Moved C-c C-c key binding to comment-region. Leave M-g M-g to do
;; the work. comment-start-skip is changed to comply with comment-start.
;;
;; Version 0.101:
;;
;; Altered indent-line-function to indent-relative.
;;
;; Version 0.100:
;;
;; First official release.
;; Present Limitations/Future Work (contributions are most welcome!):
;;
;; . Would like RET in Bird-style literate mode to add a ">" at the
;; start of a line when previous line starts with ">". Or would
;; "> " be better?
;;
;; . Support for GreenCard?
;;
;;; Code:
(eval-when-compile (require 'cl))
;; All functions/variables start with `(literate-)haskell-'.
;; Version of mode.
(defconst haskell-version "v2_3"
"`haskell-mode' version number.")
(defun haskell-version ()
"Echo the current version of `haskell-mode' in the minibuffer."
(interactive)
(message "Using haskell-mode version %s" haskell-version))
(defgroup haskell nil
"Major mode for editing Haskell programs."
:group 'languages
:prefix "haskell-")
;; Set up autoloads for the modules we supply
(autoload 'turn-on-haskell-decl-scan "haskell-decl-scan"
"Turn on Haskell declaration scanning." t)
(autoload 'turn-on-haskell-doc-mode "haskell-doc"
"Turn on Haskell Doc minor mode." t)
(autoload 'turn-on-haskell-indent "haskell-indent"
"Turn on Haskell indentation." t)
(autoload 'turn-on-haskell-simple-indent "haskell-simple-indent"
"Turn on simple Haskell indentation." t)
;; Functionality provided in other files.
(autoload 'haskell-ds-create-imenu-index "haskell-decl-scan")
(autoload 'haskell-font-lock-choose-keywords "haskell-font-lock")
(autoload 'haskell-doc-current-info "haskell-doc")
;; Obsolete functions.
(defun turn-on-haskell-font-lock ()
(turn-on-font-lock)
(message "turn-on-haskell-font-lock is obsolete. Use turn-on-font-lock instead."))
(defun turn-on-haskell-hugs ()
(message "haskell-hugs is obsolete.")
(load "haskell-hugs")
(turn-on-haskell-hugs))
(defun turn-on-haskell-ghci ()
(message "haskell-ghci is obsolete.")
(load "haskell-ghci")
(turn-on-haskell-ghci))
;; Are we looking at a literate script?
(defvar haskell-literate nil
"*If not nil, the current buffer contains a literate Haskell script.
Possible values are: `bird' and `latex', for Bird-style and LaTeX-style
literate scripts respectively. Set by `haskell-mode' and
`literate-haskell-mode'. For an ambiguous literate buffer -- ie. does
not contain either \"\\begin{code}\" or \"\\end{code}\" on a line on
its own, nor does it contain \">\" at the start of a line -- the value
of `haskell-literate-default' is used.
Always buffer-local.")
(make-variable-buffer-local 'haskell-literate)
;; Default literate style for ambiguous literate buffers.
(defcustom haskell-literate-default 'bird
"*Default value for `haskell-literate'.
Used if the style of a literate buffer is ambiguous. This variable should
be set to the preferred literate style."
:type '(choice (const bird) (const latex) (const nil)))
;; Mode maps.
(defvar haskell-mode-map
(let ((map (make-sparse-keymap)))
;; Bindings for the inferior haskell process:
;; (define-key map [?\M-C-x] 'inferior-haskell-send-defun)
;; (define-key map [?\C-x ?\C-e] 'inferior-haskell-send-last-sexp)
;; (define-key map [?\C-c ?\C-r] 'inferior-haskell-send-region)
(define-key map [?\C-c ?\C-z] 'switch-to-haskell)
(define-key map [?\C-c ?\C-l] 'inferior-haskell-load-file)
;; Non standard in other inferior-modes, but traditional in haskell.
(define-key map [?\C-c ?\C-r] 'inferior-haskell-reload-file)
(define-key map [?\C-c ?\C-b] 'switch-to-haskell)
;; (define-key map [?\C-c ?\C-s] 'inferior-haskell-start-process)
;; That's what M-; is for.
;; (define-key map "\C-c\C-c" 'comment-region)
(define-key map (kbd "C-c C-t") 'inferior-haskell-type)
(define-key map (kbd "C-c C-i") 'inferior-haskell-info)
(define-key map (kbd "C-c M-.") 'inferior-haskell-find-definition)
map)
"Keymap used in Haskell mode.")
(easy-menu-define haskell-mode-menu haskell-mode-map
"Menu for the Haskell major mode."
;; Suggestions from Pupeno <pupeno@pupeno.com>:
;; - choose the underlying interpreter
;; - look up docs
`("Haskell"
["Indent line" indent-according-to-mode]
["Indent region" indent-region mark-active]
["(Un)Comment region" comment-region mark-active]
"---"
["Start interpreter" switch-to-haskell]
["Load file" inferior-haskell-load-file]
"---"
,(if (default-boundp 'eldoc-documentation-function)
["Doc mode" eldoc-mode
:style toggle :selected (bound-and-true-p eldoc-mode)]
["Doc mode" haskell-doc-mode
:style toggle :selected (and (boundp 'haskell-doc-mode) haskell-doc-mode)])
["Customize" (customize-group 'haskell)]
))
;; Syntax table.
(defvar haskell-mode-syntax-table
(let ((table (make-syntax-table)))
(modify-syntax-entry ?\ " " table)
(modify-syntax-entry ?\t " " table)
(modify-syntax-entry ?\" "\"" table)
(modify-syntax-entry ?\' "\'" table)
(modify-syntax-entry ?_ "w" table)
(modify-syntax-entry ?\( "()" table)
(modify-syntax-entry ?\) ")(" table)
(modify-syntax-entry ?\[ "(]" table)
(modify-syntax-entry ?\] ")[" table)
(cond ((featurep 'xemacs)
;; I don't know whether this is equivalent to the below
;; (modulo nesting). -- fx
(modify-syntax-entry ?{ "(}5" table)
(modify-syntax-entry ?} "){8" table)
(modify-syntax-entry ?- "_ 1267" table))
(t
;; In Emacs 21, the `n' indicates that they nest.
;; The `b' annotation is actually ignored because it's only
;; meaningful on the second char of a comment-starter, so
;; on Emacs 20 and before we get wrong results. --Stef
(modify-syntax-entry ?\{ "(}1nb" table)
(modify-syntax-entry ?\} "){4nb" table)
(modify-syntax-entry ?- "_ 123" table)))
(modify-syntax-entry ?\n ">" table)
(let (i lim)
(map-char-table
(lambda (k v)
(when (equal v '(1))
;; The current Emacs 22 codebase can pass either a char
;; or a char range.
(if (consp k)
(setq i (car k)
lim (cdr k))
(setq i k
lim k))
(while (<= i lim)
(when (> i 127)
(modify-syntax-entry i "_" table))
(setq i (1+ i)))))
(standard-syntax-table)))
(modify-syntax-entry ?\` "$`" table)
(modify-syntax-entry ?\\ "\\" table)
(mapcar (lambda (x)
(modify-syntax-entry x "_" table))
;; Some of these are actually OK by default.
"!#$%&*+./:<=>?@^|~")
(unless (featurep 'mule)
;; Non-ASCII syntax should be OK, at least in Emacs.
(mapcar (lambda (x)
(modify-syntax-entry x "_" table))
(concat "¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿"
"×÷"))
(mapcar (lambda (x)
(modify-syntax-entry x "w" table))
(concat "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ"
"ØÙÚÛÜÝÞß"
"àáâãäåæçèéêëìíîïðñòóôõö"
"øùúûüýþÿ")))
table)
"Syntax table used in Haskell mode.")
(defun haskell-ident-at-point ()
"Return the identifier under point, or nil if none found."
(save-excursion
(if (looking-at "\\s_")
(buffer-substring-no-properties
(progn (skip-syntax-backward "_") (point))
(progn (skip-syntax-forward "_") (point)))
(buffer-substring-no-properties
(progn (skip-syntax-backward "w'") (skip-syntax-forward "'") (point))
(progn (skip-syntax-forward "w'") (point))))))
;; Various mode variables.
(defcustom haskell-mode-hook nil
"Hook run after entering Haskell mode."
:type 'hook
:options '(turn-on-haskell-indent turn-on-font-lock turn-on-eldoc-mode
imenu-add-menubar-index))
(defvar eldoc-print-current-symbol-info-function)
;; The main mode functions
;;;###autoload
(define-derived-mode haskell-mode fundamental-mode "Haskell"
"Major mode for editing Haskell programs. Last adapted for Haskell 1.4.
Blank lines separate paragraphs, comments start with `-- '.
\\<haskell-mode-map>\\[indent-for-comment] will place a comment at an appropriate place on the current line.
\\[comment-region] comments (or with prefix arg, uncomments) each line in the region.
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.
Modules can hook in via `haskell-mode-hook'. The following modules
are supported with an `autoload' command:
`haskell-decl-scan', Graeme E Moss
Scans top-level declarations, and places them in a menu.
`haskell-doc', Hans-Wolfgang Loidl
Echoes types of functions or syntax of keywords when the cursor is idle.
`haskell-indent', Guy Lapalme
Intelligent semi-automatic indentation.
`haskell-simple-indent', Graeme E Moss and Heribert Schuetz
Simple indentation.
Module X is activated using the command `turn-on-X'. For example,
`haskell-font-lock' is activated using `turn-on-haskell-font-lock'.
For more information on a module, see the help for its `turn-on-X'
function. Some modules can be deactivated using `turn-off-X'. (Note
that `haskell-doc' is irregular in using `turn-(on/off)-haskell-doc-mode'.)
Use `haskell-version' to find out what version this is.
Invokes `haskell-mode-hook' if not nil."
(set (make-local-variable 'paragraph-start) (concat "^$\\|" page-delimiter))
(set (make-local-variable 'paragraph-separate) paragraph-start)
(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 'parse-sexp-ignore-comments) t)
;; Set things up for eldoc-mode.
(set (make-local-variable 'eldoc-documentation-function)
'haskell-doc-current-info)
;; Set things up for imenu.
(set (make-local-variable 'imenu-create-index-function)
'haskell-ds-create-imenu-index)
;; Set things up for font-lock.
(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)))
;; Haskell's layout rules mean that TABs have to be handled with extra care.
;; The safer option is to avoid TABs. The second best is to make sure
;; TABs stops are 8 chars apart, as mandated by the Haskell Report. --Stef
(set (make-local-variable 'indent-tabs-mode) nil)
(set (make-local-variable 'tab-width) 8)
(setq haskell-literate nil))
;;;###autoload
(define-derived-mode literate-haskell-mode haskell-mode "LitHaskell"
"As `haskell-mode' but for literate scripts."
(setq haskell-literate
(save-excursion
(goto-char (point-min))
(cond
((re-search-forward "^\\\\\\(begin\\|end\\){code}$" nil t) 'latex)
((re-search-forward "^>" nil t) 'bird)
(t haskell-literate-default)))))
;;;###autoload(add-to-list 'auto-mode-alist '("\\.\\(?:[gh]s\\|hi\\)\\'" . haskell-mode))
;;;###autoload(add-to-list 'auto-mode-alist '("\\.l[gh]s\\'" . literate-haskell-mode))
;;;###autoload(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
;;;###autoload(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
;; Provide ourselves:
(provide 'haskell-mode)
;; arch-tag: b2237ec0-ddb0-4c86-9339-52d410264980
;;; haskell-mode.el ends here

View file

@ -0,0 +1,154 @@
;;; haskell-simple-indent.el --- Simple indentation module for Haskell Mode
;; Copyright (C) 1998 Heribert Schuetz, Graeme E Moss
;; Authors:
;; 1998 Heribert Schuetz <Heribert.Schuetz@informatik.uni-muenchen.de> and
;; Graeme E Moss <gem@cs.york.ac.uk>
;; Keywords: indentation files Haskell
;; Version: 1.0
;; URL: http://www.cs.york.ac.uk/~gem/haskell-mode/simple-indent.html
;; 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 2, 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 support simple indentation of Haskell scripts.
;;
;;
;; Installation:
;;
;; To bind TAB to the indentation command for all Haskell buffers, add
;; this to .emacs:
;;
;; (add-hook 'haskell-mode-hook 'turn-on-haskell-simple-indent)
;;
;; Otherwise, call `turn-on-haskell-simple-indent'.
;;
;;
;; Customisation:
;;
;; None supported.
;;
;;
;; History:
;;
;; If you have any problems or suggestions, after consulting the list
;; below, email gem@cs.york.ac.uk quoting the version of you are
;; using, the version of Emacs you are using, and a small example of
;; the problem or suggestion.
;;
;; Version 1.0:
;; Brought over from Haskell mode v1.1.
;;
;; Present Limitations/Future Work (contributions are most welcome!):
;;
;; (None so far.)
;;; Code:
;; All functions/variables start with
;; `(turn-(on/off)-)haskell-simple-indent'.
;; Version.
(defconst haskell-simple-indent-version "1.2"
"`haskell-simple-indent' version number.")
(defun haskell-simple-indent-version ()
"Echo the current version of `haskell-simple-indent' in the minibuffer."
(interactive)
(message "Using haskell-simple-indent version %s"
haskell-simple-indent-version))
;; Partly stolen from `indent-relative' in indent.el:
(defun haskell-simple-indent ()
"Space out to under next visible indent point.
Indent points are positions of non-whitespace following whitespace in
lines preceeding point. A position is visible if it is to the left of
the first non-whitespace of every nonblank line between the position and
the current line. If there is no visible indent point beyond the current
column, `tab-to-tab-stop' is done instead."
(interactive)
(let* ((start-column (current-column))
(invisible-from nil) ; `nil' means infinity here
(indent
(catch 'haskell-simple-indent-break
(save-excursion
(while (progn (beginning-of-line)
(not (bobp)))
(forward-line -1)
(if (not (looking-at "[ \t]*\n"))
(let ((this-indentation (current-indentation)))
(if (or (not invisible-from)
(< this-indentation invisible-from))
(if (> this-indentation start-column)
(setq invisible-from this-indentation)
(let ((end (line-beginning-position 2)))
(move-to-column start-column)
;; Is start-column inside a tab on this line?
(if (> (current-column) start-column)
(backward-char 1))
(or (looking-at "[ \t]")
(skip-chars-forward "^ \t" end))
(skip-chars-forward " \t" end)
(let ((col (current-column)))
(throw 'haskell-simple-indent-break
(if (or (= (point) end)
(and invisible-from
(> col invisible-from)))
invisible-from
col)))))))))))))
(if indent
(let ((opoint (point-marker)))
(indent-line-to indent)
(if (> opoint (point))
(goto-char opoint))
(set-marker opoint nil))
(tab-to-tab-stop))))
(defvar haskell-simple-indent-old)
;; The main functions.
(defun turn-on-haskell-simple-indent ()
"Set `indent-line-function' to a simple indentation function.
TAB will now move the cursor to the next indent point in the previous
nonblank line. An indent point is a non-whitespace character following
whitespace.
Runs `haskell-simple-indent-hook'.
Use `haskell-simple-indent-version' to find out what version this is."
(set (make-local-variable 'haskell-simple-indent-old) indent-line-function)
(set (make-local-variable 'indent-line-function) 'haskell-simple-indent)
(run-hooks 'haskell-simple-indent-hook))
(defun turn-off-haskell-simple-indent ()
"Return `indent-line-function' to original value.
I.e. the value before `turn-on-haskell-simple-indent' was called."
(when (local-variable-p 'haskell-simple-indent-old)
(setq indent-line-function haskell-simple-indent-old)
(kill-local-variable 'haskell-simple-indent-old)))
;; Provide ourselves:
(provide 'haskell-simple-indent)
;; arch-tag: 18a08122-723b-485e-b958-e1cf8218b816
;;; haskell-simple-indent.el ends here

View file

@ -0,0 +1,218 @@
;;; haskell-site-file.el --- automatically extracted autoloads
;;
;;; Code:
(add-to-list 'load-path
(or (file-name-directory load-file-name) (car load-path)))
;;;### (autoloads (haskell-cabal-mode) "haskell-cabal" "haskell-cabal.el"
;;;;;; (17875 26421))
;;; Generated autoloads from haskell-cabal.el
(add-to-list (quote auto-mode-alist) (quote ("\\.cabal\\'" . haskell-cabal-mode)))
(autoload (quote haskell-cabal-mode) "haskell-cabal" "\
Major mode for Cabal package description files.
\(fn)" t nil)
;;;***
;;;### (autoloads (haskell-decl-scan-mode) "haskell-decl-scan" "haskell-decl-scan.el"
;;;;;; (17282 16501))
;;; Generated autoloads from haskell-decl-scan.el
(autoload (quote haskell-decl-scan-mode) "haskell-decl-scan" "\
Minor mode for declaration scanning for Haskell mode.
Top-level declarations are scanned and listed in the menu item \"Declarations\".
Selecting an item from this menu will take point to the start of the
declaration.
\\[haskell-ds-forward-decl] and \\[haskell-ds-backward-decl] move forward and backward to the start of a declaration.
Under XEmacs, the following keys are also defined:
\\[fume-list-functions] lists the declarations of the current buffer,
\\[fume-prompt-function-goto] prompts for a declaration to move to, and
\\[fume-mouse-function-goto] moves to the declaration whose name is at point.
This may link with `haskell-doc' (only for Emacs currently).
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.
To turn on declaration scanning for all Haskell buffers, add this to
.emacs:
(add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan)
To turn declaration scanning on for the current buffer, call
`turn-on-haskell-decl-scan'.
Literate Haskell scripts are supported: If the value of
`haskell-literate' (automatically set by the Haskell mode of
Moss&Thorn) is 'bird, a Bird-style literate script is assumed. If it
is nil or 'latex, a non-literate or LaTeX-style literate script is
assumed, respectively.
Invokes `haskell-decl-scan-hook' if not nil.
Use `haskell-decl-scan-version' to find out what version this is.
\(fn &optional ARG)" nil nil)
;;;***
;;;### (autoloads (haskell-doc-show-type haskell-doc-mode) "haskell-doc"
;;;;;; "haskell-doc.el" (17869 26151))
;;; Generated autoloads from haskell-doc.el
(autoload (quote 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 (quote turn-on-haskell-doc-mode) (quote haskell-doc-mode))
(autoload (quote 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 (haskell-indent-mode) "haskell-indent" "haskell-indent.el"
;;;;;; (17875 21187))
;;; Generated autoloads from haskell-indent.el
(autoload (quote haskell-indent-mode) "haskell-indent" "\
``intelligent'' Haskell indentation mode that 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
Note: \\[indent-region] which applies \\[haskell-indent-cycle] for each line
of the region also works but it stops and asks for any line having more
than one possible indentation.
Use TAB to cycle until the right indentation is found and then RET to go the
next line to indent.
Invokes `haskell-indent-hook' if not nil.
\(fn &optional ARG)" t nil)
;;;***
;;;### (autoloads (literate-haskell-mode haskell-mode) "haskell-mode"
;;;;;; "haskell-mode.el" (17869 25437))
;;; Generated autoloads from haskell-mode.el
(autoload (quote haskell-mode) "haskell-mode" "\
Major mode for editing Haskell programs. Last adapted for Haskell 1.4.
Blank lines separate paragraphs, comments start with `-- '.
\\<haskell-mode-map>\\[indent-for-comment] will place a comment at an appropriate place on the current line.
\\[comment-region] comments (or with prefix arg, uncomments) each line in the region.
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.
Modules can hook in via `haskell-mode-hook'. The following modules
are supported with an `autoload' command:
`haskell-decl-scan', Graeme E Moss
Scans top-level declarations, and places them in a menu.
`haskell-doc', Hans-Wolfgang Loidl
Echoes types of functions or syntax of keywords when the cursor is idle.
`haskell-indent', Guy Lapalme
Intelligent semi-automatic indentation.
`haskell-simple-indent', Graeme E Moss and Heribert Schuetz
Simple indentation.
Module X is activated using the command `turn-on-X'. For example,
`haskell-font-lock' is activated using `turn-on-haskell-font-lock'.
For more information on a module, see the help for its `turn-on-X'
function. Some modules can be deactivated using `turn-off-X'. (Note
that `haskell-doc' is irregular in using `turn-(on/off)-haskell-doc-mode'.)
Use `haskell-version' to find out what version this is.
Invokes `haskell-mode-hook' if not nil.
\(fn)" t nil)
(autoload (quote literate-haskell-mode) "haskell-mode" "\
As `haskell-mode' but for literate scripts.
\(fn)" t nil)
(add-to-list 'auto-mode-alist '("\\.\\(?:[gh]s\\|hi\\)\\'" . haskell-mode))
(add-to-list 'auto-mode-alist '("\\.l[gh]s\\'" . literate-haskell-mode))
(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
;;;***
;;;### (autoloads (inferior-haskell-load-file switch-to-haskell)
;;;;;; "inf-haskell" "inf-haskell.el" (17875 21120))
;;; Generated autoloads from inf-haskell.el
(defalias (quote run-haskell) (quote switch-to-haskell))
(autoload (quote switch-to-haskell) "inf-haskell" "\
Show the inferior-haskell buffer. Start the process if needed.
\(fn &optional ARG)" t nil)
(autoload (quote inferior-haskell-load-file) "inf-haskell" "\
Pass the current buffer's file to the inferior haskell process.
\(fn &optional RELOAD)" t nil)
;;;***
;;;### (autoloads nil nil ("haskell-font-lock.el" "haskell-ghci.el"
;;;;;; "haskell-hugs.el" "haskell-simple-indent.el") (17875 26544
;;;;;; 864790))
;;;***
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; End:
;;; haskell-site-file.el ends here

157
emacs.d/haskell/indent.hs Normal file
View file

@ -0,0 +1,157 @@
-------------------------------------------------------------------------
-- Comments with allcaps `FIXME' indicate places where the indentation --
-- fails to find the correct indentation, whereas comments with --
-- lowercase `fixme' indicate places where impossible indentations --
-- are uselessly proposed. --
-------------------------------------------------------------------------
-- compute the list of binary digits corresponding to an integer
-- Note: the least significant bit is the first element of the list
bdigits :: Int -> [Int]
bdigits 0 = [0]
bdigits 1 = [1]
bdigits n | n>1 = n `mod` 2 :
bdigits (n `div` 2)
| otherwise = error "bdigits of a negative number"
-- compute the value of an integer given its list of binary digits
-- Note: the least significant bit is the first element of the list
bvalue :: [Int]->Int
bvalue [] = error "bvalue of []"
bvalue s = bval 1 s
where
bval e [] = 0
bval e [] = 0 -- fixme: can't align with `where'.
bval e (b:bs) | b==0 || b=="dd of " = b*e + bval (2*e) bs
| otherwise = error "ill digit" -- Spurious 3rd step.
foo
-- fixme: tab on the line above should insert `bvalue' at some point.
{- text
indentation
inside comments
-}
toto a = ( hello
, there -- indentation of leading , and ;
-- indentation of this comment.
, my friends )
lili x = do let ofs x = 1
print x
titi b =
let -- fixme: can't indent at column 0
x = let toto = 1
tata = 2 -- fixme: can't indent lower than `toto'.
in
toto in
do expr1
{- text
- indentation
- inside comments
-}
let foo s = let fro = 1
fri = 2 -- fixme: can't indent lower than `fro'.
in
hello
foo2 = bar2 -- fixme: can't align with arg `s' in foo.
foo1 = bar2 -- fixme: Can't be column 0.
expr2
tata c =
let bar = case foo -- fixme: can't be col 0.
of 1 -> blabla
2 -> blibli -- fixme: only one possible indentation here.
bar = case foo of
_ -> blabla
bar' = case foo
of _ -> blabla
toto -> plulu
turlu d = if test
then
ifturl
else
adfaf
turlu d = if test then
ifturl
else
sg
turly fg = toto
where
hello = 2
-- test from John Goerzen
x myVariableThing = case myVariablething of
Just z -> z
Nothing -> 0 -- fixme: "spurious" additional indents.
foo = let x = 1 in toto
titi -- FIXME
foo = let foo x y = toto
where
toto = 2
instance Show Toto where
foo x 4 = 50
data Toto = Foo
| Bar
deriving (Show) -- FIXME
foo = let toto x = do let bar = 2
return 1
in 3
eval env (Llambda x e) = -- FIXME: sole indentation is self???
Vfun (\v -> eval (\y -> if (x == y) then v else env y) -- FIXME
e) -- FIXME
foo = case findprop attr props of
Just x -> x
data T = T { granularity :: (Int, Int, Int, Int) -- FIXME: self indentation?
, items :: Map (Int, Int, Int, Int) [Item] }
foo = case foo of
[] ->
case bar of
[] ->
return ()
(x:xs) -> -- FIXME
bar = do toto
if titi
then tutu -- FIXME
else tata -- FIXME
insert :: Ord a => a -> b -> TreeMap a b -> TreeMap a b
insert x v Empty = Node 0 x v Empty Empty
insert x v (Node d x' v' t1 t2)
| x == x' = Node d x v t1 t2
| x < x' = Node ? x' v' (insert x v t1 Empty) t2
| -- FIXME: wrong indent *if at EOB*
tinsertb x v (Node x' v' d1 t1 d2 t2)
| x == x' = (1 + max d1 d2, Node x v d1 t1 d2 t2)
| x < x' =
case () of
_ | d1' <= d2 + 1 => (1 + max d1' d2, Node x' v' d1' t1' d2 t2)
-- d1' == d2 + 2: Need to rotate to rebalance. FIXME CRASH
else let (Node x'' v'' d1'' t1'' d2'' t2'') = t1'
test = if True then
toto
else if False then
tata -- FIXME
else -- FIXME
titi
-- arch-tag: de0069e3-c0a0-495c-b441-d4ff6e0509b1

View file

@ -0,0 +1,328 @@
;;; inf-haskell.el --- Interaction with an inferior Haskell process.
;; Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
;; Keywords: Haskell
;; 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 2, 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:
;; The code is made of 2 parts: a major mode for the buffer that holds the
;; inferior process's session and a minor mode for use in source buffers.
;;; Code:
(require 'comint)
(require 'shell) ;For directory tracking.
(require 'compile)
(require 'haskell-mode)
(eval-when-compile (require 'cl))
;; Here I depart from the inferior-haskell- prefix.
;; Not sure if it's a good idea.
(defcustom haskell-program-name
;; Arbitrarily give preference to hugs over ghci.
(or (cond
((not (fboundp 'executable-find)) nil)
((executable-find "hugs") "hugs \"+.\"")
((executable-find "ghci") "ghci"))
"hugs \"+.\"")
"The name of the command to start the inferior Haskell process.
The command can include arguments."
;; Custom only supports the :options keyword for a few types, e.g. not
;; for string.
;; :options '("hugs \"+.\"" "ghci")
:group 'haskell
:type '(choice string (repeat string)))
(defconst inferior-haskell-info-xref-re
"\t-- Defined at \\(.+\\):\\([0-9]+\\):\\([0-9]+\\)$")
(defconst inferior-haskell-error-regexp-alist
;; The format of error messages used by Hugs.
`(("^ERROR \"\\(.+?\\)\"\\(:\\| line \\)\\([0-9]+\\) - " 1 3)
;; Format of error messages used by GHCi.
("^\\(.+?\\):\\([0-9]+\\):\\(\\([0-9]+\\):\\)?\\( \\|\n +\\)\\(Warning\\)?"
1 2 4 ,@(if (fboundp 'compilation-fake-loc) '((6))))
;; Info xrefs.
,@(if (fboundp 'compilation-fake-loc)
`((,inferior-haskell-info-xref-re
1 2 3 0))))
"Regexps for error messages generated by inferior Haskell processes.
The format should be the same as for `compilation-error-regexp-alist'.")
(define-derived-mode inferior-haskell-mode comint-mode "Inf-Haskell"
"Major mode for interacting with an inferior Haskell process."
(set (make-local-variable 'comint-prompt-regexp)
"^\\*?[A-Z][\\._a-zA-Z0-9]*\\( \\*?[A-Z][\\._a-zA-Z0-9]*\\)*> ")
(set (make-local-variable 'comint-input-autoexpand) nil)
;; Setup directory tracking.
(set (make-local-variable 'shell-cd-regexp) ":cd")
(condition-case nil
(shell-dirtrack-mode 1)
(error ;The minor mode function may not exist or not accept an arg.
(set (make-local-variable 'shell-dirtrackp) t)
(add-hook 'comint-input-filter-functions 'shell-directory-tracker
nil 'local)))
;; Setup `compile' support so you can just use C-x ` and friends.
(set (make-local-variable 'compilation-error-regexp-alist)
inferior-haskell-error-regexp-alist)
(if (and (not (boundp 'minor-mode-overriding-map-alist))
(fboundp 'compilation-shell-minor-mode))
;; If we can't remove compilation-minor-mode bindings, at least try to
;; use compilation-shell-minor-mode, so there are fewer
;; annoying bindings.
(compilation-shell-minor-mode 1)
;; Else just use compilation-minor-mode but without its bindings because
;; things like mouse-2 are simply too annoying.
(compilation-minor-mode 1)
(let ((map (make-sparse-keymap)))
(dolist (keys '([menu-bar] [follow-link]))
;; Preserve some of the bindings.
(define-key map keys (lookup-key compilation-minor-mode-map keys)))
(add-to-list 'minor-mode-overriding-map-alist
(cons 'compilation-minor-mode map)))))
(defun inferior-haskell-string-to-strings (string &optional separator)
"Split the STRING into a list of strings.
The SEPARATOR regexp defaults to \"\\s-+\"."
(let ((sep (or separator "\\s-+"))
(i (string-match "[\"]" string)))
(if (null i) (split-string string sep) ; no quoting: easy
(append (unless (eq i 0) (split-string (substring string 0 i) sep))
(let ((rfs (read-from-string string i)))
(cons (car rfs)
(inferior-haskell-string-to-strings
(substring string (cdr rfs)) sep)))))))
(defun inferior-haskell-command (arg)
(inferior-haskell-string-to-strings
(if (null arg) haskell-program-name
(read-string "Command to run haskell: " haskell-program-name))))
(defvar inferior-haskell-buffer nil
"The buffer in which the inferior process is running.")
(defun inferior-haskell-start-process (command)
"Start an inferior haskell process.
With universal prefix \\[universal-argument], prompts for a command,
otherwise uses `haskell-program-name'.
It runs the hook `inferior-haskell-hook' after starting the process and
setting up the inferior-haskell buffer."
(interactive (list (inferior-haskell-command current-prefix-arg)))
(setq inferior-haskell-buffer
(apply 'make-comint "haskell" (car command) nil (cdr command)))
(with-current-buffer inferior-haskell-buffer
(inferior-haskell-mode)
(run-hooks 'inferior-haskell-hook)))
(defun inferior-haskell-process (&optional arg)
(or (if (buffer-live-p inferior-haskell-buffer)
(get-buffer-process inferior-haskell-buffer))
(progn
(let ((current-prefix-arg arg))
(call-interactively 'inferior-haskell-start-process))
;; Try again.
(inferior-haskell-process arg))))
;;;###autoload
(defalias 'run-haskell 'switch-to-haskell)
;;;###autoload
(defun switch-to-haskell (&optional arg)
"Show the inferior-haskell buffer. Start the process if needed."
(interactive "P")
(let ((proc (inferior-haskell-process arg)))
(pop-to-buffer (process-buffer proc))))
(eval-when-compile
(unless (fboundp 'with-selected-window)
(defmacro with-selected-window (win &rest body)
`(save-selected-window
(select-window ,win)
,@body))))
(defcustom inferior-haskell-wait-and-jump nil
"If non-nil, wait for file loading to terminate and jump to the error."
:type 'boolean
:group 'haskell)
(defun inferior-haskell-wait-for-prompt (proc)
"Wait until PROC sends us a prompt.
The process PROC should be associated to a comint buffer."
(with-current-buffer (process-buffer proc)
(while (progn
(goto-char comint-last-input-end)
(and (not (re-search-forward comint-prompt-regexp nil t))
(accept-process-output proc))))))
;;;###autoload
(defun inferior-haskell-load-file (&optional reload)
"Pass the current buffer's file to the inferior haskell process."
(interactive)
(let ((file buffer-file-name)
(proc (inferior-haskell-process)))
(save-buffer)
(with-current-buffer (process-buffer proc)
;; Not sure if it's useful/needed and if it actually works.
;; (unless (equal (file-name-as-directory default-directory)
;; (file-name-directory file))
;; (inferior-haskell-send-string
;; proc (concat ":cd " (file-name-directory file) "\n")))
(compilation-forget-errors)
(let ((parsing-end (marker-position (process-mark proc))))
(inferior-haskell-send-command
proc (if reload ":reload" (concat ":load \"" file "\"")))
;; Move the parsing-end marker after sending the command so
;; that it doesn't point just to the insertion point.
;; Otherwise insertion may move the marker (if done with
;; insert-before-markers) and we'd then miss some errors.
(if (boundp 'compilation-parsing-end)
(if (markerp compilation-parsing-end)
(set-marker compilation-parsing-end parsing-end)
(setq compilation-parsing-end parsing-end))))
(with-selected-window (display-buffer (current-buffer))
(goto-char (point-max)))
(when inferior-haskell-wait-and-jump
(inferior-haskell-wait-for-prompt proc)
(ignore-errors ;Don't beep if there were no errors.
(next-error))))))
(defun inferior-haskell-send-command (proc str)
(setq str (concat str "\n"))
(with-current-buffer (process-buffer proc)
(inferior-haskell-wait-for-prompt proc)
(goto-char (process-mark proc))
(insert-before-markers str)
(move-marker comint-last-input-end (point))
(comint-send-string proc str)))
(defun inferior-haskell-reload-file ()
"Tell the inferior haskell process to reread the current buffer's file."
(interactive)
(inferior-haskell-load-file 'reload))
(defun inferior-haskell-type (expr &optional insert-value)
"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'."
(interactive
(let ((sym (haskell-ident-at-point)))
(list (read-string (if (> (length sym) 0)
(format "Show type of (default %s): " sym)
"Show type of: ")
nil nil sym)
current-prefix-arg)))
(if (string-match "\\`\\s_+\\'" expr) (setq expr (concat "(" expr ")")))
(let* ((proc (inferior-haskell-process))
(type
(with-current-buffer (process-buffer proc)
(let ((parsing-end ; Remember previous spot.
(marker-position (process-mark proc))))
(inferior-haskell-send-command proc (concat ":type " expr))
;; Find new point.
(goto-char (point-max))
(inferior-haskell-wait-for-prompt proc)
;; Back up to the previous end-of-line.
(end-of-line 0)
;; Extract the type output
(buffer-substring-no-properties
(save-excursion (goto-char parsing-end)
(line-beginning-position 2))
(point))))))
(if (not (string-match (concat "\\`" (regexp-quote expr) "[ \t]+::[ \t]*")
type))
(error "No type info: %s" type)
;; Cache for reuse by haskell-doc.
(when (and (boundp 'haskell-doc-mode) haskell-doc-mode
(boundp 'haskell-doc-user-defined-ids)
;; Haskell-doc only works for idents, not arbitrary expr.
(string-match "\\`(?\\(\\s_+\\|\\(\\sw\\|\\s'\\)+\\)?[ \t]*::[ \t]*"
type))
(let ((sym (match-string 1 type)))
(setq haskell-doc-user-defined-ids
(cons (cons sym (substring type (match-end 0)))
(remove-if (lambda (item) (equal (car item) sym))
haskell-doc-user-defined-ids)))))
(if (interactive-p) (message type))
(when insert-value
(beginning-of-line)
(insert type "\n"))
type)))
(defun inferior-haskell-info (sym)
"Query the haskell process for the info of the given expression."
(interactive
(let ((sym (haskell-ident-at-point)))
(list (read-string (if (> (length sym) 0)
(format "Show info of (default %s): " sym)
"Show info of: ")
nil nil sym))))
(let ((proc (inferior-haskell-process)))
(with-current-buffer (process-buffer proc)
(let ((parsing-end ; Remember previous spot.
(marker-position (process-mark proc))))
(inferior-haskell-send-command proc (concat ":info " sym))
;; Find new point.
(goto-char (point-max))
(inferior-haskell-wait-for-prompt proc)
;; Move to previous end-of-line
(end-of-line 0)
(let ((result
(buffer-substring-no-properties
(save-excursion (goto-char parsing-end)
(line-beginning-position 2))
(point))))
;; Move back to end of process buffer
(goto-char (point-max))
(if (interactive-p) (message "%s" result))
result)))))
(defun inferior-haskell-find-definition (sym)
"Attempt to locate and jump to the definition of the given expression."
(interactive
(let ((sym (haskell-ident-at-point)))
(list (read-string (if (> (length sym) 0)
(format "Find definition of (default %s): " sym)
"Find definition of: ")
nil nil sym))))
(let ((info (inferior-haskell-info sym)))
(if (not (string-match inferior-haskell-info-xref-re info))
(error "No source information available")
(let ((file (match-string-no-properties 1 info))
(line (string-to-number
(match-string-no-properties 2 info)))
(col (string-to-number
(match-string-no-properties 3 info))))
(when file
;; Push current location marker on the ring used by `find-tag'
(require 'etags)
(ring-insert find-tag-marker-ring (point-marker))
(pop-to-buffer (find-file-noselect file))
(when line
(goto-line line)
(when col (move-to-column col))))))))
(provide 'inf-haskell)
;; arch-tag: 61804287-63dd-4052-bc0e-90f691b34b40
;;; inf-haskell.el ends here

417
emacs.d/inf-ruby.el Normal file
View file

@ -0,0 +1,417 @@
;;; -*-Emacs-Lisp-*-
;;;
;;; $Id$
;;; $Author$
;;; $Date$
;;;
;;; Inferior Ruby Mode - ruby process in a buffer.
;;; adapted from cmuscheme.el
;;;
;;; Usage:
;;;
;;; (0) check ruby-program-name variable that can run your environment.
;;;
;;; (1) modify .emacs to use ruby-mode
;;; for example :
;;;
;;; (autoload 'ruby-mode "ruby-mode"
;;; "Mode for editing ruby source files" t)
;;; (setq auto-mode-alist
;;; (append '(("\\.rb$" . ruby-mode)) auto-mode-alist))
;;; (setq interpreter-mode-alist (append '(("ruby" . ruby-mode))
;;; interpreter-mode-alist))
;;;
;;; (2) set to load inf-ruby and set inf-ruby key definition in ruby-mode.
;;;
;;; (autoload 'run-ruby "inf-ruby"
;;; "Run an inferior Ruby process")
;;; (autoload 'inf-ruby-keys "inf-ruby"
;;; "Set local key defs for inf-ruby in ruby-mode")
;;; (add-hook 'ruby-mode-hook
;;; '(lambda ()
;;; (inf-ruby-keys)
;;; ))
;;;
;;; HISTORY
;;; senda - 8 Apr 1998: Created.
;;; $Log$
;;; Revision 1.7 2004/07/27 08:11:36 matz
;;; * eval.c (rb_eval): copy on write for argument local variable
;;; assignment.
;;;
;;; * eval.c (assign): ditto.
;;;
;;; * eval.c (rb_call0): update ruby_frame->argv with the default
;;; value used for the optional arguments.
;;;
;;; * object.c (Init_Object): "===" calls rb_obj_equal() directly.
;;; [ruby-list:39937]
;;;
;;; Revision 1.6 2002/09/07 14:35:46 nobu
;;; * misc/inf-ruby.el (inferior-ruby-error-regexp-alist): regexp
;;; alist for error message from ruby.
;;;
;;; * misc/inf-ruby.el (inferior-ruby-mode): fixed for Emacs.
;;;
;;; * misc/inf-ruby.el (ruby-send-region): compilation-parse-errors
;;; doesn't parse first line, so insert separators before each
;;; evaluations.
;;;
;;; Revision 1.5 2002/08/19 10:05:47 nobu
;;; * misc/inf-ruby.el (inf-ruby-keys): ruby-send-definition
;;; conflicted with ruby-insert-end.
;;;
;;; * misc/inf-ruby.el (inferior-ruby-mode): compilation-minor-mode.
;;;
;;; * misc/inf-ruby.el (ruby-send-region): send as here document to
;;; adjust source file/line. [ruby-talk:47113], [ruby-dev:17965]
;;;
;;; * misc/inf-ruby.el (ruby-send-terminator): added to make unique
;;; terminator.
;;;
;;; Revision 1.4 2002/01/29 07:16:09 matz
;;; * file.c (rb_stat_rdev_major): added. [new]
;;;
;;; * file.c (rb_stat_rdev_minor): added. [new]
;;;
;;; * file.c (rb_stat_inspect): print mode in octal.
;;;
;;; Revision 1.3 1999/12/01 09:24:18 matz
;;; 19991201
;;;
;;; Revision 1.2 1999/08/13 05:45:18 matz
;;; 1.4.0
;;;
;;; Revision 1.1.1.1.2.1 1999/07/15 07:59:59 matz
;;; 990715
;;;
;;; Revision 1.1.1.1 1999/01/20 04:59:36 matz
;;; ruby 1.3 cycle
;;;
;;; Revision 1.1.2.1 1998/12/16 07:30:36 matz
;;; first public release of 1.1d (pre1.2) series
;;;
;;; Revision 1.4 1998/05/20 02:45:58 senda
;;; default program to irb
;;;
;;; Revision 1.3 1998/04/10 04:11:30 senda
;;; modification by Matsumoto san (1.1b9_09)
;;; remove-in-string defined
;;; global variable :
;;; inferior-ruby-first-prompt-pattern
;;; inferior-ruby-prompt-pattern
;;; defined
;;;
;;; Revision 1.2 1998/04/09 07:53:42 senda
;;; remove M-C-x in inferior-ruby-mode
;;;
;;; Revision 1.1 1998/04/09 07:28:36 senda
;;; Initial revision
;;;
;;;
(require 'comint)
(require 'compile)
(require 'ruby-mode)
;;
;; you may change these variables
;;
;(defvar ruby-program-name "rbc --noreadline"
; "*Program invoked by the run-ruby command")
;
;(defvar inferior-ruby-first-prompt-pattern "^rbc0> *"
; "first prompt regex pattern of ruby interpreter.")
;
;(defvar inferior-ruby-prompt-pattern "^\\(rbc.[>*\"'] *\\)+"
; "prompt regex pattern of ruby interpreter.")
;;;; for irb
(defvar ruby-program-name "irb --inf-ruby-mode"
"*Program invoked by the run-ruby command")
(defvar inferior-ruby-first-prompt-pattern "^irb(.*)[0-9:]+0> *"
"first prompt regex pattern of ruby interpreter.")
(defvar inferior-ruby-prompt-pattern "^\\(irb(.*)[0-9:]+[>*\"'] *\\)+"
"prompt regex pattern of ruby interpreter.")
;;
;; mode variables
;;
(defvar inferior-ruby-mode-hook nil
"*Hook for customising inferior-ruby mode.")
(defvar inferior-ruby-mode-map nil
"*Mode map for inferior-ruby-mode")
(defconst inferior-ruby-error-regexp-alist
'(("SyntaxError: compile error\n^\\([^\(].*\\):\\([1-9][0-9]*\\):" 1 2)
("^\tfrom \\([^\(].*\\):\\([1-9][0-9]*\\)\\(:in `.*'\\)?$" 1 2)))
(cond ((not inferior-ruby-mode-map)
(setq inferior-ruby-mode-map
(copy-keymap comint-mode-map))
; (define-key inferior-ruby-mode-map "\M-\C-x" ;gnu convention
; 'ruby-send-definition)
; (define-key inferior-ruby-mode-map "\C-x\C-e" 'ruby-send-last-sexp)
(define-key inferior-ruby-mode-map "\C-c\C-l" 'ruby-load-file)
))
(defun inf-ruby-keys ()
"Set local key defs for inf-ruby in ruby-mode"
(define-key ruby-mode-map "\M-\C-x" 'ruby-send-definition)
; (define-key ruby-mode-map "\C-x\C-e" 'ruby-send-last-sexp)
(define-key ruby-mode-map "\C-c\C-b" 'ruby-send-block)
(define-key ruby-mode-map "\C-c\M-b" 'ruby-send-block-and-go)
(define-key ruby-mode-map "\C-c\C-x" 'ruby-send-definition)
(define-key ruby-mode-map "\C-c\M-x" 'ruby-send-definition-and-go)
(define-key ruby-mode-map "\C-c\C-r" 'ruby-send-region)
(define-key ruby-mode-map "\C-c\M-r" 'ruby-send-region-and-go)
(define-key ruby-mode-map "\C-c\C-z" 'switch-to-ruby)
(define-key ruby-mode-map "\C-c\C-l" 'ruby-load-file)
(define-key ruby-mode-map "\C-c\C-s" 'run-ruby)
)
(defvar ruby-buffer nil "current ruby (actually irb) process buffer.")
(defun inferior-ruby-mode ()
"Major mode for interacting with an inferior ruby (irb) process.
The following commands are available:
\\{inferior-ruby-mode-map}
A ruby process can be fired up with M-x run-ruby.
Customisation: Entry to this mode runs the hooks on comint-mode-hook and
inferior-ruby-mode-hook (in that order).
You can send text to the inferior ruby process from other buffers containing
Ruby source.
switch-to-ruby switches the current buffer to the ruby process buffer.
ruby-send-definition sends the current definition to the ruby process.
ruby-send-region sends the current region to the ruby process.
ruby-send-definition-and-go, ruby-send-region-and-go,
switch to the ruby process buffer after sending their text.
For information on running multiple processes in multiple buffers, see
documentation for variable ruby-buffer.
Commands:
Return after the end of the process' output sends the text from the
end of process to point.
Return before the end of the process' output copies the sexp ending at point
to the end of the process' output, and sends it.
Delete converts tabs to spaces as it moves back.
Tab indents for ruby; with argument, shifts rest
of expression rigidly with the current line.
C-M-q does Tab on each line starting within following expression.
Paragraphs are separated only by blank lines. # start comments.
If you accidentally suspend your process, use \\[comint-continue-subjob]
to continue it."
(interactive)
(comint-mode)
;; Customise in inferior-ruby-mode-hook
;(setq comint-prompt-regexp "^[^>\n]*>+ *")
(setq comint-prompt-regexp inferior-ruby-prompt-pattern)
;;(scheme-mode-variables)
(ruby-mode-variables)
(setq major-mode 'inferior-ruby-mode)
(setq mode-name "Inferior Ruby")
(setq mode-line-process '(":%s"))
(use-local-map inferior-ruby-mode-map)
(setq comint-input-filter (function ruby-input-filter))
(setq comint-get-old-input (function ruby-get-old-input))
(compilation-shell-minor-mode t)
(make-local-variable 'compilation-error-regexp-alist)
(setq compilation-error-regexp-alist inferior-ruby-error-regexp-alist)
(run-hooks 'inferior-ruby-mode-hook))
(defvar inferior-ruby-filter-regexp "\\`\\s *\\S ?\\S ?\\s *\\'"
"*Input matching this regexp are not saved on the history list.
Defaults to a regexp ignoring all inputs of 0, 1, or 2 letters.")
(defun ruby-input-filter (str)
"Don't save anything matching inferior-ruby-filter-regexp"
(not (string-match inferior-ruby-filter-regexp str)))
;; adapted from replace-in-string in XEmacs (subr.el)
(defun remove-in-string (str regexp)
"Remove all matches in STR for REGEXP and returns the new string."
(let ((rtn-str "") (start 0) match prev-start)
(while (setq match (string-match regexp str start))
(setq prev-start start
start (match-end 0)
rtn-str (concat rtn-str (substring str prev-start match))))
(concat rtn-str (substring str start))))
(defun ruby-get-old-input ()
"Snarf the sexp ending at point"
(save-excursion
(let ((end (point)))
(re-search-backward inferior-ruby-first-prompt-pattern)
(remove-in-string (buffer-substring (point) end)
inferior-ruby-prompt-pattern)
)))
(defun ruby-args-to-list (string)
(let ((where (string-match "[ \t]" string)))
(cond ((null where) (list string))
((not (= where 0))
(cons (substring string 0 where)
(ruby-args-to-list (substring string (+ 1 where)
(length string)))))
(t (let ((pos (string-match "[^ \t]" string)))
(if (null pos)
nil
(ruby-args-to-list (substring string pos
(length string)))))))))
(defun run-ruby (cmd)
"Run an inferior Ruby process, input and output via buffer *ruby*.
If there is a process already running in `*ruby*', switch to that buffer.
With argument, allows you to edit the command line (default is value
of `ruby-program-name'). Runs the hooks `inferior-ruby-mode-hook'
\(after the `comint-mode-hook' is run).
\(Type \\[describe-mode] in the process buffer for a list of commands.)"
(interactive (list (if current-prefix-arg
(read-string "Run Ruby: " ruby-program-name)
ruby-program-name)))
(if (not (comint-check-proc "*ruby*"))
(let ((cmdlist (ruby-args-to-list cmd)))
(set-buffer (apply 'make-comint "ruby" (car cmdlist)
nil (cdr cmdlist)))
(inferior-ruby-mode)))
(setq ruby-program-name cmd)
(setq ruby-buffer "*ruby*")
(pop-to-buffer "*ruby*"))
(defconst ruby-send-terminator "--inf-ruby-%x-%d-%d-%d--"
"Template for irb here document terminator.
Must not contain ruby meta characters.")
(defconst ruby-eval-separator "")
(defun ruby-send-region (start end)
"Send the current region to the inferior Ruby process."
(interactive "r")
(let (term (file (buffer-file-name)) line)
(save-excursion
(save-restriction
(widen)
(goto-char start)
(setq line (+ start (forward-line (- start)) 1))
(goto-char start)
(while (progn
(setq term (apply 'format ruby-send-terminator (random) (current-time)))
(re-search-forward (concat "^" (regexp-quote term) "$") end t)))))
;; compilation-parse-errors parses from second line.
(save-excursion
(let ((m (process-mark (ruby-proc))))
(set-buffer (marker-buffer m))
(goto-char m)
(insert ruby-eval-separator "\n")
(set-marker m (point))))
(comint-send-string (ruby-proc) (format "eval <<'%s', nil, %S, %d\n" term file line))
(comint-send-region (ruby-proc) start end)
(comint-send-string (ruby-proc) (concat "\n" term "\n"))))
(defun ruby-send-definition ()
"Send the current definition to the inferior Ruby process."
(interactive)
(save-excursion
(ruby-end-of-defun)
(let ((end (point)))
(ruby-beginning-of-defun)
(ruby-send-region (point) end))))
;(defun ruby-send-last-sexp ()
; "Send the previous sexp to the inferior Ruby process."
; (interactive)
; (ruby-send-region (save-excursion (backward-sexp) (point)) (point)))
(defun ruby-send-block ()
"Send the current block to the inferior Ruby process."
(interactive)
(save-excursion
(ruby-end-of-block)
(end-of-line)
(let ((end (point)))
(ruby-beginning-of-block)
(ruby-send-region (point) end))))
(defun switch-to-ruby (eob-p)
"Switch to the ruby process buffer.
With argument, positions cursor at end of buffer."
(interactive "P")
(if (get-buffer ruby-buffer)
(pop-to-buffer ruby-buffer)
(error "No current process buffer. See variable ruby-buffer."))
(cond (eob-p
(push-mark)
(goto-char (point-max)))))
(defun ruby-send-region-and-go (start end)
"Send the current region to the inferior Ruby process.
Then switch to the process buffer."
(interactive "r")
(ruby-send-region start end)
(switch-to-ruby t))
(defun ruby-send-definition-and-go ()
"Send the current definition to the inferior Ruby.
Then switch to the process buffer."
(interactive)
(ruby-send-definition)
(switch-to-ruby t))
(defun ruby-send-block-and-go ()
"Send the current block to the inferior Ruby.
Then switch to the process buffer."
(interactive)
(ruby-send-block)
(switch-to-ruby t))
(defvar ruby-source-modes '(ruby-mode)
"*Used to determine if a buffer contains Ruby source code.
If it's loaded into a buffer that is in one of these major modes, it's
considered a ruby source file by ruby-load-file.
Used by these commands to determine defaults.")
(defvar ruby-prev-l/c-dir/file nil
"Caches the last (directory . file) pair.
Caches the last pair used in the last ruby-load-file command.
Used for determining the default in the
next one.")
(defun ruby-load-file (file-name)
"Load a Ruby file into the inferior Ruby process."
(interactive (comint-get-source "Load Ruby file: " ruby-prev-l/c-dir/file
ruby-source-modes t)) ; T because LOAD
; needs an exact name
(comint-check-source file-name) ; Check to see if buffer needs saved.
(setq ruby-prev-l/c-dir/file (cons (file-name-directory file-name)
(file-name-nondirectory file-name)))
(comint-send-string (ruby-proc) (concat "(load \""
file-name
"\"\)\n")))
(defun ruby-proc ()
"Returns the current ruby process. See variable ruby-buffer."
(let ((proc (get-buffer-process (if (eq major-mode 'inferior-ruby-mode)
(current-buffer)
ruby-buffer))))
(or proc
(error "No current process. See variable ruby-buffer"))))
;;; Do the user's customisation...
(defvar inf-ruby-load-hook nil
"This hook is run when inf-ruby is loaded in.
This is a good place to put keybindings.")
(run-hooks 'inf-ruby-load-hook)
(provide 'inf-ruby)
;;; inf-ruby.el ends here

1812
emacs.d/paren-mode.el Normal file

File diff suppressed because it is too large Load diff

5815
emacs.d/psvn.el Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
This is a Subversion working copy administrative directory.
Visit http://subversion.tigris.org/ for more information.

View file

@ -0,0 +1,7 @@
K 10
svn:ignore
V 20
*.elc
rails-test.el
END

View file

@ -0,0 +1,7 @@
K 10
svn:ignore
V 20
*.elc
rails-test.el
END

View file

357
emacs.d/rails/.svn/entries Normal file
View file

@ -0,0 +1,357 @@
<?xml version="1.0" encoding="utf-8"?>
<wc-entries
xmlns="svn:">
<entry
committed-rev="195"
name=""
committed-date="2007-05-23T13:17:43.359728Z"
url="svn://rubyforge.org/var/svn/emacs-rails/trunk"
last-author="dimaexe"
kind="dir"
uuid="cc5033d0-740f-0410-afc7-949910e492f2"
repos="svn://rubyforge.org/var/svn/emacs-rails"
prop-time="2007-06-19T20:24:39.000000Z"
revision="195"/>
<entry
committed-rev="123"
name="rails-bytecompile.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-03-26T14:28:44.779068Z"
checksum="89acc0034d2827aaec49cbc0d5a5afae"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:38.000000Z"/>
<entry
committed-rev="188"
name="rails-speedbar-feature.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-25T18:23:31.715128Z"
checksum="64f57b24a1fb874aece4aae4261e5d0f"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:38.000000Z"/>
<entry
committed-rev="170"
name="rails-features.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-08T16:00:29.843207Z"
checksum="ac49fc60d14ef47fa5705e7149d17135"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:38.000000Z"/>
<entry
committed-rev="194"
name="rails-test.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-05-23T13:00:56.914307Z"
checksum="865f622bad00e027307ac6ef6d96aa38"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:38.000000Z"/>
<entry
committed-rev="114"
name="rails-log.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-03-25T18:15:35.829640Z"
checksum="fb359ab955cd5b6df78ba38071d0a5c3"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:38.000000Z"/>
<entry
committed-rev="153"
name="rails-rake.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-03-31T20:30:51.795470Z"
checksum="76df635b2e09513a01019d5689c91319"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:38.000000Z"/>
<entry
committed-rev="187"
name="rails-compat.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-25T12:13:07.756554Z"
checksum="336a258e17ed5761b1f046659603da10"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="169"
name="untabify-file.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-06T19:37:11.970928Z"
checksum="3e7ccb7e7df09e7aa174a0cecce47383"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="158"
name="rails-controller-minor-mode.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-03T08:45:46.583854Z"
checksum="0f6f791b038714b234aead6be21d7064"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="186"
name="rails-core.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-20T15:34:51.848416Z"
checksum="45fdd83ae00ed1899a681c8d9b7ad131"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="195"
name="History"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-05-23T13:17:43.359728Z"
checksum="e2f2e94deecb241553c015ce59c21d63"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="158"
name="rails-migration-minor-mode.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-03T08:45:46.583854Z"
checksum="2406300809ecb99408c5a77a648ff1f2"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="175"
name="rails-snippets-feature.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-09T20:43:17.709512Z"
checksum="76f2e86cc39862cb7b72ce91a104b1ba"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="173"
name="rails-controller-layout.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-09T15:15:02.948563Z"
checksum="c08fc2ed67f91a17c20b063944d6bbaf"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="150"
name="rails-navigation.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-03-29T20:48:17.306385Z"
checksum="e74c32132476cc5ad0b95a5f0cfffc25"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="166"
name="rails-unit-test-minor-mode.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-05T17:44:57.852223Z"
checksum="5b7117cf7a4c0506bf4b5e204dd0f8e3"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="112"
name="rails-plugin-minor-mode.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-03-24T22:34:38.702927Z"
checksum="5cfc55fe4e4e089f25b27921c0a377af"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="158"
name="rails-model-minor-mode.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-03T08:45:46.583854Z"
checksum="f40f8925c4472b1177cd52d8dfa52a3b"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="168"
name="rails-lib.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-06T19:10:55.478033Z"
checksum="b3ed620251a83ffb892d6e251dac2618"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="150"
name="rails-project.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-03-29T20:48:17.306385Z"
checksum="3c10d676188773c064875a676df86ef1"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="173"
name="rails-model-layout.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-09T15:15:02.948563Z"
checksum="16168bf215bc4280283052f59b9ca884"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="173"
name="rails-ui.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-09T15:15:02.948563Z"
checksum="9668e230cac8f7542a029264573d8ea6"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="180"
name="predictive-prog-mode.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-13T07:46:13.286257Z"
checksum="5456931a84bf4df089965504945ae984"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="158"
name="rails-mailer-minor-mode.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-03T08:45:46.583854Z"
checksum="43744fbdd30dc3bd1dabc6c3a32f31a9"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="173"
name="rails-view-minor-mode.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-09T15:15:02.948563Z"
checksum="ec42613c4f153c903d008e19f43d80c7"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="129"
name="rails-find.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-03-26T18:41:17.255582Z"
checksum="fa86732ab6b4883bd1125aa8f5c63a83"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="194"
name="ChangeLog"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-05-23T13:00:56.914307Z"
checksum="cd020d0f49fe517e8c07c7cea6e4178b"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="112"
name="rails-layout-minor-mode.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-03-24T22:34:38.702927Z"
checksum="e6022a9ae89560efcfb943727658aa54"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="190"
name="rails-ruby.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-27T19:04:46.497001Z"
checksum="c04d4f60cc74062e0769699ae54cafe1"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="158"
name="rails-cmd-proxy.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-03T08:45:46.583854Z"
checksum="046a63af5d98771235ed6278a1e94f6c"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="166"
name="rails-functional-test-minor-mode.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-05T17:44:57.852223Z"
checksum="ebc8f72eed25bd5892063006f6132fec"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="158"
name="rails-helper-minor-mode.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-03T08:45:46.583854Z"
checksum="a306b8a8029136a80da66d10246f8b10"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="180"
name="README"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-13T07:46:13.286257Z"
checksum="99ba2c62118944609e8e0af5ad280e87"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="192"
name="rails-scripts.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-05-03T11:54:30.161391Z"
checksum="c78ff0833bab82e4272bb83bcc11989a"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="150"
name="rails-ws.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-03-29T20:48:17.306385Z"
checksum="33d262a5dd99e218268c8ec5ba368b4b"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="158"
name="rails-fixture-minor-mode.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-03T08:45:46.583854Z"
checksum="e71af8c0d4ea797c3e090fe407c3eaa7"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="193"
name="rails.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-05-05T18:37:00.576671Z"
checksum="ca3e19b714c46452c92b935e9ddf4e3a"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
<entry
committed-rev="178"
name="inflections.el"
text-time="2007-06-19T20:24:39.000000Z"
committed-date="2007-04-12T20:58:56.166697Z"
checksum="42ea8dafe9bb35dcd18cd354aecb3649"
last-author="dimaexe"
kind="file"
prop-time="2007-06-19T20:24:39.000000Z"/>
</wc-entries>

View file

@ -0,0 +1 @@
4

View file

@ -0,0 +1,5 @@
K 13
svn:eol-style
V 6
native
END

View file

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 13
svn:eol-style
V 6
native
END

View file

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,9 @@
K 13
svn:eol-style
V 6
native
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

View file

@ -0,0 +1,5 @@
K 12
svn:keywords
V 6
Id URL
END

Some files were not shown because too many files have changed in this diff Show more