npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

vue-command

v35.2.1

Published

A fully working, most feature-rich Vue.js terminal emulator

Downloads

4,327

Readme

vue-command

A fully working, most feature-rich Vue.js terminal emulator. See the demo and check the demo source code. Now with Vue.js 3 support!

Features

  • Simple, yet extensible API
  • Supports asynchronous commands
  • Supports fullscreen mode
  • Customize the terminal with slots
  • Provide your own parser (falls back to simple one)
  • Multiline support (with \)
  • Autocompletion resolver (with )
  • Browse history (with /)
  • Search history (with Ctrl + r)
  • Provide your own event resolver to support additional keyboard events

Installation

$ npm install vue-command --save

Usage

Let's start with a dead simple example. We want to send "Hello world" to Stdout when entering hello-world.

<template>
  <vue-command :commands="commands" />
</template>

<script>
import VueCommand, { createStdout } from "vue-command";
import "vue-command/dist/vue-command.css";

export default {
  components: {
    VueCommand,
  },

  data: () => ({
    commands: {
      "hello-world": () => createStdout("Hello world"),
    },
  }),
};
</script>

Now a more complex one. Let's assume we want to build the nano editor available in many shells.

We inject terminal to make sure the editor is only visible when the terminal is in fullscreen mode and also a function called exit to tell the terminal that the command has been finished when the user enters Ctrl + x. Furthermore, we use setFullscreen to switch the terminal into fullscreen mode.

<template>
  <div v-show="terminal.isFullscreen">
    <textarea ref="nano" @keyup.ctrl.x.exact="exit">
This is a nano text editor emulator! Press Ctrl + x to leave.</textarea
    >
  </div>
</template>

<script>
export default {
  inject: ["exit", "setFullscreen", "terminal"],

  created() {
    this.setFullscreen(true);
  },

  mounted() {
    this.$refs.nano.focus();
  },
};
</script>

<style scoped>
div,
textarea {
  height: 100%;
}
</style>

Now the command has to return the component.

<template>
  <vue-command :commands="commands" />
</template>

<script>
import VueCommand from "vue-command";
import "vue-command/dist/vue-command.css";
import NanoEditor from "@/components/NanoEditor.vue";

export default {
  components: {
    VueCommand,
  },

  data: () => ({
    commands: {
      nano: () => NanoEditor,
    },
  }),
};
</script>

Properties

Some properties can be mutated by the terminal. Therefore, adding the v-model directive is required.

| Property | Description | Type | Default value | Required | Two-way binding | | -------------------- | ------------------------------------------- | ---------- | ------------------------- | -------- | --------------- | | commands | See Commands | Object | {} | No | No | | cursor-position | Cursor position | Number | 0 | No | Yes | | dispatched-queries | Non-empty dispatched queries | Set | new Set() | No | Yes | | event-resolver | See Event resolver | Function | newDefaultEventResolver | No | No | | font | Terminal font | String | '' | No | No | | help-text | Command help | String | '' | No | Yes | | help-timeout | Command help timeout | Number | 3000 | No | No | | hide-bar | Hides the bar | Boolean | false | No | No | | hide-buttons | Hides the buttons | Boolean | false | No | No | | hide-prompt | Hides the prompt | Boolean | false | No | No | | hide-title | Hides the title | Boolean | false | No | No | | history | Terminal history | Array | [] | No | Yes | | history-position | Points to the latest dispatched query entry | Number | 0 | No | Yes | | interpreter | See Interpreter | Function | null | No | No | | invert | Inverts the terminals colors | Boolean | false | No | No | | is-fullscreen | Terminal fullscreen mode | Boolean | false | No | Yes | | options-resolver | See Options resolver | Function | null | No | No | | parser | Query parser | Function | defaultParser | No | No | | prompt | Terminal prompt | String | ~$ | No | No | | show-help | Show query help | Boolean | false | No | No | | title | Terminal title | String | ~$ | No | No | | query | Terminal query | String | '' | No | Yes |

Commands

commands must be an object containing key-value pairs where key is the command and the value is a function that will be called with the parsed arguments. The function can return a Promise and must return or resolve a Vue.js component. To return strings or a new query, use one of the convenient helper methods.

Any component that is not the query component can inject the context. The context includes the parsed and raw query as fields.

Event resolver

It's possible to provide an array property eventResolver which is called when the terminal is mounted. Each event resolver will be called with the terminals references and exposed values.

The libraries defaultHistoryEventResolver makes usage of that and allows to cycle through commands with /.

Options resolver

The terminal provides a built-in autocompletion for the given commands. As soon as the query has been autocompleted by the terminal, it's calling the options resolver provided as property. The resolver is called with the program, parsed query and a setter to update the query.

Interpreter

An interpreter allows to execute arbitrary code after the query has been dispatched and to not rely on missing functionality which includes pipes, streams or running multiple commands in parallel.

The interpreter is a property function that is called with the unparsed query right after the query component calls dispatch and terminates it at the same time. After the call, you must use the properties and exposed functions to reach the desired behaviour.

Slots

Bar

