cmder icon indicating copy to clipboard operation
cmder copied to clipboard

Question: Start a new terminal with some text already on the command line

Open ZelCloud opened this issue 3 years ago • 6 comments

Question

Is there a way to open a new tab or pane and prepopulate it with some command text on the command line without running it?

new tab
C:
> my really long and expensive command that I dont want to run right away

Checklist

  • [X] I have read the documentation and made sure what I'm looking for isn't present, or is unclear.
  • [X] I have searched for similar issues, and either this question wasn't asked before, or I didn't find any that describe my question.

ZelCloud avatar Nov 06 '22 05:11 ZelCloud

Tip: You can press to retrieve the last executed command, if that helps.

Which shell do you use (Cmd/clink, Powershell)? Maybe there is a way to insert a command without executing it in the terminal.

Of course, another way is to use an alias, or put your command in the bin folder, for example:

do-something.cmdcd ~/Project ; build --clean --make ; run tests ; cd C:\Projects ; update

then all you have to do is type do-som and press Tab ↹ so it autocompletes it to do-something.cmd for you, then press Enter to execute it.

If none of these methods suit your need, I'll check if we can add this feature to Cmder (actually ConEmu, since that's the terminal that Cmder runs on).

DRSDavidSoft avatar Nov 06 '22 18:11 DRSDavidSoft

Thanks for the suggestions and speedy reply, unfortunately they aren't possible or well suited.

I'm using cmd as the base shell to run cmder. I've done a fair bit of searching on windows terminal, cmd, and powershell if there were ways to pre put text in the command line without running them but there doesn't seem to be a flag or option for that. The closest thing I found was running an echo (/k flag) with the command so its printed at the very top of the terminal on start and can then be copy and pasted, which isn't great.

Alias, unfortunately aren't a good solution either, since ideally these setups would be placed into a script(s) that would be shared amongst a team. Trying to manage and update aliases or having things need to be setup in the bin folder would be a bit of a hassle, and prone to issues / breakage across the team.

Having an option directly in ConEmu would be fantastic!

ZelCloud avatar Nov 06 '22 19:11 ZelCloud

1. Create a file in: bin\type-command.vbs:

set objShell = WScript.CreateObject("WScript.Shell")
objShell.SendKeys "myCommand --example"

Change myCommand --example to whatever you need.

2. Edit config\user_profile.cmd and add the following:

%ccall% "/type_command" type-command.vbs

3. Modify the default Cmd task (or create a new one):

cmd /k ""%ConEmuDir%\..\init.bat" /type_command"

Now, whenever you open the task in terminal, myCommand --example will be typed automatically.

There is a drawback, though. The terminal window needs to be focused, if anything else is in focus (for example, you click on something), then the command will be typed in that window instead.

If you launch the task and don't click on anything or change windows, this should be fine.

Alternative methods

Option A You can create a start-command.cmd instead:

set start_command=myCommand --example

echo %start_command%
echo Press a key to execute, or CTRL-C to cancel...
pause > nul
%start_command%

And use %ccall% "/start_command" start-command.cmd.

This has the benefit of not relying on sending keys to the terminal window, however the drawback is that you can not edit the command or press backspace to clear it. It's always going to be started on run when you press a key, or Ctrl+C to abort it.

Option B We can ask Maximum to add an option in ConEmu where the command will be inserted in the shell

Option C We can ask Chrisant to add an option in clink where the initial command prompt is always populated with a pre-defined value

DRSDavidSoft avatar Nov 06 '22 20:11 DRSDavidSoft

@ZelCloud would it be possible to share the context for why this would be used?

  1. What text would be inserted?
  2. Why would it be inserted?
  3. What would know what to insert?
    • Is the user expected to type text in the command line for launching Cmder and then have it show up in Cmder? Why not type it after launching Cmder?
    • Would some program know what it insert before launching Cmder? How? Why leave text inserted, without executing it?

As you can tell, I don't understand the bigger picture, and it's important to understand the bigger picture so that an appropriate solution could be identified.

