Java and C++ Utilities

I’ve been working on some utilities for coding in Java. JDE and CEDET ground my emacs to a halt the last time I tried them, so I wanted something lightweight. So far, I mostly have some functions for looking up documentation - including c++ documentation - that I store locally on my computer and keep in a repository, but I also have a few utilities for auto-importing Java classes.

The utilities to follow need these macros defined. I talked about them previously at:
http://nflath.com/2009/08/emacs-timing-and-upgrades/. They are utilities for generating functions that take arguments defaulting to word at point.

(defun my-fn (fn prompt)
  "When given a function taking one argument and applying a function to it, will use that function
   and default to the word at point, with a prompt including that word."
  (let ((default (current-word)))
    (let ((needle (read-string (concat prompt " <" default ">: "))))
      (if (equal needle "")
          (funcall fn default)
        (funcall fn needle)))))
 
(defmacro defun-my (name prompt &rest body)
  "Will define both a function and a my- version of the function,
which defaults to the word at point."
  `(progn
     (defun ,name (arg) ,@body)
     (defun ,(intern (concat "my-" (symbol-name name))) ()
       (interactive)
       (my-fn (quote ,name) ,prompt))))

These functions will be used in some of the later functions I wrote. These are used for caching large directory structures in a buffer to search for files instead of parsing the output of ‘find’ each time. Specifically, I use these to quickly look up which file I should be referencing to view documentation on Java and C++ classes. create-file-list will just create a list of files in the given buffer, and find-location-for-doc-from-buffer will return the full path of the matching html file you are searching for. Java-find-html-for-class is just a helper function that fills in the arguments for find-location-for-doc-from-buffer for Java buffers.

(defun create-file-list (directory buffer)
  "Creates the list of files in a directory"
  (save-window-excursion
    (let ((default-directory directory))
      (shell-command "find . " buffer)
      (switch-to-buffer buffer)
      (flush-lines "\.svn")
      (flush-lines "class-use"))))
 
(defun find-location-for-doc-from-buffer (arg buffer-name buffer-creation-fn begin)
  "Finds the file for a given documentation name in the buffer
that may be created with buffer-creation"
  (save-excursion
    (save-window-excursion
      (let ((doc-buffer (or (get-buffer buffer-name)
                            (funcall buffer-creation-fn))))
        (switch-to-buffer doc-buffer)
        (goto-char (point-min))
        (while (not (line-matches (concat "/" arg "\.html")))
          (search-forward arg))
        (concat begin
                (buffer-substring (1+ (line-beginning-position))
                                  (line-end-position)))))))

These next functions are used to look up documentation. my-java-describe-class will open up documentation for the input class file, whereas java-describe-variable will take a variable name and look backwards to it’s declaration and find documentation for that class. c-search-docs does something similar; it will prompt you for a keyword and see if anything in my c++ documentation matches it.

(defun-my java-describe-class "Open Javadoc for Class"
  "Loads javadoc for specified class in your browser."
  (interactive "MClass Name: ")
  (browse-url (java-find-html-for-class arg)))
 
(defun-my java-describe-variable "Open Javadoc for Variable"
  "Opens the javadoc for the variable at point, if possible."
  (interactive)
  (save-excursion
    (re-search-backward (concat "[ \t\n]"
                                "[A-Za-z]+"
                                "<[][A-Za-z0-9<>]*>"
                                "[ \t\n]"
                                arg))
    (forward-char)
    (java-describe-class (current-word))))
 
(defun-my c-search-docs "Documentation For"
  "Searches C++ Documentation for the requested term"
  (browse-url (find-location-for-doc-from-buffer
               arg
               "*C Documentation*"
               (lambda () (create-file-list "~/.emacs.d/documentation/c++/" "*C Documentation*"))
               "~/.emacs.d/documentation/c++/")))

Another task that I frequently have to do is fix imports in Java classes. Doing this manually is a huge pain, so I wrote a few functions to help. my-java-import-class will prompt for a class, look up it’s full package name, and add the import to the top of your file. Java-get-undefined-classes will run compile-command and parse the output to add all unimported classes. This needs java-undefined-symbol-regexp to be defined correctly, as well as compile-command to be set to something like ‘javac filename’.

(defun-my java-import-class "Import Class"
  "Adds an import statement for the class at point."
  (save-excursion
    (let ((my-retn-value nil))
      (let ((my-string (java-find-html-for-class arg)))
        (find-file my-string)
        (end-of-buffer)
        (re-search-backward "\"\\([A-Za-z0-9]+\\.\\)+[A-Za-z0-9]+ [ci][ln][at][se][sr]" )
        (let ((start (point)))
          (re-search-forward " " )
          (setq my-retn-value (substring (buffer-string) start (- (point) 2)))))
      (kill-buffer (current-buffer))
      (beginning-of-buffer)
      (re-search-forward "import " (point-max) t)
      (beginning-of-line)
      (when (looking-at "import")
        (end-of-line)
        (newline))
      (insert "import " my-retn-value ";\n" ))))
 
(defvar java-undefined-symbol-regexp "symbol  : class \\([A-Za-z0-9]*\\)")
(defun java-get-undefined-class-names ()
  (interactive)
  (save-window-excursion
    (remove-if
     #'not
     (remove-duplicates
      (mapcar (lambda (x)
                (if (string-match java-undefined-symbol-regexp x)
                    (match-string 1 x)))
              (split-string (shell-command-to-string compile-command) "\n *^\n")) :test #'string-equal))))
 
(defun java-import-undefined-classes ()
  (interactive)
  (save-window-excursion
    (mapc #'java-import-class (java-get-undefined-class-names))))

Tags:

2 Responses to “Java and C++ Utilities”

  1. Alex says:

    “including c++ documentation - that I store locally on my computer and keep in a repository”

    How do you generate your C++ documentation?

  2. nflath says:

    I downloaded the docs from SGI.

Leave a Reply