Permalink
Browse files

stylish haskell GUI

  • Loading branch information...
1 parent 2b4555d commit d42ca9392bcd28b75fce22d7de20f4a0da7345d0 @JPMoresmau committed Jun 29, 2012
Showing with 1,607 additions and 13 deletions.
  1. +10 −0 net.sf.eclipsefp.haskell.style.test/.classpath
  2. +17 −0 net.sf.eclipsefp.haskell.style.test/.project
  3. +82 −0 net.sf.eclipsefp.haskell.style.test/src/net/sf/eclipsefp/haskell/style/SHConfigurationTest.java
  4. +55 −0 net.sf.eclipsefp.haskell.style.test/src/net/sf/eclipsefp/haskell/style/stylish-haskell-default.yaml
  5. +55 −0 net.sf.eclipsefp.haskell.style.test/src/net/sf/eclipsefp/haskell/style/stylish-haskell-full.yaml
  6. +66 −0 ...ipsefp.haskell.style.test/src/net/sf/eclipsefp/haskell/style/ui/SHConfigurationCompositeTest.java
  7. +1 −0 net.sf.eclipsefp.haskell.style/.classpath
  8. +9 −2 net.sf.eclipsefp.haskell.style/META-INF/MANIFEST.MF
  9. +3 −1 net.sf.eclipsefp.haskell.style/build.properties
  10. BIN net.sf.eclipsefp.haskell.style/lib/snakeyaml-1.10.jar
  11. +3 −1 net.sf.eclipsefp.haskell.style/plugin.properties
  12. +25 −0 net.sf.eclipsefp.haskell.style/plugin.xml
  13. +22 −0 net.sf.eclipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/StylePlugin.java
  14. +205 −0 ...sf.eclipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/SHConfiguration.java
  15. +76 −0 net.sf.eclipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/SHImports.java
  16. +90 −0 net.sf.eclipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/SHPragmas.java
  17. +67 −0 net.sf.eclipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/SHTabs.java
  18. +48 −0 ...lipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/SHTrailingWhitespace.java
  19. +61 −0 net.sf.eclipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/SHUnicode.java
  20. +196 −8 net.sf.eclipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/StylishHaskell.java
  21. +281 −0 ....haskell.style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/ui/SHConfigurationComposite.java
  22. +126 −0 ...lipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/ui/SHConfigurationPP.java
  23. +41 −0 net.sf.eclipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/util/StyleText.java
  24. +17 −0 net.sf.eclipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/util/style.properties
  25. +1 −1 ...efp.haskell.ui/src/net/sf/eclipsefp/haskell/ui/internal/editors/haskell/actions/FormatAction.java
  26. +3 −0 ...eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/ui/internal/preferences/scion/ExecutablePP.java
  27. +47 −0 ...psefp.haskell.ui/src/net/sf/eclipsefp/haskell/ui/internal/preferences/scion/StylishHaskellPP.java
