Skip to content

Commit 9b2f590

Browse files
committed
Open bash editor popup integration #82
- when a file has no file extension and its content starts with "#!/bin/bash" an "Open with Bash Editor" entry appears in popups
1 parent 7dbf18e commit 9b2f590

File tree

8 files changed

+240
-11
lines changed

8 files changed

+240
-11
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
3+
# this is just a test file for files having no file extension like .sh but be also bash script
4+
# so when finding a #!/bin/bash (shebang) on first line the editor should also be the default editor
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
# this is just a text file

basheditor-plugin/META-INF/MANIFEST.MF

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ Require-Bundle: org.eclipse.ui,
1414
org.eclipse.ui.views,
1515
org.eclipse.ui.workbench,
1616
org.eclipse.ui.editors,
17-
org.eclipse.ui.ide
17+
org.eclipse.ui.ide,
18+
org.eclipse.core.expressions
1819
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
1920
Bundle-ActivationPolicy: lazy
2021
Import-Package: org.eclipse.ui

basheditor-plugin/plugin.xml

Lines changed: 74 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,56 @@
3838
</editor>
3939
</extension>
4040

41+
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
42+
<!-- PROPERTY TESTERS -->
43+
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
44+
<extension point="org.eclipse.core.expressions.propertyTesters">
45+
<!-- see https://wiki.eclipse.org/Platform_Expression_Framework -->
46+
<!-- see http://help.eclipse.org/neon/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/workbench_cmd_expressions.htm -->
47+
<!-- see http://www.robertwloch.net/2011/01/eclipse-tips-tricks-property-testers-with-command-core-expressions/ -->
48+
<propertyTester
49+
class="de.jcup.basheditor.BashFileWithoutExtensionPropertyTester"
50+
id="de.jcup.basheditor.BashFileWithoutExtensionPropertyTester"
51+
namespace="de.jcup.basheditor"
52+
properties="isBashFileWithoutExtension"
53+
type="org.eclipse.core.resources.IResource">
54+
</propertyTester>
55+
</extension>
56+
57+
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
58+
<!-- POPUP -->
59+
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
60+
61+
<extension point="org.eclipse.ui.menus">
62+
<!-- http://help.eclipse.org/neon/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Fguide%2Fworkbench_cmd_menus.htm -->
63+
<menuContribution locationURI="popup:org.eclipse.ui.popup.any?before=additions">
64+
<!-- Detect new root project -->
65+
<command
66+
commandId="basheditor.command.openWithBashEditor"
67+
icon="icons/bash-editor.png"
68+
id="basheditor.maintoolbar.openWithBashEditor"
69+
label="Open with Bash Editor"
70+
tooltip="Opens bash file with Bash Editor."
71+
style="push">
72+
<visibleWhen
73+
checkEnabled="false">
74+
<with
75+
variable="activeMenuSelection">
76+
<and>
77+
<count value="1"/>
78+
<iterate ifEmpty="false">
79+
<adapt type="org.eclipse.core.resources.IFile">
80+
<test property="de.jcup.basheditor.isBashFileWithoutExtension" value="true"/>
81+
</adapt>
82+
</iterate>
83+
</and>
84+
</with>
85+
</visibleWhen>
86+
</command>
87+
88+
</menuContribution>
89+
</extension>
90+
4191
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
4292
<!-- MARKER -->
4393
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
@@ -65,16 +115,20 @@
65115
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
66116
<!-- COMMANDS -->
67117
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->^
68-
<extension
69-
point="org.eclipse.ui.commands">
70-
<category
118+
119+
<extension point="org.eclipse.ui.commands">
120+
<category
71121
description="Bash editor"
72122
id="basheditor.commands.category"
73123
name="Bash editor">
74-
</category>
75-
</extension>
76-
77-
<extension point="org.eclipse.ui.commands">
124+
</category>
125+
126+
<command
127+
name="Open with bash editor"
128+
description="Open file with bash editor"
129+
categoryId="basheditor.commands.category"
130+
id="basheditor.command.openWithBashEditor">
131+
</command>
78132
<command
79133
name="Quick outline"
80134
description="Show quick outline dialog"
@@ -94,6 +148,10 @@
94148
id="basheditor.editor.commands.gotomatchingbracket">
95149
</command>
96150
</extension>
151+
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
152+
<!-- HANDLERS -->
153+
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->^
154+
97155
<extension point="org.eclipse.ui.handlers">
98156
<handler
99157
commandId="basheditor.editor.commands.quickoutline"
@@ -103,10 +161,18 @@
103161
commandId="basheditor.editor.commands.source.toggleComment"
104162
class="de.jcup.basheditor.handlers.ToggleCommentHandler">
105163
</handler>
106-
<handler
164+
<handler
107165
commandId="basheditor.editor.commands.gotomatchingbracket"
108166
class="de.jcup.basheditor.handlers.GotoMatchingBracketHandler">
109167
</handler>
168+
<handler
169+
commandId="basheditor.editor.commands.gotomatchingbracket"
170+
class="de.jcup.basheditor.handlers.GotoMatchingBracketHandler">
171+
</handler>
172+
<handler
173+
commandId="basheditor.command.openWithBashEditor"
174+
class="de.jcup.basheditor.handlers.OpenWithBashEditor">
175+
</handler>
110176
</extension>
111177

