summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xautogen/configure25
-rw-r--r--lisp/ChangeLog10
-rw-r--r--lisp/progmodes/gud.el30
-rw-r--r--lisp/progmodes/python.el9
-rw-r--r--lisp/progmodes/sh-script.el4
-rw-r--r--src/ChangeLog19
-rw-r--r--src/w32fns.c72
-rw-r--r--src/w32term.c108
-rw-r--r--src/w32term.h11
-rw-r--r--test/ChangeLog4
-rw-r--r--test/automated/imenu-test.el87
11 files changed, 276 insertions, 103 deletions
diff --git a/autogen/configure b/autogen/configure
index 8e69c9ceffc..7ddac01fb10 100755
--- a/autogen/configure
+++ b/autogen/configure
@@ -4640,6 +4640,11 @@ case "${canonical}" in
opsys=freebsd
;;
+ ## DragonFly ports
+ *-*-dragonfly* )
+ opsys=dragonfly
+ ;;
+
## FreeBSD kernel + glibc based userland
*-*-kfreebsd*gnu* )
opsys=gnu-kfreebsd
@@ -8462,7 +8467,7 @@ esac
LD_SWITCH_SYSTEM=
case "$opsys" in
- freebsd)
+ freebsd|dragonfly)
## Let `ld' find image libs and similar things in /usr/local/lib.
## The system compiler, GCC, has apparently been modified to not
## look there, contrary to what a stock GCC would do.
@@ -8552,7 +8557,7 @@ case "$opsys" in
## IBM's X11R5 uses -lIM and -liconv in AIX 3.2.2.
aix4-2) LIBS_SYSTEM="-lrts -lIM -liconv" ;;
- freebsd) LIBS_SYSTEM="-lutil" ;;
+ freebsd|dragonfly) LIBS_SYSTEM="-lutil" ;;
hpux*) LIBS_SYSTEM="-l:libdld.sl" ;;
@@ -8589,7 +8594,7 @@ case $opsys in
## Adding -lm confuses the dynamic linker, so omit it.
LIB_MATH=
;;
- freebsd )
+ freebsd | dragonfly )
SYSTEM_TYPE=berkeley-unix
;;
gnu-linux | gnu-kfreebsd )
@@ -13783,7 +13788,7 @@ mail_lock=no
case "$opsys" in
aix4-2) mail_lock="lockf" ;;
- gnu|freebsd|netbsd|openbsd|darwin|irix6-5) mail_lock="flock" ;;
+ gnu|freebsd|dragonfly|netbsd|openbsd|darwin|irix6-5) mail_lock="flock" ;;
## On GNU/Linux systems, both methods are used by various mail programs.
## I assume most people are using newer mailers that have heard of flock.
@@ -14150,7 +14155,7 @@ $as_echo "$emacs_cv_freebsd_terminfo" >&6; }
fi
;;
- openbsd) LIBS_TERMCAP="-lncurses" ;;
+ openbsd | dragonfly) LIBS_TERMCAP="-lncurses" ;;
## hpux: Make sure we get select from libc rather than from libcurses
## because libcurses on HPUX 10.10 has a broken version of select.
@@ -15527,7 +15532,7 @@ $as_echo "#define HAVE_PROCFS 1" >>confdefs.h
esac
case $opsys in
- darwin | freebsd | netbsd | openbsd )
+ darwin | dragonfly | freebsd | netbsd | openbsd )
$as_echo "#define DONT_REOPEN_PTY 1" >>confdefs.h
@@ -15609,7 +15614,7 @@ case $opsys in
;;
- gnu-linux | gnu-kfreebsd | freebsd | netbsd )
+ gnu-linux | gnu-kfreebsd | dragonfly | freebsd | netbsd )
if test "x$ac_cv_func_grantpt" = xyes; then
$as_echo "#define UNIX98_PTYS 1" >>confdefs.h
@@ -15688,7 +15693,7 @@ esac
case $opsys in
- aix4-2 | cygwin | gnu | irix6-5 | freebsd | netbsd | openbsd | darwin )
+ aix4-2 | cygwin | gnu | irix6-5 | dragonfly | freebsd | netbsd | openbsd | darwin )
$as_echo "#define SIGNALS_VIA_CHARACTERS 1" >>confdefs.h
;;
@@ -15752,7 +15757,7 @@ case $opsys in
darwin) $as_echo "#define TAB3 OXTABS" >>confdefs.h
;;
- gnu | freebsd | netbsd | openbsd )
+ gnu | dragonfly | freebsd | netbsd | openbsd )
$as_echo "#define TABDLY OXTABS" >>confdefs.h
@@ -15831,7 +15836,7 @@ if test x$GCC = xyes; then
else
case $opsys in
- freebsd | netbsd | openbsd | irix6-5 | sol2* )
+ dragonfly | freebsd | netbsd | openbsd | irix6-5 | sol2* )
$as_echo "#define GC_SETJMP_WORKS 1" >>confdefs.h
;;
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index a09d37352f7..9bb155b74da 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,13 @@
+2013-04-19 Masatake YAMATO <yamato@redhat.com>
+
+ * progmodes/sh-script.el (sh-imenu-generic-expression): Handle
+ function names with a single character. (Bug#11182)
+
+2013-04-19 Dima Kogan <dima@secretsauce.net> (tiny change)
+
+ * progmodes/gud.el (gud-perldb-marker-filter): Understand position info
+ for subroutines defined in an eval (bug#14182).
+
2013-04-19 Thierry Volpiatto <thierry.volpiatto@gmail.com>
* bookmark.el (bookmark-completing-read): Improve handling of empty
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index d339495d76a..4e31c5e827c 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -1487,14 +1487,38 @@ into one that invokes an Emacs-enabled debugging session.
(let ((output ""))
;; Process all the complete markers in this chunk.
- (while (string-match "\032\032\\(\\([a-zA-Z]:\\)?[^:\n]*\\):\\([0-9]*\\):.*\n"
- gud-marker-acc)
+ ;;
+ ;; Here I match the string coming out of perldb.
+ ;; The strings can look like any of
+ ;;
+ ;; "\032\032/tmp/tst.pl:6:0\n"
+ ;; "\032\032(eval 5)[/tmp/tst.pl:6]:3:0\n"
+ ;; "\032\032(eval 17)[Basic/Core/Core.pm.PL (i.e. PDL::Core.pm):2931]:1:0\n"
+ ;;
+ ;; From those I want the filename and the line number. First I look for
+ ;; the eval case. If that doesn't match, I look for the "normal" case.
+ (while
+ (string-match
+ (eval-when-compile
+ (let ((file-re "\\(?:[a-zA-Z]:\\)?[^:\n]*"))
+ (concat "\032\032\\(?:"
+ (concat
+ "(eval [0-9]+)\\["
+ "\\(" file-re "\\)" ; Filename.
+ "\\(?: (i\\.e\\. [^)]*)\\)?"
+ ":\\([0-9]*\\)\\]") ; Line number.
+ "\\|"
+ (concat
+ "\\(?1:" file-re "\\)" ; Filename.
+ ":\\(?2:[0-9]*\\)") ; Line number.
+ "\\):.*\n")))
+ gud-marker-acc)
(setq
;; Extract the frame position from the marker.
gud-last-frame
(cons (match-string 1 gud-marker-acc)
- (string-to-number (match-string 3 gud-marker-acc)))
+ (string-to-number (match-string 2 gud-marker-acc)))
;; Append any text before the marker to the output we're going
;; to return - we don't include the marker in this text.
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 06d07d6ee3c..2165c835057 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -3176,6 +3176,7 @@ To this:
(\"decorator\" . 173)
(\"decorator.wrap\" . 353)
(\"decorator.wrapped_f\" . 393))"
+ ;; Inspired by imenu--flatten-index-alist removed in revno 21853.
(apply
'nconc
(mapcar
@@ -3187,14 +3188,14 @@ To this:
(cond ((or (numberp pos) (markerp pos))
(list (cons name pos)))
((listp pos)
- (message "%S" item)
(cons
(cons name (cdar pos))
(python-imenu-create-flat-index (cddr item) name))))))
(or alist
- (let ((python-imenu-format-item-label-function (lambda (type name) name))
- (python-imenu-format-parent-item-label-function (lambda (type name) name))
- (python-imenu-format-parent-item-jump-label-function (lambda (type name) name)))
+ (let* ((fn (lambda (type name) name))
+ (python-imenu-format-item-label-function fn)
+ (python-imenu-format-parent-item-label-function fn)
+ (python-imenu-format-parent-item-jump-label-function fn))
(python-imenu-create-index))))))
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index e197f9cfabe..07e9bb85c4e 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -335,11 +335,11 @@ shell it really is."
. ((nil
;; function FOO
;; function FOO()
- "^\\s-*function\\s-+\\\([[:alpha:]_][[:alnum:]_]+\\)\\s-*\\(?:()\\)?"
+ "^\\s-*function\\s-+\\\([[:alpha:]_][[:alnum:]_]*\\)\\s-*\\(?:()\\)?"
1)
;; FOO()
(nil
- "^\\s-*\\([[:alpha:]_][[:alnum:]_]+\\)\\s-*()"
+ "^\\s-*\\([[:alpha:]_][[:alnum:]_]*\\)\\s-*()"
1)
)))
"Alist of regular expressions for recognizing shell function definitions.
diff --git a/src/ChangeLog b/src/ChangeLog
index 04a6c353619..5164dc8ff8d 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,22 @@
+2013-04-20 Erik Charlebois <erikcharlebois@gmail.com>
+
+ * w32fns.c (w32_fullscreen_rect): New function to compute the
+ window rectangle for the given fullscreen mode.
+ (w32_wnd_proc): When in a fullscreen mode, WM_WINDOWPOSCHANGING no
+ longer tunes the window size. This keeps the window's edges flush
+ with the screen and allows the taskbar to hide itself in fullboth.
+
+ * w32term.c (w32fullscreen_hook): 'fullboth' now shows without
+ window decorations and uses the entire screen.
+
+ * w32term.h (w32_fullscreen_rect) Add prototype.
+ (struct w32_output): Replace normal_width, normal_height,
+ normal_top, and normal_left members with a single normal_placement
+ struct.
+ (FRAME_NORMAL_WIDTH, FRAME_NORMAL_HEIGHT, FRAME_NORMAL_TOP):
+ Remove macros.
+ (FRAME_NORMAL_PLACEMENT): New macro.
+
2013-04-16 Juanma Barranquero <lekktu@gmail.com>
* minibuf.c (Ftest_completion): Silence compiler warning.
diff --git a/src/w32fns.c b/src/w32fns.c
index de52ff144e3..0785e685e6a 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -157,6 +157,8 @@ typedef HWND (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context,
typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags);
typedef BOOL (WINAPI * GetMonitorInfo_Proc)
(IN HMONITOR monitor, OUT struct MONITOR_INFO* info);
+typedef HMONITOR (WINAPI * MonitorFromWindow_Proc)
+ (IN HWND hwnd, IN DWORD dwFlags);
TrackMouseEvent_Proc track_mouse_event_fn = NULL;
ImmGetCompositionString_Proc get_composition_string_fn = NULL;
@@ -165,6 +167,7 @@ ImmReleaseContext_Proc release_ime_context_fn = NULL;
ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL;
MonitorFromPoint_Proc monitor_from_point_fn = NULL;
GetMonitorInfo_Proc get_monitor_info_fn = NULL;
+MonitorFromWindow_Proc monitor_from_window_fn = NULL;
#ifdef NTGUI_UNICODE
#define unicode_append_menu AppendMenuW
@@ -336,6 +339,66 @@ x_real_positions (FRAME_PTR f, int *xptr, int *yptr)
*yptr = rect.top;
}
+/* Returns the window rectangle appropriate for the given fullscreen mode.
+ The normal rect parameter was the window's rectangle prior to entering
+ fullscreen mode. If multiple monitor support is available, the nearest
+ monitor to the window is chosen. */
+
+void
+w32_fullscreen_rect (HWND hwnd, int fsmode, RECT normal, RECT *rect)
+{
+ struct MONITOR_INFO mi = { sizeof(mi) };
+ if (monitor_from_window_fn && get_monitor_info_fn)
+ {
+ HMONITOR monitor =
+ monitor_from_window_fn (hwnd, MONITOR_DEFAULT_TO_NEAREST);
+ get_monitor_info_fn (monitor, &mi);
+ }
+ else
+ {
+ mi.rcMonitor.left = 0;
+ mi.rcMonitor.top = 0;
+ mi.rcMonitor.right = GetSystemMetrics (SM_CXSCREEN);
+ mi.rcMonitor.bottom = GetSystemMetrics (SM_CYSCREEN);
+ mi.rcWork.left = 0;
+ mi.rcWork.top = 0;
+ mi.rcWork.right = GetSystemMetrics (SM_CXMAXIMIZED);
+ mi.rcWork.bottom = GetSystemMetrics (SM_CYMAXIMIZED);
+ }
+
+ switch (fsmode)
+ {
+ case FULLSCREEN_BOTH:
+ rect->left = mi.rcMonitor.left;
+ rect->top = mi.rcMonitor.top;
+ rect->right = mi.rcMonitor.right;
+ rect->bottom = mi.rcMonitor.bottom;
+ break;
+ case FULLSCREEN_MAXIMIZED:
+ rect->left = mi.rcWork.left;
+ rect->top = mi.rcWork.top;
+ rect->right = mi.rcWork.right;
+ rect->bottom = mi.rcWork.bottom;
+ break;
+ case FULLSCREEN_WIDTH:
+ rect->left = mi.rcWork.left;
+ rect->top = normal.top;
+ rect->right = mi.rcWork.right;
+ rect->bottom = normal.bottom;
+ break;
+ case FULLSCREEN_HEIGHT:
+ rect->left = normal.left;
+ rect->top = mi.rcWork.top;
+ rect->right = normal.right;
+ rect->bottom = mi.rcWork.bottom;
+ break;
+ case FULLSCREEN_NONE:
+ default:
+ *rect = normal;
+ break;
+ }
+}
+
DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color,
@@ -3693,6 +3756,13 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
/* Don't restrict the sizing of tip frames. */
if (hwnd == tip_window)
return 0;
+
+ /* Don't restrict the sizing of fullscreened frames, allowing them to be
+ flush with the sides of the screen. */
+ f = x_window_to_frame (dpyinfo, hwnd);
+ if (f && FRAME_PREV_FSMODE (f) != FULLSCREEN_NONE)
+ return 0;
+
{
WINDOWPLACEMENT wp;
LPWINDOWPOS lppos = (WINDOWPOS *) lParam;
@@ -7637,6 +7707,8 @@ globals_of_w32fns (void)
GetProcAddress (user32_lib, "MonitorFromPoint");
get_monitor_info_fn = (GetMonitorInfo_Proc)
GetProcAddress (user32_lib, "GetMonitorInfoA");
+ monitor_from_window_fn = (MonitorFromWindow_Proc)
+ GetProcAddress (user32_lib, "MonitorFromWindow");
{
HMODULE imm32_lib = GetModuleHandle ("imm32.dll");
diff --git a/src/w32term.c b/src/w32term.c
index d249d6e3252..58b1d3ca308 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -5663,88 +5663,40 @@ w32fullscreen_hook (FRAME_PTR f)
{
if (FRAME_VISIBLE_P (f))
{
- int width, height, top_pos, left_pos, pixel_height, pixel_width;
- int cur_w = FRAME_COLS (f), cur_h = FRAME_LINES (f);
- RECT workarea_rect;
+ HWND hwnd = FRAME_W32_WINDOW(f);
+ DWORD dwStyle = GetWindowLong (hwnd, GWL_STYLE);
+ RECT rect;
- block_input ();
- /* Record current "normal" dimensions for restoring later. */
- if (!( FRAME_PREV_FSMODE (f) == FULLSCREEN_BOTH
- || FRAME_PREV_FSMODE (f) == FULLSCREEN_MAXIMIZED))
- {
- if (FRAME_PREV_FSMODE (f) != FULLSCREEN_HEIGHT)
- {
- FRAME_NORMAL_HEIGHT (f) = cur_h;
- FRAME_NORMAL_TOP (f) = f->top_pos;
- }
- if (FRAME_PREV_FSMODE (f) != FULLSCREEN_WIDTH)
- {
- FRAME_NORMAL_WIDTH (f) = cur_w;
- FRAME_NORMAL_LEFT (f) = f->left_pos;
- }
- }
- eassert (FRAME_NORMAL_HEIGHT (f) > 0);
- eassert (FRAME_NORMAL_WIDTH (f) > 0);
- x_real_positions (f, &f->left_pos, &f->top_pos);
- x_fullscreen_adjust (f, &width, &height, &top_pos, &left_pos);
-
- SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0);
- pixel_height = workarea_rect.bottom - workarea_rect.top;
- pixel_width = workarea_rect.right - workarea_rect.left;
- /* Need to send SC_RESTORE to the window, in case we are
- resizing from FULLSCREEN_MAXIMIZED. Otherwise, the mouse
- resize hints will not be shown by the window manager when the
- mouse pointer hovers over the window edges, because the WM
- will still think the window is maximized. */
- if (f->want_fullscreen != FULLSCREEN_BOTH)
- SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_RESTORE, 0);
+ block_input();
+ f->want_fullscreen &= ~FULLSCREEN_WAIT;
+
+ if (FRAME_PREV_FSMODE (f) == FULLSCREEN_NONE)
+ GetWindowPlacement (hwnd, &FRAME_NORMAL_PLACEMENT (f));
+
+ if (FRAME_PREV_FSMODE (f) == FULLSCREEN_BOTH)
+ {
+ SetWindowLong (hwnd, GWL_STYLE, dwStyle | WS_OVERLAPPEDWINDOW);
+ SetWindowPos (hwnd, NULL, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
+ SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
+ }
+ w32_fullscreen_rect (hwnd, f->want_fullscreen,
+ FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect);
FRAME_PREV_FSMODE (f) = f->want_fullscreen;
- switch (f->want_fullscreen)
- {
- case FULLSCREEN_BOTH:
- PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MAXIMIZE, 0);
- break;
- case FULLSCREEN_MAXIMIZED:
- height =
- FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height)
- - XINT (Ftool_bar_lines_needed (selected_frame))
- + (NILP (Vmenu_bar_mode) ? 1 : 0);
- width =
- FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width)
- - FRAME_SCROLL_BAR_COLS (f);
- left_pos = workarea_rect.left;
- top_pos = workarea_rect.top;
- break;
- case FULLSCREEN_WIDTH:
- width =
- FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width)
- - FRAME_SCROLL_BAR_COLS (f);
- height = FRAME_NORMAL_HEIGHT (f);
- left_pos = workarea_rect.left;
- break;
- case FULLSCREEN_HEIGHT:
- height =
- FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height)
- - XINT (Ftool_bar_lines_needed (selected_frame))
- + (NILP (Vmenu_bar_mode) ? 1 : 0);
- width = FRAME_NORMAL_WIDTH (f);
- top_pos = workarea_rect.top;
- break;
- case FULLSCREEN_NONE:
- height = FRAME_NORMAL_HEIGHT (f);
- width = FRAME_NORMAL_WIDTH (f);
- left_pos = FRAME_NORMAL_LEFT (f);
- top_pos = FRAME_NORMAL_TOP (f);
- break;
- }
+ if (f->want_fullscreen == FULLSCREEN_BOTH)
+ {
+ SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW);
+ SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top,
+ SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
+ }
+ else
+ {
+ SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top, 0);
+ }
- if (cur_w != width || cur_h != height)
- {
- x_set_offset (f, left_pos, top_pos, 1);
- x_set_window_size (f, 1, width, height);
- do_pending_window_change (0);
- }
f->want_fullscreen = FULLSCREEN_NONE;
unblock_input ();
}
diff --git a/src/w32term.h b/src/w32term.h
index 9bb37b31ef5..9c27c09d03d 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -71,6 +71,8 @@ struct w32_palette_entry {
};
extern void w32_regenerate_palette (struct frame *f);
+extern void w32_fullscreen_rect (HWND hwnd, int fsmode, RECT normal,
+ RECT *rect);
/* For each display (currently only one on w32), we have a structure that
@@ -362,7 +364,7 @@ struct w32_output
/* Frame geometry and full-screen mode before it was resized by
specifying the 'fullscreen' frame parameter. Used to restore the
geometry when 'fullscreen' is reset to nil. */
- int normal_width, normal_height, normal_top, normal_left;
+ WINDOWPLACEMENT normal_placement;
int prev_fsmode;
};
@@ -396,11 +398,8 @@ extern struct w32_output w32term_display;
#define FRAME_SMALLEST_FONT_HEIGHT(F) \
FRAME_W32_DISPLAY_INFO(F)->smallest_font_height
-#define FRAME_NORMAL_WIDTH(F) ((F)->output_data.w32->normal_width)
-#define FRAME_NORMAL_HEIGHT(F) ((F)->output_data.w32->normal_height)
-#define FRAME_NORMAL_TOP(F) ((F)->output_data.w32->normal_top)
-#define FRAME_NORMAL_LEFT(F) ((F)->output_data.w32->normal_left)
-#define FRAME_PREV_FSMODE(F) ((F)->output_data.w32->prev_fsmode)
+#define FRAME_NORMAL_PLACEMENT(F) ((F)->output_data.w32->normal_placement)
+#define FRAME_PREV_FSMODE(F) ((F)->output_data.w32->prev_fsmode)
/* W32-specific scroll bar stuff. */
diff --git a/test/ChangeLog b/test/ChangeLog
index 0c240394c5c..52cc61bdc06 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,7 @@
+2013-04-01 Masatake YAMATO <yamato@redhat.com>
+
+ * automated/imenu-tests.el: New file. (Bug#14112)
+
2013-04-19 Fabián Ezequiel Gallina <fgallina@gnu.org>
* automated/python-tests.el (python-imenu-prev-index-position-1):
diff --git a/test/automated/imenu-test.el b/test/automated/imenu-test.el
new file mode 100644
index 00000000000..83e19ebd914
--- /dev/null
+++ b/test/automated/imenu-test.el
@@ -0,0 +1,87 @@
+;;; imenu-tests.el --- Test suite for imenu.
+
+;; Copyright (C) 2013 Free Software Foundation, Inc.
+
+;; Author: Masatake YAMATO <yamato@redhat.com>
+;; Keywords: tools convenience
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'imenu)
+
+;; (imenu-simple-scan-deftest-gather-strings-from-list
+;; '(nil t 'a (0 . "x") ("c" . "d") ("a" 0 "b") ))
+;; => ("b" "a" "d" "c" "x")
+(defun imenu-simple-scan-deftest-gather-strings-from-list(input)
+ "Gather strings from INPUT, a list."
+ (let ((result ()))
+ (while input
+ (cond
+ ((stringp input)
+ (setq result (cons input result)
+ input nil))
+ ((atom input)
+ (setq input nil))
+ ((listp (car input))
+ (setq result (append
+ (imenu-simple-scan-deftest-gather-strings-from-list (car input))
+ result)
+ input (cdr input)))
+ ((stringp (car input))
+ (setq result (cons (car input) result)
+ input (cdr input)))
+ (t
+ (setq input (cdr input)))))
+ result))
+
+(defmacro imenu-simple-scan-deftest (name doc major-mode content expected-items)
+ "Generate an ert test for mode-own imenu expression.
+Run `imenu-create-index-function' at the buffer which content is
+CONTENT with MAJOR-MODE. A generated test runs `imenu-create-index-function'
+at the buffer which content is CONTENT with MAJOR-MODE. Then it compares a list
+of strings which are picked up from the result with EXPECTED-ITEMS."
+ (let ((xname (intern (concat "imenu-simple-scan-deftest-" (symbol-name name)))))
+ `(ert-deftest ,xname ()
+ ,doc
+ (with-temp-buffer
+ (insert ,content)
+ (funcall ',major-mode)
+ (let ((result-items (sort (imenu-simple-scan-deftest-gather-strings-from-list
+ (funcall imenu-create-index-function))
+ #'string-lessp))
+ (expected-items (sort (copy-sequence ,expected-items) #'string-lessp)))
+ (should (equal result-items expected-items))
+ )))))
+
+(imenu-simple-scan-deftest sh "Test imenu expression for sh-mode." sh-mode "a()
+{
+}
+function b
+{
+}
+function c()
+{
+}
+function ABC_D()
+{
+}
+" '("a" "b" "c" "ABC_D"))
+
+(provide 'imenu-tests)
+
+;;; imenu-tests.el ends here