From: Cay Horstmann <cay@horstmann.com>
To: "João Távora" <joaotavora@gmail.com>, "Eli Zaretskii" <eliz@gnu.org>
Cc: 66726@debbugs.gnu.org
Subject: bug#66726: 29.1; Eglot jdtls formatter ignored
Date: Mon, 6 Nov 2023 18:16:01 +0100 [thread overview]
Message-ID: <b52b69c8-047e-478f-9dba-e1d88a2ad9a8@horstmann.com> (raw)
In-Reply-To: <CALDnm53x+Z_ATXrbn+FX=zAY5otySajcu2dctn29CPJ+3PZNqg@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 4933 bytes --]
On 29/10/2023 15.40, João Távora wrote:
> On Sun, Oct 29, 2023 at 12:08 PM Eli Zaretskii <eliz@gnu.org> wrote:
>>
>>> Date: Tue, 24 Oct 2023 11:17:09 +0200
>>> From: Cay Horstmann <cay@horstmann.com>
>>>
>>> Eglot does not trigger a custom formatter with jdtls, while lsp-java and VS Code with the Red Hat Java plugin can do this. See https://github.com/joaotavora/eglot/discussions/1222 for more background.
>>>
>>> I attach files
>>> * eglot-debug.el (the minimal configuration to see the failure)
>>> * NotHelloWorld.java (a sample Java file)
>>> * cay-eclipse-formatter.xml (the formatting rules for jdtls)
>>> * eglot-events.txt (the events log from eglot)
>>> * lsp-java-debug.el (the minimal configuration to see how it works with lsp-java)
>>> * lsp-log.txt (the log from the successful run with lsp)
>>>
>>> Download jdtls from https://download.eclipse.org/jdtls/snapshots/?d. I
>>> have the version from Oct. 14, 2023. Put it somewhere on your PATH
>>>
>>> Put the NotHelloWorld.java file in some directory (I use /tmp/hello)
>>>
>>> Put the cay-eclipse-formatter.xml file somewhere and adjust the path in eglot-debug.el and lsp-java-debug.el.
>>>
>>> emacs -q -l eglot-debug.el /tmp/hello/NotHelloWorld.java
>>>
>>> M-x eglot RET
>>>
>>> Wait for jdtls to start
>>>
>>> M-x eglot-format-buffer RET
>>>
>>> The formatting should now use the rules in the cay-eclipse-formatter.xml
>>> file, resulting in 8 changes but the same Allman indentation
>>> style. Instead, it uses a K&R indentation style.
>>>
>>> To see the proper formatting, install lsp-mode and lsp-java and start with lsp-java-debug.el. Or use VS Code with the Red Hat Java plugin and the settings.json
>>>
>>> {
>>> "java.format.settings.url": "file:///data/cay/bin/cay-eclipse.formatter.xml",
>>> "java.format.settings.profile": "cay"
>>> }
>>
>> João, any comments?
>
> Not many. Seems like a good error recipe, assuming someone
> finds the time to reproduce it. If I had to guess, I'd say
> almost surely a server-side quirk about it not finding the
> xml file from that slightly strange url. Maybe lsp-mode is
> setting some environment variable. But that would
> require me debugging Java which I haven't done in just
> about 20 years and not really looking forward to.
>
> Cay, is there some kind of jtdls error log where it reports
> things? Can you also attach the Eglot stderr buffer, in case
> it has something useful? Use `M-x eglot-stderr-buffer`.
>
> The only thing that seems to be missing is the Emacs version,
> but I'll assume it's the version used in M-x report-emacs-bug
> itself, which is 29.1.
>
> João
Hello, here is another stab at this.
* There is no problem with that funny looking file:/// URL. jdtls can find it when invoked from VS Code and lsp-mode.
* I attach the initialization that happens from VS Code. It looks just like the one that I am setting up in eglot. Look at the path initializationOptions.settings.java.format.settings.
Formatting works fine in VS Code. The logs show requests such as this one:
[Trace - 3:51:32 PM] Sending request 'textDocument/formatting - (71)'.
Params: {
"textDocument": {
"uri": "file:///tmp/test/NotHelloWorld.java"
},
"options": {
"tabSize": 4,
"insertSpaces": true
}
}
These look just like the ones that eglot sends. But the response is a formatting directive that follows the formatter, whereas with eglot, the response is a directive that follows some default.
* Here is the requested eglot-stderr-buffer:
WARNING: Using incubator modules: jdk.incubator.vector, jdk.incubator.foreign
Nov 06, 2023 4:20:36 PM org.apache.aries.spifly.BaseActivator log
INFO: Registered provider ch.qos.logback.classic.servlet.LogbackServletContainerInitializer of service jakarta.servlet.ServletContainerInitializer in bundle ch.qos.logback.classic
Nov 06, 2023 4:20:36 PM org.apache.aries.spifly.BaseActivator log
INFO: Registered provider ch.qos.logback.classic.spi.LogbackServiceProvider of service org.slf4j.spi.SLF4JServiceProvider in bundle ch.qos.logback.classic
* Yes, it is Emacs 29.1.
* The jdtls logs are a mystery to me. According to https://github.com/eclipse-jdtls/eclipse.jdt.ls/issues/752#issuecomment-412275314,
"Should be in workspace/.metadata/.log, workspace location is a parameter you pass when starting the server."
Who is "you"? I suppose the client, i.e. eglot or VS Code. I find files such as
./eglot-java-eclipse-jdt-cache/a397d9cc217eb5e87ff722051c2f059b/.metadata/.log
but they don't contain any info on today's interactions. There is no other directory in that cache. I can tell from that log that the directory was passed as a --data command-line argument. But when I intercept jdtls today via a script to log the command-line args, there is no --data command-line argument passed when invoking jdtls.
Thanks,
Cay
--
Cay S. Horstmann | http://horstmann.com | mailto:cay@horstmann.com
[-- Attachment #2: vs-code-jdtls.log --]
[-- Type: text/x-log, Size: 29252 bytes --]
Params: {
"processId": 425037,
"clientInfo": {
"name": "VSCodium",
"version": "1.84.0"
},
"locale": "en",
"rootPath": "/home/cay/projects/versuchspersonendatenbank-backend",
"rootUri": "file:///home/cay/projects/versuchspersonendatenbank-backend",
"capabilities": {
"workspace": {
"applyEdit": true,
"workspaceEdit": {
"documentChanges": true,
"resourceOperations": [
"create",
"rename",
"delete"
],
"failureHandling": "textOnlyTransactional",
"normalizesLineEndings": true,
"changeAnnotationSupport": {
"groupsOnLabel": true
}
},
"configuration": true,
"didChangeWatchedFiles": {
"dynamicRegistration": true,
"relativePatternSupport": true
},
"symbol": {
"dynamicRegistration": true,
"symbolKind": {
"valueSet": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26
]
},
"tagSupport": {
"valueSet": [
1
]
},
"resolveSupport": {
"properties": [
"location.range"
]
}
},
"codeLens": {
"refreshSupport": true
},
"executeCommand": {
"dynamicRegistration": true
},
"didChangeConfiguration": {
"dynamicRegistration": true
},
"workspaceFolders": true,
"semanticTokens": {
"refreshSupport": true
},
"fileOperations": {
"dynamicRegistration": true,
"didCreate": true,
"didRename": true,
"didDelete": true,
"willCreate": true,
"willRename": true,
"willDelete": true
},
"inlineValue": {
"refreshSupport": true
},
"inlayHint": {
"refreshSupport": true
},
"diagnostics": {
"refreshSupport": true
}
},
"textDocument": {
"publishDiagnostics": {
"relatedInformation": true,
"versionSupport": false,
"tagSupport": {
"valueSet": [
1,
2
]
},
"codeDescriptionSupport": true,
"dataSupport": true
},
"synchronization": {
"dynamicRegistration": true,
"willSave": true,
"willSaveWaitUntil": true,
"didSave": true
},
"completion": {
"dynamicRegistration": true,
"contextSupport": true,
"completionItem": {
"snippetSupport": true,
"commitCharactersSupport": true,
"documentationFormat": [
"markdown",
"plaintext"
],
"deprecatedSupport": true,
"preselectSupport": true,
"tagSupport": {
"valueSet": [
1
]
},
"insertReplaceSupport": true,
"resolveSupport": {
"properties": [
"documentation",
"detail",
"additionalTextEdits"
]
},
"insertTextModeSupport": {
"valueSet": [
1,
2
]
},
"labelDetailsSupport": true
},
"insertTextMode": 2,
"completionItemKind": {
"valueSet": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25
]
},
"completionList": {
"itemDefaults": [
"commitCharacters",
"editRange",
"insertTextFormat",
"insertTextMode"
]
}
},
"hover": {
"dynamicRegistration": true,
"contentFormat": [
"markdown",
"plaintext"
]
},
"signatureHelp": {
"dynamicRegistration": true,
"signatureInformation": {
"documentationFormat": [
"markdown",
"plaintext"
],
"parameterInformation": {
"labelOffsetSupport": true
},
"activeParameterSupport": true
},
"contextSupport": true
},
"definition": {
"dynamicRegistration": true,
"linkSupport": true
},
"references": {
"dynamicRegistration": true
},
"documentHighlight": {
"dynamicRegistration": true
},
"documentSymbol": {
"dynamicRegistration": true,
"symbolKind": {
"valueSet": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26
]
},
"hierarchicalDocumentSymbolSupport": true,
"tagSupport": {
"valueSet": [
1
]
},
"labelSupport": true
},
"codeAction": {
"dynamicRegistration": true,
"isPreferredSupport": true,
"disabledSupport": true,
"dataSupport": true,
"resolveSupport": {
"properties": [
"edit"
]
},
"codeActionLiteralSupport": {
"codeActionKind": {
"valueSet": [
"",
"quickfix",
"refactor",
"refactor.extract",
"refactor.inline",
"refactor.rewrite",
"source",
"source.organizeImports"
]
}
},
"honorsChangeAnnotations": false
},
"codeLens": {
"dynamicRegistration": true
},
"formatting": {
"dynamicRegistration": true
},
"rangeFormatting": {
"dynamicRegistration": true
},
"onTypeFormatting": {
"dynamicRegistration": true
},
"rename": {
"dynamicRegistration": true,
"prepareSupport": true,
"prepareSupportDefaultBehavior": 1,
"honorsChangeAnnotations": true
},
"documentLink": {
"dynamicRegistration": true,
"tooltipSupport": true
},
"typeDefinition": {
"dynamicRegistration": true,
"linkSupport": true
},
"implementation": {
"dynamicRegistration": true,
"linkSupport": true
},
"colorProvider": {
"dynamicRegistration": true
},
"foldingRange": {
"dynamicRegistration": true,
"rangeLimit": 5000,
"lineFoldingOnly": true,
"foldingRangeKind": {
"valueSet": [
"comment",
"imports",
"region"
]
},
"foldingRange": {
"collapsedText": false
}
},
"declaration": {
"dynamicRegistration": true,
"linkSupport": true
},
"selectionRange": {
"dynamicRegistration": true
},
"callHierarchy": {
"dynamicRegistration": true
},
"semanticTokens": {
"dynamicRegistration": true,
"tokenTypes": [
"namespace",
"type",
"class",
"enum",
"interface",
"struct",
"typeParameter",
"parameter",
"variable",
"property",
"enumMember",
"event",
"function",
"method",
"macro",
"keyword",
"modifier",
"comment",
"string",
"number",
"regexp",
"operator",
"decorator"
],
"tokenModifiers": [
"declaration",
"definition",
"readonly",
"static",
"deprecated",
"abstract",
"async",
"modification",
"documentation",
"defaultLibrary"
],
"formats": [
"relative"
],
"requests": {
"range": true,
"full": {
"delta": true
}
},
"multilineTokenSupport": false,
"overlappingTokenSupport": false,
"serverCancelSupport": true,
"augmentsSyntaxTokens": true
},
"linkedEditingRange": {
"dynamicRegistration": true
},
"typeHierarchy": {
"dynamicRegistration": true
},
"inlineValue": {
"dynamicRegistration": true
},
"inlayHint": {
"dynamicRegistration": true,
"resolveSupport": {
"properties": [
"tooltip",
"textEdits",
"label.tooltip",
"label.location",
"label.command"
]
}
},
"diagnostic": {
"dynamicRegistration": true,
"relatedDocumentSupport": false
}
},
"window": {
"showMessage": {
"messageActionItem": {
"additionalPropertiesSupport": true
}
},
"showDocument": {
"support": true
},
"workDoneProgress": true
},
"general": {
"staleRequestSupport": {
"cancel": true,
"retryOnContentModified": [
"textDocument/semanticTokens/full",
"textDocument/semanticTokens/range",
"textDocument/semanticTokens/full/delta"
]
},
"regularExpressions": {
"engine": "ECMAScript",
"version": "ES2020"
},
"markdown": {
"parser": "marked",
"version": "1.1.0"
},
"positionEncodings": [
"utf-16"
]
},
"notebookDocument": {
"synchronization": {
"dynamicRegistration": true,
"executionSummarySupport": true
}
}
},
"initializationOptions": {
"bundles": [
"/home/cay/.vscode-oss/extensions/vscjava.vscode-java-debug-0.55.0-universal/server/com.microsoft.java.debug.plugin-0.50.0.jar"
],
"workspaceFolders": [
"file:///home/cay/projects/versuchspersonendatenbank-backend"
],
"settings": {
"java": {
"home": "/usr/lib/jvm/java-11-openjdk-amd64",
"jdt": {
"ls": {
"java": {
"home": null
},
"vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx1G -Xms100m -Xlog:disable",
"lombokSupport": {
"enabled": true
},
"protobufSupport": {
"enabled": true
},
"androidSupport": {
"enabled": false
}
}
},
"errors": {
"incompleteClasspath": {
"severity": "warning"
}
},
"configuration": {
"checkProjectSettingsExclusions": false,
"updateBuildConfiguration": "interactive",
"maven": {
"userSettings": null,
"globalSettings": null,
"notCoveredPluginExecutionSeverity": "warning",
"defaultMojoExecutionAction": "ignore"
},
"workspaceCacheLimit": 90,
"runtimes": [
{
"name": "JavaSE-11",
"path": "/usr/lib/jvm/java-11-openjdk-amd64"
}
],
"detectJdksAtStart": true
},
"trace": {
"server": "verbose"
},
"import": {
"maven": {
"enabled": true,
"offline": {
"enabled": false
},
"disableTestClasspathFlag": false
},
"gradle": {
"enabled": true,
"wrapper": {
"enabled": true
},
"version": null,
"home": null,
"java": {
"home": null
},
"offline": {
"enabled": false
},
"arguments": null,
"jvmArguments": null,
"user": {
"home": null
},
"annotationProcessing": {
"enabled": true
}
},
"exclusions": [
"**/node_modules/**",
"**/.metadata/**",
"**/archetype-resources/**",
"**/META-INF/maven/**"
],
"generatesMetadataFilesAtProjectRoot": false
},
"maven": {
"downloadSources": false,
"updateSnapshots": false
},
"eclipse": {
"downloadSources": false
},
"referencesCodeLens": {
"enabled": false
},
"signatureHelp": {
"enabled": true,
"description": {
"enabled": false
}
},
"implementationsCodeLens": {
"enabled": false
},
"format": {
"enabled": true,
"settings": {
"url": "file:///data/cay/bin/cay-eclipse.formatter.xml",
"profile": "cay"
},
"comments": {
"enabled": true
},
"onType": {
"enabled": true
},
"insertSpaces": true,
"tabSize": 4
},
"saveActions": {
"organizeImports": false
},
"project": {
"referencedLibraries": [
"lib/**/*.jar"
],
"importOnFirstTimeStartup": "automatic",
"importHint": true,
"resourceFilters": [
"node_modules",
"\\.git"
],
"encoding": "ignore"
},
"contentProvider": {
"preferred": null
},
"autobuild": {
"enabled": true
},
"maxConcurrentBuilds": 1,
"recommendations": {
"dependency": {
"analytics": {
"show": true
}
}
},
"completion": {
"maxResults": 0,
"enabled": true,
"guessMethodArguments": "insertBestGuessedArguments",
"favoriteStaticMembers": [
"org.junit.Assert.*",
"org.junit.Assume.*",
"org.junit.jupiter.api.Assertions.*",
"org.junit.jupiter.api.Assumptions.*",
"org.junit.jupiter.api.DynamicContainer.*",
"org.junit.jupiter.api.DynamicTest.*",
"org.mockito.Mockito.*",
"org.mockito.ArgumentMatchers.*",
"org.mockito.Answers.*"
],
"filteredTypes": [
"java.awt.*",
"com.sun.*",
"sun.*",
"jdk.*",
"org.graalvm.*",
"io.micrometer.shaded.*"
],
"importOrder": [
"#",
"java",
"javax",
"org",
"com",
""
],
"postfix": {
"enabled": true
},
"chain": {
"enabled": false
},
"matchCase": "firstLetter",
"lazyResolveTextEdit": {
"enabled": true
}
},
"foldingRange": {
"enabled": true
},
"codeGeneration": {
"hashCodeEquals": {
"useJava7Objects": false,
"useInstanceof": false
},
"useBlocks": false,
"generateComments": false,
"toString": {
"template": "${object.className} [${member.name()}=${member.value}, ${otherMembers}]",
"codeStyle": "STRING_CONCATENATION",
"skipNullValues": false,
"listArrayContents": true,
"limitElements": 0
},
"insertionLocation": "afterCursor"
},
"selectionRange": {
"enabled": true
},
"showBuildStatusOnStart": {
"enabled": "notification"
},
"server": {
"launchMode": "Hybrid"
},
"sources": {
"organizeImports": {
"starThreshold": 99,
"staticStarThreshold": 99
}
},
"imports": {
"gradle": {
"wrapper": {
"checksums": []
}
}
},
"templates": {
"fileHeader": [],
"typeComment": []
},
"references": {
"includeAccessors": true,
"includeDecompiledSources": true
},
"typeHierarchy": {
"lazyLoad": false
},
"settings": {
"url": null
},
"symbols": {
"includeSourceMethodDeclarations": false
},
"quickfix": {
"showAt": "line"
},
"inlayHints": {
"parameterNames": {
"enabled": "literals",
"exclusions": []
}
},
"codeAction": {
"sortMembers": {
"avoidVolatileChanges": true
}
},
"compile": {
"nullAnalysis": {
"nonnull": [
"javax.annotation.Nonnull",
"org.eclipse.jdt.annotation.NonNull",
"org.springframework.lang.NonNull"
],
"nullable": [
"javax.annotation.Nullable",
"org.eclipse.jdt.annotation.Nullable",
"org.springframework.lang.Nullable"
],
"mode": "interactive"
}
},
"cleanup": {
"actionsOnSave": []
},
"sharedIndexes": {
"enabled": "auto",
"location": ""
},
"refactoring": {
"extract": {
"interface": {
"replace": true
}
}
},
"edit": {
"validateAllOpenBuffersOnChanges": false,
"smartSemicolonDetection": {
"enabled": false
}
},
"editor": {
"reloadChangedSources": "ask"
},
"debug": {
"logLevel": "warn",
"settings": {
"showHex": false,
"showStaticVariables": false,
"showQualifiedNames": false,
"showLogicalStructure": true,
"showToString": true,
"maxStringLength": 0,
"numericPrecision": 0,
"hotCodeReplace": "manual",
"enableRunDebugCodeLens": true,
"forceBuildBeforeLaunch": true,
"onBuildFailureProceed": false,
"console": "integratedTerminal",
"exceptionBreakpoint": {
"exceptionTypes": [],
"allowClasses": [],
"skipClasses": []
},
"stepping": {
"skipClasses": [],
"skipSynthetics": false,
"skipStaticInitializers": false,
"skipConstructors": false
},
"jdwp": {
"limitOfVariablesPerJdwpRequest": 100,
"requestTimeout": 3000,
"async": "auto"
},
"vmArgs": "",
"debugSupportOnDecompiledSource": "on"
}
},
"silentNotification": false,
"telemetry": {
"enabled": false
}
}
},
"extendedClientCapabilities": {
"classFileContentsSupport": true,
"overrideMethodsPromptSupport": true,
"hashCodeEqualsPromptSupport": true,
"advancedOrganizeImportsSupport": true,
"generateToStringPromptSupport": true,
"advancedGenerateAccessorsSupport": true,
"generateConstructorsPromptSupport": true,
"generateDelegateMethodsPromptSupport": true,
"advancedExtractRefactoringSupport": true,
"inferSelectionSupport": [
"extractMethod",
"extractVariable",
"extractField"
],
"moveRefactoringSupport": true,
"clientHoverProvider": true,
"clientDocumentSymbolProvider": true,
"gradleChecksumWrapperPromptSupport": true,
"advancedIntroduceParameterRefactoringSupport": true,
"actionableRuntimeNotificationSupport": true,
"onCompletionItemSelectedCommand": "editor.action.triggerParameterHints",
"extractInterfaceSupport": true,
"advancedUpgradeGradleSupport": true,
"executeClientCommandSupport": true
},
"triggerFiles": [
"file:///tmp/test/Test10.java"
]
},
"trace": "verbose",
"workspaceFolders": [
{
"uri": "file:///home/cay/projects/versuchspersonendatenbank-backend",
"name": "versuchspersonendatenbank-backend"
}
]
}
next prev parent reply other threads:[~2023-11-06 17:16 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-24 9:17 bug#66726: 29.1; Eglot jdtls formatter ignored Cay Horstmann
2023-10-29 12:08 ` Eli Zaretskii
2023-10-29 14:40 ` João Távora
2023-11-06 17:16 ` Cay Horstmann [this message]
2023-11-18 8:40 ` Eli Zaretskii
2023-11-18 9:36 ` João Távora
2024-01-07 9:39 ` Cay Horstmann
2024-01-08 11:37 ` João Távora
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b52b69c8-047e-478f-9dba-e1d88a2ad9a8@horstmann.com \
--to=cay@horstmann.com \
--cc=66726@debbugs.gnu.org \
--cc=eliz@gnu.org \
--cc=joaotavora@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).