;;; hm-c-menu.el.el: 
;;; v1.20; 30 Jun 1993
;;; Copyright (C) 1993  Heiko Muenkel
;;; email: muenkel@tnt.uni-hannover.de
;;;
;;;  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 1, 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.
;;;
;;; 
;;; Description:
;;;
;;;	Provides a popup and a pulldown (programming) menu for the c++-c-mode
;;;	and the c-mode.
;;; 	The menus provides functions like compile, repeat compile,
;;;	debugging, sexp, indent and comment functions, functions
;;;	to customize mode properties like blinking parenthesis,
;;;	font lock mode, open parenthesis match, expanding macros
;;;	and so on.
;;;     There exists also some menu items to include header files. 
;;;     You can specify the files by setting the lisp variables:
;;;		hm--c-file-header
;;;		hm--h-file-header
;;;		hm--c-function-header
;;;		hm--h-macro-header
;;;	The values can be overwrite by the following environment variables:
;;;		C_FILE_HEADER
;;;		H_FILE_HEADER
;;;		C_FUNCTION_HEADER
;;;		H_MACRO_HEADER
;;;     You should have receive the following prototype header files with 
;;;	this file:
;;;		c-file.header
;;;		h-file.header
;;;		c-function.header
;;;		h-macro.header
;;;	We are working at a better support for these headerfiles. At the
;;;	moment the header are simple included. Only if the file header
;;;	(c-file.header, h-file.header) are included, the username, date
;;;	and filename are inserted automaticly.
;;;	The file header should only be included once per c or h file.
;;;	Every function in a file should become a c function header. The
;;;	h macro header is for macros, which are used as functions.
;;;
;;;	If you don't like these header functions you should delete the
;;;	menu-item "Header" with the lisp function 'delete-menu-item'.
;;;	Therefore you should add the lisp code to the c-mode-hook.
;;; 
;;;     You need also the following lisp files:
;;;		hm--menu.el
;;;		hm--programming-menu.el
;;;		hm--date.el
;;;		c++-mode.el
;;;		c-style.el
;;;		c-fill.el
;;;		c-comment.el
;;;		comm-regn.el
;;;
;;;	The files c++-mode.el, c-style.el, c-fill.el, c-comment.el
;;;	should be in the standart lemacs distribution.
;;;	The file comm-regn.el is a little modified file from the
;;;	emacs lisp archive. You should use the functions hm--comment-region
;;;	and hm--uncomment-region instead of the funtions comment-region
;;;	and uncomment-region in the menu, if you want to use the original 
;;;	file. Therefore you must uncomment the function definitions.
;;;
;;; Installation: 
;;;   
;;;	Put the files hm--c-menu.el, hm--menu.el, hm--programming-menu.el
;;;	in one of your lisp load path directories.
;;;
;;;	Put the following line in your .emacs
;;;		(load-library "hm--c-menu.el")
;;;
;;;	Look at the description part of these file and set the lisp or
;;;	unix environment variables for the header files and put the
;;;	header files in an appropriate directory (The other menu-items
;;;	works without these settings.).
;;;


