Configurando Emacs como Java IDE
Table of Contents
IntelliJ, Android Studio e outras IDEs são extremamente poderosas, isso é fato. Mas muitas vezes queremos leveza, um ambiente produtivo sem dezenas de features que levam minutos para carregar.
Um ambiente onde nos permite abrir o editor o mais rápido possível e apenas começar a programar!
No Emacs, podemos usar um servidor de linguagem (LSP) para ter o mínimo de IntelliSense disponível no editor. Assim como o IntelliJ, Eclipse e outras IDEs fazem.
Ele funciona graças ao frontend eglot que já vem junto com o Emacs.
Vou mostrar um exemplo de configuração no MacOS, contudo vai funcionar também em outros sistemas operacionais, desde que você tenha o jdtls em seu computador e apontando corretamente o caminho dele no script que irei mostrar no decorrer deste post.
Instalando o Java Language Server
Com o Homebrew, instale com o jdtls com o comando
brew install jdtls.
Encontre o caminho de instalação com o brew --prefix jdtls.
Se estiver em outro sistema operacional, baixe o language server diretamente do repositório oficial do jdtls.
Script jdtls
Dentro do dotfiles você encontra o script start-jdtls.sh que irá inicializar o servidor de linguagem Java a partir do workspace definido como argumento.
Os parâmetros está configurado para o ambiente macOS. Logo, adapte o JDTLS_HOME para o seu sistema operacional e o -configuration se necessário.
Ainda não deu tempo de deixar o script cross-platform, uso macOS 90% do tempo. Sorry!
O workspace será encontrado automaticamente pelo Emacs a partir do diretório do projeto que contenha a estrutura base com um dos arquivos na raiz: .project, .classpath, pom.xml ou build.gradle.
Ou seja, se o projeto estiver na estrutura correta ele irá carregar automaticamente e iniciar o E-glot com LSP.
Coloque o script start-jdtls.sh na HOME, seja com link simbólico ou copiando para o caminho ~/.start-jdtls.sh - note que está oculto com ponto (.) no diretório HOME.
Faça o mesmo para o .emacs e .emacs.d.
.emacs
Caso não utilize o meu .emacs, você pode configurar no seu próprio. Eu extrai somente as partes relevantes para o ambiente Java IDE no Emacs.
O gerenciador de pacotes que utilizo é o use-package.
Instale também o company para o autocomplete.
Garanta que o java esteja instalado corretamente e que o Emacs possa encontrá-lo em seu JAVA_HOME.
Por aqui eu utilizo o java 21.
;;
;; .emacs (coloque no ~/.emacs)
;;
(setq taguiar-jdtls-script "~/.start-jdtls.sh")
(use-package eglot
:config
(setq eldoc-echo-area-use-multiline-p nil)
(setq eglot-events-buffer-size 0)
(add-hook 'eglot-managed-mode-hook (lambda () (eglot-inlay-hints-mode -1))) ;; disable param hint
:config
(add-to-list 'eglot-server-programs
`(java-mode . ,#'my-jdtls-command)))
;; auto complete com company
(add-hook 'java-mode-hook 'global-company-mode)
(defun my-java-project-root ()
(or
(locate-dominating-file default-directory ".project")
(locate-dominating-file default-directory ".classpath")
(locate-dominating-file default-directory "pom.xml")
(locate-dominating-file default-directory "build.gradle")
default-directory))
(defun my-jdtls-command (&rest _)
(let* ((root (my-java-project-root))
(project-name (file-name-nondirectory
(directory-file-name root)))
(workspace (expand-file-name
(concat "~/.jdtls-workspace/" project-name))))
(message "------------------------------")
(message "[JDTLS] Root: %s" root)
(message "[JDTLS] Project: %s" project-name)
(message "[JDTLS] Workspace: %s" workspace)
(message "[JDTLS] Default dir (before): %s" default-directory)
(make-directory workspace t)
(message "[JDTLS] Starting server...")
(list (expand-file-name taguiar-jdtls-script) workspace)))
(defun my-eglot-java-init ()
(let ((project-root (my-java-project-root)))
(when project-root
(setq default-directory project-root))
(eglot-ensure)))
(add-hook 'java-mode-hook #'my-eglot-java-init)
;; format Java code after save
(add-hook 'java-mode-hook
(lambda ()
(add-hook 'before-save-hook #'eglot-format-buffer nil t)))
Veja um exemplo de projeto Java com a estrutura básica (usando maven ou gradle o lsp encontrará automaticamente também).
root
├── .classpath
├── .project
└── src
└── dev
└── tiagoaguiar
└── projeto
└── App.java
Meu Acesso Rápido
- Baixar o jdtls com homebrew
- Clonar o dotfiles
- Criar links simbólicos para ~/.emacs, ~/.emacs.d, ~/.start-jdtls.sh
- Estruturar projeto java com .project e .classpath na raiz