IntelliJ plugin autocomplete formatting - intellij-idea

I add an autocomplete fonctionnality to my IntelliJ plugin like this :
String completionString = "myFunction(err, data){if(err){}else{}}";
return LookupElementBuilder
.create(completionString)
.withBoldness(true)
.withIcon(SailsJSIcons.SailsJS)
.withPresentableText("myFunction()")
.withCaseSensitivity(true)
.withTypeText(type)
.withTailText(" (" + item + ")", true)
.withAutoCompletionPolicy(AutoCompletionPolicy.GIVE_CHANCE_TO_OVERWRITE);
How can I format the new method I will put on editor ? I don't want a custom formatting, just want the default formatting of IntelliJ

You can add an InsertHandler to your LookupElement and perform CodeStyleManager.reformat(psiElement) in its handleInsert method.
However, I don't see why you're making this available through a completion contributor at all. This looks like a live template, and your plugin can contribute live templates with far less effort than custom completion. Live templates are automatically shown in completion lists and support automatic reformatting.

Related

Keyboard shortcuts on Flutter web

I'm adding keyboard shortcuts to a Flutter web application.
I have a form within a custom FocusableActionDetector where the shortcut has form like this:
SingleActivator(LogicalKeyboardKey.digit2)
and action is like:
CustomActivateIntent: CallbackAction<CustomActivateIntent>(
onInvoke: (intent) { provider.value = "2"; },)
In the same form I have a couple of numeric TextFormFields. To permit writing the character "2" I have to put these text fields inside some new FocusableActionDetector, otherwise the previous detector catches the command and the text field loses the "2" character, and this is already quite weird... Moreover, after writing in any of the text fields the form focus detector doesn't work anymore.
I think this could be related to the focus system, which is yet not that clear to me.
Can anyone help find a clean solution?
I found a workaround: the FocusableActionDetector is now preceded by an if statement. The code looks like the following:
// I extract the form to a widget to make it clearer
var searchWidget = SearchWidget();
child: textEditingInProgress
? searchWidget
: FocusableActionDetector(
child: searchWidget,
...,
),
The textEditingInProgress bool is a field in a provider and is controlled by the FocusNodes belonging to the TextControllers.
Still this is not a perfect solution, in particular I'd like to understand why the previous approach was not working.

How can I create the resource string without a big string?

In After Effects scripts, if you want your script to be able to be docked in the program's workspace, the only way to do it as far as I know is to use a resource string like this:
var res = "Group{orientation:'column', alignment:['fill', 'fill'], alignChildren:['fill', 'fill'],\
group1: Group{orientation:'column', alignment:['fill', ''], alignChildren:['fill', ''],\
button1: Button{text: 'Button'},\
},\
}";
myPanel.grp = myPanel.add(res);
The above code creates a script UI with one button ("button1") inside a group ("group1").
I would like to know other ways to create the same resource string. Is it possible to make it using a JSON object and then stringifying it??
I know it can be done somehow, because I have inspected the Duik Bassel script that is dockable and, for example, adds elements like this:
var button1 = myPal.add( 'button' );
but I cannot understand how to do it myself.
TL;DR: I want to make a dockable scriptUI without writing a giant string all at once, but bit by bit, like a floating script.
UI container elements have an add() method which allows you to add other UI elements to them, and you can treat them as normal objects.
var grp = myPanel.add("group");
grp.orientation = "column";
grp.alignment = ['fill', 'fill'];
grp.alignChildren = ['fill', 'fill'];
var group1 = grp.add("group");
…
var button1 = group1.add("button");
button1.text = 'Button'
More details and examples here: https://extendscript.docsforadobe.dev/user-interface-tools/types-of-controls.html#containers
Also worth checking out https://scriptui.joonas.me/ which is a visual scriptUI interface builder. You have to do some work on the code it produces to get panels for AE, but it's not hard.
extendscript still uses a 20th century version of javaScript, which doesn't have JSON built-in, but I have successfully used a JSON polyfill with it.
I used json2.js to get structured data in and out of Illustrator, and it worked beautifully, but I can see there's now a json3.js which might be better for whatever reason. This stackoverflow question addresses the differences.
To load another .js file (such as a polyfill) into your script, you need to do something like
var scriptsFolder = (new File($.fileName)).parent; // hacky but effective
$.evalFile(scriptsFolder + "/lib/json2.js"); // load JSON polyfill
These file locations may differ in other Adobe apps. Not sure what it would be in AfterEffects. I seem to remember that InDesign has a different location for scripts. You can also hardcode the path, of course.
Good luck!

Intellij shortcut to create code snippet for testing