(provide 'hm--c-menu)
(require 'hm--menu)
(require 'hm--programming-menu)


;;
;; Menue "Programming" für C
;;

(defvar hm--c-programming-menu nil 
  "*List with the \"Programming\" menu for the c and c++-c mode.")


(setq hm--c-programming-menu
      '("Programming Menu"
	("Eval C"
	 ["Compile..." hm--compile t]
	 ["Repeat compile" hm--repeat-compile t]
	 ["Debugger" gdb t]
	 )
	("Goto"
	 ["Beginning of defun" c++-beginning-of-defun t]
	 ["End of defun" c++-end-of-defun t]
	 ["Jump Match paren" c++-match-paren t]
	 ["Goto line..." goto-line t]
	 ["Find tag other window..." find-tag-other-window t]
	 )
	("Header"
	 ["Insert c function header" (hm--insert-header 
				      hm--c-function-header
				      "C_FUNCTION_HEADER"
				      nil) t]
	 ["Insert h macro header" (hm--insert-header 
				   hm--h-macro-header
				   "H_MACRO_HEADER"
				   nil) t]
	 ["Insert c file header" (hm--insert-header 
				  hm--c-file-header
				  "C_FILE_HEADER"
				  t) t]
	 ["Insert h file header" (hm--insert-header
				  hm--h-file-header
				  "H_FILE_HEADER"
				  t) t]
	 )
	("Misc"
	 ["Mark c function" mark-c-function t]
	 ["Insert braces" hm--c-insert-braces t]
	 ["Expand macros" c-macro-expand t]
	 )
	"----"
	("Syntax Expr Cmds"
	 ["Forward c++-sexp" c++-forward-sexp t]
	 ["Backward c++-sexp" c++-backward-sexp t]
	 ["Forward sexp" forward-sexp t]
	 ["Backward sexp" backward-sexp t]
	 ["Kill sexp" kill-sexp t]
	 ["Mark sexp" mark-sexp t]
	 )
	("Indent/Comment"
	 ["Indent region" indent-region t]
	 ["Indent sexp" indent-sexp t]
	 "----"
;	 ["Comment region" hm--comment-region t]
;	 ["Uncomment region" hm--uncomment-region t]
	 ["Comment region" comment-region t]
	 ["Uncomment region" uncomment-region t]
	 ["Blockcomment" hm--c-menu-blockcomment t]
	 ["Edit old comment" hm--c-comment-edit t]
	 )
	("Mode Properties"
	 ["Font lock mode" font-lock-mode t]
	 ["Fontify buffer" font-lock-fontify-buffer t]
	 "----"
	 ["Init blinking parenthesis" hm--init-blinking-parenthesis t]
	 ["No open parenthesis match" hm--unset-matching-open-parenthesis t]
	 "----"
	 ["Set c indent style" set-c-style t]
	 )
	))


(defun hm--install-c-programming-menu ()
  (delete-menu-item '("Programming"))
  (set-buffer-menubar (copy-sequence current-menubar))
  (hm--set-popup-menu 'hm--c-programming-menu)
  (add-menu nil "Programming" (cdr hm--c-programming-menu)))


(defun hm--c-menu-blockcomment ()
  "Start of a new blockcomment."
  (interactive)
  (add-menu-item '("Programming" "Indent/Comment")
		 "End of blockcomment"
		 'hm--c-menu-end-of-blockcomment
		 t
		 "Blockcomment")
  (delete-menu-item '("Programming" 
		      "Indent/Comment" 
		      "Blockcomment"))
  (c-comment))

(defun hm--c-menu-end-of-blockcomment ()
  "End of a new blockcomment."
  (interactive)
  (add-menu-item '("Programming" "Indent/Comment")
		 "Blockcomment"
		 'hm--c-menu-blockcomment
		 t
		 "End of blockcomment")
  (delete-menu-item '("Programming" 
		      "Indent/Comment" 
		      "End of blockcomment"))
  (exit-recursive-edit))


(defvar hm--c-comment-edit-menu nil 
  "*List with the menu for the c comment edit buffer.")


(setq hm--c-comment-edit-menu
      '("C Comment Edit Menu"
	["Exit comment editing" c-comment-edit-end t]
	["Abort comment editing" c-comment-edit-abort t]
	))


(defun hm--c-comment-edit (search-prefix)
  "Edit the comment in the current line."
  (interactive "*P")
  (c-comment-edit search-prefix)
  (hm--set-popup-menu 'hm--c-comment-edit-menu))


; Use this function, if you want use the c++-comment-region function
;
;(defun hm--comment-region ()
;  "Comments a region."
;  (interactive)
;  (if (equal major-mode 'c++-c-mode)
;      (c++-comment-region (region-beginning) (region-end))
;    (comment-region)))


; Use this function, if you want use the c++-uncomment-region function
;
;(defun hm--uncomment-region ()
;  "Uncomments a region."
;  (interactive)
;  (if (equal major-mode 'c++-c-mode)
;      (c++-uncomment-region (region-beginning) (region-end))
;    (uncomment-region)))


(defun hm--require-c++-mode.el ()
  "Loads the file c++-mode.el."
  (require 'c++-mode))

;; Hooks

(add-hook 'c-mode-hook 'hm--install-c-programming-menu)
(add-hook 'c-mode-hook 'hm--require-c++-mode.el)
;(add-hook 'c-mode-hook 'hm--c-new-keys)

(add-hook 'c++-c-mode-hook 'hm--install-c-programming-menu)
;(add-hook 'c++-mode-hook 'hm--c++-new-keys)



;; autoloads

(autoload 
 'c++-comment-region 
 "c++-mode" 
 "Comment out all lines in a region between mark and current point by
inserting comment-start in front of each line." 
 t)


(autoload
 'c++-uncomment-region
 "c++-mode"
 "Uncomment all lines in region between mark and current point by deleting
the leading \"// \" from each line, if any."
 t)


(autoload
 'c-comment-edit
 "c-comment"
 "Edit multi-line C comments.
This command allows the easy editing of a multi-line C comment like this:
   /*
    * ...
    * ...
    */
The comment may be indented or flush with the left margin.

If point is within a comment, that comment is used.  Otherwise the
comment to be edited is found by searching forward from point.

With one \\[universal-argument] searching starts after moving back one
  paragraph.
With two \\[universal-argument]'s searching starts at the beginning of the
  current or proceeding C function.
With three \\[universal-argument]'s searching starts at the beginning of the
  current page.
With four \\[universal-argument]'s searching starts at the beginning of the
  current buffer (clipping restrictions apply).

Once located, the comment is copied into a temporary buffer, the comment
leaders and delimiters are stripped away and the resulting buffer is
selected for editing.  The major mode of this buffer is controlled by
the variable `c-comment-edit-mode'.

Use \\[c-comment-edit-end] when you have finished editing the comment.  The
comment will be inserted into the original buffer with the appropriate
delimiters and indention, replacing the old version of the comment.  If
you don't want your edited version of the comment to replace the
original, use \\[c-comment-edit-abort]."
 )


(autoload
 'c-comment
 "c-fill"
 "Edit a C comment with filling and indentation.
This performs hanging indentation, symmetric placement of delimiters,
 and Indented-Text mode style indentation.  Type 'M-x apropos
c-comment' for information on options."
 )


(autoload
 'set-c-style
 "c-style"
 "Set up the c-mode style variables from STYLE if it is given, or
default-c-style otherwise.  It makes the c indentation style variables
buffer local."
 )


(autoload 'comment-region 
	  "comm-regn" 
	  "Insert the proper comment characters into the region of a program.
Used to comment blocks of Lisp or C code."
	  t)


(autoload 'uncomment-region 
	  "comm-regn" 
	  "Remove comment delimiters from a region of code.  Works with
comments created by function comment-region.  Lisp or C."
	  t)
