Manually trigger completion popup in IntelliJ Platform SDK - intellij-idea

I am developing a plugin for the IntelliJ Platform. I have created an implementation of CompletionContributor, and it is successfully giving suggestions. I'm currently overriding the invokeAutoPopup method to trigger the completion popup. I'm using an implementation of InsertHandler to add additional text to the document immediately after making the selected insertion.
However, I'd like to make it so that when a user successfully inserts the suggestion, they are immediately prompted with another completion popup. For example, in this InsertHandler (written in Kotlin), after selecting a method, they should be immediately given suggestions about the parameters to that method:
val handler = InsertHandler<LookupElement> { context: InsertionContext, element: LookupElement ->
val offset = context.tailOffset
context.document.insertString(offset, "()")
context.editor.caretModel.moveToOffset(offset + 1)
TODO("trigger popup")
}
Or immediately after selecting a field, they could be given methods that they can call on that field:
val handler = InsertHandler<LookupElement> { context: InsertionContext, element: LookupElement ->
val offset = context.tailOffset
context.document.insertString(offset, ".")
context.editor.caretModel.moveToOffset(offset + 1)
TODO("trigger popup")
}
In other words, I'd like to make it so that after inserting suggested text, it is as if the user pressed Ctrl+Space. Is this possible? Am I approaching the problem in the right way? Is there something in my code above that's missing the point? (Solutions in either Java or Kotlin would be welcome.)

If autopopup completion is enough for your needs, you could try invoking com.intellij.codeInsight.AutoPopupController.getInstance(context.project).scheduleAutoPopup(context.editor).

Related

Problem with Firestore Snapshot Listener in Android Compose and Callback Lambda

In my Compose Project I wanted to implement a Snapshot Listener that updates the LiveData of my ViewModel. To keep the code related to firestore apart from logic in the viewModel I added a Repository with the following funtion:
override fun getInvitations(onDataUpdate: (List<Session>) -> Unit) {
val invitationsQuery = db.collection("invitations").whereEqualTo("player_id", auth.currentUser?.uid)
val listener = invitationsQuery.addSnapshotListener{ querySnapshot, exception ->
if (exception != null){
Log.w("ONLINE", "Error handling Snapshot",exception)
return#addSnapshotListener
}
val sessions = mutableListOf<Session>()
querySnapshot?.documents?.forEach{
sessions.add(it.toSession())
}
onDataUpdate(sessions)
}
listeners.add(listener)
}
The idea was then to only call this function once in the viewModel and give it a Lambda that updates the LiveData like this:
multiplayerRepository.getInvitations {
invitations.value = it
}
The problem is that there is no Recomposition caused although the LiveData gets updated. Multiple Logs gave me that.
I already tried using postValue() instead of invitations.value = ...with no other effect.
I really want to keep the LiveData away from the Repository, but am aware it will be an alternative to get the LiveData from the Listener.
Anything appreciated.
The solution to my problem was rather simple.
This was not a problem of Compose nor was Firebase doing weird stuff. It was the Code I wrote.
It turned out that I overlooked that I deleted a function that queries Userdata when I deleted another old function. Without it my UI cannot update due to a empty list.
I went through my commits multiple times and missed it multiple times. But the moment I saw that was a great relief.
Still thanks to all your help.

Show the warning message upon outbound delivery item deletion in VL03N?