chrisant996 avatar Nov 06 '22 22:11 chrisant996

@ZelCloud would it be possible to share the context for why this would be used?

Yes, example at the end.

  1. What text would be inserted?

Mainly text to start an exe with certain flags and options passed in. ex.

C:\Development\MonoRepo\backend-service
> backend-service.exe --use-http3 --port=XXXX --use-redis-cache
  1. Why would it be inserted?

We want to setup a script that will launch a set of terminals / panes, with each pane being in a certain directory with its corresponding command pre-populated.

  1. What would know what to insert?
    • Is the user expected to type text in the command line for launching Cmder and then have it show up in Cmder? Why not type it after launching Cmder?

Some of the commands we want to prepopulate are quite a bit long, so this is mainly to improve developer experience. Currently a lot of the devs are just copying and pasting the line from the readme when they're launching said service.

  • Would some program know what it insert before launching Cmder? How? Why leave text inserted, without executing it?

Some of the services are extremely heavy and slow to start and they aren't needed in every case. We'd want to have the pane with the heavy service in question ready and setup but not ran unless that developer actually needs to use it.

As you can tell, I don't understand the bigger picture, and it's important to understand the bigger picture so that an appropriate solution could be identified.

Here's a more flushed out and ideal example.

Let's say we have a bat script to launch windows terminal with an assortment of cmder panes. (Just using windows terminal since I'm more familiar with the syntax).

wt -w 0 -d "C:\Dev\MonoRepo\a-service" cmd.exe /k "C:\\cmder\\vendor\\init.bat && --text='some-command --with-some-flags' " ; ^
split-pane -H -d "C:\Dev\MonoRepo\b-service" cmd.exe /k "C:\\cmder\\vendor\\init.bat --text='some-command --with-some-flags' " ; ^
split-pane -V -d "C:\Dev\MonoRepo\c-service" cmd.exe /k "C:\\cmder\\vendor\\init.bat --text='some-command --with-some-flags' " ; ^
move-focus up ; ^
split-pane -V -d "C:\Dev\MonoRepo" cmd.exe /k "C:\\cmder\\vendor\\init.bat --text='expensive-command --with-some-flags' "

Then we would have the setup like so

A-service B-service
>some-command --with-some-flags >some-command --with-some-flags
C-service Mono
>some-command --with-some-flags >expensive-command --with-some-flags

Now, we have a tab open with a bunch of panes with all the services needed to run together. We didn't start the services yet, since depending on the developer and the task they might only need to run 2-3 of the services instead of all 4.

So having a way to prepopulate the cmder command line helps us automate launching everything needed for a specific product with all the commands ready to go, but left upto the developer discresion which services they need running for their specific work / task.

Hopefully that helps clear up the use case a bit.

ZelCloud avatar Nov 07 '22 00:11 ZelCloud

@ZelCloud Ok, I think what you're saying is:

  1. There is a desire to start new console windows.
  2. There are commands that maybe should run but maybe shouldn't run, depending on preference.
  3. So the proposed solution is to insert typed text, and then the user MUST either clear the input, or press Enter, or edit the input and press Enter. I.e. the user MUST NEVER queue keystrokes of their own via the keyboard, as that would lead to a corrupted command being run, and who knows what would happen then.

Have these other approaches been considered?

  • Let the user choose in advance which command(s) should run when choosing to launch a shell, and then the launch can run whichever commands were selected.
  • In the new console, run a script that shows a menu, so the user can pick (1), (2), or (3) or etc which selects which command(s) to run.
  • Have a config file that lets the user decide which of the commands to run (this is how my team at work handles this same situation -- by default the dev environment init script runs some of the predefined available commands, and skips others -- and the config file can override which ones runs or are skipped).

In any case, this comment from DRSDavidSoft shows a few ways to accomplish this. The objShell.SendKeys approach works with all shells.

chrisant996 avatar Nov 07 '22 02:11 chrisant996