View
10 net.sf.eclipsefp.haskell.style.test/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/net.sf.eclipsefp.haskell.style"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+ <classpathentry kind="var" path="ECLIPSE_HOME/plugins/org.eclipse.swt_3.7.1.v3738a.jar"/>
+ <classpathentry kind="var" path="ECLIPSE_HOME/plugins/org.eclipse.swt.win32.win32.x86_3.7.1.v3738a.jar"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
View
17 net.sf.eclipsefp.haskell.style.test/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>net.sf.eclipsefp.haskell.style.test</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
View
82 ....eclipsefp.haskell.style.test/src/net/sf/eclipsefp/haskell/style/SHConfigurationTest.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2012 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.style;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import net.sf.eclipsefp.haskell.style.stylishhaskell.SHConfiguration;
+import net.sf.eclipsefp.haskell.style.stylishhaskell.SHImports.SHImportAlign;
+import net.sf.eclipsefp.haskell.style.stylishhaskell.SHPragmas.SHPragmaStyle;
+import net.sf.eclipsefp.haskell.style.stylishhaskell.StylishHaskell;
+
+import org.junit.Test;
+
+/**
+ * Tests the Stylish Haskell configuration, especially YAML I/O
+ * @author JP Moresmau
+ *
+ */
+public class SHConfigurationTest {
+
+
+ @Test
+ public void testDefault(){
+ SHConfiguration def=new SHConfiguration();
+ assertNull(def.getTabs());
+ assertNull(def.getUnicode());
+ assertNotNull(def.getImports());
+ assertEquals(SHImportAlign.GLOBAL, def.getImports().getAlign());
+ assertNotNull(def.getPragmas());
+ assertTrue(def.getPragmas().isRemoveRedundant());
+ assertEquals(SHPragmaStyle.VERTICAL,def.getPragmas().getStyle());
+ assertNotNull(def.getTrailingWhitespace());
+ }
+
+ @Test
+ public void testIODefault() throws IOException{
+ SHConfiguration def=new SHConfiguration();
+ InputStream is=getClass().getResourceAsStream("stylish-haskell-default.yaml");
+ assertNotNull(is);
+ SHConfiguration defRead=StylishHaskell.load(is);
+ assertEquals(def,defRead);
+ ByteArrayOutputStream baos=new ByteArrayOutputStream();
+ StylishHaskell.save(defRead, baos);
+ SHConfiguration defRead2=StylishHaskell.load(new ByteArrayInputStream(baos.toByteArray()));
+ assertEquals(def,defRead2);
+ }
+
+ @Test
+ public void testIOFull() throws IOException{
+ InputStream is=getClass().getResourceAsStream("stylish-haskell-full.yaml");
+ assertNotNull(is);
+ SHConfiguration confRead=StylishHaskell.load(is);
+ assertNotNull(confRead.getTabs());
+ assertEquals(4,confRead.getTabs().getSpaces());
+ assertNotNull(confRead.getUnicode());
+ assertTrue(confRead.getUnicode().isUnicodePragmas());
+
+ assertNotNull(confRead.getImports());
+ assertEquals(SHImportAlign.GROUP, confRead.getImports().getAlign());
+ assertNotNull(confRead.getPragmas());
+ assertFalse(confRead.getPragmas().isRemoveRedundant());
+ assertEquals(SHPragmaStyle.COMPACT,confRead.getPragmas().getStyle());
+ assertNotNull(confRead.getTrailingWhitespace());
+
+ ByteArrayOutputStream baos=new ByteArrayOutputStream();
+ StylishHaskell.save(confRead, baos);
+ SHConfiguration confRead2=StylishHaskell.load(new ByteArrayInputStream(baos.toByteArray()));
+ assertEquals(confRead,confRead2);
+ }
+}
View
55 ...ipsefp.haskell.style.test/src/net/sf/eclipsefp/haskell/style/stylish-haskell-default.yaml
@@ -0,0 +1,55 @@
+# stylish-haskell configuration file
+# ==================================
+#
+# The stylish-haskell tool is mainly configured by specifying steps. These steps
+# are a list, so they have an order, and one specific step may appear more than
+# once (if needed). Each file is processed by these steps in the given order.
+steps:
+ # Convert some ASCII sequences to their Unicode equivalents. This is disabled
+ # by default.
+ # - unicode_syntax:
+ # # In order to make this work, we also need to insert the UnicodeSyntax
+ # # language pragma. If this flag is set to true, we insert it when it's
+ # # not already present. You may want to disable it if you configure
+ # # language extensions using some other method than pragmas. Default:
+ # # true.
+ # add_language_pragma: true
+
+ # Import cleanup
+ - imports:
+ # There are different ways we can align names and lists.
+ #
+ # - global: Align the import names and import list throughout the entire
+ # file.
+ #
+ # - group: Only align the imports per group (a group is formed by adjacent
+ # import lines).
+ #
+ # - none: Do not perform any alignment.
+ #
+ # Default: global.
+ align: global
+
+ # Language pragmas
+ - language_pragmas:
+ # We can generate different styles of language pragma lists.
+ #
+ # - vertical: Vertical-spaced language pragmas, one per line.
+ #
+ # - compact: A more compact style.
+ #
+ # Default: vertical.
+ style: vertical
+
+ # stylish-haskell can detect redundancy of some language pragmas. If this
+ # is set to true, it will remove those redundant pragmas. Default: true.
+ remove_redundant: true
+
+ # Replace tabs by spaces. This is disabled by default.
+ # - tabs:
+ # # Number of spaces to use for each tab. Default: 8, as specified by the
+ # # Haskell report.
+ # spaces: 8
+
+ # Remove trailing whitespace
+ - trailing_whitespace: {}
View
55 ...eclipsefp.haskell.style.test/src/net/sf/eclipsefp/haskell/style/stylish-haskell-full.yaml
@@ -0,0 +1,55 @@
+# stylish-haskell configuration file
+# ==================================
+#
+# The stylish-haskell tool is mainly configured by specifying steps. These steps
+# are a list, so they have an order, and one specific step may appear more than
+# once (if needed). Each file is processed by these steps in the given order.
+steps:
+ # Convert some ASCII sequences to their Unicode equivalents. This is disabled
+ # by default.
+ - unicode_syntax:
+ # In order to make this work, we also need to insert the UnicodeSyntax
+ # language pragma. If this flag is set to true, we insert it when it's
+ # not already present. You may want to disable it if you configure
+ # language extensions using some other method than pragmas. Default:
+ # true.
+ add_language_pragma: true
+
+ # Import cleanup
+ - imports:
+ # There are different ways we can align names and lists.
+ #
+ # - global: Align the import names and import list throughout the entire
+ # file.
+ #
+ # - group: Only align the imports per group (a group is formed by adjacent
+ # import lines).
+ #
+ # - none: Do not perform any alignment.
+ #
+ # Default: global.
+ align: group
+
+ # Language pragmas
+ - language_pragmas:
+ # We can generate different styles of language pragma lists.
+ #
+ # - vertical: Vertical-spaced language pragmas, one per line.
+ #
+ # - compact: A more compact style.
+ #
+ # Default: vertical.
+ style: compact
+
+ # stylish-haskell can detect redundancy of some language pragmas. If this
+ # is set to true, it will remove those redundant pragmas. Default: true.
+ remove_redundant: false
+
+ # Replace tabs by spaces. This is disabled by default.
+ - tabs:
+ # Number of spaces to use for each tab. Default: 8, as specified by the
+ # Haskell report.
+ spaces: 4
+
+ # Remove trailing whitespace
+ - trailing_whitespace: {}
View
66 ...askell.style.test/src/net/sf/eclipsefp/haskell/style/ui/SHConfigurationCompositeTest.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2012 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.style.ui;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import net.sf.eclipsefp.haskell.style.stylishhaskell.SHConfiguration;
+import net.sf.eclipsefp.haskell.style.stylishhaskell.StylishHaskell;
+import net.sf.eclipsefp.haskell.style.stylishhaskell.ui.SHConfigurationComposite;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * test composite
+ * @author JP Moresmau
+ *
+ */
+public class SHConfigurationCompositeTest {
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ Display display=new Display();
+
+ Shell shell=new Shell(display);
+ shell.setLayout(new GridLayout(1,true));
+ final SHConfigurationComposite comp=new SHConfigurationComposite(shell, SWT.NONE);
+ comp.setConfiguration(new SHConfiguration());
+ Button b=new Button(shell,SWT.PUSH);
+ b.setText("click");
+ b.addSelectionListener(new SelectionAdapter() {
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ SHConfiguration conf=comp.getConfiguration();
+ ByteArrayOutputStream baos=new ByteArrayOutputStream();
+ try {
+ StylishHaskell.save(conf, baos);
+ System.out.println(new String(baos.toByteArray()));
+ } catch (IOException ioe){
+ ioe.printStackTrace();
+ }
+ }
+ });
+ shell.open();
+ while (!shell.isDisposed ()) {
+ if (!display.readAndDispatch ())
+ display.sleep ();
+ }
+ display.dispose ();
+ }
+
+}
View
1 net.sf.eclipsefp.haskell.style/.classpath
@@ -3,5 +3,6 @@
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
+ <classpathentry kind="lib" path="lib/snakeyaml-1.10.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
View
11 net.sf.eclipsefp.haskell.style/META-INF/MANIFEST.MF
@@ -7,10 +7,17 @@ Bundle-Activator: net.sf.eclipsefp.haskell.style.StylePlugin
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.core.resources,
net.sf.eclipsefp.haskell.util,
- org.eclipse.ui.workbench
+ org.eclipse.ui.workbench,
+ org.eclipse.swt,
+ org.eclipse.jface,
+ org.eclipse.ui
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-Vendor: %bundleVendor
Bundle-Localization: plugin
Export-Package: net.sf.eclipsefp.haskell.style,
- net.sf.eclipsefp.haskell.style.stylishhaskell
+ net.sf.eclipsefp.haskell.style.stylishhaskell,
+ net.sf.eclipsefp.haskell.style.stylishhaskell.ui,
+ net.sf.eclipsefp.haskell.style.util
+Bundle-ClassPath: lib/snakeyaml-1.10.jar,
+ .
View
4 net.sf.eclipsefp.haskell.style/build.properties
@@ -2,4 +2,6 @@ source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
- plugin.properties
+ plugin.properties,\
+ lib/snakeyaml-1.10.jar,\
+ plugin.xml
View
BIN net.sf.eclipsefp.haskell.style/lib/snakeyaml-1.10.jar
Binary file not shown.
View
4 net.sf.eclipsefp.haskell.style/plugin.properties
@@ -1,3 +1,5 @@
# bundle manifest
bundleVendor = The EclipseFP Project
-bundleName = Haskell Style and Formatting Utilities
+bundleName = Haskell Style and Formatting Utilities
+
+stylishHaskellPP_name=Stylish Haskell
View
25 net.sf.eclipsefp.haskell.style/plugin.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.ui.propertyPages">
+
+ <page
+ name="%stylishHaskellPP_name"
+ class="net.sf.eclipsefp.haskell.style.stylishhaskell.ui.SHConfigurationPP"
+ id="net.sf.eclipsefp.haskell.style.stylishhaskell.ui.SHConfigurationPP">
+ <filter
+ name="nature"
+ value="net.sf.eclipsefp.haskell.core.project.HaskellNature">
+ </filter>
+ <filter
+ name="open"
+ value="true">
+ </filter>
+ <enabledWhen>
+ <adapt type="org.eclipse.core.resources.IProject" />
+ </enabledWhen>
+ </page>
+ </extension>
+
+</plugin>
View
22 net.sf.eclipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/StylePlugin.java
@@ -5,7 +5,10 @@
*/
package net.sf.eclipsefp.haskell.style;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.ui.statushandlers.StatusManager;
import org.osgi.framework.BundleContext;
/**
@@ -16,14 +19,33 @@
public class StylePlugin extends AbstractUIPlugin {
private static StylePlugin plugin=null;
+ // The plug-in ID
+ public static final String PLUGIN_ID = "net.sf.eclipsefp.haskell.style";
+
/**
* @return the plugin
*/
public static StylePlugin getStylePlugin() {
return plugin;
}
+
+ public static void logError(Throwable cause) {
+ log(Status.ERROR, cause.getLocalizedMessage(), cause);
+ }
+ public static void logError(String message, Throwable cause) {
+ log(Status.ERROR, message, cause);
+ }
+
+ public static void log(int severity, String message, Throwable cause) {
+ Status status = new Status(severity, PLUGIN_ID, severity, message, cause);
+ logStatus(status);
+ }
+ public static void logStatus(IStatus status) {
+ StatusManager.getManager().handle(status);
+ }
+
/*
* (non-Javadoc)
View
205 ...sefp.haskell.style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/SHConfiguration.java
@@ -0,0 +1,205 @@
+/**
+ * Copyright (c) 2012 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.style.stylishhaskell;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A stylish haskell configuration
+ * @author JP Moresmau
+ *
+ */
+public class SHConfiguration {
+ private SHUnicode unicode=null;
+
+ private SHImports imports=new SHImports();
+
+ private SHPragmas pragmas=new SHPragmas();
+
+ private SHTabs tabs=null;
+
+ private SHTrailingWhitespace trailingWhitespace=new SHTrailingWhitespace();
+
+ public SHUnicode getUnicode() {
+ return unicode;
+ }
+
+ public void setUnicode(SHUnicode unicode) {
+ this.unicode = unicode;
+ }
+
+ public SHImports getImports() {
+ return imports;
+ }
+
+ public void setImports(SHImports imports) {
+ this.imports = imports;
+ }
+
+ public SHPragmas getPragmas() {
+ return pragmas;
+ }
+
+ public void setPragmas(SHPragmas pragmas) {
+ this.pragmas = pragmas;
+ }
+
+ public SHTabs getTabs() {
+ return tabs;
+ }
+
+ public void setTabs(SHTabs tabs) {
+ this.tabs = tabs;
+ }
+
+ public SHTrailingWhitespace getTrailingWhitespace() {
+ return trailingWhitespace;
+ }
+
+ public void setTrailingWhitespace(SHTrailingWhitespace trailingWhitespace) {
+ this.trailingWhitespace = trailingWhitespace;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((imports == null) ? 0 : imports.hashCode());
+ result = prime * result + ((pragmas == null) ? 0 : pragmas.hashCode());
+ result = prime * result + ((tabs == null) ? 0 : tabs.hashCode());
+ result = prime
+ * result
+ + ((trailingWhitespace == null) ? 0 : trailingWhitespace
+ .hashCode());
+ result = prime * result + ((unicode == null) ? 0 : unicode.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ SHConfiguration other = (SHConfiguration) obj;
+ if (imports == null) {
+ if (other.imports != null)
+ return false;
+ } else if (!imports.equals(other.imports))
+ return false;
+ if (pragmas == null) {
+ if (other.pragmas != null)
+ return false;
+ } else if (!pragmas.equals(other.pragmas))
+ return false;
+ if (tabs == null) {
+ if (other.tabs != null)
+ return false;
+ } else if (!tabs.equals(other.tabs))
+ return false;
+ if (trailingWhitespace == null) {
+ if (other.trailingWhitespace != null)
+ return false;
+ } else if (!trailingWhitespace.equals(other.trailingWhitespace))
+ return false;
+ if (unicode == null) {
+ if (other.unicode != null)
+ return false;
+ } else if (!unicode.equals(other.unicode))
+ return false;
+ return true;
+ }
+
+ public void fromYAML(Object o){
+ clear();
+ if (o instanceof Map<?, ?>){
+ Object val1=((Map<?,?>)o).get("steps");
+ if (val1 instanceof Collection<?>){
+ for (Object o2:(Collection<?>)val1){
+ if (o2 instanceof Map<?,?>){
+ Map<?,?> m2=(Map<?,?>)o2;
+ if (!m2.isEmpty()){
+ Map.Entry<?, ?> e=m2.entrySet().iterator().next();
+ Object k1=e.getKey();
+ if (k1 instanceof String){
+ Object v1=e.getValue();
+ if (v1 instanceof Map<?,?>){
+ addStep((String)k1,(Map<?,?>)v1);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public Map<String,Object> toYAML(){
+ List<Object> steps=new ArrayList<Object>();
+ if (unicode!=null){
+ Map<String,Object> m=new HashMap<String, Object>();
+ m.put("unicode_syntax", unicode.toYAML());
+ steps.add(m);
+ }
+ if (imports!=null){
+ Map<String,Object> m=new HashMap<String, Object>();
+ m.put("imports", imports.toYAML());
+ steps.add(m);
+ }
+ if (pragmas!=null){
+ Map<String,Object> m=new HashMap<String, Object>();
+ m.put("language_pragmas", pragmas.toYAML());
+ steps.add(m);
+ }
+ if (tabs!=null){
+ Map<String,Object> m=new HashMap<String, Object>();
+ m.put("tabs", tabs.toYAML());
+ steps.add(m);
+ }
+ if (trailingWhitespace!=null){
+ Map<String,Object> m=new HashMap<String, Object>();
+ m.put("trailing_whitespace", trailingWhitespace.toYAML());
+ steps.add(m);
+ }
+
+ Map<String,Object> ret=new HashMap<String, Object>();
+ ret.put("steps", steps);
+ return ret;
+ }
+
+ public void clear(){
+ imports=null;
+ pragmas=null;
+ tabs=null;
+ trailingWhitespace=null;
+ unicode=null;
+ }
+
+ private void addStep(String name,Map<?,?> params){
+ if ("unicode_syntax".equalsIgnoreCase(name)){
+ unicode=new SHUnicode();
+ unicode.fromYAML(params);
+ } else if ("imports".equalsIgnoreCase(name)){
+ imports=new SHImports();
+ imports.fromYAML(params);
+ } else if ("language_pragmas".equalsIgnoreCase(name)){
+ pragmas=new SHPragmas();
+ pragmas.fromYAML(params);
+ } else if ("tabs".equalsIgnoreCase(name)){
+ tabs=new SHTabs();
+ tabs.fromYAML(params);
+ }else if ("trailing_whitespace".equalsIgnoreCase(name)){
+ trailingWhitespace=new SHTrailingWhitespace();
+ trailingWhitespace.fromYAML(params);
+ }
+ }
+}
View
76 ....eclipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/SHImports.java
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2012 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.style.stylishhaskell;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.eclipsefp.haskell.style.StylePlugin;
+
+/**
+ * Stylish Haskell import management options
+ * @author JP Moresmau
+ *
+ */
+public class SHImports {
+ public static enum SHImportAlign {
+ GLOBAL,
+ GROUP,
+ NONE;
+ }
+
+ private SHImportAlign align=SHImportAlign.GLOBAL;
+
+ public SHImportAlign getAlign() {
+ return align;
+ }
+
+ public void setAlign(SHImportAlign align) {
+ if (align==null){
+ align=SHImportAlign.GLOBAL;
+ }
+ this.align = align;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((align == null) ? 0 : align.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ SHImports other = (SHImports) obj;
+ if (align != other.align)
+ return false;
+ return true;
+ }
+
+ public void fromYAML(Map<?,?> map){
+ Object o=map.get("align");
+ if (o!=null){
+ try {
+ align=SHImportAlign.valueOf(String.valueOf(o).toUpperCase());
+ } catch (IllegalArgumentException iae){
+ StylePlugin.logError(iae);
+ }
+ }
+ }
+
+ public Map<String,String> toYAML(){
+ Map<String,String> m=new HashMap<String, String>();
+ m.put("align", align.name().toLowerCase());
+ return m;
+ }
+}
View
90 ....eclipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/SHPragmas.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2012 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.style.stylishhaskell;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.eclipsefp.haskell.style.StylePlugin;
+
+/**
+ * Stylish Haskell language pragmas management options
+ * @author JP Moresmau
+ *
+ */
+public class SHPragmas {
+ public static enum SHPragmaStyle{
+ VERTICAL,
+ COMPACT;
+ }
+
+ private SHPragmaStyle style=SHPragmaStyle.VERTICAL;
+
+ private boolean removeRedundant=true;
+
+ public SHPragmaStyle getStyle() {
+ return style;
+ }
+
+ public void setStyle(SHPragmaStyle style) {
+ this.style = style;
+ }
+
+ public boolean isRemoveRedundant() {
+ return removeRedundant;
+ }
+
+ public void setRemoveRedundant(boolean removeRedundant) {
+ this.removeRedundant = removeRedundant;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (removeRedundant ? 1231 : 1237);
+ result = prime * result + ((style == null) ? 0 : style.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ SHPragmas other = (SHPragmas) obj;
+ if (removeRedundant != other.removeRedundant)
+ return false;
+ if (style != other.style)
+ return false;
+ return true;
+ }
+
+ public void fromYAML(Map<?,?> map){
+ Object o=map.get("style");
+ if (o!=null){
+ try {
+ style=SHPragmaStyle.valueOf(String.valueOf(o).toUpperCase());
+ } catch (IllegalArgumentException iae){
+ StylePlugin.logError(iae);
+ }
+ }
+ o=map.get("remove_redundant");
+ if (o!=null){
+ removeRedundant=Boolean.TRUE.toString().equalsIgnoreCase(String.valueOf(o));
+ }
+ }
+
+ public Map<String,Object> toYAML(){
+ Map<String,Object> m=new HashMap<String, Object>();
+ m.put("style", style.name().toLowerCase());
+ m.put("remove_redundant", removeRedundant);
+ return m;
+ }
+}
View
67 net.sf.eclipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/SHTabs.java
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2012 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.style.stylishhaskell;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.eclipsefp.haskell.style.StylePlugin;
+
+/**
+ * Stylish Haskell tabs management options
+ * @author JP Moresmau
+ *
+ */
+public class SHTabs {
+ private int spaces=8;
+
+ public int getSpaces() {
+ return spaces;
+ }
+
+ public void setSpaces(int spaces) {
+ this.spaces = spaces;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + spaces;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ SHTabs other = (SHTabs) obj;
+ if (spaces != other.spaces)
+ return false;
+ return true;
+ }
+
+ public void fromYAML(Map<?,?> map){
+ Object o=map.get("spaces");
+ if (o!=null){
+ try {
+ spaces=Integer.parseInt(String.valueOf(o));
+ } catch (NumberFormatException nfe){
+ StylePlugin.logError(nfe);
+ }
+ }
+ }
+
+ public Map<String,Object> toYAML(){
+ Map<String,Object> m=new HashMap<String, Object>();
+ m.put("spaces", spaces);
+ return m;
+ }
+}
View
48 ...haskell.style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/SHTrailingWhitespace.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2012 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.style.stylishhaskell;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Stylish Haskell trailing space management options
+ * @author JP Moresmau
+ *
+ */
+public class SHTrailingWhitespace {
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ return true;
+ }
+
+ public void fromYAML(Map<?,?> map){
+
+ }
+
+ public Map<String,String> toYAML(){
+ Map<String,String> m=new HashMap<String, String>();
+ return m;
+ }
+}
View
61 ....eclipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/SHUnicode.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2012 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.style.stylishhaskell;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Stylish Haskell unicode management options
+ * @author JP Moresmau
+ *
+ */
+public class SHUnicode {
+ private boolean unicodePragmas=false;
+
+ public boolean isUnicodePragmas() {
+ return unicodePragmas;
+ }
+
+ public void setUnicodePragmas(boolean unicodePragmas) {
+ this.unicodePragmas = unicodePragmas;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (unicodePragmas ? 1231 : 1237);
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ SHUnicode other = (SHUnicode) obj;
+ if (unicodePragmas != other.unicodePragmas)
+ return false;
+ return true;
+ }
+
+ public void fromYAML(Map<?,?> map){
+ Object o=map.get("add_language_pragma");
+ if (o!=null){
+ unicodePragmas=Boolean.TRUE.toString().equalsIgnoreCase(String.valueOf(o));
+ }
+ }
+
+ public Map<String,Object> toYAML(){
+ Map<String,Object> m=new HashMap<String, Object>();
+ m.put("add_language_pragma", unicodePragmas);
+ return m;
+ }
+}
View
204 ...psefp.haskell.style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/StylishHaskell.java
@@ -5,26 +5,50 @@
*/
package net.sf.eclipsefp.haskell.style.stylishhaskell;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import net.sf.eclipsefp.haskell.style.StylePlugin;
+import net.sf.eclipsefp.haskell.util.FileUtil;
import net.sf.eclipsefp.haskell.util.ProcessRunner;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.Yaml;
/**
- * Utilities to invoke stylish-haskell
+ * Utilities to invoke stylish-haskell and manage its configuration files
* @author JP Moresmau
*
*/
public class StylishHaskell {
-
- public static void runStylishHaskell(String exe, IProject project, File filePath) throws Exception{
+ /**
+ * run stylish haskell
+ * @param exe the path to the exe (may not be full if we hope it's in the path)
+ * @param project the project we're in
+ * @param filePath the file to format
+ * @param charset the charset of the file
+ * @throws Exception
+ */
+ public static void runStylishHaskell(String exe, IProject project, File filePath,String charset) throws Exception{
List<String> cmd=new ArrayList<String>();
cmd.add(exe);
cmd.add("-i"); // in place
@@ -33,16 +57,28 @@ public static void runStylishHaskell(String exe, IProject project, File filePath
cmd.add("--config="+cf);
}
cmd.add(filePath.getAbsolutePath());
- Process p = Runtime.getRuntime()
- .exec( cmd.toArray(new String[cmd.size()]), null, filePath.getParentFile() );
- ProcessRunner.consume( p );
- p.waitFor();
+ // keep old contents
+ String contents=FileUtil.getContents(filePath, charset);
+
+ // capture errors
+ StringWriter sw=new StringWriter();
+ int code=new ProcessRunner().executeBlocking(filePath.getParentFile(), new StringWriter(), sw,cmd.toArray(new String[cmd.size()]));
+ if (code!=0){
+ // we restore the file contents if we failed
+ FileUtil.writeSharedFile(filePath, contents, 1);
+ throw new IOException(sw.toString());
+ }
}
+ /**
+ * get the path of the config file to use for a given project, or null to use defaults
+ * @param project the project
+ * @return
+ */
public static String getConfigFile(IProject project){
IFile f=project.getFile(".stylish-haskell.yaml");
if (f!=null && f.exists()){
- return f.getFullPath().toOSString();
+ return f.getLocation().toOSString();
}
IPath pluginp=StylePlugin.getStylePlugin().getStateLocation().append(".stylish-haskell.yaml");
File jf=pluginp.toFile();
@@ -51,4 +87,156 @@ public static String getConfigFile(IProject project){
}
return null;
}
+
+ /**
+ * has this project a specific config?
+ * @param project
+ * @return
+ */
+ public static boolean hasProjectConfiguration(IProject project){
+ IFile f=project.getFile(".stylish-haskell.yaml");
+ return f!=null && f.exists();
+ }
+
+ /**
+ * get the configuration to display for a project
+ * @param project
+ * @return the configuration, non null (may be the default)
+ */
+ public static SHConfiguration getProjectConfiguration(IProject project){
+ IFile f=project.getFile(".stylish-haskell.yaml");
+ if (f!=null && f.exists()){
+ try {
+ return load(f.getLocation().toOSString());
+ } catch (IOException ioe){
+ StylePlugin.logError(ioe);
+ }
+ }
+ return getWorkspaceConfiguration();
+ }
+
+ /**
+ * set the project configuration
+ * @param conf the configuration, or null to not use a project-specific config
+ * @param project
+ * @throws Exception
+ */
+ public static void setProjectConfiguration(SHConfiguration conf,IProject project) throws Exception{
+ IFile f=project.getFile(".stylish-haskell.yaml");
+ if (conf!=null){
+
+ try {
+ ByteArrayOutputStream os=new ByteArrayOutputStream();
+ try {
+ save(conf, os);
+ } finally {
+ os.close();
+ }
+ if (!f.exists()){
+ f.create(new ByteArrayInputStream(os.toByteArray()), true, new NullProgressMonitor());
+ } else {
+ f.setContents(new ByteArrayInputStream(os.toByteArray()), true, true, new NullProgressMonitor());
+ }
+ } catch (IOException ioe){
+ StylePlugin.logError(ioe);
+ throw ioe;
+ }
+ } else if (f.exists()){
+ try {
+ f.delete(true, new NullProgressMonitor());
+ } catch (CoreException ce){
+ StylePlugin.logError(ce);
+ throw ce;
+ }
+ }
+ project.refreshLocal(IResource.DEPTH_ONE, new NullProgressMonitor());
+ }
+
+ /**
+ * get the workspace configuration
+ * @return the configuration, non null (may be the default)
+ */
+ public static SHConfiguration getWorkspaceConfiguration(){
+ IPath pluginp=StylePlugin.getStylePlugin().getStateLocation().append(".stylish-haskell.yaml");
+ File jf=pluginp.toFile();
+ if (jf.exists() && jf.isFile()){
+ try {
+ return load(jf.getAbsolutePath());
+ } catch (IOException ioe){
+ StylePlugin.logError(ioe);
+ }
+ }
+ return new SHConfiguration();
+ }
+
+ /**
+ * set the workspace configuration
+ * @param conf
+ * @throws IOException
+ */
+ public static void setWorkspaceConfiguration(SHConfiguration conf) throws IOException{
+ IPath pluginp=StylePlugin.getStylePlugin().getStateLocation().append(".stylish-haskell.yaml");
+ File jf=pluginp.toFile();
+ jf.getParentFile().mkdirs();
+
+ try {
+ OutputStream os=new BufferedOutputStream(new FileOutputStream(jf));
+ try {
+ save(conf, os);
+ } finally {
+ os.close();
+ }
+ } catch (IOException ioe){
+ StylePlugin.logError(ioe);
+ throw ioe;
+ }
+
+ }
+
+ /**
+ * load YAML from a file
+ * @param fileLocation
+ * @return
+ * @throws IOException
+ */
+ public static SHConfiguration load(String fileLocation) throws IOException{
+ File f=new File(fileLocation);
+ InputStream is=new BufferedInputStream(new FileInputStream(f));
+ try {
+ SHConfiguration config=load(is);
+ return config;
+ } finally {
+ is.close();
+ }
+ }
+
+ /**
+ * load YAML from a stream
+ * @param is
+ * @return
+ * @throws IOException
+ */
+ public static SHConfiguration load(InputStream is) throws IOException{
+ Yaml y=new Yaml();
+ Object o=y.load(is);
+ SHConfiguration config=new SHConfiguration();
+ config.fromYAML(o);
+ return config;
+ }
+
+ /**
+ * save to a stream as YAML
+ * @param config
+ * @param os
+ * @throws IOException
+ */
+ public static void save(SHConfiguration config,OutputStream os) throws IOException {
+
+ Map<String,Object> o=config.toYAML();
+ DumperOptions options = new DumperOptions();
+ options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
+ Yaml yaml = new Yaml(options);
+ String s=yaml.dump(o);
+ os.write(s.getBytes()); // platform encoding
+ }
}
View
281 ....style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/ui/SHConfigurationComposite.java
@@ -0,0 +1,281 @@
+/**
+ * Copyright (c) 2012 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.style.stylishhaskell.ui;
+
+import net.sf.eclipsefp.haskell.style.stylishhaskell.SHConfiguration;
+import net.sf.eclipsefp.haskell.style.stylishhaskell.SHImports;
+import net.sf.eclipsefp.haskell.style.stylishhaskell.SHPragmas;
+import net.sf.eclipsefp.haskell.style.stylishhaskell.SHTabs;
+import net.sf.eclipsefp.haskell.style.stylishhaskell.SHTrailingWhitespace;
+import net.sf.eclipsefp.haskell.style.stylishhaskell.SHUnicode;
+import net.sf.eclipsefp.haskell.style.stylishhaskell.SHImports.SHImportAlign;
+import net.sf.eclipsefp.haskell.style.stylishhaskell.SHPragmas.SHPragmaStyle;
+import net.sf.eclipsefp.haskell.style.util.StyleText;
+
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.model.WorkbenchViewerComparator;
+
+/**
+ * Composite to manage a stylish haskell configuration
+ * @author JP Moresmau
+ *
+ */
+public class SHConfigurationComposite extends Composite{
+ private Button bUnicode;
+ private Button bUnicodePragmas;
+ private Button bImports;
+ private ComboViewer bImportsAlign;
+ private Button bPragmas;
+ private ComboViewer bPragmasStyle;
+ private Button bPragmasRemove;
+ private Button bTabs;
+ private Text tTabsSpaces;
+ private Button bTrailing;
+
+
+ public SHConfigurationComposite(Composite parent, int style) {
+ super(parent, style);
+ initUI();
+ }
+
+ private void styleMain(Control c){
+ GridData gdUP=new GridData(GridData.FILL_HORIZONTAL);
+ gdUP.horizontalSpan=2;
+ c.setLayoutData(gdUP);
+ }
+
+ private void styleIndent(Control c,int span){
+ GridData gdUP=new GridData();
+ gdUP.horizontalIndent=30;
+ gdUP.horizontalSpan=span;
+ c.setLayoutData(gdUP);
+
+ }
+
+ private void initUI(){
+ setLayout(new GridLayout(2,false));
+
+ bUnicode=new Button(this,SWT.CHECK);
+ bUnicode.setText(StyleText.sh_unicode);
+ styleMain(bUnicode);
+
+ bUnicodePragmas=new Button(this,SWT.CHECK);
+ bUnicodePragmas.setText(StyleText.sh_unicode_pragmas);
+ bUnicodePragmas.setSelection(true);
+ styleIndent(bUnicodePragmas,2);
+
+ bUnicode.addSelectionListener(new SelectionAdapter() {
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ bUnicodePragmas.setEnabled(bUnicode.getSelection());
+ }
+ });
+
+ bImports=new Button(this,SWT.CHECK);
+ bImports.setText(StyleText.sh_import);
+ styleMain(bImports);
+
+ final Label lImportsAlign=new Label(this, SWT.NONE);
+ lImportsAlign.setText(StyleText.sh_import_alignment);
+ styleIndent(lImportsAlign, 1);
+
+ bImportsAlign=new ComboViewer(this);
+ bImportsAlign.setComparator(new WorkbenchViewerComparator());
+ bImportsAlign.setContentProvider(new ArrayContentProvider());
+ bImportsAlign.setInput(SHImportAlign.values());
+ bImportsAlign.setSelection(new StructuredSelection(SHImportAlign.GLOBAL));
+
+ bImports.addSelectionListener(new SelectionAdapter() {
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ lImportsAlign.setEnabled(bImports.getSelection());
+ bImportsAlign.getCombo().setEnabled(bImports.getSelection());
+ }
+ });
+
+ bPragmas=new Button(this,SWT.CHECK);
+ bPragmas.setText(StyleText.sh_pragmas);
+ styleMain(bPragmas);
+
+ final Label lPragmasStyle=new Label(this, SWT.NONE);
+ lPragmasStyle.setText(StyleText.sh_pragmas_style);
+ styleIndent(lPragmasStyle, 1);
+
+ bPragmasStyle=new ComboViewer(this);
+ bPragmasStyle.setComparator(new WorkbenchViewerComparator());
+ bPragmasStyle.setContentProvider(new ArrayContentProvider());
+ bPragmasStyle.setInput(SHPragmaStyle.values());
+ bPragmasStyle.setSelection(new StructuredSelection(SHPragmaStyle.VERTICAL));
+
+ bPragmasRemove=new Button(this,SWT.CHECK);
+ bPragmasRemove.setText(StyleText.sh_pragmas_remove_redundant);
+ bPragmasRemove.setSelection(true);
+ styleIndent(bPragmasRemove,2);
+
+
+ bPragmas.addSelectionListener(new SelectionAdapter() {
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ bPragmasRemove.setEnabled(bPragmas.getSelection());
+ lPragmasStyle.setEnabled(bPragmas.getSelection());
+ bPragmasStyle.getCombo().setEnabled(bPragmas.getSelection());
+ }
+ });
+
+
+ bTabs=new Button(this,SWT.CHECK);
+ bTabs.setText(StyleText.sh_tabs);
+ styleMain(bTabs);
+
+ final Label lTabsSpaces=new Label(this, SWT.NONE);
+ lTabsSpaces.setText(StyleText.sh_tabs_spaces);
+ styleIndent(lTabsSpaces, 1);
+
+ tTabsSpaces=new Text(this,SWT.BORDER);
+ tTabsSpaces.setText("8");
+ GridData gdUP=new GridData();
+ gdUP.widthHint=30;
+ tTabsSpaces.setLayoutData(gdUP);
+
+ tTabsSpaces.addVerifyListener(new VerifyListener() {
+
+ @Override
+ public void verifyText(VerifyEvent arg0) {
+ if (Character.isDigit(arg0.character)){
+ arg0.doit=true;
+ return;
+ }
+ if (arg0.character=='\b'){
+ arg0.doit=tTabsSpaces.getText().length()>1;
+ return;
+ }
+ arg0.doit=false;
+ }
+ });
+
+ bTabs.addSelectionListener(new SelectionAdapter() {
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ lTabsSpaces.setEnabled(bTabs.getSelection());
+ tTabsSpaces.setEnabled(bTabs.getSelection());
+ }
+ });
+
+
+ bTrailing=new Button(this,SWT.CHECK);
+ bTrailing.setText(StyleText.sh_trailing_whitespace);
+ styleMain(bTrailing);
+
+ }
+
+ public void setConfiguration(SHConfiguration config){
+ selectButton(bUnicode,config.getUnicode());
+ if (config.getUnicode()!=null){
+ bUnicodePragmas.setSelection(config.getUnicode().isUnicodePragmas());
+ }
+
+ selectButton(bImports,config.getImports());
+ if (config.getImports()!=null){
+ bImportsAlign.setSelection(new StructuredSelection(config.getImports().getAlign()));
+ }
+
+ selectButton(bPragmas,config.getPragmas());
+ if (config.getPragmas()!=null){
+ bPragmasStyle.setSelection(new StructuredSelection(config.getPragmas().getStyle()));
+ bPragmasRemove.setSelection(config.getPragmas().isRemoveRedundant());
+ }
+
+ selectButton(bTabs,config.getTabs());
+ if (config.getTabs()!=null){
+ tTabsSpaces.setText(String.valueOf(config.getTabs().getSpaces()));
+ }
+
+ selectButton(bTrailing,config.getTrailingWhitespace());
+
+ }
+
+ private void selectButton(Button b,Object o){
+ b.setSelection(o!=null);
+ b.notifyListeners(SWT.Selection, new Event());
+ }
+
+ public SHConfiguration getConfiguration(){
+ SHConfiguration conf=new SHConfiguration();
+ conf.clear();
+ if (bUnicode.getSelection()){
+ SHUnicode uni=new SHUnicode();
+ uni.setUnicodePragmas(bUnicodePragmas.getSelection());
+ conf.setUnicode(uni);
+ }
+ if (bImports.getSelection()){
+ SHImports imps=new SHImports();
+ SHImportAlign al=(SHImportAlign)((IStructuredSelection)bImportsAlign.getSelection()).getFirstElement();
+ imps.setAlign(al);
+ conf.setImports(imps);
+ }
+ if (bPragmas.getSelection()){
+ SHPragmas pr=new SHPragmas();
+ pr.setRemoveRedundant(bPragmasRemove.getSelection());
+ SHPragmaStyle ps=(SHPragmaStyle)((IStructuredSelection)bPragmasStyle.getSelection()).getFirstElement();
+ pr.setStyle(ps);
+ conf.setPragmas(pr);
+ }
+ if (bTabs.getSelection()){
+ SHTabs tabs=new SHTabs();
+ tabs.setSpaces(Integer.parseInt(tTabsSpaces.getText()));
+ conf.setTabs(tabs);
+ }
+ if (bTrailing.getSelection()){
+ conf.setTrailingWhitespace(new SHTrailingWhitespace());
+ }
+
+ return conf;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.widgets.Control#setEnabled(boolean)
+ */
+ @Override
+ public void setEnabled(boolean enabled) {
+ super.setEnabled(enabled);
+ for (Control c:getChildren()) {
+ c.setEnabled(enabled);
+ }
+ if (enabled){
+ for (Control c:getChildren()) {
+ c.notifyListeners(SWT.Selection, new Event());
+ }
+ }
+ }
+}
View
126 ...haskell.style/src/net/sf/eclipsefp/haskell/style/stylishhaskell/ui/SHConfigurationPP.java
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2012 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.style.stylishhaskell.ui;
+
+import net.sf.eclipsefp.haskell.style.stylishhaskell.StylishHaskell;
+import net.sf.eclipsefp.haskell.style.util.StyleText;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.dialogs.PropertyPage;
+
+/**
+ * Property page to assign a stylish haskell configuration to a project
+ * @author JP Moresmau
+ *
+ */
+public class SHConfigurationPP extends PropertyPage implements
+ IWorkbenchPreferencePage {
+ private Button bProject;
+ private SHConfigurationComposite confComp;
+
+ /**
+ *
+ */
+ public SHConfigurationPP() {
+ setDescription(StyleText.sh_title);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+ */
+ @Override
+ public void init(IWorkbench arg0) {
+ // NOOP
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected Control createContents(Composite parent) {
+ Composite container = new Composite( parent, SWT.NULL );
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 1;
+ container.setLayout( layout );
+
+ bProject=new Button(container, SWT.CHECK);
+ bProject.setText(StyleText.sh_project);
+
+ final Group g=new Group(parent,SWT.NONE);
+ //g.setText(StyleText.sh_title);
+ g.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.GRAB_VERTICAL));
+ g.setLayout(new GridLayout(1,true));
+
+ IProject project=( IProject )getElement();
+ confComp=new SHConfigurationComposite(g, SWT.NONE);
+ confComp.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.GRAB_VERTICAL));
+ confComp.setConfiguration(StylishHaskell.getProjectConfiguration(project));
+
+ bProject.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
+ confComp.setEnabled(bProject.getSelection());
+ g.setEnabled(bProject.getSelection());
+ };
+ });
+
+ boolean hasConfig=StylishHaskell.hasProjectConfiguration(project);
+ bProject.setSelection(hasConfig);
+ confComp.setEnabled(hasConfig);
+ g.setEnabled(bProject.getSelection());
+
+ Label space=new Label(parent,SWT.NONE);
+ space.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+
+ Dialog.applyDialogFont( parent );
+ return container;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.preference.PreferencePage#performOk()
+ */
+ @Override
+ public boolean performOk() {
+ IProject project=( IProject )getElement();
+ try {
+ if (bProject.getSelection()){
+ StylishHaskell.setProjectConfiguration(confComp.getConfiguration(), project);
+ } else {
+ StylishHaskell.setProjectConfiguration(null, project);
+ }
+ } catch (Exception ioe){
+ MessageDialog.openError( getShell(), StyleText.sh_save_error, ioe.getLocalizedMessage() );
+ return false;
+ }
+ return super.performOk();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
+ */
+ @Override
+ protected void performDefaults() {
+ bProject.setSelection(false);
+ confComp.setConfiguration(StylishHaskell.getWorkspaceConfiguration());
+ bProject.notifyListeners(SWT.Selection, new Event());
+ super.performDefaults();
+ }
+}
View
41 net.sf.eclipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/util/StyleText.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2012 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.style.util;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Stylish Haskell text resources
+ * @author JP Moresmau
+ *
+ */
+public class StyleText extends NLS {
+
+
+ public static String sh_unicode;
+ public static String sh_unicode_pragmas;
+ public static String sh_import;
+ public static String sh_import_alignment;
+ public static String sh_pragmas;
+ public static String sh_pragmas_style;
+ public static String sh_pragmas_remove_redundant;
+ public static String sh_tabs;
+ public static String sh_tabs_spaces;
+ public static String sh_tabs_spaces_error;
+ public static String sh_trailing_whitespace;
+
+ public static String sh_title;
+ public static String sh_project;
+ public static String sh_default;
+
+ public static String sh_save_error;
+
+ private static final String BUNDLE_NAME = StyleText.class.getPackage().getName() + ".style"; //$NON-NLS-1$
+
+ static {
+ NLS.initializeMessages(BUNDLE_NAME, StyleText.class);
+ }
+}
View
17 net.sf.eclipsefp.haskell.style/src/net/sf/eclipsefp/haskell/style/util/style.properties
@@ -0,0 +1,17 @@
+sh_unicode=Convert ASCII sequence to Unicode
+sh_unicode_pragmas=Add UnicodeSyntax language pragma
+sh_import=Import cleanup
+sh_import_alignment=Alignment
+sh_pragmas=Organize language pragmas
+sh_pragmas_style=Style
+sh_pragmas_remove_redundant=Remove redundant pragmas
+sh_tabs=Replace tabs by spaces
+sh_tabs_spaces=Number of spaces
+sh_tabs_spaces_error=Number of spaces must be a number >=0
+sh_trailing_whitespace=Remove trailing whitespace
+
+sh_title=Stylish Haskell configuration
+sh_project=Project specific settings
+sh_default=Default settings
+
+sh_save_error=Error saving Stylish Haskell configuration
View
2 ...ell.ui/src/net/sf/eclipsefp/haskell/ui/internal/editors/haskell/actions/FormatAction.java
@@ -76,7 +76,7 @@ public void run() {
if (p!=null){
try {
// go!
- StylishHaskell.runStylishHaskell( ScionManager.getExecutablePath( IPreferenceConstants.STYLISHHASKELL_EXECUTABLE, "stylish-haskell", false ), p, f );
+ StylishHaskell.runStylishHaskell( ScionManager.getExecutablePath( IPreferenceConstants.STYLISHHASKELL_EXECUTABLE, "stylish-haskell", false ), p, f,file.getCharset() );
// re read the file on disk and tell the editor about it
hEditor.getDocument().set( FileUtil.getContents( f,file.getCharset() ) );
} catch (Exception ioe){
View
3 ...p.haskell.ui/src/net/sf/eclipsefp/haskell/ui/internal/preferences/scion/ExecutablePP.java
@@ -10,9 +10,11 @@
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
@@ -58,6 +60,7 @@ public void propertyChange( final PropertyChangeEvent arg0 ) {
}
};
executableField=new AutodetectExecutableField( this, parentComposite, pgmName, exeName, pref,propertyListener );
+ new Label(parentComposite,SWT.NONE);
setValid( isValid() );
return parentComposite;
}
View
47 ...skell.ui/src/net/sf/eclipsefp/haskell/ui/internal/preferences/scion/StylishHaskellPP.java
@@ -5,7 +5,16 @@
*/
package net.sf.eclipsefp.haskell.ui.internal.preferences.scion;
+import java.io.IOException;
+import net.sf.eclipsefp.haskell.style.stylishhaskell.SHConfiguration;
+import net.sf.eclipsefp.haskell.style.stylishhaskell.StylishHaskell;
+import net.sf.eclipsefp.haskell.style.stylishhaskell.ui.SHConfigurationComposite;
+import net.sf.eclipsefp.haskell.style.util.StyleText;
import net.sf.eclipsefp.haskell.ui.internal.preferences.IPreferenceConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
/**
@@ -14,9 +23,47 @@
*
*/
public class StylishHaskellPP extends ExecutablePP {
+ private SHConfigurationComposite confComp;
public StylishHaskellPP(){
super("stylish-haskell","stylish-haskell",IPreferenceConstants.STYLISHHASKELL_EXECUTABLE);
}
+
+ /* (non-Javadoc)
+ * @see net.sf.eclipsefp.haskell.ui.internal.preferences.scion.ExecutablePP#createContents(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected Control createContents( final Composite parentComposite ) {
+ Control c=super.createContents( parentComposite );
+
+ confComp=new SHConfigurationComposite( parentComposite, SWT.NONE );
+ confComp.setConfiguration( StylishHaskell.getWorkspaceConfiguration() );
+
+ return c;
+ }
+
+ /* (non-Javadoc)
+ * @see net.sf.eclipsefp.haskell.ui.internal.preferences.scion.ExecutablePP#performOk()
+ */
+ @Override
+ public boolean performOk() {
+ SHConfiguration conf=confComp.getConfiguration();
+ try {
+ StylishHaskell.setWorkspaceConfiguration( conf );
+ return super.performOk();
+ } catch (IOException ioe){
+ MessageDialog.openError( getShell(), StyleText.sh_save_error, ioe.getLocalizedMessage() );
+ return false;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
+ */
+ @Override
+ protected void performDefaults() {
+ confComp.setConfiguration(new SHConfiguration());
+ super.performDefaults();
+ }
}

0 comments on commit d42ca93

Please sign in to comment.