An upcoming feature of the Windows Terminal preview is that it has full emoji support:
Compared to:
In Node.js, how do I detect if I'm running in a terminal wrapped by the Windows Terminal instead of its "naked" variation? Is there an environmental variable I can extract or a synchronous test I can do?
You can check for the WT_SESSION environmental variable which is set to a v4 UUID: https://github.com/microsoft/terminal/issues/1040
If you're looking for a quick and dirty way to check, this should work:
!!process.env.WT_SESSION
There's also a more elaborate method you can use, taking advantage of is-uuid, is-wsl and process.platform:
import isUUID from 'is-uuid';
import isWsl from 'is-wsl';
const isWindowsTerminal = (process.platform === "win32" || isWsl) && isUUID.v4(process.env.WT_SESSION);
I prefer this approach from https://github.com/microsoft/terminal/issues/6269 (in PowerShell):
function IsWindowsTerminal ($childProcess) {
if (!$childProcess) {
return $false
} elseif ($childProcess.ProcessName -eq 'WindowsTerminal') {
return $true
} else {
return IsWindowsTerminal -childProcess $childProcess.Parent
}
}
which I then use in my profile to turn on e.g. oh-my-posh.
$IsWindowsTerminal = IsWindowsTerminal -childProcess (Get-Process -Id $PID)
if($IsWindowsTerminal) {
oh-my-posh --init --shell pwsh --config $HOME\Documents\mytheme.omp.json | Invoke-Expression
}
Related
I'm getting a webpack error when trying to require an image file I know exists in my v-img component here:
imgSrcFancy (imgsize) {
try {
// if in production, unless no imgsize is specified, use .imgs instead of fullsize
// if (imgsize === '' || process.env.NODE_ENV === 'development') {
if (imgsize === '') { // temporarily force always use .imgs for testing only
console.log('fallback on full-rez load')
return require(`~/content${this.dirp}/${this.src}`)
} else { // production and imgsize not empty
const path = require('path')
const ext = path.extname(this.src)
const name = path.basename(this.src, ext)
const loadstring = `~/content${this.dirp}/.imgs/${name}_${imgsize}${ext}`
console.log('fancy load from ' + loadstring)
return require(`~/content${this.dirp}/.imgs/${name}_${imgsize}${ext}`)
}
} catch (error) {
console.log('error with finding image for: ' + this.src)
console.log(error)
return null
}
Background:
I have a blog that uses nuxt-content.
The project is organized so that images are grouped along with post .md files in a folder for each post inside /content/posts. My starting v-img component works fine, requiring these images no problem. (note this last link is to the master branch that is deployed, while the earlier is to a feature branch)
My deployed site is very slow to load, so I wrote a python program to generate smaller versions of the images, all stored in a .imgs folder within each slug folder as follows:
- content/
- posts/
- post-slug-one/
- index.md
- my_image1.jpg
...
- .imgs/
- my_image1_large.jpg
- my_image1_tn.jpg
...
The python program is invoked as part of my netlify build command, e.g. python3 ./gen_tn.py && nuxt build && nuxt generate. This works fine.
To avoid clogging up disk space locally, I'm using NODE_ENV to just use full sizes when in development; this works fine too, but I've temporarily disabled this to test.
I generated thumbnails locally for testing, but the problem comes when I hit the line:
return require(`~/content${this.dirp}/.imgs/${name}_${imgsize}${ext}`)
I get an exception:
Error: Cannot find module './content/posts/sept-2021-photos-things/.imgs/pos_DSC01274_large.jpg'
at webpackContextResolve (content.*$:752)
at webpackContext (content.*$:747)
at VueComponent.imgSrcFancy (VImg.vue:59)
at Proxy.render (VImg.vue?ad21:7)
at VueComponent.Vue._render (vue.runtime.esm.js:3548)
at VueComponent.updateComponent (vue.runtime.esm.js:4055)
at Watcher.get (vue.runtime.esm.js:4479)
at Watcher.run (vue.runtime.esm.js:4554)
at flushSchedulerQueue (vue.runtime.esm.js:4310)
at Array.<anonymous> (vue.runtime.esm.js:1980)
But this file exists:
MBPro:bst-blog$ ls content/posts/sept-2021-photos-things/.imgs/pos_DSC01274_large.jpg
content/posts/sept-2021-photos-things/.imgs/pos_DSC01274_large.jpg
I've tried even hard-coding the image size, but that doesn't work either:
return require(\`~/content${this.dirp}/.imgs/${name}_large${ext}`)
What am I doing wrong? How do I fix this? Any guidance appreciated!
Ok.
Turns out the problem was with the name I was using for the thumbnails - webpack did not like .imgs. Changing it to imgs (or gen_tn_imgs to make adding a specific rule to .gitignore easy, in my case).
My final block looks like this:
methods: {
imgSrcFancy (imgsize) {
try {
// if in production, unless no imgsize is specified, use .imgs instead of fullsize
if (imgsize === '' || imgsize === 'orig' || process.env.NODE_ENV === 'development') {
// if (imgsize === '') { // temporarily force always use .imgs for testing only
console.log('fallback on full-rez load')
return require(`~/content${this.dirp}/${this.src}`)
} else { // production and imgsize not empty
const path = require('path')
const ext = path.extname(this.src)
const name = path.basename(this.src, ext)
const loadstring = `~/content${this.dirp}/gen_tn_imgs/${name}_${imgsize}.png`
console.log('fancy load from ' + loadstring)
return require(`~/content${this.dirp}/gen_tn_imgs/${name}_${imgsize}.png`) // working
}
} catch (error) {
console.log('error with finding image for: ' + this.src)
console.log(error)
return null
}
}
}
and it's called like so:
<a :href="imgSrcFancy('orig')">
<img :src="imgSrcFancy('large')" :alt="alt">
</a>
So I'm fairly new to react native and mobile development in general, this error keeps cropping up, the test file in question that is failing is the standard generated file provided by Facebook with a react native build.
Here's the test:
- (void)testRendersWelcomeScreen
{
UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
BOOL foundElement = NO;
__block NSString *redboxError = nil;
RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
if (level >= RCTLogLevelError) {
redboxError = message;
}
});
while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
return YES;
}
return NO;
}];
}
RCTSetLogFunction(RCTDefaultLogFunction);
XCTAssertNil(redboxError, #"RedBox error: %#", redboxError);
XCTAssertTrue(foundElement, #"Couldn't find element with text '%#' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
}
And here is the error:
redacted/ios/ProjectTests/Project.m:40:29: error: bad receiver type 'int'
UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
The app seems to actually compile and work in iOS simulator so I'm not really sure what the problem is, the obvious answer could be just remove the test. However I'm interested in a possible cause, cheers.
Try reinstalling dependencies:
$ rm -rf node_modules
$ npm i
I had the same issue and it worked for me, as I had downgraded some libs in a different branch before (check: https://github.com/facebook/react-native/issues/13901).
I want to create a nodejs file, that simple runs/wraps an executable binary file with all inputs and outputs.
For now at least on windows.
Why:
wanted to install an executable tool over npm install -g, to have it in console, without PATH changes. (npm global packages are included in PATH)
i used such solution:
const path = require("path");
const spawnSync = require('child_process').spawnSync;
const pathToMyExe = path.join(__dirname, 'bin', 'myfile.exe'); //just path to exe
const input = process.argv.slice(2); //minus "node" and "this js" arguments
spawnSync(pathToMyExe, input, {stdio: 'inherit'});
but for ".exe to PATH" problem, there is a simplier way (if you want windows only).
just set bin property in package.json to pathToExe.
https://docs.npmjs.com/files/package.json#bin
You can use the bin-wrapper npm package.
EDIT:
There's a better alternative called bin-manager.
Installation:
$ npm install --save bin-manager
Usage
const bmanager = require('bin-manager');
const base = 'https://github.com/imagemin/gifsicle-bin/raw/master/vendor';
const bin = bmanager('bin', 'gifsicle')
.src(base + '/macos/gifsicle', 'darwin')
.src(base + '/linux/x64/gifsicle', 'linux', 'x64')
.src(base + '/win/x64/gifsicle.exe', 'win32', 'x64')
.use(process.platform === 'win32' ? 'gifsicle.exe' : 'gifsicle');
bin.run(['--version'], (err, out) => {
if (err) {
console.log(error);
return;
}
console.log(out.stdout);
});
When developing an NPM package, it's common to use:
npm link
It allows to modify <myPackage> under development without the need of publishing and unpublishing all the time! The developer can make any changes locally and see it immediately.
It's installed into a project by using:
npm link <myPackage>
It's great, but there's a problem if the <myPackage> have a require(path).
It'll use the real location of <myPackage> as __dirname, for example, instead of the expected location of the symlink, that should be local to the project, like a regular node_module.
The solution I found so far, for my particular case works fine:
module.exports = {
loadImage: function (filename) {
var img
if (typeof window !== 'undefined' && ({}).toString.call(window) === '[object Window]') {
try {
img = require('../../src/images/' + filename)
} catch (e) {
// Development only
img = require('./template/src/images/' + filename)
}
} else {
img = '/assets/images/' + filename
}
return img
}
}
But as you can imagine, this cause Warning messages in the Browser.
While I'm aware of the reason why of this problem, ideally, I'd like to suppress the error.
I believe it won't be a very popular question, in that case, here's a nice option that won't cause any warning messages and that is quite specific to the NPM Package development stage.
The following modules.exports expose some code snippets you'd like to import into your application. You'll find the loadImage method, with a fallback for the require(path):
module.exports = {
loadImage: function (filename) {
if (typeof window !== 'undefined' && ({}).toString.call(window) === '[object Window]') {
return (process.env.NPM_PACKAGE_DEV && require('./template/src/images/' + filename) ||
require('./template/src/images/' + filename))
} else {
return '/assets/images/' + filename
}
},
isBrowser: function () {
return (typeof window !== 'undefined' && ({}).toString.call(window) === '[object Window]')
}
}
What's good about this, is that you can set the NPM_PACKAGE_DEV by running the command, than initialize the node server (osx terminal syntax):
export NPM_PACKAGE_DEV=1 && node server.js
If the NPM_PACKAGE_DEV is omitted, the require() fallback to the end use path, that is relative to the project node_modules directory.
Hope this helps someone else in the future!
I want to give the user any option he want to edit a file, how can I open a file with the default program of the specific file type? I need it to work with Windows and Linux but Mac option would be great too.
as PSkocik said, first detect the platform and get the command line :
function getCommandLine() {
switch (process.platform) {
case 'darwin' : return 'open';
case 'win32' : return 'start';
case 'win64' : return 'start';
default : return 'xdg-open';
}
}
second , execute the command line followed by the path
var exec = require('child_process').exec;
exec(getCommandLine() + ' ' + filePath);
You can use the open module:
npm install --save open
and then call it in your Node.js file:
const open = require('open');
open('my-file.txt');
This module already contains the logic to detect the operating system and it runs the default program that is associated to this file type by your system.
For file on a disk:
var nwGui = require('nw.gui');
nwGui.Shell.openItem("/path/to/my/file");
For remote files (eg web page):
var nwGui = require('nw.gui');
nwGui.Shell.openExternal("http://google.com/");
Detect the platform and use:
'start' on Windows
'open' on Macs
'xdg-open' on Linux
I am not sure if start used to work as is on earlier windows versions, however on windows 10 it doesn't work as indicated in the answer. It's first argument is the title of the window.
Furthermore the behavior between windows and linux is different. Windows "start" will exec and exit, under linux, xdg-open will wait.
This was the function that eventually worked for me on both platforms in a similar manner:
function getCommandLine() {
switch(process.platform) {
case 'darwin' :
return 'open';
default:
return 'xdg-open';
}
}
function openFileWithDefaultApp(file) {
/^win/.test(process.platform) ?
require("child_process").exec('start "" "' + file + '"') :
require("child_process").spawn(getCommandLine(), [file],
{detached: true, stdio: 'ignore'}).unref();
}
If you aim to script some kind of prompt with a default editor or simply chain files opening, you will have to wait until the program ends or fail.
Inspired from PSkocik and Khalid answers.
const {exec} = require('child_process');
let openFile=function(filePath,mute){
let command=(function() {
switch (process.platform) {
case 'darwin' : return 'open '+filePath+' && lsof -p $! +r 1 &>/dev/null';
case 'win32' :
case 'win64' : return 'start /wait '+filePath;
default : return 'xdg-open '+filePath+' && tail --pid=$! -f /dev/null';
}
})();
if(!mute)console.log(command);
let child=exec(command);
if(!mute)child.stdout.pipe(process.stdout);
return new function(){
this.on=function(type,callback){
if(type==='data')child.stdout.on('data',callback);
else if(type==='error')child.stderr.on('data',callback);
else child.on('exit',callback);
return this;
};
this.toPromise=function(){
return new Promise((then,fail)=>{
let out=[];
this.on('data',d=>out.push(d))
.on('error',err=>fail(err))
.on('exit',()=>then(out));
});
};
}();
};
use :
openFile('path/to/some_text.txt')
.on('data',data=>{
console.log('output :'+data);
})
.on('error',err=>{
console.log('error :'+err);
})
.on('exit',()=>{
console.log('done');
});
or :
openFile('path/to/some_text.txt').toPromise()
.then(output=>{
console.log('done output :'+output.join('\n'));
}).catch(err=>{
console.log('error :'+err);
});
PS : Let me know if it waits for other sytems than winXX ( Inspired from Rauno Palosaari post but not tested yet ).