I am trying to find a way of implementing the new warning message window in the standard transaction when the user tries to delete Item on Item Overview window.
Right now there is a standard warning window with "Delete selected item(s)? Y/N" question and after that, my custom window should occur.
Because it is the standard transaction, I am not sure about the way of implementing that task. Should I look at enhancement or some other ways?
After exploring the code through the debugger, I found the line in which warning window is showed, Am I allowed to put mine part of code after call function for the first warning window?
The path is SAPMV50A -> MV50AF0F_FUNKTION_AUSFUEHREN -> call functioin FUNKTION_AUSFUEHREN (after line 65)
Use can use method CHECK_ITEM_DELETION or ITEM_DELETION of BadI LE_SHP_DELIVERY_PROC for showing your warning, here the official doc:
This method is called before a delivery item is deleted. You can use this method to perform checks to see whether an item can be deleted, and if necessary, to then prevent deletion of a delivery item.
DATA: lf_error TYPE abap_bool.
delete_item(
EXPORTING
is_xlips = is_xlips
if_check_only = abap_true
CHANGING
cf_error = lf_error
ct_log = ct_log
).
IF lf_error EQ abap_true.
cf_item_not_deletable = abap_true.
ENDIF.
I believe that the only way to add your customized message is by adding custom enhancement-point, and then implementing it with the message.
add an enhancement point where you need to implement the message
enhancement-point <enhancement> spots <spot>.
add an enhancement to this spot:
enhancement 1 <name>.
message 'my_msg' type 'W'.
endenhancement.

PyDev custom code complete plug-in only detects every other key stroke

I have an Eclipse plug-in that I created to add Code Completion entries. I configured Eclipse to automatically show code completion as I type (Windows | Preferences | PyDev | Editor | Code Completion | Request completion on all letter chars and '_'?). At first when I typed I kept getting the templates showing instead of my code completion entries, so I removed all the templates ( Windows | Preferences | PyDev | Templates --selected all, then "Remove"). Now when I type it works properly for every other key pressed. For example, when I type 'print', the code completion list drops down with my entries as expected when I press 'p'. However, when I press 'r', the list disappears. When I press 'i' the list shows again, but disappears when I press the next key ('n'), etc. Is this a Pydev defect, or am I doing something wrong? It works fine for the templates and other default code completion, just not for my plug-in. Here is a code snipped of a watered down version of my code:
//...
public class MyPlugin implements IPyDevCompletionParticipant
#Override
public Collection<Object> getGlobalCompletions(CompletionRequest arg0,
ICompletionState arg1) throws MisconfigurationException {
String replacementString = "{" + arg0.qualifier + "}";
int replacementOffset = arg0.documentOffset - arg0.qlen;
int replacementLength = arg0.qlen;
int cursorPosition = arg0.documentOffset;
String displayString = arg0.qualifier;
final IContextInformation contextInformation = new ContextInformation(
"displayStr", "message");
String additionalProposalInfo = "additionalProposalInfo";
final String bundle = "com.github.EclipseChameleonPlugins";
final org.eclipse.swt.graphics.Image image = new org.eclipse.swt.graphics.Image(getDisplay(), locateFile(bundle, "icons/smiley.gif").getPath());
arg0.showTemplates = false;
final CompletionProposal proposal = new CompletionProposal(
replacementString, replacementOffset, replacementLength,
cursorPosition, image, displayString, contextInformation, additionalProposalInfo);
List<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>();
// ADD IT...
proposals.add(proposal);
final Collection<Object> returnProposals = new ArrayList<Object>(
proposals);
return returnProposals;
}
I have searched Google and StackOverflow, and have seen very little about code development for PyDev plug-ins, and nothing that mentions or addresses this issue.
Here are a few of the links I have looked at, but none have answered my question:
Auto-completion in PyDev
Code completion for custom modules not working with PyDev
pydev remote debuging - code completion in interactive console?
Well, plain PyDev behaves as expected for me (i.e.: the code completions appear on all the key strokes).
Now, let's see if we can track it down a bit better:
instead of removing the templates, what you should do is go to the preferences > pydev > editor > code completion (ctx insensitive and common tokens) and disable the 'use common tokens auto code completion?'.
The reference code for you to follow is: com.python.pydev.codecompletion.participant.ImportsCompletionParticipant and com.python.pydev.codecompletion.ctxinsensitive.CtxParticipant (i.e.: the IPyDevCompletionParticipant interface -- as you're doing already)
I think the main issue you're having is because you're not implementing the additional extensions for completions (to validate its context and keep it there) -- either you can make your own subclass of org.python.pydev.editor.codecompletion.AbstractPyCompletionProposalExtension2 or you can use org.python.pydev.editor.codecompletion.PyLinkedModeCompletionProposal (just constructing it with the proper parameters -- I believe it supports having a null IToken -- and you can pass an image to it which will be used if the token is null).
You should probably not mess with the CompletionRequest at that point (when it gets there to an extension it should be considered immutable -- even if it's not in reality).

Ninject: More than one matching bindings are available

I have a dependency with parameters constructor. When I call the action more than 1x, it show this error:
Error activating IValidationPurchaseService
More than one matching bindings are available.
Activation path:
1) Request for IValidationPurchaseService
Suggestions:
1) Ensure that you have defined a binding for IValidationPurchaseService only once.
public ActionResult Detalhes(string regionUrl, string discountUrl, DetalhesModel detalhesModel)
{
var validationPurchaseDTO = new ValidationPurchaseDTO {...}
KernelFactory.Kernel.Bind<IValidationPurchaseService>().To<ValidationPurchaseService>()
.WithConstructorArgument("validationPurchaseDTO", validationPurchaseDTO)
.WithConstructorArgument("confirmPayment", true);
this.ValidationPurchaseService = KernelFactory.Kernel.Get<IValidationPurchaseService>();
...
}
I'm not sure what are you trying to achieve by the code you cited. The error is raised because you bind the same service more than once, so when you are trying to resolve it it can't choose one (identical) binding over another. This is not how DI Container is supposed to be operated. In your example you are not getting advantage of your DI at all. You can replace your code:
KernelFactory.Kernel.Bind<IValidationPurchaseService>().To<ValidationPurchaseService>()
.WithConstructorArgument("validationPurchaseDTO", validationPurchaseDTO)
.WithConstructorArgument("confirmPayment", true);
this.ValidationPurchaseService = KernelFactory.Kernel.Get<IValidationPurchaseService>();
With this:
this.ValidationPurchaseService = new ValidationPurchaseService(validationPurchaseDTO:validationPurchaseDTO, confirmPayment:true)
If you could explain what you are trying to achieve by using ninject in this scenario the community will be able to assist further.
Your KernelFactory probably returns the same kernel (singleton) on each successive call to the controller. Which is why you add a similar binding every time you hit the URL that activates this controller. So it probably works the first time and starts failing after the second time.

