1
+ /*******************************************************************************
2
+ * Copyright (c) 2024 Christoph Läubrich and others.
3
+ *
4
+ * This program and the accompanying materials
5
+ * are made available under the terms of the Eclipse Public License 2.0
6
+ * which accompanies this distribution, and is available at
7
+ * https://www.eclipse.org/legal/epl-2.0/
8
+ *
9
+ * SPDX-License-Identifier: EPL-2.0
10
+ *******************************************************************************/
11
+ package org .eclipse .m2e .editor .lemminx .bnd ;
12
+
13
+ import java .util .function .Function ;
14
+ import java .util .logging .Level ;
15
+ import java .util .logging .Logger ;
16
+
17
+ import org .eclipse .lemminx .dom .DOMDocument ;
18
+ import org .eclipse .lemminx .dom .DOMNode ;
19
+ import org .eclipse .lemminx .services .extensions .IXMLExtension ;
20
+ import org .eclipse .lemminx .services .extensions .XMLExtensionsRegistry ;
21
+ import org .eclipse .lemminx .services .extensions .completion .ICompletionParticipant ;
22
+ import org .eclipse .lemminx .services .extensions .completion .ICompletionRequest ;
23
+ import org .eclipse .lemminx .services .extensions .completion .ICompletionResponse ;
24
+ import org .eclipse .lemminx .services .extensions .save .ISaveContext ;
25
+ import org .eclipse .lsp4j .CompletionItem ;
26
+ import org .eclipse .lsp4j .CompletionItemKind ;
27
+ import org .eclipse .lsp4j .InitializeParams ;
28
+ import org .eclipse .lsp4j .InsertTextFormat ;
29
+ import org .eclipse .lsp4j .jsonrpc .CancelChecker ;
30
+
31
+ import aQute .bnd .help .Syntax ;
32
+
33
+ /**
34
+ * Extension to provide bnd instruction autocompletion to maven
35
+ */
36
+ public class BndLemminxPlugin implements IXMLExtension {
37
+
38
+ @ Override
39
+ public void start (InitializeParams params , XMLExtensionsRegistry registry ) {
40
+ Logger logger = Logger .getLogger ("bnd" );
41
+ logger .log (Level .INFO , "Loading bnd-lemminx extension" );
42
+ registry .registerCompletionParticipant (new ICompletionParticipant () {
43
+
44
+ @ Override
45
+ public void onAttributeName (boolean generateValue , ICompletionRequest completionRequest ,
46
+ ICompletionResponse response , CancelChecker checker ) throws Exception {
47
+ }
48
+
49
+ @ Override
50
+ public void onAttributeValue (String valuePrefix , ICompletionRequest completionRequest ,
51
+ ICompletionResponse response , CancelChecker checker ) throws Exception {
52
+ }
53
+
54
+ @ Override
55
+ public void onDTDSystemId (String valuePrefix , ICompletionRequest completionRequest ,
56
+ ICompletionResponse response , CancelChecker checker ) throws Exception {
57
+ }
58
+
59
+ @ Override
60
+ public void onTagOpen (ICompletionRequest completionRequest , ICompletionResponse response ,
61
+ CancelChecker checker ) throws Exception {
62
+ }
63
+
64
+ @ Override
65
+ public void onXMLContent (ICompletionRequest completionRequest , ICompletionResponse response ,
66
+ CancelChecker checker ) throws Exception {
67
+ try {
68
+ DOMDocument xmlDocument = completionRequest .getXMLDocument ();
69
+ DOMNode node = xmlDocument .findNodeBefore (completionRequest .getOffset ());
70
+ logger .log (Level .INFO , "onXMLContent: " + node );
71
+ if (isBndInstructionNode (node )) {
72
+ addCompletion (response , syntax -> syntax .getHeader () + ": " );
73
+ } else if (isFelixInstructionNode (node )) {
74
+ addCompletion (response , syntax -> {
75
+ String header = syntax .getHeader ();
76
+ if (header .startsWith ("-" )) {
77
+ header = "_" + header .substring (1 );
78
+ }
79
+ return String .format ("<%s>${0}</%s>" , header , header );
80
+ });
81
+ }
82
+ } catch (Exception e ) {
83
+ logger .log (Level .WARNING , "err=" + e );
84
+ }
85
+ }
86
+
87
+ private void addCompletion (ICompletionResponse response , Function <Syntax , String > insert ) {
88
+ Syntax .HELP .values ().stream ().forEach (syntax -> {
89
+ CompletionItem item = new CompletionItem ();
90
+ item .setLabel (syntax .getHeader ());
91
+ item .setDocumentation (syntax .getLead ());
92
+ item .setDetail (syntax .getExample ());
93
+ item .setInsertText (insert .apply (syntax ));
94
+ item .setKind (CompletionItemKind .Property );
95
+ item .setInsertTextFormat (InsertTextFormat .Snippet );
96
+ response .addCompletionItem (item );
97
+ });
98
+ }
99
+ });
100
+ }
101
+
102
+ private static boolean isBndInstructionNode (DOMNode node ) {
103
+ if (node != null ) {
104
+ if (node .getNodeName ().equals ("bnd" )) {
105
+ return true ;
106
+ }
107
+ return isBndInstructionNode (node .getParentNode ());
108
+ }
109
+ return false ;
110
+ }
111
+
112
+ private static boolean isFelixInstructionNode (DOMNode node ) {
113
+ if (node != null ) {
114
+ if (node .getNodeName ().equals ("instructions" )) {
115
+ return true ;
116
+ }
117
+ return isFelixInstructionNode (node .getParentNode ());
118
+ }
119
+ return false ;
120
+ }
121
+
122
+ @ Override
123
+ public void stop (XMLExtensionsRegistry registry ) {
124
+ // nothing special to do...
125
+ }
126
+
127
+ @ Override
128
+ public void doSave (ISaveContext context ) {
129
+ IXMLExtension .super .doSave (context );
130
+ }
131
+
132
+ }
0 commit comments