123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- var common = require('./common');
- var _cd = require('./cd');
- var path = require('path');
-
- // Pushd/popd/dirs internals
- var _dirStack = [];
-
- function _isStackIndex(index) {
- return (/^[\-+]\d+$/).test(index);
- }
-
- function _parseStackIndex(index) {
- if (_isStackIndex(index)) {
- if (Math.abs(index) < _dirStack.length + 1) { // +1 for pwd
- return (/^-/).test(index) ? Number(index) - 1 : Number(index);
- } else {
- common.error(index + ': directory stack index out of range');
- }
- } else {
- common.error(index + ': invalid number');
- }
- }
-
- function _actualDirStack() {
- return [process.cwd()].concat(_dirStack);
- }
-
- //@
- //@ ### pushd([options,] [dir | '-N' | '+N'])
- //@
- //@ Available options:
- //@
- //@ + `-n`: Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated.
- //@
- //@ Arguments:
- //@
- //@ + `dir`: Makes the current working directory be the top of the stack, and then executes the equivalent of `cd dir`.
- //@ + `+N`: Brings the Nth directory (counting from the left of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.
- //@ + `-N`: Brings the Nth directory (counting from the right of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.
- //@
- //@ Examples:
- //@
- //@ ```javascript
- //@ // process.cwd() === '/usr'
- //@ pushd('/etc'); // Returns /etc /usr
- //@ pushd('+1'); // Returns /usr /etc
- //@ ```
- //@
- //@ Save the current directory on the top of the directory stack and then cd to `dir`. With no arguments, pushd exchanges the top two directories. Returns an array of paths in the stack.
- function _pushd(options, dir) {
- if (_isStackIndex(options)) {
- dir = options;
- options = '';
- }
-
- options = common.parseOptions(options, {
- 'n' : 'no-cd'
- });
-
- var dirs = _actualDirStack();
-
- if (dir === '+0') {
- return dirs; // +0 is a noop
- } else if (!dir) {
- if (dirs.length > 1) {
- dirs = dirs.splice(1, 1).concat(dirs);
- } else {
- return common.error('no other directory');
- }
- } else if (_isStackIndex(dir)) {
- var n = _parseStackIndex(dir);
- dirs = dirs.slice(n).concat(dirs.slice(0, n));
- } else {
- if (options['no-cd']) {
- dirs.splice(1, 0, dir);
- } else {
- dirs.unshift(dir);
- }
- }
-
- if (options['no-cd']) {
- dirs = dirs.slice(1);
- } else {
- dir = path.resolve(dirs.shift());
- _cd('', dir);
- }
-
- _dirStack = dirs;
- return _dirs('');
- }
- exports.pushd = _pushd;
-
- //@
- //@ ### popd([options,] ['-N' | '+N'])
- //@
- //@ Available options:
- //@
- //@ + `-n`: Suppresses the normal change of directory when removing directories from the stack, so that only the stack is manipulated.
- //@
- //@ Arguments:
- //@
- //@ + `+N`: Removes the Nth directory (counting from the left of the list printed by dirs), starting with zero.
- //@ + `-N`: Removes the Nth directory (counting from the right of the list printed by dirs), starting with zero.
- //@
- //@ Examples:
- //@
- //@ ```javascript
- //@ echo(process.cwd()); // '/usr'
- //@ pushd('/etc'); // '/etc /usr'
- //@ echo(process.cwd()); // '/etc'
- //@ popd(); // '/usr'
- //@ echo(process.cwd()); // '/usr'
- //@ ```
- //@
- //@ When no arguments are given, popd removes the top directory from the stack and performs a cd to the new top directory. The elements are numbered from 0 starting at the first directory listed with dirs; i.e., popd is equivalent to popd +0. Returns an array of paths in the stack.
- function _popd(options, index) {
- if (_isStackIndex(options)) {
- index = options;
- options = '';
- }
-
- options = common.parseOptions(options, {
- 'n' : 'no-cd'
- });
-
- if (!_dirStack.length) {
- return common.error('directory stack empty');
- }
-
- index = _parseStackIndex(index || '+0');
-
- if (options['no-cd'] || index > 0 || _dirStack.length + index === 0) {
- index = index > 0 ? index - 1 : index;
- _dirStack.splice(index, 1);
- } else {
- var dir = path.resolve(_dirStack.shift());
- _cd('', dir);
- }
-
- return _dirs('');
- }
- exports.popd = _popd;
-
- //@
- //@ ### dirs([options | '+N' | '-N'])
- //@
- //@ Available options:
- //@
- //@ + `-c`: Clears the directory stack by deleting all of the elements.
- //@
- //@ Arguments:
- //@
- //@ + `+N`: Displays the Nth directory (counting from the left of the list printed by dirs when invoked without options), starting with zero.
- //@ + `-N`: Displays the Nth directory (counting from the right of the list printed by dirs when invoked without options), starting with zero.
- //@
- //@ Display the list of currently remembered directories. Returns an array of paths in the stack, or a single path if +N or -N was specified.
- //@
- //@ See also: pushd, popd
- function _dirs(options, index) {
- if (_isStackIndex(options)) {
- index = options;
- options = '';
- }
-
- options = common.parseOptions(options, {
- 'c' : 'clear'
- });
-
- if (options['clear']) {
- _dirStack = [];
- return _dirStack;
- }
-
- var stack = _actualDirStack();
-
- if (index) {
- index = _parseStackIndex(index);
-
- if (index < 0) {
- index = stack.length + index;
- }
-
- common.log(stack[index]);
- return stack[index];
- }
-
- common.log(stack.join(' '));
-
- return stack;
- }
- exports.dirs = _dirs;
|