Welcome! Nacre is an open source object-oriented shell leveraging the full potential of JavaScript for those who prefer to work with objects rather than text.
This guide will help you to understand the fundamental principles of Nacre.
Nacre relies on NodeJS version 18, so you must have it installed on your system. Follow their installation instructions. Once this is done, install it using:
$ npm install --global nacre
To launch a nacre shell, simply run:
$ nacre
A prompt will invite you to run commands interactively.
List the content of the working directory by running ls()
:
Welcome to Nacre version Beta. Find help at https://nacre.sh.> ls()['.git','.gitignore','.idea','LICENSE','README.md','docs','gatsby-theme-doctornpm','node_modules','package-lock.json','package.json']
You may notice that ls()
command, unlike ls
on more traditional shells, requires parentheses to display items in the current working directory. The reason is simple, Nacre is empowered by NodeJS, which means everything you write must follow the JavaScript syntax.
Without parentheses, ls
returns a value of type function:
> ls[Function: ls] {help: 'List directory',recursive: [Function (anonymous)] { help: 'List directory recursively' }}
This is particulary handy to understand to inspect the command and understand what you can do with it. In this case, it tells us that ls
has a recursive()
function.
> ls.recursive()['components','components/index-component.mdx','components/index.mdx','components/variant-select.mdx','configuration','configuration/header-links.mdx','configuration/index.mdx','configuration/navigation.mdx','configuration/plugin.mdx','getting-started.mdx','index.mdx']
Nacre provides a bunch of builtins such as ls()
, cd()
, stat()
, pwd()
, etc. with names similar to those of traditional shells, so you can quickly find your marks. You may know that stat()
returns some information about a file, let's try it:
> stat('index.mdx'){name: 'index.mdx',type: 'file',size: 844,createdAt: 2022-02-10T10:20:52.844Z,modifiedAt: 2022-02-12T09:48:15.158Z,owner: 'arnauddebec',group: 'staff'}
If you are not familiar with map()
, this is a JavaScript method which creates a new array populated with the results of calling a provided function on every element in the calling array. Let's take an example:
const myArray = [1, 2, 3, 4];// for each element of the array, we multiply the element by 2const result = myArray.map((element) => { return element * 2 });// expected result: Array [1, 4, 6, 8]console.log(result);
You know that ls()
list the items of directory and that stat()
displays information about an item. Let's combine them using map()
:
// for each element of the array, we apply the stat function on it> ls.map((element) => { return stat(element) })// or simply> ls.map(stat)[{name: 'components',type: 'directory',size: 160,createdAt: 2022-02-10T10:20:52.844Z,modifiedAt: 2022-02-10T10:20:52.844Z,owner: 'arnauddebec',group: 'staff'},{name: 'index-component.mdx',type: 'file',size: 383,createdAt: 2022-02-10T10:20:52.844Z,modifiedAt: 2022-02-10T10:20:52.844Z,owner: 'arnauddebec',group: 'staff'},{name: 'index.mdx',type: 'file',size: 154,createdAt: 2022-02-10T10:20:52.844Z,modifiedAt: 2022-02-10T10:20:52.844Z,owner: 'arnauddebec',group: 'staff'},...}
This a typical example on how you can leverage JavaScript's language and functions. Here is a last example, can you guess what it does?
> ls.recursive().filter((e) => e.endsWith('.js')).map(stat).filter(s => s.size > 100).map(e => e.name)
Such long line becomes hard to read, you may prefer to write your code in a proper Integrated Development Environment (IDE) for nicer indentation and autocompletion. The next section will guide you on how to execute Nacre scripts.
You can save your script in file like you would do for a normal JavaScript file. In your preferred IDE, create print-files.js
.
#!/usr/bin/env nacre'use strict';/*** This is a file which demonstrates that nacre can also run a script file like NodeJS!*/// get the list of all items in the current directory and sub directoriesconst everyone = ls.recursive();// filter all items to get only the filesconst onlyFiles = everyone.filter(item => {const info = stat(item);return info.type === 'file';});// will print the list of filesconsole.log('list of all files:', onlyFiles);// filter all files to get only those that ends with .jsconst onlyJs = onlyFiles.filter((f) => f.endsWith('.js'));// will print the list of js filesconsole.log('list of all JavaScript files:',onlyJs);
To run it (from bash):
$ nacre print-files.js
Or directly (from bash):
$ chmod +x ./print-file.js # adds permission to execute$ ./print-file.js
In the interactive mode, a module is automatically loaded when you type its name. Note that the module must be installed at a global level or in the current working directory.
Usage local auto-require:
// install chalk module in the current working directorynpm.install('chalk')chalk.blue('hello')
Usage global auto-require:
// install lodash module at a global level$('npm install --global lodash')lodash.random();
Use require
to explicitly import a command.
> const myScript = require(path.resolve('./myScript.js'))
Those following shortcuts can save you some precious time. The exhaustive list of shortcuts can be found in the documentation.
Shortcut | Description |
---|---|
<ctrl> + C | Quit Nacre / Remove the current line |
<ctrl> + A | Move the cursor to the begining of the line |
<ctrl> + E | Move the cursor to the end of the line |
<ctrl> + L | Clear the screen of the terminal |
<ctrl> + R | Search backward in the history |