Skip to content

Commit b10c12f

Browse files
feat: add kconfig editor support (#1327)
* fix: handle NoSuchMethodError in SerialSettingsPage - Add defensive error handling for EclipseUtil.getSelectedIDFProjectInExplorer() - Implement fallback to getSelectedProjectInExplorer() with IDF nature check - Prevent terminal opening crash when no project is selected - Gracefully handle bundle version conflicts in OSGi runtime * feat: add kconfig editor support * fix: add documentation kconfig editor * docs: cleanup the docs and format * fix: add lang configuration files to the build * fix: added generic text editor scopecontext for kconfig
1 parent 1227b83 commit b10c12f

File tree

10 files changed

+530
-3
lines changed

10 files changed

+530
-3
lines changed

bundles/com.espressif.idf.terminal.connector.serial/src/com/espressif/idf/terminal/connector/serial/controls/SerialSettingsPage.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,30 @@ public void createControl(Composite parent)
101101

102102
projectCombo = new Combo(comp, SWT.NONE);
103103
projectCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
104-
Optional<IProject> optProject = Optional.ofNullable(EclipseUtil.getSelectedIDFProjectInExplorer());
104+
105+
// Safely get selected IDF project with error handling
106+
IProject selectedProject = null;
107+
try {
108+
selectedProject = EclipseUtil.getSelectedIDFProjectInExplorer();
109+
} catch (NoSuchMethodError e) {
110+
// Fallback: try to get any selected project
111+
try {
112+
selectedProject = EclipseUtil.getSelectedProjectInExplorer();
113+
if (selectedProject != null) {
114+
try {
115+
if (!selectedProject.hasNature(IDFProjectNature.ID)) {
116+
selectedProject = null; // Not an IDF project
117+
}
118+
} catch (CoreException ce) {
119+
selectedProject = null;
120+
}
121+
}
122+
} catch (Exception ex) {
123+
// If all else fails, selectedProject remains null
124+
}
125+
}
126+
127+
Optional<IProject> optProject = Optional.ofNullable(selectedProject);
105128
optProject.ifPresent(project -> projectCombo.setText(project.getName()));
106129
IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
107130
for (IProject project : projects)

bundles/com.espressif.idf.ui/META-INF/MANIFEST.MF

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Require-Bundle: org.eclipse.core.runtime,
1313
org.eclipse.cdt.cmake.ui,
1414
org.eclipse.swt;visibility:=reexport,
1515
org.eclipse.ui;visibility:=reexport,
16+
org.eclipse.ui.workbench,
1617
org.eclipse.jface,
1718
org.eclipse.cdt.core.native,
1819
org.eclipse.cdt.core;bundle-version="9.0.0",
@@ -33,6 +34,9 @@ Require-Bundle: org.eclipse.core.runtime,
3334
org.eclipse.nebula.widgets.xviewer;bundle-version="1.1.0",
3435
org.eclipse.nebula.widgets.xviewer.core;bundle-version="1.0.0",
3536
org.eclipse.text,
37+
org.eclipse.jface.text,
38+
org.eclipse.ui.genericeditor,
39+
org.eclipse.ui.editors,
3640
org.eclipse.cdt.native.serial,
3741
org.eclipse.ui.workbench.texteditor,
3842
org.eclipse.ui.intro,
@@ -45,7 +49,9 @@ Require-Bundle: org.eclipse.core.runtime,
4549
org.freemarker.freemarker,
4650
org.eclipse.tools.templates.freemarker,
4751
org.eclipse.cdt.lsp;bundle-version="3.0.0",
48-
org.eclipse.cdt.lsp.clangd;bundle-version="3.0.0"
52+
org.eclipse.cdt.lsp.clangd;bundle-version="3.0.0",
53+
org.eclipse.tm4e.registry,
54+
org.eclipse.tm4e.languageconfiguration
4955
Automatic-Module-Name: com.espressif.idf.ui
5056
Bundle-ActivationPolicy: lazy
5157
Bundle-RequiredExecutionEnvironment: JavaSE-17

bundles/com.espressif.idf.ui/build.properties

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,7 @@ bin.includes = META-INF/,\
1515
index.html,\
1616
go.css,\
1717
lib/commonmark-0.24.0.jar,\
18-
lib/jfreechart-1.5.5.jar
18+
lib/jfreechart-1.5.5.jar,\
19+
syntaxes/,\
20+
kconfig-language-configuration.json
1921

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"comments": {
3+
"lineComment": "#"
4+
},
5+
"brackets": [
6+
["(", ")"],
7+
["menu", "endmenu"],
8+
["choice", "endchoice"]
9+
],
10+
"autoClosingPairs": [
11+
["(", ")"],
12+
["\"", "\""]
13+
],
14+
"surroundingPairs": [
15+
["(", ")"],
16+
["\"", "\""]
17+
],
18+
"indentationRules": {
19+
"increaseIndentPattern": "^([\\s]*)(menu|config|menuconfig|choice|help|comment)(.*)$",
20+
"decreaseIndentPattern": "^(endmenu|endchoice|endif)(.*)$"
21+
},
22+
"wordPattern": "\\b[a-zA-Z_][a-zA-Z0-9_]*\\b",
23+
"folding": {
24+
"markers": {
25+
"start": "^\\s*#\\s*region\\b",
26+
"end": "^\\s*#\\s*endregion\\b"
27+
}
28+
}
29+
}

