diff --git a/haskell-decl-scan.el b/haskell-decl-scan.el index 49ac80e78..7519e4d3b 100644 --- a/haskell-decl-scan.el +++ b/haskell-decl-scan.el @@ -2,6 +2,7 @@ ;; Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. ;; Copyright (C) 1997-1998 Graeme E Moss +;; Copyright (C) 2016 Chris Gregory ;; Author: 1997-1998 Graeme E Moss ;; Maintainer: Stefan Monnier @@ -354,7 +355,38 @@ there." "Move forward to the first character that starts a top-level declaration. As `haskell-ds-backward-decl' but forward." (interactive) - (haskell-ds-move-to-decl t (haskell-ds-bird-p) nil)) + (let ((p (point)) b e empty was-at-bob) + ;; Go back to beginning of defun, then go to beginning of next + (haskell-ds-move-to-decl nil (haskell-ds-bird-p) nil) + (setq b (point)) + (haskell-ds-move-to-decl t (haskell-ds-bird-p) nil) + (setq e (point)) + ;; tests if line is empty + (setq empty (and (<= (point) p) + (not (eolp)))) + (setq was-at-bob (and (= (point-min) b) + (= b p) + (< p e))) + ;; this conditional allows for when empty lines at end, first + ;; `C-M-e' will go to end of defun, next will go to end of file. + (when (or was-at-bob + empty) + (if (or (and was-at-bob + (= ?\n + (save-excursion + (goto-char (point-min)) + (following-char)))) + empty) + (haskell-ds-move-to-decl t (haskell-ds-bird-p) nil)) + ;; Then go back to end of current + (forward-line -1) + (while (and (eolp) + ;; prevent infinite loop + (not (= (point) + (point-min)))) + (forward-line -1)) + (forward-line 1))) + (point)) (defun haskell-ds-generic-find-next-decl (bird-literate) "Find the name, position and type of the declaration at or after point. diff --git a/tests/haskell-decl-scan-tests.el b/tests/haskell-decl-scan-tests.el new file mode 100644 index 000000000..a20d1c589 --- /dev/null +++ b/tests/haskell-decl-scan-tests.el @@ -0,0 +1,97 @@ +;;; haskell-decl-scan-tests.el -*- lexical-binding: t -*- + +;; Copyright © 2016 Chris Gregory. All rights reserved. + +;; This file is part of haskell-mode package. +;; You can contact with authors using GitHub issue tracker: +;; https://github.com/haskell/haskell-mode/issues + +;; This file is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; This file is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; This package provides regression tests for haskell-decl-scan package. + +;;; Code: + +(require 'ert) +(require 'haskell-decl-scan) +(require 'haskell-test-utils) + +(ert-deftest haskell-ds-backward-decl-1 () + "Test running haskell-ds-backward-decl" + (with-temp-buffer + (insert-lines "" "fun :: Int -> Int" "fun = id" + "" "f2 :: Int" "f2 = 3" "") + (goto-char (point-max)) + (should (haskell-ds-backward-decl)) + (should (looking-at-p "f2 :: Int")) + (should (haskell-ds-backward-decl)) + (should (looking-at-p "fun :: Int -> Int")) + (should-not (haskell-ds-backward-decl)) + (should (= (point-min) (point))))) + +(ert-deftest haskell-ds-backward-decl-2 () + "Test running haskell-ds-backward-decl" + (with-temp-buffer + (insert-lines "" "" "fun :: Int -> Int" + "" "" "fun = id" + "" "" "f2 :: Int" + "" "" "f2 = 3" + "" "" "") + (goto-char (point-max)) + (should (haskell-ds-backward-decl)) + (should (looking-at-p "f2 :: Int")) + (should (haskell-ds-backward-decl)) + (should (looking-at-p "fun :: Int -> Int")) + (should-not (haskell-ds-backward-decl)) + (should (= (point-min) (point))))) + +(ert-deftest haskell-ds-forward-decl-1 () + "Test running haskell-ds-backward-decl" + (with-temp-buffer + (insert-lines "" "fun :: Int -> Int" "fun = id" + "" "f2 :: Int" "f2 = 3" + "") + (goto-char (point-min)) + (should (haskell-ds-forward-decl)) + (should (looking-at-p "$")) + (should (= (point) (save-excursion (goto-line 4) (point)))) + (should (haskell-ds-forward-decl)) + (should (looking-at-p "f2 :: Int")) + (should (= (point-max) (haskell-ds-forward-decl))))) + +(ert-deftest haskell-ds-forward-decl-2 () + "Test running haskell-ds-backward-decl" + (with-temp-buffer + (insert-lines "" "" "fun :: Int -> Int" + "" "" "fun = id" + "" "" "f2 :: Int" + "" "" "f2 = 3" + "" "" "") + (goto-char (point-min)) + (should (haskell-ds-forward-decl)) + (should (looking-at-p "$")) + (should (= (point) (save-excursion (goto-line 7) (point)))) + (should (haskell-ds-forward-decl)) + (should (looking-at-p "f2 :: Int")) + (should (haskell-ds-forward-decl)) + (should (= (point) (save-excursion (goto-line 13) (point)))) + (should (= (point-max) (progn (haskell-ds-forward-decl) (point)))))) + +(provide 'haskell-decl-scan-tests) + +;;; haskell-decl-scan-tests.el ends here