Is there any shortcut/setting/plugin available in intellij where I can create test data structure with some default values ?
e.g.
Map<String,String> stringMap = new HashMap();
stringMap.put("1","A")
stringMap.put("2","B")
stringMap.put("3","C")
I dont want to type all of the above as I want to test very quick with any values.
You can use the 'Live Templates' functionality, for instance. A guide on how to create such a template can be found here.
Use live templates to insert common constructs into your code, such as
loops, conditions, various declarations, or print statements.
To expand a code snippet, type the corresponding template abbreviation
and press Tab
In the screenshot below, I created a custom template called smap in the 'other' template group, added your code to it and selected the language (Java) that this template can be applied to.
Once in the editor, I can type smap and a pop-up will appear suggesting me to use the existing template to replace the abbreviation with code. Hitting Tab or Enter will perform the replacement.

logd shortcut doesn't work in Intellij with Kotlin

Logging Java in Intellij is easy with shortcuts such as 'logt', 'logd', 'loge'... and so on. But I moved to Kotlin, I noticed that those shortcuts doesn't work anymore. I don't know if it has something to do with my configuration, but if not, how can I fix this?
You should create separate templates to make them work correctly.
Here is the step-by-step guide:
Firstly, Copy and paste AndroidLog templates to Kotlin (Just select them and use CMD+C, CMD+V (or Ctrl+C, Ctrl+V)
Secondly, You have to adjust them manually:
1. logd (and others)
Select the logd item and press "Edit variables"
Change expression to: kotlinFunctionName()
Also, remove ; from the end of the template, as you don't need it in Kotlin.
Now your method name will be shown correctly
logt
This one is a bit trickier.
Solution 1 TAG = class name.
Template text :
private val TAG = "$className$"
Edit variables -> Expression:
groovyScript("_1.take(Math.min(23, _1.length()));", kotlinClassName())
Solution 2 TAG = file name (can be used inside Companion)
Template text :
private const val TAG = "$className$
or:
companion object {
private const val TAG = "$className$"
}
Edit variables -> Expression:
groovyScript("_1.take(Math.min(23, _1.length()));", fileNameWithoutExtension())
Edit 19.02.19
Also, it might be useful for someone.
In order to avoid creating the TAG variable, you can use the class name as a variable, for instance:
Log.d("BaseActivity", "onCreate: ")
Where BaseActivity is the class name.
The template will look now as:
android.util.Log.d("$CLASS_NAME$", "$METHOD_NAME$: $content$")
Where CLASS_NAME variable is:
groovyScript("_1.take(Math.min(23, _1.length()));", fileNameWithoutExtension())
These are provided in IntelliJ as a Live Template configuration for AndroidLog (found in Preferences -> Editor -> Live Templates), and are applicable specifically to Java code:
There isn't anything broken in your configuration, but if you want to make these Live Templates available for Kotlin you will need to add new Live Template for AndroidLog and make them applicable to Kotlin code.
https://www.jetbrains.com/help/idea/2017.1/creating-and-editing-live-templates.html
There's an open feature request to have them added as defaults here: https://youtrack.jetbrains.com/issue/KT-10464
Change the scope of the template in the applicable option.
In Android Studio 4.0 there's new AndroidLogKotlin block. You can implement #LeoDroidcoder's solution there.

How to make jedit file-dropdown to display absolute path (not filename followed by directory)?

All is in the title.
If a have opened the three files:
/some/relatively/long/path/dir1/file_a
/some/relatively/long/path/dir1/file_b
/some/relatively/long/path/dir2/file_a
The file dropdown contains:
file_a (/some/relatively/long/path/dir1)
file_a (/some/relatively/long/path/dir2)
file_b (/some/relatively/long/path/dir1)
And that bother me because I have to look on the right to differentiate the two file_a, and on the left for the others. This happens a lot to me mostly because I code in python, and thus I often have several __init__.py files opened.
How do I get jedit to display
/some/relatively/long/path/dir1/file_a
/some/relatively/long/path/dir1/file_b
/some/relatively/long/path/dir2/file_a
config:
jedit 5.1.0
java 1.6.0_26
mac osx 10.6
Unfortunately this is not easily possible currently, I just had a look at the source and this is not configurable.
You can:
Submit a Feature Request to make this configurable (good idea in any case)
Create or let create a startup macro that
registers an EBComponent with the EditBus that listens for new EditPanes getting created
retrieve the BufferSwitcher from the EditPane
retrieve the ListCellRenderer from the BufferSwitcher
set a new ListCellRenderer to the BufferSwitcher that first calls the retrieved ListCellRenderer and then additionally sets the text to value.getPath()
Try the Buffer List plugin as to whether it maybe suits your needs
Now follows code that implements the work-part of option two, runnable as BeanShell code which does this manipulation for the current edit pane. The third line is not necessary when done in an EBComponent, this is just that the on-the-fly manipulation is shown immediately.
r = editPane.getBufferSwitcher().getRenderer();
editPane.getBufferSwitcher().setRenderer(
new ListCellRenderer() {
public Component getListCellRendererComponent(list, value, index, isSelected, cellHasFocus) {
rc = r.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
rc.setText(value.getPath());
return rc;
}
});
editPane.repaint();