Beauty |
Version 0.8 (@@tstamp@@) Dale Anson |
Introduction |
The Beauty plugin is a general framework for code beautifiers and provides several built-in beautifiers. While there are several existing plugins for beautifying/formatting various source file formats, this plugin aims to consolidate those formatters into a standard API so that beautifying can be performed in a general way, similar to how the SideKick plugin provides a general framework for code browsers.
There are several beautifiers/formatters included:
Two other plugins have been updated to support the Beauty framework:
With the 0.4 release, Beauty has the ability to configure a custom beautifier per mode, which allows padding of various items, clean up of extra blank lines, and the ability to use the jEdit indenter. I've included custom beautifiers for
(Note: the custom CSS beautifier is still included, but the built-in CSS beautifier introduced in Beauty 0.5 does a much better job.)
(Another note: The built in Java beautifier does a much better job than the custom Java beautifier, but the built in Java beautifier requires grammatically correct Java code, where the custom beautifier does not. The custom beautifier is used by the JSP beautifier for JSP pages to format Java scriptlet blocks.)
Making custom beautifiers is very easy to do, and you are encouraged to create and share beautifiers for any language that jEdit supports.
All other modes can default to use the built-in jEdit indenter, which works pretty well for most modes. To turn on this option, check the box in the Beauty options.
Usage |
To beautify a buffer, go to Plugins - Beauty - Beautify Buffer. This action is mappable as a keyboard shortcut. Go to Utilities - Global Options - Shortcuts - Plugin: Beauty. I've mapped Ctrl+B for this action.
Configuration |
Configuration depends on the specific beautifier. Generally, beautifiers will honor the settings for the buffer and/or mode. So, if you're editing an html file in html mode, then the html beautifier will be used to format the file, and the html beautifier will use the right line enders and tab settings. These settings are controlled by the settings for the buffer and the mode:
To set which beautifier to use per mode, use the Beauty option settings under the Plugins - Plugin Options menu.
CSS Beautifier
The CSS beautifier introduced in Beauty 0.5 has some additional configuration options. See the plugin option pane for details.
JSP Beautifier
In addition to the buffer settings mentioned above, the JSP beautifier has a few options that can be set in the plugin options. Additionally, some configuration of java scriptlets, style blocks, and javascript blocks is possible.
This beautifier delegates to the CSS beautifier for style blocks, so any configuration you make for the CSS beautifier applies to the style blocks within a JSP file.
Similarly, this beautifier delegates to the custom beautifiers for java and javascript blocks within a JSP file, so you can make adjustments via the custom beautifier dialog in the plugin options.
Java Beautifier
Just to clarify the Java beautifiers: Assuming you have the AStyle plugin installed, you have 3 choices for Java beautification:
java:custom
java:astyle
java:beauty
java:astyle
or java:beauty
. The java:custom
beautifier is the one used by the JSP beautifier. It does not beautify as well as either java:astyle
or java:beauty
but will accept the Java code commonly found in JSP scriptlets where the other two won't.
An option pane was added for the Java beautifier in version 0.6.
An "attached" bracket is one that is on the end of a line, for example:
try {
...
} catch(...) {
...
}
A "broken" bracket is one that always starts on the next line, for example:
try
{
...
}
catch(...)
{
...
}
Other settings are to "break" 'else', 'catch', and 'while', for example:
versus not broken:
try {
...
}
catch (...) {
...
}
try {
...
} catch (...) {
...
}
Also, padding parenthesis, so if (i == 1)
versus
if ( i == 1 )
New Java Options in Beauty 0.9 The Java beautifier now includes new options for handling blank lines and sorting and grouping imports:
Here is an example of these settings:
// blank lines before package declaration package a.b.c; // blank lines after package declaration import a.b.A; // sorted and grouped imports import a.b.C; // blank lines between groups import b.c.*; import java.util.ArrayList; import java.util.List; // blank lines after imports public class Demo { // blank lines after class declaration public int a = 6; // collapse multiple blank lines // blank lines before methods public static final String toString() { // sort modifiers return "demo"; } // blank lines after methods } // blank lines after class body
Others
It is quite possible that new beautifiers are introduced as jEdit plugins for specific languages. Please consult the documentation for those beautifiers for any settings that might be possible.
Custom Beautifier |
Custom beautifiers can be shared. If you create one for a mode, post it on the jEdit mailing lists or add it to the jEdit plugin feature tracker or email it to me at danson@grafidog.com, and I'll include it in the next release of Beauty.
To post the custom beautifier, just copy the appropriate properties file from $USER_HOME/.jedit/plugins/beauty.BeautyPlugin
. To locate your $USER_HOME
, in jEdit go to Utilities - Beanshell - Evaluate Beanshell Expression..., then enter
System.getProperty("user.home")
To set up a custom beautifier:
The configuration should need only a little explanation:
There are 2 tabs, "Padding" and "Indenting".
Token Padding
This beautifier works by using jEdit syntax highlighting engine to tokenize the buffer, so the same tokens that are identified by the syntax highlighting are used by the custom beautifier. For example, "+" may be defined in the mode file as an operator. Checking the "before" and "after" for "Pad operators" will cause the beautifier to make sure that there is a space before and after all "+" characters. Functions, digits, operators, and keywords are defined in the mode file, so the quality of this tokenization really depends on the quality of the mode file.
Padding can be added before and/or after these tokens:
FUNCTION
DIGIT
KEYWORD1
KEYWORD2
KEYWORD3
KEYWORD4
OPERATOR
Labels are also defined in the mode file, and you may want to put labels on a separate line. This may or may not work well, again, it depends on the quality of the mode file. For example, in the Ada language, a label is defined as <<sometext>>, but in the Ada mode file, both << and >> are defined as labels. This means that if you elect to put a label on a separate line, you'll end up with
<<sometext >>
Character padding
Four text fields are for setting up padding of individual characters. Just enter the characters, don't separate with a comma. If you do separate with a comma, then the padding will also be applied to any commas in your file.
These are applied by the beautifier in this order, so if you say to pad before ":" and then say don't pad before ":", the don't pad wins. For example, you might use these when you want a space following each ( and before each ).
The "don't pad" characters are handy for modes like javascript that define ".", ",", and ";" as operators. Adding these characters to the don't pad text fields will cause the beautifier to remove spaces before and after these characters even though they may be padded as operators.
Line insertion
The next two text fields are for entering regular expressions to describe items that should have a line separator inserted either before and/or after:
Endless trouble can happen here, so be careful!
The "Insert line separators before" and "Insert line separators after" text fields can take a comma separated list of strings. Do not put spaces in this string unless you really mean it. These strings are used as regular expressions, but note that this is a comma separated list, so if your regex contains commas, you must escape the commas or things probably won't work as you'd want. Warning: be sure to escape special regular expression characters within your regular expressions.For example, if you want to insert a line separator before the start of a C-style comment, /*, enter "/\*" rather than "/*". Round, curly, and square brackets also need to be escaped. Other possible characters that might need escaped are ".", "?", "*", and "+". There may be more. Here's a good example: Suppose you are wanting to insert line separators in a json file after any of {, [, comma, ], and }. In the "Insert line separators after these strings" box, enter
\{,\[,\,,\],\}
You can elect to have multiple blank lines collapsed into a single blank line.
You can also elect to have horizontal whitespace collapsed to a single space. This only examines spaces and tabs. A single tab will remain a tab. This does not affect whitespace in comments or string literals.
The custom beautifier applies the configuration in order from top to bottom (mostly), so, for example, operators are padded before applying the 'don't pad before' configuration. Padding is only applied if there is no whitespace before or after the item to be padded, so additional whitespace is not added unnecessarily. Similarly, if you want to insert a line break before or after an item and there already is a line separator, no additional blank lines will be added. The exception to the "top to bottom" rule is padding of keywords. Keywords are padded last. This is to prevent the other pad/don't pad rules from removing padding from keywords. For example, if you have
for (int i = 0; i < a.length(); i++)
You can set to not pad before ( so that a.length()
looks good and still have the space between for (
.
Indenting
Indenting is applied by the beautifier after padding. On the "Indenting" tab, you can have the custom beautifier use the jEdit indenter to do the line indentation. Each of the text fields on this tab correspond exactly to the properties of the same names used by the jEdit mode files. They are filled in initially with the values from the jEdit mode file for the mode you are working with. Unfortunately, the documentation for these in the jEdit help file is not very good, so it may take some experimentation to make these work as you'd like.
These are the supported indenting properties:
These take a list of characters:
These take regular expressions:
These are true/false:
For Developers |
While the ability to create a custom beautifier from within the Beauty plugin is fairly good, even better are beautifiers designed specifically with a strong understanding of the language to be beautified. This is why Beauty can delegate to the AStyle plugin and the XML plugin for beautification of Java, C, C++, XML, and HTML files.
Adding a new beautifier/formatter is quite simple:
String beautify(String text)
method. Your formatter will be passed the complete contents of a buffer in the
text
parameter, and should return formatted text. The buffer contents will be replaced with this returned text.
services.xml
file to your plugin like this:
<?xml version="1.0"?>
<!DOCTYPE SERVICES SYSTEM "services.dtd">
<SERVICES>
<SERVICE CLASS="beauty.beautifiers.Beautifier" NAME="lispy">
new lisp.lispy.Beautify();
</SERVICE>
</SERVICES>
For
NAME
, either use the name of the editing mode that the beautifier supports, or a unique name for your plugin. The beanshell code must return an object that can be cast to
beauty.beautifiers.Beautifier
.
mode.MODENAME.beauty.beautifier=NAME
where
MODENAME
is the name of an editing mode that your beautifier supports, and
NAME
is the same name used in the services.xml file. So continuing the example, you might have:
mode.lisp.beauty.beautifier=lispy
for your beautifier that supports the Lisp language.
It has become common practice for NAME to be in the format of mode:pluginname, for example, c++:astyle or java:beauty, meaning the C++ beautifier from the AStyle plugin and the Java beautifier from the Beauty plugin. In the above example, a better name might be lisp:lispy.
As of Beauty 0.9, Eric Le Lay has contributed OuterBeauty, which makes it very easy to integrate external beautifiers. For a real-world example, see Eric's js-beauty plugin, which integrates the external js-beautifier application with Beauty to be able to beautify javascript from within jEdit.
The steps are very similar to those above:
getCommandLine()
method, which should return the program and parameters to run.Credits |
I'd like to give credit to these people whose work I built off of: