vue-command icon indicating copy to clipboard operation
vue-command copied to clipboard

Bug: Wrong prompt display when updated during command execution

Open DropSnorz opened this issue 4 years ago • 2 comments

Hi,

Thank you for the hard work on this library! I can't manage to update the prompt property from a custom command component. Maybe it's a misuse on my side.

For example, I've created a cd command bound to a ChangeDirectoryCommand component.


<vue-command
  :commands="commands"
  :executed="new Set()"
  show-intro
  show-help
  :title="prompt"
  :prompt="prompt"
/>

// ...
  computed: {
    commands() {
      return {
        cd: () => ChangeDirectoryCommand,
        help: () =>
          createStdout(`
          cd: Change directory<br />
          help: Display help text<br />`),
      };
    },
    prompt() {
      // Prompt is retrieved from a global store.
      return this.$root.$data.prompt;
    },
  },
};


The ChangeDirectoryCommand is in charge of the display and business logic (retrieve command parameters and updating props accordingly)

<script>
export default {
  name: "ChangeDirectoryCommand",
  inject: ["terminate"],
  computed: {
    targetDirectory: function () {
      return this.context.parsed._[1];
    },
  },
  mounted() {
    this.$root.$data.prompt = this.$root.$data.prompt + "/" + this.targetDirectory;
    this.terminate();
  },
};
</script>

You can find the complete example here: https://codesandbox.io/s/vue-command-cd-o58s2?file=/src/App.vue

When I run this sample code and execute cd home the next prompt displayed after command execution is outdated.

user@system:# cd home

Moving to home
user@system:#

But if I hit enter (or run a new command) the current prompt will be updated with the correct value.

user@system:# cd home

Moving to home
user@system:#/home
user@system:#/home 

After some checks, I think I've found why it's happening. When my stdout component is pushed to the history, the next stdin is rendered with it's local.prompt property. At this time, my command has not been executed so the prompt in the global state is still user@system:#. When my command terminates the global state has been updated to user@system:#/home but not the stdin local state. Then, when we run a new command the current stdin prompt is persisted with the root component prompt property which is bound to the global state (user@system:#/home).

How to ensure that the next prompt is up to date?

Thank you,

DropSnorz avatar Nov 11 '20 19:11 DropSnorz

@DropSnorz I found a workaround to this issue, you can access the last stdin component reference and call setPrompt() manully to set the next prompt. Code may be like this:

  const stdins = this.$refs.vueCommand.$refs.stdin;
  const lastStdin = stdins[stdins.length - 1];
  lastStdin.setPrompt(<next prompt>);

MudOnTire avatar Dec 16 '20 07:12 MudOnTire

@MudOnTire Thank you for sharing this workaround. It works well! 😉

DropSnorz avatar Dec 17 '20 22:12 DropSnorz

Please test it with the newest version.

ndabAP avatar Dec 18 '22 10:12 ndabAP