How to get path of selected directory into renderer process - select

I want to store in variable the path of local directory selected using dialog.showOpenDialog.
I tried every tutorial and stack answer without any luck.
Best part is that even the electron-api-demos solution isn't working (I am using one here)
So, dialog opens, I can select a folder or a file - but nothing is send back to renderer process.
Here I am testing this with opening files but also no results.
I am using jquery btw and elcetron v 12.
Here is my code:
Renderer process:
$('.js_select_folder').on('click', (e) =>{
ipcRenderer.send('open-folder')
e.preventDefault();
})
ipcRenderer.on('selected-folder', (event, path) => {
console.log('wtf',path)
$('#info').text('Result :'+path)
})
Main process:
ipcMain.on('open-folder', (event) => {
dialog.showOpenDialog({ properties:['openFile']}, (files) => {
if(files){
console.log(files)
event.reply('selected-folder', files)
}
})
})
No trace of console.log(files) anywhere.
Any ideas what I am doing wrong?

I figured it out:
renderer process:
$('.js_test').on('click', (e)=>{
e.preventDefault();
ipcRenderer.send('open-folder')
})
ipcRenderer.on('sel-dir', (event, path) => {
const message = `This app is located at: ${path}`
$('#info').text(message)
})
main process:
ipcMain.on('open-folder', (event, arg) => {
dialog.showOpenDialog({properties: ['openDirectory']}).then(result=>{
event.sender.send('sel-dir', result.filePaths)
})
})
So it is actually super simple as you can see but took me two days to figure it out.
The result is that I get the path (or any data) back to renderer after choosing dir or file.
Regards, Mac.

Related

How to listen event on specific file in Visual Studio Code?

I am new to visual studio code API.
I would like to listen some event like onSave , onClose etc...
I am currently using this API.But I think this is vary expensive like this. When you only need to listen event for only a specific file.
let { workspace } = require("vscode");
module.exports = {
activate(ctx) {
ctx.subscriptions.push(
workspace.onDidSaveTextDocument(({ fileName, version }) => {
})
)
},
deactivate() {}
};
Not a great solution .But worked for me.
Still Though is there any other way,The better way?...
My solution is...
let onSaveCleaner = workspace.onDidSaveTextDocument((e) => {
// watch for all file save event ... yuck!
});
let onCloseCleaner = workspace.onDidCloseTextDocument(({ fileName, languageId }) => {
// some condition like once `specific` file closed
if (languageId == "python" && fileName == "...") {
onSaveCleaner.dispose()
onCloseCleaner.dispose()
}
});
By doing that We only run expensive code when file is not closed!
Once the file closed...Destroy everything!

NWJS window loaded is not available