bundles/com.espressif.idf.ui/plugin.xml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,16 @@
639639
id="com.espressif.idf.ui.editor.idfsize"
640640
name="%editor.name">
641641
</editor>
642+
<editor
643+
class="com.espressif.idf.ui.kconfig.KConfigEditor"
644+
contributorClass="org.eclipse.ui.editors.text.TextEditorActionContributor"
645+
default="true"
646+
id="com.espressif.idf.ui.editor.kconfig"
647+
name="KConfig Editor">
648+
<contentTypeBinding
649+
contentTypeId="com.espressif.idf.ui.kconfig.contentType">
650+
</contentTypeBinding>
651+
</editor>
642652
</extension>
643653
<extension
644654
point="org.eclipse.cdt.launch.coreBuildTab">
@@ -845,6 +855,44 @@
845855
name="Partition Table"
846856
priority="normal">
847857
</content-type>
858+
<content-type
859+
base-type="org.eclipse.core.runtime.text"
860+
file-patterns="Kconfig,Kconfig.projbuild,Kconfig.in"
861+
id="com.espressif.idf.ui.kconfig.contentType"
862+
name="KConfig"
863+
priority="normal">
864+
</content-type>
865+
<file-association
866+
content-type="com.espressif.idf.ui.kconfig.contentType"
867+
file-extensions="Kconfig,Kconfig.projbuild,Kconfig.in">
868+
</file-association>
869+
</extension>
870+
<extension
871+
point="org.eclipse.tm4e.registry.grammars">
872+
<grammar
873+
contentTypeId="com.espressif.idf.ui.kconfig.contentType"
874+
path="syntaxes/kconfig.tmLanguage.json"
875+
scopeName="source.kconfig">
876+
</grammar>
877+
<scopeNameContentTypeBinding
878+
contentTypeId="com.espressif.idf.ui.kconfig.contentType"
879+
scopeName="source.kconfig">
880+
</scopeNameContentTypeBinding>
881+
</extension>
882+
<extension
883+
point="org.eclipse.tm4e.languageconfiguration.languageConfigurations">
884+
<languageConfiguration
885+
contentTypeId="com.espressif.idf.ui.kconfig.contentType"
886+
path="kconfig-language-configuration.json">
887+
</languageConfiguration>
888+
</extension>
889+
<extension
890+
point="org.eclipse.ui.genericeditor.contentAssistProcessors">
891+
<contentAssistProcessor
892+
class="com.espressif.idf.ui.kconfig.KConfigContentAssistProcessor"
893+
contentType="com.espressif.idf.ui.kconfig.contentType"
894+
triggerCharacters=" ">
895+
</contentAssistProcessor>
848896
</extension>
849897
<extension
850898
point="org.eclipse.ltk.core.refactoring.renameParticipants">
@@ -865,5 +913,10 @@
865913
id="com.espressif.idf.ui.espLaunchScope"
866914
name="Espressif Launch Scope">
867915
</context>
916+
<context
917+
id="com.espressif.idf.ui.kconfig.editorContext"
918+
name="KConfig Editor Context"
919+
parentId="org.eclipse.ui.textEditorScope">
920+
</context>
868921
</extension>
869922
</plugin>
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*******************************************************************************
2+
* Copyright 2024 Espressif Systems (Shanghai) PTE LTD. All rights reserved.
3+
* Use is subject to license terms.
4+
*******************************************************************************/
5+
package com.espressif.idf.ui.kconfig;
6+
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
10+
import org.eclipse.jface.text.contentassist.CompletionProposal;
11+
import org.eclipse.jface.text.contentassist.ICompletionProposal;
12+
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
13+
import org.eclipse.jface.text.contentassist.IContextInformation;
14+
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
15+
16+
/**
17+
* @author Kondal Kolipaka <[email protected]>
18+
*/
19+
public class KConfigContentAssistProcessor implements IContentAssistProcessor
20+
{
21+
private static final String[] MAIN_KEYWORDS = {
22+
"config", "menuconfig", "choice", "endchoice", "menu", "endmenu",
23+
"if", "endif", "source", "comment", "mainmenu"
24+
};
25+
26+
private static final String[] TYPES = {
27+
"bool", "tristate", "int", "hex", "string"
28+
};
29+
30+
private static final String[] PROPERTIES = {
31+
"default", "depends", "select", "imply", "range", "help", "prompt",
32+
"visible", "optional"
33+
};
34+
35+
private static final String[] VALUES = {
36+
"y", "n", "m"
37+
};
38+
39+
@Override
40+
public ICompletionProposal[] computeCompletionProposals(org.eclipse.jface.text.ITextViewer viewer, int offset)
41+
{
42+
List<ICompletionProposal> proposals = new ArrayList<>();
43+
44+
String text = viewer.getDocument().get();
45+
int lineStart = text.lastIndexOf('\n', offset - 1) + 1;
46+
String lineText = text.substring(lineStart, offset).trim();
47+
48+
for (String keyword : MAIN_KEYWORDS) {
49+
if (keyword.toLowerCase().startsWith(lineText.toLowerCase())) {
50+
proposals.add(createProposal(keyword, offset - lineText.length(), lineText.length(), keyword));
51+
}
52+
}
53+
54+
for (String type : TYPES) {
55+
if (type.toLowerCase().startsWith(lineText.toLowerCase())) {
56+
proposals.add(createProposal(type, offset - lineText.length(), lineText.length(), type));
57+
}
58+
}
59+
60+
for (String property : PROPERTIES) {
61+
if (property.toLowerCase().startsWith(lineText.toLowerCase())) {
62+
proposals.add(createProposal(property, offset - lineText.length(), lineText.length(), property));
63+
}
64+
}
65+
66+
for (String value : VALUES) {
67+
if (value.toLowerCase().startsWith(lineText.toLowerCase())) {
68+
proposals.add(createProposal(value, offset - lineText.length(), lineText.length(), value));
69+
}
70+
}
71+
72+
return proposals.toArray(new ICompletionProposal[proposals.size()]);
73+
}
74+
75+
private ICompletionProposal createProposal(String text, int offset, int length, String displayText) {
76+
return new CompletionProposal(text, offset, length, text.length(), null, displayText, null, null);
77+
}
78+
79+
@Override
80+
public IContextInformation[] computeContextInformation(org.eclipse.jface.text.ITextViewer viewer, int offset)
81+
{
82+
return null;
83+
}
84+
85+
@Override
86+
public char[] getCompletionProposalAutoActivationCharacters()
87+
{
88+
return new char[] { ' ', '\t', '\n' };
89+
}
90+
91+
@Override
92+
public char[] getContextInformationAutoActivationCharacters()
93+
{
94+
return null;
95+
}
96+
97+
@Override
98+
public String getErrorMessage()
99+
{
100+
return null;
101+
}
102+
103+
@Override
104+
public IContextInformationValidator getContextInformationValidator()
105+
{
106+
return null;
107+
}
108+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*******************************************************************************
2+
* Copyright 2024 Espressif Systems (Shanghai) PTE LTD. All rights reserved.
3+
* Use is subject to license terms.
4+
*******************************************************************************/
5+
package com.espressif.idf.ui.kconfig;
6+
7+
import org.eclipse.ui.internal.genericeditor.ExtensionBasedTextEditor;
8+
9+
/**
10+
* @author Kondal Kolipaka <[email protected]>
11+
*/
12+
@SuppressWarnings("restriction")
13+
public class KConfigEditor extends ExtensionBasedTextEditor
14+
{
15+
public static final String KCONFIG_EDITOR_ID = "com.espressif.idf.ui.kconfig.KConfigEditor";
16+
public static final String KCONFIG_CONTENT_TYPE = "com.espressif.idf.ui.kconfig.contentType";
17+
private static final String CONTEXT_ID = "com.espressif.idf.ui.kconfig.editorContext";
18+
19+
public KConfigEditor()
20+
{
21+
super();
22+
}
23+
24+
@Override
25+
protected void initializeKeyBindingScopes() {
26+
setKeyBindingScopes(new String[] { CONTEXT_ID });
27+
}
28+
}

0 commit comments

Comments
 (0)