Is it possible to call commands between extensions in VSCode? - visual-studio-code

For example, there are two VSCode extensions:
extension1 has registered command exCommand1
extension2 has registered command exCommand2
According to documentation, a VSCode extension can call commands
(ref: https://code.visualstudio.com/docs/extensionAPI/vscode-api)
executeCommand<T>(command: string, ...rest: any[]): Thenable<T | undefined>
If API Doc is correct then
extension1 can call exCommand2 provided by extension2
extension2 can call exCommand1 provided by extension1
But, VSCode's extensions are lazily loaded, so how does one call a command from another extension that may not already be loaded?

I know this is an old post, if you still have the same requirement or for others googling, this is how I have done it.
var xmlExtension = vscode.extensions.getExtension( 'DotJoshJohnson.xml' );
// is the ext loaded and ready?
if( xmlExtension.isActive == false ){
xmlExtension.activate().then(
function(){
console.log( "Extension activated");
// comment next line out for release
findCommand();
vscode.commands.executeCommand("xmlTools.formatAsXml");
},
function(){
console.log( "Extension activation failed");
}
);
} else {
vscode.commands.executeCommand("xmlTools.formatAsXml");
}
// dev helper function to dump all the command identifiers to the console
// helps if you cannot find the command id on github.
var findCommand = function(){
vscode.commands.getCommands(true).then(
function(cmds){
console.log("fulfilled");
console.log(cmd);
},
function() {
console.log("failed");
console.log(arguments);
}
)
};

Related

Loopback Operation hook receives options as empty

I'll try to explain this weird situation as simple as I can.
I've created an operation hook "before save" and make it in a mixin to add it to some models.
this mixin uses context.options to get current userId to do something.
this mixin is working perfectly if I call the operation directly (like POST /Accounts for example).
But if I call it inside a remote method, the context.options is empty, for example, if we have a method called POST /Accounts/Signup, and inside it, we call Account.create(...), the "before save" hook receives the options as empty object {}
A sandbox project has been hosted here
https://github.com/mustafamagdy/loopback-sandbox-issue
the mixin code snippet is as follows:
module.exports = function(Model, options) {
Model.observe("before save", async function(ctx) {
if (ctx.instance.id) return;
const userId = ctx.options && ctx.options.accessToken && ctx.options.accessToken.userId;
if (userId) {
//... do stuff
}
else
{
console.error("Failed to scope " + Model.name + " to user (null)");
}
});
};
After the investigation, I found this issue that talks about similar behaviour, however, the comments are very destractive. So I thoughlt to write the conclusion here for anyone who are facing the same issue.
Loopback require you to pass the options you declared from the remote method to the model method(s) if you want to receive it on operation hook, so I ended up doing so.
module.exports = function(Note) {
Note.makeNew = makeNew;
async function makeNew(options) {
await Note.create(obj, options);
}
};

How to add custom javascript code to validate field in contacts module in sugarcrm

I want custom code to be made on onblur of first_name field in sugarcrm.
The code should also be upgrade safe.
Please help!
Copy modules/Contacts/metadata/editviewdefs.php
into
custom/modules/Contacts/metadata/editviewdefs.php
(if it does not already exist. If so, use the existing one)
All your changes in this file are upgrade safe. Now open your new file, and you'll see one big array containing everything that's in the EditView of the Contacts-module.
Add the following inside the "templateMeta" array, for instance, right after "form".
'includes'=> array(
array('file'=>'custom/modules/Contacts/EditView.js'),
),
This includes the file custom/modules/Contacts/EditView.js, in which you are free to write all the javascript you feel like!
Remember to do a Quick Repair & Rebuild when you are done.
I don't know which version of SugarCRM you uses, but in SugarCRM 7, the following works:
Create a file 'record.js' in /custom/modules/Contacts/clients/base/views/record/. In that file, you can add custom validation.
Some code you could use is:
({
extendsFrom: 'YourModuleRecordView',
initialize: function (options) {
app.error.errorName2Keys['field_error'] = 'This is an error message';
this._super('initialize', [options]);
this.model.addValidationTask('check_field', _.bind(this._doValidateField, this));
},
_doValidateField: function(fields, errors, callback) {
if (this.model.get('myField') .... ) {
errors['myField'] = errors['myField'] || {};
errors['myField'].field_error = true;
}
callback(null, fields, errors);
}
});
Don't forget to change the fields names like you named them!
This result is only for edit mode. To add this validation to the creation mode, add the file 'create_actions.js' to /custom/modules/Contacts/clients/base/views/create_actions/
Enter the folling code in your 'create_actions.js':
({
extendsFrom: 'CreateActionsView',
initialize: function (options) {
app.error.errorName2Keys['field_error'] = 'Thsis is an error message';
this._super('initialize', [options]);
this.model.addValidationTask('check_field', _.bind(this._doValidateField, this));
},
_doValidateField: function(fields, errors, callback) {
if (.....) {
errors['myField'] = errors['myField'] || {};
errors['myField'].field_error = true;
}
callback(null, fields, errors);
}
});
Perform a repair/rebuild when you added this files with the right code.
You can customize this code to your own needs.

Using port.emit and port.on in a firefox extension

Can someone please explain the context in which port.on and port.emit are used in a firefox extension?
From the official documentation I imagine that this should work:
//main.js
var someData = "Message received";
self.port.emit("myMessage", someData);
self.port.on("myMessage", alert(someData));
but I get
Error: self is not defined.
After attaching this to a defined object like this:
var self = require("sdk/self");
self.port.emit("myMessage", someData);
I get
Error: port is not defined.
If you use the page-mod module to inject a content script into a web page, you then use self.port in the content script to communicate back with main.js. For example:
main.js:
var data = require('sdk/self').data;
require('sdk/page-mod').PageMod({
include: ["*"],
contentScriptFile: [data.url('cs.js')],
attachTo: ["existing", "top"],
onAttach: function(worker) {
worker.port.emit('attached', true);
}
});
cs.js:
self.port.on('attached', function() {
console.log('attached...');
});
For the related documentation, start here:
https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts

Custom PhoneGap Plugin (iOS) Function Issue

I'm using this tutorial to create a custom PhoneGap plugin:
http://wiki.phonegap.com/w/page/36753496/How%20to%20Create%20a%20PhoneGap%20Plugin%20for%20iOS
I have had success using the author's example, but I have a few questions that I have not been able to find out the answers to.
When the JavaScript function is created, the code is:
var MyPlugin = {
nativeFunction: function(types, success, fail) {
return PhoneGap.exec(success, fail, "PluginClass", "print", types);
}
};
Is there a way to set this up without var MyPlugin = {...}; and nativeFunction? In other words, can we define a function of our plugin like myfunc = function()...
Secondly, assuming there is a way to do the above, could this code:
MyPlugin.nativeFunction(
["HelloWorld"] ,
function(result) {
alert("Success : \r\n"+result);
},
function(error) {
alert("Error : \r\n"+error);
}
);
(which is the test code to test the plugin) also be written in a more standardized way? I.e., just a call to Javascript function without the nativeFunction part?
I would very much appreciate any input, thank you!
the phonegap documentation for plugins sucks. Honestly I had a bunch of issues when trying to create my own. A few tips :
the reason for doing
var MyPlugin = {};
is because this allows us to us scope things specific to that js object.
example:
MyPlugin.myFunction();
My favorite method to create plugins, similar to your question, is to prototype them
var MyPlugin = {}; // our object
MyPlugin.prototype.myFunction = function(success,fail,types){
}
The key to making a plugin fire is this -
PhoneGap.exec(success,fail,"MyPlugin","myFunction",types);
But something that they leave out is, what if we want to have options to our plugin? What if we want to do more than pass a string, then the example doesn't work. The fix is easy but not talked about at all.
var MyPlugin = {};
MyPlugin.prototype.myFunction = function(success,fail,options){
var defaults = {
foo: '', // these are options
bar: '',
};
// this parses our "options"
for(var key in defaults) {
if(typeof options[key] !== "undefined") defaults[key] = options[key];
}
return PhoneGap.exec(success,fail,"MyPlugin","myFunction",[defaults]);
}
when we call this with out javascript -
var foo = MyPlugin.myFunction(success,fail,{
foo:'hello',
bar:'world'
});
You'll notice that most of the phonegap API uses this syntax, which I found strange that their documentation didn't really talk about how to do this.
I have a post about a plugin I create you can check it out for reference.
Blog - http://www.drewdahlman.com/meusLabs/?p=138
Git - https://github.com/DrewDahlman/ImageFilter

callbacks google chrome extension

I am writing a Google Chrome Extension (and learning an awful lot in the process). Callback functions are something of a mystery. I started researching the subject to solve a problem from an earlier question I posted and found a post from #serg containing a model I could use. Here is the solution:
function getKeyWords(action, callback){
chrome.extension.sendRequest(
{
cmd: action
},
function(response)
{
callback(response.keyWordsFound);
}
);
}
var keyWords="";
getKeyWords("sendKeyWords", function(reply) {
keyWordList=reply;
for (var i = 0; i<keyWordList.length; ++i)
{
keyWords=keyWords+" "+keyWordList[i];
}
msgComment1.innerHTML="<strong>"+keyWords+"</strong>";
console.log("Reply is:", keyWords);
});
Now I want to extend this solution but this time the function has to return two arguments instead of one. I modified the code above the best I could understand it but it fails. Here is the modified code:
function getFacePageDat(action, callback){
chrome.extension.sendRequest(
{
cmd: action
},
function(response)
{
callback(response.ageList, response.seekList);
}
);
}
getFacePageDat("sendSearchPageInfo", function(reply1, reply2) {
profileAgeCityMetro=reply1;
profileSeeks=reply2;
alert("Reply is:", profileAgeCityMetro+" seeks "+profileSeeks);
console.log("Reply is:", profileAgeCityMetro+" seeks "+profileSeeks);
});
Unfortunately this fails on "Error in event handler for 'undefined': TypeError: Property 'log' of object # is not a function. I know the answer to this question is rather simple if you have a grasp of callbacks but I don't. Any help out there?
Serg is likely correct above:
console.log("Reply is:", profileAgeCityMetro+" seeks "+profileSeeks);
should be
console.log("Reply is:" + profileAgeCityMetro + " seeks " + profileSeeks);