The NWJS documentation states that after opening a window, you have to wait for the loaded event before you can interact with it:
You should wait for the Window’s loaded event before interacting with any of its components.
So I tried to add a loaded event handler for the win object after opening it.
nw.Window.open('test.html', {}, (win) => {
win.showDevTools()
win.addEventListener("loaded", () => {
console.log("NW Window loaded not working...")
})
}
I get the following error:
Uncaught TypeError: win.addEventListener is not a function
How can I listen for NWWindow events in NWJS? Sidenote: I CAN listen for DOM window load events, but that's not the same is it?
nw.Window.open('test.html', options, (win) => {
win.showDevTools()
win.window.addEventListener("load", () => {
console.log("dom window load IS working...")
})
}
There is an example on how to use the Event Listener on the nw.Window:
nw.Window.open('test.html', {}, win => {
win.showDevTools();
win.on("loaded", () => {
console.log("NW Window loaded not working...")
})
}
Example from here, I changed it so that it fits to your problem
Edit: I changed the nw.Window.get() to win
addEventListener is from DOM. Refer https://nodejs.org/api/events.html#events_emitter_addlistener_eventname_listener & then try again. Also console may work as win.window.console here.

Implementing a "Save As" using the vscode API

I've been trying to figure out the best way to implement a "Save As" using the vscode extension API.
So far, here's the best I've got:
// First turn the path we were given into an absolute path
// Relative paths are interpreted as relative to the original file
const newFileAbsolutePath = path.isAbsolute(saveFileDetails.newPath) ?
saveFileDetails.newPath :
path.resolve(path.dirname(saveFileDetails.filePath), saveFileDetails.newPath);
// Create an "untitled-scheme" path so that VSCode will let us create a new file with a given path
const newFileUri = vscode.Uri.parse("untitled:" + newFileAbsolutePath);
// Now we need to copy the content of the current file,
// then create a new file at the given path, insert the content,
// save it and open the document
return vscode.workspace.openTextDocument(saveFileDetails.filePath)
.then((oldDoc) => {
return vscode.workspace.openTextDocument(newFileUri)
.then((newDoc) => {
return vscode.window.showTextDocument(newDoc, 1, false)
.then((editor) => {
return editor.edit((editBuilder) => {
editBuilder.insert(new vscode.Position(0, 0), oldDoc.getText());
})
.then(() => {
return newDoc.save()
.then(() => EditorOperationResponse.Completed);
});
});
});
});
We open the old doc, then open a new doc (which is an untitled document), then insert the old doc's text into the new doc and then save the new doc.
The new doc then closes (for some reason).
Anyone have any advice?
It seems like this is a known issue and caused by the use of the untitled:// scheme:
TextDocument.save() closes untitled documents (#29156)
For now, you could work around it by just reopening the file again since you know the final URI (unlike in the case of the person who reported the issue).
newDoc.save().then((completed) => {
const finalUri = vscode.Uri.file(newFileAbsolutePath);
vscode.workspace.openTextDocument(finalUri).then((doc) => {
vscode.window.showTextDocument(doc, {preview: false});
})
});
Unfortunatenly this does lead to a noticable "flicker"-effect. To avoid this, I'd suggest to simply bypass the VSCode API and use fs for file IO, and only use vscode for showing the file at the end. This also simplifies the code quite a bit:
import * as fs from 'fs';
function runCommand() {
// obtain newFileAbsolutePath / oldFileAbsolutePath
var oldDocText = fs.readFileSync(oldFileAbsolutePath);
fs.writeFileSync(newFileAbsolutePath, oldDocText);
const finalUri = vscode.Uri.file(newFileAbsolutePath);
vscode.workspace.openTextDocument(finalUri).then((doc) => {
vscode.window.showTextDocument(doc, {preview: false});
});
}

Adding keyboard shortcuts for move cell up and move cell down

I am trying to add the Cntl+K and Cntl+J shortcuts to move cells up and down quickly. I viewed the issue on Github here for adding the shortcuts and found what looked to be a workable answer:
"For those (like me) who liked this shortcut, add this to your ~/.ipython/profile_default/static/custom/custom.js:
$([IPython.events]).on("app_initialized.NotebookApp", function () {
IPython.keyboard_manager.command_shortcuts.add_shortcut('ctrl-k', function (event) {
IPython.notebook.move_cell_up();
return false;
});
IPython.keyboard_manager.command_shortcuts.add_shortcut('ctrl-j', function (event) {
IPython.notebook.move_cell_down();
return false;
});
});
"
But my users/{my name}/.ipython/profile_default directory did not have a static folder. I tried adding the missing folders and custom.js file, and reopened Anaconda prompt, but this did not add the missing shortcuts.
Another answer had the same issue:
"Use the following:
$ cat ~/.jupyter/custom/custom.js
define(["base/js/namespace"], function(Jupyter){
console.info('Binding Ctrl-J/K to move cell up/down');
Jupyter.keyboard_manager.command_shortcuts.add_shortcut('Ctrl-k','jupyter-notebook:move-cell-up');
Jupyter.keyboard_manager.command_shortcuts.add_shortcut('Ctrl-j','jupyter-notebook:move-cell-down');
});
"
This answer also did not work (adding the missing folder and custom.js file did not work).
As proposed in the official doc (got with the "Help>Notebook" menu action),
you could try first in a live notebook. The browser javascript console helps too.
I tried:
%%javascript
IPython.keyboard_manager.command_shortcuts.add_shortcut('Ctrl-k','jupyter-notebook:move-cell-up');
// replacing IPython with Jupyter should work as well:
Jupyterkeyboard_manager.command_shortcuts.add_shortcut('Ctrl-j','jupyter-notebook:move-cell-down');
It works but, just as when clicking on the corresponding toolbar button, the console warns about deprecation
in favor of IPython.notebook.move_selection_up() .
The string "jupyter-notebook:move-cell-up" refers to the same action.
So I suppose a reasonnable thing to do is to redefine it from scratch:
IPython.keyboard_manager.command_shortcuts.add_shortcut('Ctrl-k', {
help : 'move up selected cells',
help_index : 'jupyter-notebook:move-selection-up',
handler : function (event) {
IPython.notebook.move_selection_up();
return false;
}}
);
IPython.keyboard_manager.command_shortcuts.add_shortcut('Ctrl-j', {
help : 'move down selected cells',
help_index : 'jupyter-notebook:move-selection-down',
handler : function (event) {
IPython.notebook.move_selection_down();
return false;
}}
);
After executing the notbook cell (or the code in your browser console), it should
be active and you can experiment with it.
Once happy, check the path of your jupyter profile with !jupyter --config, and from there
you'd know where to copy your code : <profile>/static/custom/custom.js
so that it would be active in next jupyter sessions.

Error In Rendering Jade Files

I get an error while rendering the Jade file. The code that I use in app.js is:
app.get('/photos/new' function(req, res) {
res.render('/photos/new', {
locals: {
photo: new Photo()
}
});
});
The corresponding Jade file is:
h1 New Photo
form(action='/photos', method ='post', enctype ='form-data')
!= partial('../partials/photo_form', { locals: { photo: photo}})
p
input(type = 'submit')
But I get an error saying photo is not defined. I don't know where I am doing wrong. Please help.
The locals in the partial is implied, so give this a try:
!= partial('../partials/photo_form', {photo: photo})
when doing partial include, it refers to the current directory the view is in..
so the response you are rendering comes from:
/views/photos/new.jade
right?
so then the partial include is in the new.jade file.. which means if you do
partial('../partials/photo_form',{'whatever':'whatever'})
its looking in:
/views/partials/photo_form.jade
is that what you are expecting?
because if it is in
/views/photos/photo_form.jade
just do partials('photo_form',{'whatever':'whatever'})
and it will default to the directory the parent view is in.
http://expressjs.com/guide.html
and check view lookup
cheers