You can replace the whole terminal bar with the named slot bar. This will replace the whole element, including the action buttons and its assigned CSS classes. Example:

<vue-command>
  <template #bar>
    ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
  </template>
</vue-command>

Buttons

Inside the bar, you can customize the buttons. If you use this slot, hideButtons property has no effect. Example:

<vue-command>
  <template #buttons>
    &times; &#95; &square;
  </template>
</vue-command>

Title

Inside the bar, you can customize the title. If you use this slot, hideTitle and title property have no effect. Example:

<vue-command>
  <template #title>
    bash - 720x350
  </template>
</vue-command>

Prompt

You can overwrite the prompt with the prompt slot. If you use this slot, hidePrompt and prompt property have no effect. Example:

<vue-command>
  <template #prompt>
    ~$
  </template>
</vue-command>

Library

Library provides helper methods to render terminal related content.

| Function | Parameters | Description | | ----------------------------- | ------------------------------------------------------------------ | ------------------------------------- | | createCommandNotFound | command, text = 'command not found', name = 'VueCommandNotFound' | Creates a command not found component | | createStderr | formatterOrText, name = 'VueCommandStderr' | Creates a "stderr" component | | createStdout | formatterOrText, name = 'VueCommandStdout' | Creates a "stdout" component | | createQuery | | Creates a query component | | defaultHistoryEventResolver | refs, eventProvider | The default history event resolver | | defaultParser | query | The default parser | | defaultSignalEventResolver | refs, eventProvider | The default signal event resolver | | jsonFormatter | value | See Formatters | | listFormatter | ...lis | See Formatters | | newDefaultEventResolver | | Returns a new default event resolver | | newDefaultHistory | | Returns a new default history | | tableFormatter | rows | See Formatters | | textFormatter | text, innerHtml = false | See Formatters |

Helper methods can be imported by name:

import { createStdout, createQuery } from "vue-command";

Formatters

The first argument of createStdout can be either a primitive (Boolean, Number or String) or a formatter. A formatter formats the content as a list or table or something else.

| Function | Parameters | | ---------------- | ------------------------- | | jsonFormatter | value | | listFormatter | ...lis | | tableFormatter | rows | | textFormatter | text, innerHtml = false |

Formatters can be imported by name:

import { listFormatter } from "vue-command";

Provided

| Identifier | Type | Parameters | | -------------------- | ---------- | -------------------------------- | | addDispatchedQuery | Function | dispatchedQuery | | appendToHistory | Function | ...components | | dispatch | Function | query | | decrementHistory | Function | | | exit | Function | | | context | Object | | | helpText | String | | | helpTimeout | Number | | | hidePrompt | Boolean | | | incrementHistory | Function | | | optionsResolver | Function | program, parsedQuery, setQuery | | parser | Function | query | | programs | Array | | | sendSignal | Function | signal | | setCursorPosition | Function | cursorPosition | | setFullscreen | Function | isFullscreen | | setHistoryPosition | Function | historyPosition | | setQuery | Function | query | | showHelp | Boolean | | | signals | Object | | | slots | Object | | | terminal | Object | |

Provider can be injected into your component by name:

inject: ["exit", "terminal"],

Exposed

| Identifier | Type | Parameters | | -------------------- | ---------- | ----------------- | | addDispatchedQuery | Function | dispatchedQuery | | appendToHistory | Function | ...components | | decrementHistory | Function | | | dispatch | Function | query | | exit | Function | | | incrementHistory | Function | | | programs | Array | | | sendSignal | Function | signal | | setCursorPosition | Function | cursorPosition | | setFullscreen | Function | isFullscreen | | setHistoryPosition | Function | historyPosition | | setQuery | Function | query | | signals | Object | | | terminal | Object | |

Events

| Name | Description | | ------------------- | ---------------------------------- | | closeClicked | Emitted on button close click | | minimizeClicked | Emitted on button minimize click | | fullscreenClicked | Emitted on button fullscreen click |

Signals

You can send and receive signals like SIGINT, SIGTERM or SIGKILL. SIGINT is the only implemented signal for now. When the user presses Ctrl + c, you can listen to this event by providing a signal name and a callback:

const signals = inject("signals");
const sigint = () => {
  // Tear down component
};
signals.on("SIGINT", sigint);

To unsubscribe from the signal, pass the same signal name and callback you used to subscribe to the signal.

signals.off("SIGINT", sigint);

The libraries query component makes usage of that and allows to cancel a query with SIGINT and appending ^C to the query.

Nice-to-haves

These features didn't make it into the last release. If you would like to contribute please consult CONTRIBUTING.md.

  • Draggable terminal
  • More events (like query dispatched)
  • More key combinations

Browser support

This library uses the ResizeObserver to track if the terminal needs to scroll to the bottom. You may need a pollyfill to support your target browser.

Projects using vue-command

Chuck Norris API

The Chuck Norris jokes are comming from this API. This library has no relation to Chuck Norris or the services provided by the API.

Author

Julian Claus and contributors. Special thanks to krmax44 for the amazing work!

I apologize to some contributors that are not in the Git history anymore since I had to delete the repository because of problems with semantic-release.

License

MIT