emacs-java-imports icon indicating copy to clipboard operation
emacs-java-imports copied to clipboard

Add java imports easily in Emacs

#+TITLE: Emacs Java Imports #+AUTHOR: Lee Hinman #+EMAIL: [email protected] #+LANGUAGE: en #+PROPERTY: header-args :results code replace :exports both :noweb yes :tangle no #+HTML_HEAD: #+EXPORT_SELECT_TAGS: export #+EXPORT_EXCLUDE_TAGS: noexport #+OPTIONS: H:4 num:nil toc:t \n:nil @:t ::t |:t ^:{} -:t f:t *:t #+OPTIONS: skip:nil d:(HIDE) tags:not-in-toc #+STARTUP: fold nodlcheck lognotestate showall

  • Introduction

[[https://travis-ci.org/dakrone/emacs-java-imports][file:https://travis-ci.org/dakrone/emacs-java-imports.svg]] [[http://melpa.org/#/java-imports][file:http://melpa.org/packages/java-imports-badge.svg]]

I needed a way to import java classes easily in Emacs. I also didn't want a package that was tied to a particular tool like maven or gradle (especially a potentially long startup time tool).

This adds the =import-java-class= function, which will prompt for the class at point, then the package, then add the required import statement for the class and cache a "class-name -> package" relationship for any future importing of the class.

It does this because I didn't want to drop into Intellij to add all the import statements for my Java code, I just want to hit a key and have an import statement added for the class under the point.

  • Installation

=java-imports= is available in the MELPA repository.

Do this, if MELPA isn't already in your sources:

#+BEGIN_SRC emacs-lisp (require 'package) (add-to-list 'package-archives '("MELPA" . "https://melpa.org/packages/" )) #+END_SRC

Then run =M-x package-refresh-contents= to load the contents of the new repository, and =M-x package-install RET java-imports RET= to install =java-imports=.

  • Usage

#+BEGIN_SRC emacs-lisp (require 'java-imports)

;; whatever you want to bind it to (define-key java-mode-map (kbd "M-I") 'java-imports-add-import-dwim)

;; See customization below for where to put java imports (setq java-imports-find-block-function 'java-imports-find-place-sorted-block) #+END_SRC

I also recommend having java-imports automatically add any seen imports to the import cache by adding:

#+BEGIN_SRC emacs-lisp (add-hook 'java-mode-hook 'java-imports-scan-file) #+END_SRC

** Functions

Functions you may want to bind to a key in Java-mode:

| Function | Use | |--------------------------------+--------------------------------------------------------| | =java-imports-add-import-dwim= | Add import for the symbol at point (or ask if none) | | =java-imports-add-import= | Add import for symbol at point, confirming class first | | =java-imports-scan-file= | Scan imports in the file, adding them to the cache |

Other useful functions for writing your own tools:

Function
=java-imports-add-import-with-package=
=java-imports-list-imports=

** Customization

*** Saving buffer automatically after adding an import

=java-imports= will default to saving the buffer after adding an import, but you can customize =java-imports-save-buffer-after-import-added= to change this.

*** Caching

By default packages are cached the first time they're manually entered, if you want to overwrite what's in the cache you can invoke =java-imports-add-import= with the prefix key (=C-u=).

To disable caching, set =java-imports-use-cache= to =nil=.

*** Import style

You can customize =java-imports-find-block-function=, either setting it to a custom function, or one of the included ones:

  • =java-imports-find-place-after-last-import= (default)

    Simply appends the import to the end of the list of imports

  • =java-imports-find-place-sorted-block=

    Places the import alphabetically sorted into the list of imports, so they will go into:

#+BEGIN_SRC fundamental

public class Whatever { ... } #+END_SRC

For example:

#+BEGIN_SRC java package org.writequit;

import org.writequit.Strings;

import java.util.ArrayList; import java.util.List;

class Foo { public void main() { String[] s = Strings.EMPTY_ARRAY; List<String> = new ArrayList<>(); } } #+END_SRC

*** Cache name

By default java-imports will use "=java-imports=" as the name of the cache of class->package names, however, if you want to have separate caches per project, you can customize =java-imports-cache-name= to have a separate String name (perhaps in a =.dir-locals.el= for per-project imports).

  • Things to do:
  • [X] Avoid importing packages that already have import statements
  • [X] Handle annotations correctly
  • [ ] Handle =*= imports
  • [ ] Inner classes?
  • [X] Scan java files for classes and add to the cache
  • [X] Add tests
  • [X] Hook up to travis-ci