112178
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->

basheditor-plugin/src/main/java-eclipse/de/jcup/basheditor/BashEditor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
public class BashEditor extends TextEditor implements StatusMessageSupport, IResourceChangeListener {
7777

7878
/** The COMMAND_ID of this editor as defined in plugin.xml */
79-
public static final String EDITOR_ID = "org.basheditor.editors.BashEditor";
79+
public static final String EDITOR_ID = "basheditor.editors.BashEditor";
8080
/** The COMMAND_ID of the editor context menu */
8181
public static final String EDITOR_CONTEXT_MENU_ID = EDITOR_ID + ".context";
8282
/** The COMMAND_ID of the editor ruler context menu */

basheditor-plugin/src/main/java-eclipse/de/jcup/basheditor/BashEditorUtil.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,18 @@
1515
*/
1616
package de.jcup.basheditor;
1717

18+
import java.io.File;
19+
20+
import org.eclipse.core.filebuffers.FileBuffers;
21+
import org.eclipse.core.filesystem.EFS;
22+
import org.eclipse.core.filesystem.IFileStore;
1823
import org.eclipse.core.resources.IResource;
1924
import org.eclipse.core.runtime.CoreException;
2025
import org.eclipse.core.runtime.ILog;
26+
import org.eclipse.core.runtime.IPath;
27+
import org.eclipse.core.runtime.IProgressMonitor;
2128
import org.eclipse.core.runtime.IStatus;
29+
import org.eclipse.core.runtime.NullProgressMonitor;
2230
import org.eclipse.core.runtime.Status;
2331
import org.eclipse.ui.IEditorInput;
2432
import org.eclipse.ui.IEditorPart;
@@ -27,13 +35,40 @@
2735
import de.jcup.basheditor.script.BashError;
2836

2937
public class BashEditorUtil {
30-
38+
private static final IProgressMonitor NULL_MONITOR = new NullProgressMonitor();
39+
3140
private static UnpersistedMarkerHelper scriptProblemMarkerHelper = new UnpersistedMarkerHelper(
3241
"de.jcup.basheditor.script.problem");
3342

3443
public static BashEditorPreferences getPreferences() {
3544
return BashEditorPreferences.getInstance();
3645
}
46+
47+
/**
48+
* Returns the file or <code>null</code>
49+
* @param path
50+
* @return file or <code>null</code>
51+
* @throws CoreException
52+
*/
53+
public static File toFile(IPath path) throws CoreException {
54+
if (path==null){
55+
return null;
56+
}
57+
IFileStore fileStore = FileBuffers.getFileStoreAtLocation(path);
58+
if (fileStore==null){
59+
return null;
60+
}
61+
File file = null;
62+
file = fileStore.toLocalFile(EFS.NONE, NULL_MONITOR);
63+
return file;
64+
}
65+
66+
public static File toFile(IResource resource) throws CoreException {
67+
if (resource==null){
68+
return toFile((IPath)null);
69+
}
70+
return toFile(resource.getLocation());
71+
}
3772

3873
public static void logInfo(String info) {
3974
getLog().log(new Status(IStatus.INFO, BashEditorActivator.PLUGIN_ID, info));
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package de.jcup.basheditor;
2+
3+
import java.io.BufferedReader;
4+
import java.io.File;
5+
import java.io.FileInputStream;
6+
import java.io.IOException;
7+
import java.io.InputStreamReader;
8+
9+
import org.eclipse.core.expressions.PropertyTester;
10+
import org.eclipse.core.resources.IFile;
11+
import org.eclipse.core.runtime.CoreException;
12+
13+
public class BashFileWithoutExtensionPropertyTester extends PropertyTester {
14+
15+
public static final String PROPERTY_NAMESPACE = "de.jcup.basheditor";
16+
public static final String PROPERTY_IS_BASHFILE_WITHOUT_EXTENSION = "isBashFileWithoutExtension";
17+
18+
@Override
19+
public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
20+
if (!PROPERTY_IS_BASHFILE_WITHOUT_EXTENSION.equals(property)) {
21+
return false;
22+
}
23+
if (!(receiver instanceof IFile)) {
24+
/* not supported */
25+
return false;
26+
}
27+
28+
IFile file = (IFile) receiver;
29+
if (!file.exists()) {
30+
return false;
31+
}
32+
boolean isBashFileWithoutFileExtension = file.getFileExtension() == null;
33+
if (!isBashFileWithoutFileExtension) {
34+
return false;
35+
}
36+
File theFile;
37+
try {
38+
theFile = BashEditorUtil.toFile(file);
39+
} catch (CoreException e) {
40+
BashEditorUtil.logError("Was not able to test if file is a bash file:"+file.getName(), e);
41+
return false;
42+
}
43+
if (theFile==null || !theFile.exists()){
44+
return false;
45+
}
46+
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(theFile)))) {
47+
String line = br.readLine();
48+
if (line.startsWith("#!/bin/bash")) {
49+
return true;
50+
}
51+
return false;
52+
53+
}catch(IOException e){
54+
BashEditorUtil.logError("Was not able to test if file is a bash file:"+file.getName(), e);
55+
return false;
56+
}
57+
58+
59+
}
60+
61+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package de.jcup.basheditor.handlers;
2+
3+
import org.eclipse.core.commands.AbstractHandler;
4+
import org.eclipse.core.commands.ExecutionEvent;
5+
import org.eclipse.core.commands.ExecutionException;
6+
import org.eclipse.core.resources.IFile;
7+
import org.eclipse.core.runtime.IAdaptable;
8+
import org.eclipse.jface.viewers.ISelection;
9+
import org.eclipse.jface.viewers.IStructuredSelection;
10+
import org.eclipse.ui.IWorkbenchPage;
11+
import org.eclipse.ui.IWorkbenchWindow;
12+
import org.eclipse.ui.PartInitException;
13+
import org.eclipse.ui.PlatformUI;
14+
import org.eclipse.ui.part.FileEditorInput;
15+
16+
import de.jcup.basheditor.BashEditor;
17+
import de.jcup.basheditor.EclipseUtil;
18+
19+
public class OpenWithBashEditor extends AbstractHandler{
20+
21+
@Override
22+
public Object execute(ExecutionEvent event) throws ExecutionException {
23+
IFile file = getSelectedFile();
24+
if (file==null){
25+
return null;
26+
}
27+
IWorkbenchPage page = EclipseUtil.getActivePage();
28+
if (page==null){
29+
return null;
30+
}
31+
try {
32+
page.openEditor(new FileEditorInput(file), BashEditor.EDITOR_ID);
33+
} catch (PartInitException e) {
34+
throw new ExecutionException("Was not able to open bash editor for file:"+file.getName(),e);
35+
}
36+
return null;
37+
}
38+
39+
protected IFile getSelectedFile() {
40+
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
41+
if (window == null) {
42+
return null;
43+
}
44+
45+
ISelection selection = window.getSelectionService().getSelection();
46+
if (! (selection instanceof IStructuredSelection)){
47+
return null;
48+
}
49+
IStructuredSelection structuredSelection = (IStructuredSelection) selection;
50+
51+
Object firstElement = structuredSelection.getFirstElement();
52+
if (!(firstElement instanceof IAdaptable)) {
53+
return null;
54+
}
55+
56+
IFile file = (IFile) ((IAdaptable) firstElement).getAdapter(IFile.class);
57+
return file;
58+
}
59+
60+
}

0 commit comments

Comments
 (0)