vscode - Is there a way to create an instance of `vscode.TextDocument`? - visual-studio-code

I'm listening for onWillSaveTextDocument and getting an instance of vscode.TextDocument which I use for file content and file path information.
It would be convenient to just create a new instance of this object, rather than recreating all of the information from a file path.
I'm hoping there is something like:
const document = new TextDocument(myFilePath);

You could simply use vscode.workspace.openTextDocument method to create TextDocument instance.
An example would be:
vscode.workspace.openTextDocument( {
language: 'text'
} )
.then( doc => {
// Do something useful with the document.
});
If you'd like to see it used in context, feel free to see this part of code.

Related

VSCode extension API: simple local Quick Diff

Trying to understand how to implement simple source control management in my language extension.
I need to show a Quick Diff for a single file (my extension doesn't work with folders) compared with some special one.
Let's say i have this TextDocumentContentProvider and QuickDiffProvider:
class MyLangDocumentContentProvider implements vscode.TextDocumentContentProvider
{
provideTextDocumentContent(uri: vscode.Uri)
{
return getFileText(uri); // returns text of provided file uri
}
}
class MyLangRepository implements vscode.QuickDiffProvider
{
provideOriginalResource(uri: vscode.Uri)
{
return getOriginalFileUri(uri); // returns uri of the special file to compare with
}
}
Then in activate method of extension i initialize them:
const docProvider = new MyLangDocumentContentProvider();
const gitSCM = vscode.scm.createSourceControl('git', 'Git');
gitSCM.quickDiffProvider = new MyLangRepository();
const workingTree = gitSCM.createResourceGroup('workingTree', 'Changes');
workingTree.resourceStates = [
{ resourceUri: vscode.window.activeTextEditor.document.uri }
];
Then i need to call registerTextDocumentContentProvider with some custom uri scheme. So why do i need custom uri scheme? And what else should i do to track changes of current file relative to the special one?
I was looking at vscode-extension-samples/source-control-sample, but it looks more complicated then my case.
Thanks for any advices!
Though my question was rather sily, let me save here some kind of instruction, how I've done this.
to make QuickDif work you don't need neither ResourceGroups nor TextDocumentContentProvider, this is a separate functionality.
SourceControl (and also its quickDiffProvider) will work if you pass some root directory in constructor (I've got no luck without thoug I don't need it for my purpose).

What does `namespaceMappings` mean in Word.CustomXMLPart API

I have created a small snippet in Script Lab which basically:
Creates a custom XML:
<AP xmlns="accordproject.org">
<template xmlns="acceptance-of-delivery">
<shipper>Aman Sharma</shipper>
</template>
</AP>
Tries to query this xml by using the xPath /AP/template. I run this block of code:
await Word.run(async context => {
const customXmlParts = context.document.customXmlParts;
const AP = customXmlParts.getByNamespace("accordproject.org").getOnlyItemOrNullObject();
await context.sync();
const nodes = AP.query('/AP/template', {}); // how does this work?
await context.sync();
console.log(nodes);
})
Deletes the customXML.
The second argument of query API is namespaceMappings. I think I am passing that incorrectly and that's why I get this as ouput (empty object).
But when I pass * instead of /AP/template, I get the whole XML (while the second argument, namespaceMappings remain the same).
Where am I going wrong? Can anyone share some snippets to help me query customXML.
The short answer is that you can use
const nodes = AP.query("/n1:AP/n2:template", {n1:"accordproject.org", n2:"acceptance-of-delivery"});
I don't know JS/TS at all but I assume these are basically key-value pairs of some kind. You can also use
const nodes = AP.query("/n1:AP/n2:template", {"n1":"accordproject.org", "n2":"acceptance-of-delivery"});
if you prefer to think of the Namespace prefixes as strings.
(For anyoneunfamiliar, the "n1" and "n2" are just prefixes that you invent so you can reference the full Namespace URIs. They don't have anything to do with any prefixes you might have used in the piece of XML you are querying.)
I couldn't find documentation on this either and originally assumed you might need something more like { Prefix:"ns1", namespaceURI:"the namespace URI" }, but that's just because those are the property names used in the VBA model.

Can't get changed property from attachPropertyChange

I would like to know which property in the JSON model has changed when modified by a view.
For a test I took OpenUI5 walkthrough example and added the following lines in the application controller
oProductModel.attachPropertyChange( function(oEvent){
console.log("event: ", oEvent);
}, this);
When I change a property in the text input, the function in the attachPropertyChange is called but oEvent object is empty as I print it in console.
I know I could connect to text input change event, but I would like to use attachPropertyChange in case there would be multiple views of the same model.
As far as I understood, you'd like to avoid using the change event of the Input control because there is no information about which property in the model has changed. However, you can still get all the relevant information within the change handler via:
oControl.getBinding(/*controlPropertyName*/).getPath() to get the name of the bound property, or
oControl.getBindingContext(/*modelName*/).getPath(/*suffix*/) to get the path of the bound context. The getPath here awaits an optional suffix that will be appended to the context path with a "/" in between.
Combine those two APIs to get an absolute path in case the property binding was relative. E.g.:
onInputChange: function (event) {
const inputControl = event.getSource();
const property = inputControl.getBinding("value").getPath(); // "myProperty"
const absolutePath = inputControl.getBindingContext(/*modelName*/).getPath(property) // "/0/myProperty"
// ...
},
You can use change event for all input field in UI, and write event handling method in the controller. You will get the property as well as value in the oEvent of the event handling method easily. I hope you understood.

Get newly created id of a record before redirecting page

I would like to retrieve the id of a newly created record using javascript when I click on save button and just before redirecting page.
Do you have any idea please ?
Thank you !
One way to do this in Sugar 7 would be by overriding the CreateView.
Here an example of a CustomCreateView that outputs the new id in an alert-message after a new Account was successfully created, but before Sugar gets to react to the created record.
custom/modules/Accounts/clients/base/views/create/create.js:
({
extendsFrom: 'CreateView',
// This initialize function override does nothing except log to console,
// so that you can see that your custom view has been loaded.
// You can remove this function entirely. Sugar will default to CreateView's initialize then.
initialize: function(options) {
this._super('initialize', [options]);
console.log('Custom create view initialized.');
},
// saveModel is the function used to save the new record, let's override it.
// Parameters 'success' and 'error' are functions/callbacks.
// (based on clients/base/views/create/create.js)
saveModel: function(success, error) {
// Let's inject our own code into the success callback.
var custom_success = function() {
// Execute our custom code and forward all callback arguments, in case you want to use them.
this.customCodeOnCreate(arguments)
// Execute the original callback (which will show the message and redirect etc.)
success(arguments);
};
// Make sure that the "this" variable will be set to _this_ view when our custom function is called via callback.
custom_success = _.bind(custom_success , this);
// Let's call the original saveModel with our custom callback.
this._super('saveModel', [custom_success, error]);
},
// our custom code
customCodeOnCreate: function() {
console.log('customCodeOnCreate() called with these arguments:', arguments);
// Retrieve the id of the model.
var new_id = this.model.get('id');
// do something with id
if (!_.isEmpty(new_id)) {
alert('new id: ' + new_id);
}
}
})
I tested this with the Accounts module of Sugar 7.7.2.1, but it should be possible to implement this for all other sidecar modules within Sugar.
However, this will not work for modules in backward-compatibility mode (those with #bwc in their URL).
Note: If the module in question already has its own Base<ModuleName>CreateView, you probably should extend from <ModuleName>CreateView (no Base) instead of from the default CreateView.
Be aware that this code has a small chance of breaking during Sugar upgrades, e.g. if the default CreateView code receives changes in the saveModel function definition.
Also, if you want to do some further reading on extending views, there is an SugarCRM dev blog post about this topic: https://developer.sugarcrm.com/2014/05/28/extending-view-javascript-in-sugarcrm-7/
I resolved this by using logic hook (after save), for your information, I am using Sugar 6.5 no matter the version of suitecrm.
Thank you !

Coffeescript "#" variables

What does it mean in Coffeescript when a variable name begins with an "#" sign?
For example, I've been looking through the hubot source code and just in the first few lines I've looked at, I found
class Brain extends EventEmitter
# Represents somewhat persistent storage for the robot. Extend this.
#
# Returns a new Brain with no external storage.
constructor: (robot) ->
#data =
users: { }
_private: { }
#autoSave = true
robot.on "running", =>
#resetSaveInterval 5
I've seen it several other places, but I haven't been able to guess what it means.
The # symbol is a shorcut for this as you can see in Operators and Aliases.
As a shortcut for this.property, you can use #property.
It basically means that the “#” variables are instance variables of the class, that is, class members. Which souldn't be confused with class variables, that you can compare to static members.
Also, you can think of #variables as the this or self operators of OOP languages, but it's not the exact same thing as the old javascript this. That javascript this refer to the current scope, which causes some problems when your are trying to refer to the class scope inside a callback for example, that's why coffescript have introduced the #variables, to solve this kind of problem.
For example, consider the following code:
Brain.prototype = new EventEmitter();
function Brain(robot){
// Represents somewhat persistent storage for the robot. Extend this.
//
// Returns a new Brain with no external storage.
this.data = {
users: { },
_private: { }
};
this.autoSave = true;
var self = this;
robot.on('running', fucntion myCallback() {
// here is the problem, if you try to call `this` here
// it will refer to the `myCallback` instead of the parent
// this.resetSaveInterval(5);
// therefore you have to use the cached `self` way
// which coffeescript solved using #variables
self.resetSaveInterval(5);
});
}
Final thought, the # these days means that you are referring to the class instance (i.e., this or self). So, #data basically means this.data, so, without the #, it would refer to any visible variable data on scope.