How can I send different SMS' to multiple recipients in a loop

I'm using Symbian C++ to create my code, I'm using S60 5th Ed SDK
I want to know how to send different messages - Their body text not the same - to multiple recipients in a for-loop ?
I've tried the example below, but when I try to use it in a loop it crashes due to ActiveObjects properties, as I should wait to AO to finish before calling it again.
Sending_SMS_in_S60_3rd_Edition_MTM
Below is example of what I need to do:
SendSMSL(); // **I call this function once to start the process**
// **iRecepients is a CDesCArray contains phone numbers**
// ** iSMSBody is a CDesCArray contains each contact SMS body text**
void CSMS::SendSMSL()
{
if(iRecepients->Count() >= 1)
{
TInt x = iRecepients->Count()-1;
TInt y = iSMSBody->Count()-1;
// **If the sms validating and scheduling succeeded then delete last item from both arrays**
if(iSMSHandler->SendL((*iRecepients)[x],(*iSMSBody)[y])
{
iRecepients->Delete(x);
iSMSBody->Delete(y);
}
}
}
Now, in the code above I call iSMSHandler->SendL() which send sms using AO, and in iSMSHandler object RunL() function, I call back the function above CSMS::SendSMSL() , which in turn checks if there is still anymore iRecepients elements and then call again iSMSHandler->SendL() AO , and keeps this way till no more iRecepients.
Looking forward to hear your feedback on the modification above.
Many thanks in advance.
The link you posted doesn't work for me so I can't see the rest of the code.
Assuming that iSmsHandler is a class that uses active objects to send SMS messages,
I see several issues with your loop.
1) You need to wait for the first asynchronous SendL to complete before you can issue the next SendL
2) The buf variable can not go out of scope until the SendL completes. (This may be the reason for your crash)
I suggest that you keep the textbuffer somewhere else, like together with iSmsHandler, and then code the active object that is called when SendL completes to issue the next SendL.
All of this is guesses since I have no idea what class iSmsHandler is....