;; Emacs lisp mode for editing java files.
;; @(#)java-mode.el	1.2 28 Mar 1995  Mitch Chapman
;;
;; java-mode.el
;; ------------
;; Major mode for editing Java programs.
;; java-mode is an extension of c++-mode, and it uses alot of variables
;; from that mode.
;;
;; Author:  Mitch Chapman
;;          Ohio Electronic Engravers, Inc., Dayton, OH  USA
;;

;; Maintainer: none
;; Keywords: languages, major modes

;; This file is *NOT* part of GNU Emacs.

;; java-mode.el 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.

;; java-mode.el 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 java-mode.el; see the file COPYING.  If not, write to
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.

;;; Commentary:

;; This module derives an editing mode from c++-mode.  The derived mode
;; is for editing Java code.  (In the first release of this mode there's
;; very little specialized code; mostly you get a new mode-hook variable
;; ('java-mode-hook) and a new name ("Java") for your emacs mode line.

;; To use java-mode, put this in your .emacs file:
;; (autoload 'java-mode "yourLispCodeDirectory/java-mode" "java mode" t nil)
;; (setq auto-mode-alist
;;       (append '(("\\.java$" . java-mode)) auto-mode-alist))
;;

(provide 'java-mode)

(defvar java-mode-map ()
  "Keymap used in Java mode.")

(defun java-mode ()
  "Major mode for editing java code.
See the documentation for c++-mode:  java-mode is an extension of
c++-mode.
Use the hook java-mode-hook to execute custom code when entering Java
mode.
\\{java-mode-map}"
  (interactive)
  (let ((current-c++-mode-hook (and (boundp 'c++-mode-hook) c++-mode-hook)))
    ;; Temporarily disable the c++-mode hook; don't wanna run
    ;; it when loading up c++-mode.
    (setq c++-mode-hook nil)

    (c++-mode)

    ;; Now customize c++-mode to give us any behaviors specific to
    ;; java mode.  (Hm; not much there right now...)
   
    ;; The Java mode map is the C++ mode map, but with a different name.
    (setq java-mode-map c++-mode-map)
    (use-local-map java-mode-map)

    (setq major-mode 'java-mode
	  mode-name "Java")

    ;; Customize defun-matching expression to allow Java
    ;; functions to be identified.  This is tricky, and all I'm trying to
    ;; do is make it possible to put opening braces at the end of the
    ;; function signature definition, as in the distributed Java code.
    ;; I'm assuming that any line which starts with exactly one level of
    ;; indentation (four spaces in my case; adjust it for your style)
    ;; immediately followed by a letter, matches the beginning of a function
    ;; definition.
    ;; This won't match member data definitions because the function
    ;; "beginning-of-defun-raw" (see lisp.el) insists that a paragraph
    ;; start expression ends with some sort of open character (e.g. "{").
    (set (make-local-variable 'defun-prompt-regexp) "^    \\sw.*")

    ;; Restore the original c++-mode-hook.
    (setq c++-mode-hook current-c++-mode-hook)
    (run-hooks 'java-mode-hook)))


;;;
;;; Variables and functions for use with imenu -- lets you pop up a
;;; menu of functions defined in a Java module.
;;; 
;;; 
;; Regular expression to find Java functions
;; Okay, so this works only with ASCII...
(defun java-imenu--function-name-regexp ()
  (concat 
   "^"
   ;; Include the number of spaces which would lead a properly-
   ;; indented Java member function.  This is a bad way to do
   ;; business because it fails to find functions if things aren't
   ;; already properly indented.
   (make-string c-continued-statement-offset ? )
   "[a-zA-Z0-9:]+[ \t]?"		; type specs; there can be no
   "\\([a-zA-Z0-9_$]+[ \t]+\\)?"	; more than 3 tokens, right?
   "\\([a-zA-Z0-9_$]+[ \t]+\\)?"
   "\\([ \t]*\\)?"			; pointer
   "\\([a-zA-Z0-9_$]+\\)[ \t]*("	; name
   ))

(defun java-imenu--create-index ()
  (imenu-example--create-c-index (java-imenu--function-name-regexp)))

