Permalink
Browse files

Added import jumping/navigation.

  • Loading branch information...
1 parent f0c3195 commit a9e9e959c1979b964320201554145381ea73613e @chrisdone chrisdone committed Mar 17, 2012
Showing with 112 additions and 0 deletions.
  1. +1 −0 Makefile
  2. +1 −0 haskell-mode.el
  3. +110 −0 haskell-navigate-imports.el
View
@@ -16,6 +16,7 @@ ELFILES = \
haskell-sort-imports.el \
haskell-align-imports.el \
haskell-move-nested.el \
+ haskell-navigate-imports.el \
ghc-core.el \
inf-haskell.el
View
@@ -247,6 +247,7 @@ be set to the preferred literate style."
(define-key map (kbd "C-c C-d") 'inferior-haskell-find-haddock)
(define-key map (kbd "C-c C-.") 'haskell-mode-format-imports)
+ (define-key map (kbd "C-c i") 'haskell-navigate-imports)
(define-key map [?\C-c ?\C-v] 'haskell-check)
View
@@ -0,0 +1,110 @@
+;; haskell-navigate-imports.el — A function for cycling through Haskell import lists.
+;; Copyright (C) 2010 Chris Done <chrisdone@gmail.com>
+
+;; The cycling step will stop once at the last import list so
+;; that it is easy to add a new import list.
+
+;; This module works completely independently of any libraries
+;; (including haskell-mode).
+
+;; Exports three interactive functions:
+;; 1. haskell-navigate-imports
+;; 2. haskell-navigate-imports-go
+;; 3. haskell-navigate-imports-return
+
+;; Example usage:
+
+;; (require 'haskell-navigate-imports)
+;; (define-key haskell-mode-map [f8] 'haskell-navigate-imports)
+
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of
+;; the License, or (at your option) any later version.
+
+;; This program is distributed in the hope that it will be
+;; useful, but WITHOUT ANY WARRANTY; without even the implied
+;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+;; PURPOSE. See the GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public
+;; License along with this program. If not, see
+;; <http://www.gnu.org/licenses/>.
+
+(defvar haskell-navigate-imports-start-point nil)
+
+;;;###autoload
+(defun haskell-navigate-imports (&optional return)
+ "Cycle the Haskell import lines or return to point (with prefix arg)."
+ (interactive "P")
+ (if return
+ (haskell-navigate-imports-return)
+ (haskell-navigate-imports-go)))
+
+;;;###autoload
+(defun haskell-navigate-imports-go ()
+ "Go to the first line of a list of consequtive import lines. Cycles."
+ (interactive)
+ (unless (or (haskell-navigate-imports-line)
+ (equal (line-beginning-position) (point-min))
+ (save-excursion (previous-line)
+ (haskell-navigate-imports-line)))
+ (setq haskell-navigate-imports-start-point (point)))
+ (haskell-navigate-imports-go-internal))
+
+;;;###autoload
+(defun haskell-navigate-imports-return ()
+ "Return to the non-import point we were at before going to the module list.
+ If we were originally at an import list, we can just cycle through easily."
+ (interactive)
+ (when haskell-navigate-imports-start-point
+ (goto-char haskell-navigate-imports-start-point)))
+
+(defun haskell-navigate-imports-go-internal ()
+ "Go to the first line of a list of consequtive import lines. Cycle."
+ (if (haskell-navigate-imports-line)
+ (progn (haskell-navigate-imports-goto-end)
+ (when (haskell-navigate-imports-find-forward-line)
+ (haskell-navigate-imports-go-internal)))
+ (let ((point (haskell-navigate-imports-find-forward-line)))
+ (if point
+ (goto-char point)
+ (progn (goto-char (point-min))
+ (when (haskell-navigate-imports-find-forward-line)
+ (haskell-navigate-imports-go-internal)))))))
+
+(defun haskell-navigate-imports-goto-end ()
+ "Skip a bunch of consequtive import lines."
+ (while (not (or (equal (point)
+ (point-max))
+ (not (haskell-navigate-imports-line))))
+ (forward-line)))
+
+(defun haskell-navigate-imports-find-forward-line ()
+ "Return a point with at an import line, or nothing."
+ (save-excursion
+ (while (not (or (equal (point) (point-max))
+ (haskell-navigate-imports-after-imports-p) ;; This one just speeds it up.
+ (haskell-navigate-imports-line)))
+ (forward-line))
+ (let ((point (point)))
+ (if (haskell-navigate-imports-line)
+ (point)
+ nil))))
+
+(defun haskell-navigate-imports-line ()
+ "Try to match the current line as a regexp."
+ (let ((line (buffer-substring-no-properties (line-beginning-position)
+ (line-end-position))))
+ (if (string-match "^import " line)
+ line
+ nil)))
+
+(defun haskell-navigate-imports-after-imports-p ()
+ "Are we after the imports list? Just for a speed boost."
+ (save-excursion
+ (goto-char (line-beginning-position))
+ (not (not (search-forward-regexp "\\( = \\|\\<instance\\>\\| :: \\)"
+ (line-end-position) t 1)))))
+
+(provide 'haskell-navigate-imports)

0 comments on commit a9e9e95

Please sign in to comment.