On ms Windows from node.js code, how can I open a specific directory (ex: c:\documents) in Windows file explorer?
I guess in c#, it would be:
process.Start(#"c:\test")
Try the following, which opens a File Explorer window on the computer running Node.js:
require('child_process').exec('start "" "c:\\test"');
If your path doesn't contain whitespace, you can also get away with 'start c:\\test', but the above - which requires "" as the 2nd argument[1] is the most robust approach.
Note:
The File Explorer window will launch asynchronously, and will receive focus when it does.
This related question asks for a solution that prevents the window from "stealing" focus.
[1] cmd.exe's internal start command by default interprets a "..."-enclosed 1st argument as the window title for the new console window to create (which doesn't apply here). By supplying a (dummy) window title - "" - explicitly, the 2nd argument is reliably interpreted as the target executable / document path.
Would be good to use this package so it would open on diffrent platform
https://www.npmjs.com/package/open-file-explorer
Or just use this part of it
function openExplorerin(path, callback) {
var cmd = ``;
switch (require(`os`).platform().toLowerCase().replace(/[0-9]/g, ``).replace(`darwin`, `macos`)) {
case `win`:
path = path || '=';
cmd = `explorer`;
break;
case `linux`:
path = path || '/';
cmd = `xdg-open`;
break;
case `macos`:
path = path || '/';
cmd = `open`;
break;
}
let p = require(`child_process`).spawn(cmd, [path]);
p.on('error', (err) => {
p.kill();
return callback(err);
});
}
I found another way on the WSL and potentially windows itself.
Note that you have to make sure you're formatting the path for Windows not Linux (WSL).
I wanted to save something on Windows, so in order to do that you use /mnt directory on WSL.
// format the path, so Windows isn't mad at us
// first we specify that we want the path to be compatible with windows style
// then we replace the /mnt/c/ with the format that windows explorer accepts
// the path would look like `c:\\Users\some\folder` after this line
const winPath = path.win32.resolve(dir).replace('\\mnt\\c\\', 'c:\\\\');
// then we use the same logic as the previous answer but change it up a bit
// do remember about the "" if you have spaces in your name
require('child_process').exec(`explorer.exe "${winPath}"`);
This should open the file explorer for you.
A slightly simpler, and more cross-platform solution, would be to use this.
var explorer;
switch (platform()) {
case "win32": explorer = "explorer"; break;
case "linux": explorer = "xdg-open"; break;
case "darwin": explorer = "open"; break;
}
spawn(explorer, [path], { detached: true }).unref();
platform() is from the os module, and spawn is from the child_process module.
Related
I am trying to utilize NVIM's built-in LSPs. While I've been able to implement the LSP for css and python, I haven't been successful with javascript and html.
I installed the LSPs with
:LspInstall <LSP>
Here's how I'm loading the LSPs:
packadd nvim-lspconfig
packadd completion-nvim
:lua << EOF
local nvim_lsp = require('nvim_lsp')
local on_attach = function(_, bufnr)
require('completion').on_attach()
local opts = { noremap=true, silent=true }
end
local servers = {'tsserver', 'cssls', 'html', 'pyls'}
for _, lsp in ipairs(servers) do
nvim_lsp[lsp].setup {
on_attach = on_attach
}
print("lsp istalled -", lsp)
end
EOF
:LspInstallInfo shows:
{
cssls = {
bin_dir = "~/.cache/nvim/nvim_lsp/cssls/node_modules/.bin",
binaries = {
["css-languageserver"] = "~/.cache/nvim/nvim_lsp/cssls/node_modules/.bin/css-languageserver"
},
install_dir = "~/.cache/nvim/nvim_lsp/cssls",
is_installed = true
},
html = {
bin_dir = "~/.cache/nvim/nvim_lsp/html/node_modules/.bin",
binaries = {
["html-languageserver"] = "~/.cache/nvim/nvim_lsp/html/node_modules/.bin/html-languageserver"
},
install_dir = "~/.cache/nvim/nvim_lsp/html",
is_installed = true
},
tsserver = {
bin_dir = "~/.cache/nvim/nvim_lsp/tsserver/node_modules/.bin",
binaries = {
["typescript-language-server"] = "~/.cache/nvim/nvim_lsp/tsserver/node_modules/.bin/typescript
-language-server"
},
install_dir = "~/.cache/nvim/nvim_lsp/tsserver",
is_installed = true
}
}
They seem to be installed and the LSPs for *.css and *.py work fine.
When I open a *.js, *.ts, or *.html file I get the same response with the :LspInstallInfo command. However, I don't think the LSP is active because I do not receive any warning or error messages regarless of what I type.
I've tried loading the LSP different ways, including:
require'nvim_lsp'.tsserver.setup{}
require'nvim_lsp'.html.setup{}
I came across a post about installing typescript and I did, but it didn't seem to have any effect.
I've deactivated all of the other plugins and had the same results.
After installation, you should take consider root_dir. So if you don't have a matching root directory LSP doesn't launch.
In order to automatically launch a language server, lspconfig
searches up the directory tree from your current buffer to find a file
matching the root_dir pattern defined in each server's configuration.
For pyright, this is any directory containing ".git", "setup.py",
"setup.cfg", "pyproject.toml", or "requirements.txt").
Language servers require each project to have a root in order to
provide completion and search across symbols that may not be defined
in your current file, and to avoid having to index your entire
filesystem on each startup.
But if you want to launch LSP in any directory, you can use something like this for Javscript:
require'lspconfig'.tsserver.setup{
filetypes = { "typescript", "typescriptreact", "typescript.tsx" },
root_dir = function() return vim.loop.cwd() end -- run lsp for javascript in any directory
}
I was working on setting up neovim 0.5 today and landed up here looking for something else related to LSP. Anyho, I do have a working setup; here's a brief:
Install neovim nightly (>= 0.5 version)
Install nvim-lspconfig package (I used vim-plug)
Install tsserver: npm i -g typescript-language-server
Add setup in init.vim (remove EOF lines if init.lua):
lua << EOF
require'lspconfig'.tsserver.setup{}
EOF
Restart neovim
I noticed you're using commands like LspInstall & LspInstallInfo, but they are not present in my setup. I'm afraid I cannot comment of why they it work as expected.
LSP by itself doesn't show autocompletion. Have to use another plugin. I am getting good results with completion-nvim
This is a good reference : neovim-and-its-built-in-language-server-protocol
Oh, do give :help lsp a read if you haven't already. Cheers!
I'm trying to solve this Windows filename issue
Basically our CI job fails, with the 'filename too long' error for Windows.
warning: Could not stat path 'node_modules/data-validator/tests/data/data-examples/ds000247/sub-emptyroom/ses-18910512/meg/sub-emptyroom_ses-18910512_task-noise_run-01_meg.ds/sub-emptyroom_ses-18910512_task-noise_run-01_meg.acq': Filename too long
I've read the docs for Node's path module, which seems like a possible solution. I also read about a Windows prefix (\\?\) to bypass the MAX_PATH...but have no idea how to implement these in a clean way.
This part of the codebase with the tests that are failing. The hardcoded path (testDatasetPath) is likely part of the problem.
function getDirectories(srcpath) {
return fs.readdirSync(srcpath).filter(function(file) {
return (
file !== '.git' && fs.statSync(path.join(srcpath, file)).isDirectory()
)
})
}
var missing_session_files = //array of strings here
const dataDirectory = 'data-validator/tests/data/'
function createDatasetFileList(path) {
const testDatasetPath = `${dataDirectory}${path}`
if (!isNode) {
return createFileList(testDatasetPath)
} else {
return testDatasetPath
}
}
createFileList function
function createFileList(dir) {
const str = dir.substr(dir.lastIndexOf('/') + 1) + '$'
const rootpath = dir.replace(new RegExp(str), '')
const paths = getFilepaths(dir, [], rootpath)
return paths.map(path => {
return createFile(path, path.replace(rootpath, ''))
})
}
tl;dr A GitLab CI Job fails on Windows because the node module filenames become too long. How can I make this nodejs code OS agnostic?
This is a known error in the Windows Environment, however, there is a fix..
If you're using an NTFS based filesystem, you should be able to enable long paths in
Local Computer Policy > Computer Configuration > Administrative Templates > System > Filesystem > NTFS
This is also specified in the document you just linked, and theoretically, should work. However, the path shouldn't really be longer than 32 bits,
This will come with some performance hits, but should get the job done.
Also, you should preferably switch to a better package or search for alternatives. If this is your own package, maybe restructure it?
Finally, if none of these work, move your project folder directly to your data drive, (C:\) this will cut down on the other nested and parent folders.
This is inherently bad, and you may run into issues during deployment, if you choose to do it.
People get the error when opening a file in Visual Studio Code when using OmniPascal:
Ordner nicht angegeben
which translates to:
Folder not specified
The first thought to ensure the paths in user settings.json are set:
objectpascal.delphiInstallationPath
objectpascal.objectpascal.searchPath
Would of course be a wrong tree to bark up:
settings.json:
// Place your settings in this file to overwrite the default settings
{
"objectpascal.delphiInstallationPath": "D:\\Programs\\Embarcadero\\Studio\\14.0",
"objectpascal.searchPath": "D:\\Delphi Components"
}
The error is definitely coming from OmniPascal, as it is a string inside
bin\win\OmniPascalServer.exe
I'm not the only person to get this
Anonymous has the same issue:
When I open a .pas file by right clicking on the file in windows explorer, the file opens correctly, but then a messagedialog appears with "Ordner nicht angegeben"' and an OK button.
Is there a way to debug Code?
I can see inside VSCode there is a variable to the workspace root path:
objectPascalServiceClient.js
var config = vscode.workspace.getConfiguration('objectpascal');
var delphiSDK = config.get('delphiInstallationPath', '');
var searchPath = config.get('searchPath', '');
var workspacePath = vscode.workspace.rootPath;
if (typeof delphiSDK == 'undefined')
delphiSDK = "";
if (typeof searchPath == 'undefined')
searchPath = "";
if (isWin) {
childProcess = cp.spawn(path.join(__dirname, 'bin/win/OmniPascalServer.exe'), [workspacePath, delphiSDK, searchPath]);
}
Is there source code?
It looks like OmniPascal is abandonware. Is there source code out there where someone can try to decipher exactly?
The real question is how to get rid of the modal dialog that blocks using the window.
It looks like OmniPascal is abandonware
No it's definetely not abandonware even though there was no new public release within the last months. OmniPascal is still in active development.
The real question is how to get rid of the modal dialog that blocks using the window.
This error message is coming from OmniPascalServer.exe shipped with the OmniPascal plugin for VSCode in (the current) version 0.10.0 released on 2016-04-14.
Workaround for version < 0.11.0
As far as I know this error message only appears when a file is opened in Visual Studio Code instead of a folder. So the simplest workaround is to open the folder which contains the file(s) you want to work with:
By command line: Type code C:\Projects\MyProjectRootFolder
With the Windows Explorer: Perform a right click on the folder (or a white area inside the folder) and select Open with Code. Do not select a .pas file to open VSCode!
From within VSCode: Go to File -> Open Folder...
Or apply the hotfix
Open the file C:\Users\USERNAME\.vscode\extensions\Wosi.omnipascal-0.10.0\objectPascalServiceClient.js
Replace this line
var workspacePath = vscode.workspace.rootPath;
with these lines
var workspacePath = vscode.workspace.rootPath;
if (typeof workspacePath == 'undefined') {
var filePath = vscode.workspace.textDocuments[0].fileName;
workspacePath = path.dirname(filePath);
}
Now the error should no longer appear.
I'm trying to get a way to reach and parse all JSON file from a directory, witch inside an Intel Xdk project. All files in my case stored in '/cards' folder of the project.
I have tried to reach theme with fs.readdirSync('/cards') method, but that wasn't pointed to the location what I expected, and I haven't got luck with 'intel.xdk.webRoot' path.
With the simulator I've managed to get files, with a trick:
fs.readdirSync(intel.xdk.webRoot.replace('localhost:53862/http-services/emulator-webserver/ripple/userapp/', '')+'cards');
(intel.xdk.webRoot contains absolute path to my '/cards' folder)
and its work like a charm, but it isn't working in any real device what I'd like to build it.
I have tried it with iOS7 and Android 4.2 phones.
Please help me to use in a great way the fs.readdirSync() method, or give me some alternate solution.
Thanks and regards,
satire
You can't use nodejs api's on mobile apps. It is a bug that the XDK emulator lets you do it. The bug is fixed in the next release of XDK.
You could write a node program that scans the directory and then writes out a js file with the contents of the directory. You would run the node script on your laptop before packaging the app in the build tab. The output would look like this:
files.js:
dir = {files: ['file1.txt', 'file2.txt']}
Then use a script tag to load it:
And your js can read the dir variable. This assumes that the contents does not change while the app is running.
The location of your application's root directory will vary depending on the target platform and can also vary with the emulator and the debug containers (e.g., App Preview versus App Analyzer). Here's what I've done to locate files within the project:
// getWebPath() returns the location of index.html
// getWebRoot() returns URI pointing to index.html
function getWebPath() {
"use strict" ;
var path = window.location.pathname ;
path = path.substring( 0, path.lastIndexOf('/') ) ;
return 'file://' + path ;
}
function getWebRoot() {
"use strict" ;
var path = window.location.href ;
path = path.substring( 0, path.lastIndexOf('/') ) ;
return path ;
}
I have not been able to test this exhaustively, but it appears to be working so far. Here's an example where I'm using a Cordova media object and want it to play a file stored locally in the project. Note that I have to "special case" the iOS container:
var x = window.device && window.device.platform ;
console.log("platform = ", x) ;
if(x.match(/(ios)|(iphone)|(ipod)|(ipad)/ig)) {
var media = new Media("audio/bark.wav", mediaSuccess, mediaError, mediaStatus) ;
}
else {
var media = new Media(getWebRoot() + "/audio/bark.wav", mediaSuccess, mediaError, mediaStatus) ;
}
console.log("media.src = ", media.src) ;
media.play() ;
Not quite sure if this is what you are looking for...
You will need to use the Cordova build in the Intel XDK, here is information on building with Cordova:
https://software.intel.com/en-us/html5/articles/using-the-cordova-for-android-ios-etc-build-option
And a DirectoryReader example:
function success(entries) {
var i;
for (i=0; i<entries.length; i++) {
console.log(entries[i].name);
}
}
function fail(error) {
alert("Failed to list directory contents: " + error.code);
}
// Get a directory reader
var directoryReader = dirEntry.createReader();
// Get a list of all the entries in the directory
directoryReader.readEntries(success,fail);
I am new to nodejs. Can node resolve ~ (unix home directory) example ~foo, ~bar
to /home/foo, /home/bar
> path.normalize('~mvaidya')
'~mvaidya'
> path.resolve('~mvaidya')
'/home/mvaidya/~mvaidya'
>
This response is wrong; I am hoping that ~mvaidya must resolve to /home/mvaidya
As QZ Support noted, you can use process.env.HOME on OSX/Linux. Here's a simple function with no dependencies.
const path = require('path');
function resolveHome(filepath) {
if (filepath[0] === '~') {
return path.join(process.env.HOME, filepath.slice(1));
}
return filepath;
}
The reason this is not in Node is because ~ expansion is a bash (or shell) specific thing. It is unclear how to escape it properly. See this comment for details.
There are various libraries offering this, most just a few lines of code...
https://npm.im/untildify ; doesn't do much more than os.homedir(), see index.js#L10
https://npm.im/expand-tilde ; basically uses os-homedir to achieve the same, see index.js#L12
https://npm.im/tilde-expansion ; this uses etc-passwd so doesn't seem very cross platform, see index.js#L21
So you probably want to do this yourself.
This NodeJS library supports this feature via an async callback. It uses the etc-passswd lib to perform the expansion so is probably not portable to Windows or other non Unix/Linux platforms.
https://www.npmjs.org/package/tilde-expansion
https://github.com/bahamas10/node-tilde-expansion
If you only want to expand the home page for the current user then this lighter weight API may be all you need. It's also synchronous so simpler to use and works on most platforms.
https://www.npmjs.org/package/expand-home-dir
Examples:
expandHomeDir = require('expand-home-dir')
expandHomeDir('~')
// => /Users/azer
expandHomeDir('~/foo/bar/qux.corge')
// => /Users/azer/foo/bar/qux.corge
Another related lib is home-dir that returns a user's home directory on any platform:
https://www.npmjs.org/package/home-dir
An example:
const os = require("os");
"~/Dropbox/sample/music".replace("~", os.homedir)
This is a combination of some of the previous answers with a little more safety added in.
/**
* Resolves paths that start with a tilde to the user's home directory.
*
* #param {string} filePath '~/GitHub/Repo/file.png'
* #return {string} '/home/bob/GitHub/Repo/file.png'
*/
function resolveTilde (filePath) {
const os = require('os');
if (!filePath || typeof(filePath) !== 'string') {
return '';
}
// '~/folder/path' or '~' not '~alias/folder/path'
if (filePath.startsWith('~/') || filePath === '~') {
return filePath.replace('~', os.homedir());
}
return filePath;
}
Uses more modern os.homedir() instead of process.env.HOME.
Uses a simple helper function that can be called from anywhere.
Has basic type checking. You may want to default to returning os.homedir() if a non-string is passed in instead of returning empty string.
Verifies that path starts with ~/ or is just ~, to not replace other aliases like ~stuff/.
Uses a simple "replace first instance" approach, instead of less intuitive .slice(1).
I just needed it today and the only less-evasive command was the one from the os.
$ node
> os.homedir()
'/Users/mdesales'
I'm not sure if your syntax is correct since ~ is already a result for the home dir of the current user
Today I used https://github.com/sindresorhus/untildify
I run on OSX, worked well.