Skip to content

Instantly share code, notes, and snippets.

@mmarcon
Last active June 25, 2024 11:03
Show Gist options
  • Save mmarcon/ee6440fc34df05923e76b9b3587b593a to your computer and use it in GitHub Desktop.
Save mmarcon/ee6440fc34df05923e76b9b3587b593a to your computer and use it in GitHub Desktop.
Load (or copy-paste) this into your ~/.mongoshrc.js
// Use nerd fonts for the terminal to get the pretty icons
// https://github.com/ryanoasis/nerd-fonts
(() => {
// Support for colors
// NPM install chalk where mongosh can find it
// (or set NODE_PATH to where the global modules are installed)
const chalk = require('chalk');
_prompt = () => {
try {
db.getMongo();
} catch {
return chalk.blue('\uf701') + ' → ';
}
const dbName = db.getName();
const serverBuildInfo = db.serverBuildInfo();
const readPref = db.getMongo().getReadPrefMode();
const atlas = /mongodb.net/.test(db.getMongo()._uri);
const rpTagSet = db.getMongo().getReadPrefTagSet();
const analyticsNode = rpTagSet ? rpTagSet.findIndex(({
nodeType
}) => nodeType === 'ANALYTICS') >= 0 : false;
const localhost = /localhost|127\.0\.0\.1/.test(db.getMongo()._uri);
//const isSecondary = !!db.hello().secondary;
let hasPrimary;
try {
hasPrimary = !!rs.status().members.find(({state}) => state === 1);
} catch {
// Fails when not started as replica set
hasPrimary = true;
}
const leaf = '\ue7a4';
const laptop = '\uf109';
const ship = '\uf2cd';
let serverInfo = '';
if (serverBuildInfo.dataLake) {
serverInfo += chalk.green(ship) + ' ';
} else if (serverBuildInfo.modules.includes('enterprise')) {
serverInfo += `${atlas ? chalk.green('\uf0c2'): 'Enterprise'} `;
} else if (localhost) {
serverInfo += chalk.blue(laptop) + ' ';
}
return `${serverInfo}${hasPrimary ? '₁' : '₂'} \uf831 ${readPref} ${analyticsNode ? chalk.cyan('\uf080 ') : ''} \ue706 ${dbName} → `;
};
boringPrompt = () => { prompt = undefined };
prettyPrompt = () => { prompt = _prompt };
prettyPrompt();
})();
@damanis
Copy link

damanis commented Sep 13, 2022

@mmarcon
Very good example.
But how it works? Most of shell-api is asynchronous, for example, rs.status(). But _prompt() is not async and it calls rs.status() without await.

@mmarcon
Copy link
Author

mmarcon commented Sep 13, 2022

@damanis the MongoDB Shell actually rewrites shell API calls so that you can use them in a way that makes them look synchronous.

So when you call rs.status() inside _prompt or even just from the REPL when you use the shell interactively, it gets rewritten into something else. My colleague Anna did a talk about how it works, if you are interested in the internals: https://www.youtube.com/watch?v=uHw21GaCsFE. From minute ~9 on is the async rewriting part.

@damanis
Copy link

damanis commented Sep 13, 2022

@mmarcon
Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment