lsp-java
使用Eclipse JDT Language Server的Emacs Java IDE。
要求
- JDK 17
特性
LSP Java模式支持以下JDT功能:
- 实时报告解析和编译错误(通过flycheck/lsp-ui)
- 代码补全 - 使用company-capf或内置的
complete-at-point
- Javadoc悬停 - 使用lsp-ui
- 代码操作 - 使用lsp-ui
- 代码大纲 - 使用内置的imenu
- 代码导航 - 使用内置的xref
- 代码镜头(引用/实现) - 使用内置的xref
- 高亮
- 代码格式化
- Maven pom.xml项目支持
- 有限的Gradle支持
- 可视化调试器 - dap-mode
- 测试运行器 - dap-mode
- 项目浏览器集成 - treemacs
- 与Spring Initializr集成
演示
这里是EmacsConf2019的演示 https://www.youtube.com/watch?v=Bbjxn9yVNJ8
教程
这里有一个涵盖设置和使用的教程 https://xpressrazor.wordpress.com/2020/11/04/java-programming-in-emacs/
截图
安装
Spacemacs
lsp-java已包含在spacemacs中(目前仅在dev分支)。如果你使用的是spacemacs的开发版本,只需在dotspacemacs-configuration-layers
中添加(java :variables java-backend 'lsp)
。
通过melpa安装
推荐通过package.el
安装LSP Java,这是Emacs内置的包管理器。LSP Java可在两个主要的package.el
社区维护的仓库中找到 - MELPA Stable和MELPA。
M-x package-install
[RET] lsp-java
[RET]
然后在你的.emacs
文件中添加以下行,并打开指定项目中的任意文件。
(require 'lsp-java)
(add-hook 'java-mode-hook #'lsp)
Eclipse JDT Language Server
lsp-java会自动检测服务器是否缺失,并在首次启动前下载Eclipse JDT Language Server。服务器安装将在lsp-java-server-install-dir
中进行。它会检测是否存在dap-mode,并下载所需的服务器端插件/组件。如果你想更新服务器,可以运行lsp-java-update-server
。要运行特定版本的Eclipse JDT Language Server,请使用lsp-java-server-install-dir
。
快速开始
使用company-capf、lsp-ui和dap-mode的最小配置。如果你有现有的Java项目,请设置lsp-java-workspace-dir
。现在你可以探索lsp-java-*
、dap-java-*
、dap-*
和lsp-*
下的方法。
(condition-case nil
(require 'use-package)
(file-error
(require 'package)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
(package-initialize)
(package-refresh-contents)
(package-install 'use-package)
(setq use-package-always-ensure t)
(require 'use-package)))
(use-package projectile)
(use-package flycheck)
(use-package yasnippet :config (yas-global-mode))
(use-package lsp-mode :hook ((lsp-mode . lsp-enable-which-key-integration)))
(use-package hydra)
(use-package company)
(use-package lsp-ui)
(use-package which-key :config (which-key-mode))
(use-package lsp-java :config (add-hook 'java-mode-hook 'lsp))
(use-package dap-mode :after lsp-mode :config (dap-auto-configure-mode))
(use-package dap-java :ensure nil)
(use-package helm-lsp)
(use-package helm
:config (helm-mode))
(use-package lsp-treemacs)
支持的命令
LSP模式命令
lsp-execute-code-action
- 执行代码操作。lsp-rename
- 重命名光标处的符号lsp-describe-thing-at-point
- 显示光标处事物的帮助。lsp-goto-type-definition
- 跳转到类型定义lsp-goto-implementation
- 跳转到实现lsp-restart-workspace
- 重启项目lsp-format-buffer
- 格式化当前缓冲区lsp-symbol-highlight
- 高亮光标下符号的所有相关引用。lsp-workspace-folders-add
- 添加工作区文件夹lsp-workspace-folders-remove
- 移除工作区文件夹lsp-workspace-folders-switch
- 切换工作区文件夹
LSP Java命令
lsp-java-organize-imports
- 组织导入lsp-java-build-project
- 执行项目的部分或完整构建lsp-java-update-project-configuration
- 更新项目配置lsp-java-actionable-notifications
- 解决可操作的通知lsp-java-update-user-settings
- 更新用户设置(查看下表中的选项。)lsp-java-update-server
- 更新服务器安装。lsp-java-generate-to-string
- 生成toString
方法。lsp-java-generate-equals-and-hash-code
- 生成equals
和hashCode
方法。lsp-java-generate-overrides
- 生成方法重写
lsp-java-generate-getters-and-setters
- 生成getter和setter。lsp-java-type-hierarchy
- 打开类型层次结构。使用前缀参数指定层次结构类型。
重构
LSP Java通过Eclipse JDT Language Server代码操作提供丰富的重构集,其中一些绑定到Emacs命令:
lsp-java-extract-to-constant
- 提取常量重构lsp-java-add-unimplemented-methods
- 添加未实现方法重构lsp-java-create-parameter
- 创建参数重构lsp-java-create-field
- 创建字段重构lsp-java-create-local
- 创建局部变量重构lsp-java-extract-method
- 提取方法重构lsp-java-add-import
- 添加缺失的导入
测试支持
lsp-jt-browser
- 浏览测试并运行/调试它们。 ** 使用x
运行光标下的测试;d
调试光标下的测试。R
刷新。 ** 支持GUI操作。lsp-jt-report-open
- 打开测试报告lsp-jt-lens-mode
- 测试镜头模式(需要启用lsp-lens-mode
)
依赖查看器
lsp-java-dependency-list
- 查看Java依赖
STS4集成(实验性)
LSP Java与STS4集成,提供以下功能。
Spring Boot支持(实验性)
除了与Eclipse JDT Language Server集成外,lsp-java还提供了与STS4的集成,涵盖Spring Boot的application.properties
、application.yml
和.java
文件。
使用方法:
确保已配置JAVA_HOME
。当您调用lsp-java-update-server
时,lsp-java
将自动下载STS4。要启用STS4集成,请在配置中添加以下行:
(require 'lsp-java-boot)
;; 启用镜头
(add-hook 'lsp-mode-hook #'lsp-lens-mode)
(add-hook 'java-mode-hook #'lsp-java-boot-lens-mode)
.java
文件功能
源代码导航 - 在文件/工作区中跳转到符号
轻松导航到源代码中的Spring特定元素。
命令
lsp-workspace-symbol
- (使用helm-lsp效果更佳)
示例
@/
显示所有定义的请求映射(映射路径、请求方法、源位置)@+
显示所有定义的bean(bean名称、bean类型、源位置)@>
显示所有函数(原型实现)@
显示代码中所有Spring注解
快速访问运行中的应用
轻松导航到运行中应用的提供的请求映射。
命令
lsp-workspace-symbol
- (使用helm-lsp效果更佳)
示例
//
显示所有运行中Spring Boot应用的请求映射,并为选定的端点打开浏览器
实时应用信息悬停
STS4自动检测本地机器上运行的Boot应用的JVM进程。
对于某些类型的信息,STS 4还可能在代码镜头中显示"快速摘要"。
如果您的机器上运行多个应用实例,所有这些实例的实时数据都将显示在悬停信息中。
(add-hook 'java-mode-hook #'lsp-java-boot-lens-mode)
示例
@Profile
:显示运行中应用的活动配置信息@Component
、@Bean
、@Autowired
:显示来自实时应用的bean及其装配的详细信息@ContidionalOn...
:显示运行时条件及其评估信息
代码模板
使用模板编写Spring代码,通过常规代码补全可用。
示例
@GetMapping
@PostMapping
@PutMapping
智能代码补全
Spring特定注解的附加代码补全
.properties
和.yml
文件功能
此扩展分析项目的类路径,解析并索引找到的任何Spring Boot属性元数据。支持Maven和Gradle项目。
索引中的数据用于在编辑.properties
或.yml
格式的Spring Boot属性时提供验证、代码补全和信息悬停。
属性文件中的验证和代码补全
YAML文件中的验证和代码补全
Spring Initializr
lsp-java
为 Spring Initializr 提供了一个前端界面,通过 lsp-java-spring-initializr
可以直接在 Emacs 中简化创建 Spring Boot 项目的过程。
支持的设置
lsp-java-server-install-dir
- eclipse.jdt.ls-server 的安装目录。末尾需要有斜杠。lsp-java-jdt-download-url
- JDT JS 下载链接。如果想使用 Eclipse Che JDT LS,请使用 http://download.eclipse.org/che/che-ls-jdt/snapshots/che-jdt-language-server-latest.tar.gz。lsp-java-java-path
- Java 可执行文件的路径。lsp-java-progress-string
- 语言服务器报告的 Java 进度状态。lsp-java-workspace-dir
- LSP Java 工作空间目录。lsp-java-workspace-cache-dir
- LSP Java 工作空间缓存目录。lsp-java-themes-directory
- 包含主题的目录。lsp-java-theme
- 要使用的主题。lsp-java-pop-buffer-function
- 用于显示帮助窗口的函数。lsp-java-vmargs
- 指定用于启动 Java 语言服务器的额外 VM 参数。例如,使用-noverify -Xmx1G -XX:+UseG1GC -XX:+UseStringDeduplication
可以绕过类验证,将堆大小增加到 1GB,并启用 G1 垃圾收集器的字符串重复数据删除功能。lsp-java-9-args
- 指定 Java 9 及更高版本特定的参数。lsp-java-errors-incomplete-classpath-severity
- 指定 Java 文件的类路径不完整时消息的严重程度。lsp-java-configuration-check-project-settings-exclusions
- 检查是否应从文件浏览器中排除扩展生成的项目设置文件(.project、.classpath、.factorypath、.settings/)。lsp-java-configuration-update-build-configuration
- 指定对构建文件的修改如何更新 Java 类路径/配置。lsp-java-trace-server
- 跟踪 VS Code 和 Java 语言服务器之间的通信。lsp-java-import-gradle-enabled
- 启用/禁用 Gradle 导入器。lsp-java-import-maven-enabled
- 启用/禁用 Maven 导入器。lsp-java-maven-download-sources
- 启用/禁用 Maven 源代码构件的急切下载。lsp-java-references-code-lens-enabled
- 启用/禁用引用代码镜头。lsp-java-signature-help-enabled
- 启用/禁用签名帮助。lsp-java-implementations-code-lens-enabled
- 启用/禁用实现代码镜头。lsp-java-configuration-maven-user-settings
- Maven 的 settings.xml 路径。lsp-java-format-enabled
- 启用/禁用默认 Java 格式化程序。lsp-java-save-actions-organize-imports
- 启用/禁用保存时自动整理导入。lsp-java-import-exclusions
- 配置用于排除文件夹的 glob 模式。lsp-java-content-provider-preferred
- 首选内容提供者(通常是第三方反编译器 ID)。我们支持 https://github.com/dgileadi/vscode-java-decompiler。要启用它,请添加:(setq lsp-java-content-provider-preferred "fernflower")
lsp-java-autobuild-enabled
- 启用/禁用"自动构建"。lsp-java-max-concurrent-builds
- 最大同时进行的项目构建数。lsp-java-completion-enabled
- 启用/禁用代码完成支持。lsp-java-completion-overwrite
- 设置为 true 时,代码完成会覆盖当前文本。设置为 false 时,代码会简单地添加。lsp-java-completion-guess-method-arguments
- 设置为 true 时,从代码辅助提案列表中选择方法时会猜测方法参数。lsp-java-completion-favorite-static-members
- 定义静态成员或带有静态成员的类型列表。即使缺少导入,内容辅助也会提出这些静态成员。lsp-java-completion-import-order
- 定义导入语句的排序顺序。包或类型名称前缀(如 'org.eclipse')是有效的条目。导入总是添加到最具体的组中。lsp-java-folding-range-enabled
- 启用/禁用智能折叠范围支持。如果禁用,将使用 VS Code 提供的默认基于缩进的折叠范围。indentation-based
- [实验性] 启用/禁用服务器上后台进程的进度报告。lsp-java-progress-reports-enabled
- [实验性] 启用/禁用服务器上后台进程的进度报告。lsp-java-format-settings-url
- 指定 Eclipse 格式化程序 xml 设置 的 url 或文件路径。lsp-java-format-settings-profile
- Eclipse 格式化程序设置中的可选格式化程序配置文件名称。lsp-java-format-comments-enabled
- 在代码格式化期间包含注释。lsp-java-format-on-type-enabled
- 启用/禁用在输入;
、<enter>
或}
时自动格式化代码块。lsp-java-bundles
- 将在 JDT 服务器中加载的包列表。lsp-java-code-generation-hash-code-equals-use-java7objects
- 生成 hashCode 和 equals 方法时使用 Objects.hash 和 Objects.equals。此设置仅适用于 Java 7 及更高版本。lsp-java-code-generation-hash-code-equals-use-instanceof
- 生成 hashCode 和 equals 方法时使用 'instanceof' 比较类型。lsp-java-code-generation-use-blocks
- 生成方法时在 'if' 语句中使用代码块。lsp-java-code-generation-generate-comments
- 生成方法时生成方法注释。lsp-java-code-generation-to-string-template
- 生成 toString 方法的模板。lsp-java-code-generation-to-string-code-style
- 生成 toString 方法的代码风格。lsp-java-code-generation-to-string-skip-null-values
- 生成 toString 方法时跳过空值。lsp-java-code-generation-to-string-list-array-contents
- 列出数组内容而不是使用原生 toString()。lsp-java-code-generation-to-string-limit-elements
- 限制要列出的数组/集合/映射中的项目数量,如果为 0 则列出所有项目。lsp-java-inhibit-message
- 如果非 nil,通过inhibit-message
抑制 java 消息回显。
附加包
- lsp-ui:Flycheck、文档和代码操作支持。
- company-capf:Company 后端支持。
- treemacs:项目查看器。
- lsp-treemacs:使用 treemacs 实现的
lsp-mode
GUI 控件。
常见问题
- LSP Java 显示了太多调试消息,如何停止? 添加以下配置:
(setq lsp-inhibit-message t)
- lsp-ui 没有显示当前点上的所有操作(例如"提取常量")? LSP UI 默认发送当前行边界作为操作区域,这会导致 JDT 服务器只返回"提取方法操作"。
(setq lsp-ui-sideline-update-mode 'point)
- LSP Java 对某些文件没有提供补全、跳转定义等功能?
当特定文件不是导入项目的一部分时,Eclipse JDT Language Server 无法计算当前类路径。
- 如何更改 LSP 使用的 Java 版本?
查看 ~/.emacs.d/workspace/.metadata/.plugins/org.eclipse.jdt.launching/libraryInfos.xml
。如果您更新了本地 Java 路径并希望 LSP 使用新版本,请尝试删除 ~/.emacs.d/workspace/
目录并重新启动 LSP。另请参阅 #114。
如果您安装了多个 Java JDK 版本并想更改 LSP 使用的 Java 版本,还需要设置 lsp-java-configuration-runtimes
。以下是设置 lsp-java-configuration-runtimes
的示例:
(setq lsp-java-configuration-runtimes '[(:name "JavaSE-1.8"
:path "/home/kyoncho/jdk1.8.0_201.jdk/")
(:name "JavaSE-11"
:path "/home/kyoncho/jdk-11.0.1.jdk/"
:default t)])
- 如何更改传递给JDT服务器的JVM参数? LSP的缓慢可能是由于JDT服务器速度慢造成的,尤其是在大型JAVA项目中。增加堆内存大小可能是个好主意。
;; 当前VSCode的默认设置
(setq lsp-java-vmargs '("-XX:+UseParallelGC" "-XX:GCTimeRatio=4" "-XX:AdaptiveSizePolicyWeight=90" "-Dsun.zip.disableMemoryMapping=true" "-Xmx2G" "-Xms100m"))