Console: Add a Snippet Manager

Created on 3 Feb 2016  路  25Comments  路  Source: cbucher/console

It would be great if ConsoleZ could have some form of Snippet Manager. What I mean by this is a way of specifying text that could be applied with a shortcut or menu action.

For example, I have a series of Powershell commands that I have listed in a text file. To use these I copy them from my text file and paste them into ConsoleZ. If there were a way of storing these directly in ConsoleZ I could name them, assign them to a shortcut and then apply them quickly without needing to have the text file.

feature request discussion

Most helpful comment

Basically, snippets are xml files.
By default, snippets files location is Snippets sub-directory of the settings directory.
The settings directory is the directory containing your configuration file.
So usually snippets are located in %appdata%\Snippets.

XML files schema is not yet fully documented.
You can play with examples provided in this thread.

To date, all shells are hard coded with the type cmd and types are not checked.
You can define 0 to 99 Literaltags in Declarations.
Declarations tag is optional.
You can define one or multiple Snippettags in ConsoleZSnippets.

here an example

<?xml version="1.0" encoding="utf-8"?>
<ConsoleZSnippets>
    <DownloadUrl>https://raw.githubusercontent.com/cbucher/console/master/Snippets/system.xml</DownloadUrl>

        <!-- ping -->
    <Snippet>
        <Header>
            <Title>ping</Title>
            <Description>ping command</Description>
            <Author Url="https://github.com/cbucher/console" Email="[email protected]">cbucher</Author>
            <Version>1.0</Version>
            <ShellTypes>
                <ShellType>cmd</ShellType>
                <ShellType>powershell</ShellType>
            </ShellTypes>
        </Header>
        <Declarations>
            <Literal>
                <ID>target_name</ID>
                <ToolTip>The target name.</ToolTip>
                                <Default>localhost</Default>
            </Literal>              
            <Literal>
                <ID>count</ID>
                <ToolTip>Number of echo requests to send.</ToolTip>
                <Default>4</Default>
            </Literal>
            <Literal>
                <ID>timeout</ID>
                <ToolTip>Timeout in milliseconds to wait for each reply.</ToolTip>
                <Default>500</Default>
            </Literal>
        </Declarations>
        <Code Delimiter="$">
            <![CDATA[ping.exe -4 -n "$count$" -w "$timeout$" "$target_name$"
]]> <!-- return of line, the command is launched after clicking OK -->
        </Code>
    </Snippet>

        <!-- restart -->
    <Snippet>
        <Header>
            <Title>restart</Title>
            <Description>restart computer</Description>
            <Author Url="https://github.com/cbucher/console" Email="[email protected]">cbucher</Author>
            <Version>1.0</Version>
            <ShellTypes>
                <ShellType>cmd</ShellType>
            </ShellTypes>
        </Header>
        <Declarations>
            <Literal>
                <ID>comment</ID>
                <ToolTip>Comment on the reason for the restart or shutdown.</ToolTip>
                                <Default>I have a really good reason!</Default>
            </Literal>              
        </Declarations>
        <Code Delimiter="$">
            <![CDATA[shutdown /r /t 0 /c "$comment$"]]> <!-- no return of line, you must press return after clicking OK -->
        </Code>
    </Snippet>

        <!-- hello world -->
    <Snippet>
        <Header>
            <Title>hello world</Title>
            <Description>The most trivial snippet!</Description>
            <Author Url="https://github.com/cbucher/console" Email="[email protected]">cbucher</Author>
            <Version>1.0</Version>
            <ShellTypes>
                <ShellType>cmd</ShellType>
            </ShellTypes>
        </Header>

        <Code>
            <![CDATA[@echo hello world]]>
        </Code>
    </Snippet>

    <Snippet>
        <Header>
            <Title>hello world</Title>
            <Description>The most trivial snippet!</Description>
            <Author Url="https://github.com/cbucher/console" Email="[email protected]">cbucher</Author>
            <Version>1.0</Version>
            <ShellTypes>
                <ShellType>powershell</ShellType>
            </ShellTypes>
        </Header>

        <Code>
            <![CDATA[Write-Host 'hello world' -ForegroundColor yellow]]>
        </Code>
    </Snippet>

</ConsoleZSnippets>

All 25 comments

You can create functions and aliases in PowerShell... I don't understand why you need a text file.

If you are using PowerShell v5, it might also be worth checking out Set-PSReadlineKeyHandler. This is provided by the PSReadLine module which is included in v5.

This would allow you to bind a keyboard shortcut to a PowerShell command.

Not saying that a snippet manager is generally a bad idea, but functions+aliases+PSReadline might give you most of what you want

I was not saying that a snippet manager was a bad idea.
I wanted to discuss needs and usage to obtain a specification.
Here the need was like a cheat sheet.

He preferred to close instead of an explanation. Too bad for others who could use.

@cbucher I didn't think you were saying that, but it's possible @AnturGyffrous misinterpreted your previous comment.

I think it's an interesting idea that might warrant more discussion - but in the meantime, there are things that might get him part of the way there.

If you read my response, you can see I didn't write anything about the snippet idea.

I reacted on the copy/paste from a text file to PowerShell.

In general copy/paste in a shell can be fatal: paste a bad command with a line return and cry!
With PowerShell you can create your own environment, rename every command ...
Instead of copy/paste long commands, you should do functions!

So snippet: yes, why not
but the PowerShell example: no, you have to convince me

[sigh]

Ok

I could propose that a better idea for usage, is for those who use multiple different shells. (I have a pair of cmd.exe tabs with different environs, and a pair of bash tabs with different environs, and i've had others configured before but they were more test items than things i used seriously. I've also never used PowerShell ... and i'm considering trying to configure ssh to remote hosts as shell for some tabs, but i haven't tried that yet) Despite having different shells with different commands and syntaxes and so on, it can be handy to be able to quickly paste the same data into several of them, such as a particular use that i have where i'm constantly copying/pasting large strings of json data to command lines.

Normally, I use MobaXterm with it's Macro feature for that.

Just a thought. It's not something I use a lot of, but when I do need to run a large quantity of stuff repeatedly through shell, it's occasionally handy.

and i'm considering trying to configure ssh to remote hosts as shell for some tabs, but i haven't tried that yet)

It works fine for me. I use OpenSSH for Windows.

Despite having different shells with different commands and syntaxes and so on, it can be handy to be able to quickly paste the same data into several of them, such as a particular use that i have where i'm constantly copying/pasting large strings of json data to command lines.

I'm not sure I understand the need. You want improve the clipboard or always paste same data ( data never change) ?

It's something that could easily be done with a multi-clipboard app, or macros, or probably a bunch of other ways. I paste a lot of large strings from a file as input to a particular console application, regardless of which shell I'm running it in.

Your usage is only a "super" clipboard. I google "super clipboard", I find many free applications
which can meet your requirements (for example Ditto).
An added value is required. If specifications have nothing specific to ConsoleZ, why limit the usage to ConsoleZ? It will be smarter to create an external tool usable by all.

ConsoleZ properties:

  • CLI wrapper
  • settings by shell
    ...

Snippet properties:

  • text to paste
  • piece of code/command
  • variables to replace
    ...

Due to lack of participation, here is my personal specification of the snippet files (inspired by Visual Studio snippet files):

<?xml version="1.0" encoding="utf-8"?>
<ConsoleZSnippets>
    <DownloadUrl>https://raw.githubusercontent.com/cbucher/console/master/Snippets/test.xml</DownloadUrl>
    <Snippet>
        <Header>
            <Title>test</Title>
            <Description>This is a test.</Description>
            <Author Url="https://github.com/cbucher/console" Email="[email protected]">cbucher</Author>
            <Version>1.0</Version>
            <ShellTypes>
                <ShellType>cmd</ShellType>
                <ShellType>bash</ShellType>
            </ShellTypes>
        </Header>
        <Declarations>
            <Literal>
                <ID>first</ID>
                <ToolTip>The first param</ToolTip>
                <Default>one</Default>
            </Literal>
            <Literal>
                <ID>second</ID>
                <ToolTip>The second param</ToolTip>
                <Default>two</Default>
            </Literal>
            <Literal>
                <ID>third</ID>
                <ToolTip>The third param</ToolTip>
                <Default>three</Default>
            </Literal>
        </Declarations>
        <Code Delimiter="$">
            <![CDATA[echo "$first$" "$second$" "$third$"]]>
        </Code>
    </Snippet>
</ConsoleZSnippets>

work progress:

  • a directory with xml snippet files is parsed
  • dialog with fields to fill is dynamically generated from the snippet content

image

You can test snippets implementation in last experimental release - _version 1.17.0.16080_.
Please give feedback here or on Join the chat at <a href="https://gitter.im/cbucher/console">https://gitter.im/cbucher/console</a>.

Snippets are, by default, located in <settings file folder>\Snippets.

@AnturGyffrous @JohnLudlow @ericblade Waiting for feedback.

I'm confused by this thread. Why even implement snippets? @cbucher you spent time figuring out perfectly legitimate alternatives for both of the scenarios posed as reasons for a snippet manager. Then you implemented the feature anyway. It's clear that the users in this thread don't even actually need a snippet manager, so why not just either ship the feature (so you can get feedback from the larger population of users) or leave it out entirely (since no one has been able to express a need that can't be solved by other tools)?

I'm confused by this pointless comment.
Why are you concerned by a project in which you don't contribute.

The purpose of this thread was an open discussion / specification.
My expectations: help for specification and testing feedback.
So, as on every occasion, I'm disappointed...

you spent time figuring out perfectly legitimate alternatives for both of the scenarios posed as reasons for a snippet manager. Then you implemented the feature anyway.

I code what I want...
I criticized a dangerous usage of copy/paste.
I criticized a specification that was a clipboard's specification without added value.
But "Snippet Manager" is not a wrong feature.

so why not just either ship the feature

As developer, I do specifications before coding...
This feature is now in beta version and will be released in stable version in few days.

You seem to be taking offense which is not what I intended. GitHub is meant to be an open community, and IMHO contributions are not just code. I believe discussion is a contribution as well. And although I have not contributed code to this project, the way you've addressed me would deter me from doing so in the future.
I was under the impression that you coded the snippet manager because you got feedback from your user community that it was a feature that they needed. I didn't realize it was just something you really wanted to code. With that in mind, you might see how I was confused that you still decided to implement the feature after proving (at least for the cases posed by the users in this thread) that the feature wasn't actually necessary.
_Disclaimer: this next part is an opinion_
Following from the fact that you showed the users how to solve their problem another way (thereby rendering the feature unnecessary from their perspective), it didn't make much sense to block the feature's release by waiting for their input, since at this point the feature is really just something that you want to do. That is, I like that you are inclusive and want feedback, but I just thought you waited longer than necessary. I'm assuming it doesn't cost you much effort to release milestone 1.17 w/o this feature and then do a subsequent release with the feature, so forgive me if that's an incorrect assumption.
Anyway, kudos on your project and keep up the good work!

@cbucher can you please provide a (preferably multiple) use case and example of how the snippet manager is specifically developed to work?

It is just not intuitive enough for me to understand how to utilise it and this thread and the help file is not spelling it out specifically.

Cheers,

Bundy

Basically, snippets are xml files.
By default, snippets files location is Snippets sub-directory of the settings directory.
The settings directory is the directory containing your configuration file.
So usually snippets are located in %appdata%\Snippets.

XML files schema is not yet fully documented.
You can play with examples provided in this thread.

To date, all shells are hard coded with the type cmd and types are not checked.
You can define 0 to 99 Literaltags in Declarations.
Declarations tag is optional.
You can define one or multiple Snippettags in ConsoleZSnippets.

here an example

<?xml version="1.0" encoding="utf-8"?>
<ConsoleZSnippets>
    <DownloadUrl>https://raw.githubusercontent.com/cbucher/console/master/Snippets/system.xml</DownloadUrl>

        <!-- ping -->
    <Snippet>
        <Header>
            <Title>ping</Title>
            <Description>ping command</Description>
            <Author Url="https://github.com/cbucher/console" Email="[email protected]">cbucher</Author>
            <Version>1.0</Version>
            <ShellTypes>
                <ShellType>cmd</ShellType>
                <ShellType>powershell</ShellType>
            </ShellTypes>
        </Header>
        <Declarations>
            <Literal>
                <ID>target_name</ID>
                <ToolTip>The target name.</ToolTip>
                                <Default>localhost</Default>
            </Literal>              
            <Literal>
                <ID>count</ID>
                <ToolTip>Number of echo requests to send.</ToolTip>
                <Default>4</Default>
            </Literal>
            <Literal>
                <ID>timeout</ID>
                <ToolTip>Timeout in milliseconds to wait for each reply.</ToolTip>
                <Default>500</Default>
            </Literal>
        </Declarations>
        <Code Delimiter="$">
            <![CDATA[ping.exe -4 -n "$count$" -w "$timeout$" "$target_name$"
]]> <!-- return of line, the command is launched after clicking OK -->
        </Code>
    </Snippet>

        <!-- restart -->
    <Snippet>
        <Header>
            <Title>restart</Title>
            <Description>restart computer</Description>
            <Author Url="https://github.com/cbucher/console" Email="[email protected]">cbucher</Author>
            <Version>1.0</Version>
            <ShellTypes>
                <ShellType>cmd</ShellType>
            </ShellTypes>
        </Header>
        <Declarations>
            <Literal>
                <ID>comment</ID>
                <ToolTip>Comment on the reason for the restart or shutdown.</ToolTip>
                                <Default>I have a really good reason!</Default>
            </Literal>              
        </Declarations>
        <Code Delimiter="$">
            <![CDATA[shutdown /r /t 0 /c "$comment$"]]> <!-- no return of line, you must press return after clicking OK -->
        </Code>
    </Snippet>

        <!-- hello world -->
    <Snippet>
        <Header>
            <Title>hello world</Title>
            <Description>The most trivial snippet!</Description>
            <Author Url="https://github.com/cbucher/console" Email="[email protected]">cbucher</Author>
            <Version>1.0</Version>
            <ShellTypes>
                <ShellType>cmd</ShellType>
            </ShellTypes>
        </Header>

        <Code>
            <![CDATA[@echo hello world]]>
        </Code>
    </Snippet>

    <Snippet>
        <Header>
            <Title>hello world</Title>
            <Description>The most trivial snippet!</Description>
            <Author Url="https://github.com/cbucher/console" Email="[email protected]">cbucher</Author>
            <Version>1.0</Version>
            <ShellTypes>
                <ShellType>powershell</ShellType>
            </ShellTypes>
        </Header>

        <Code>
            <![CDATA[Write-Host 'hello world' -ForegroundColor yellow]]>
        </Code>
    </Snippet>

</ConsoleZSnippets>

That is a much better explanation thanks @cbucher I just have a couple of opinions.

Why not offer the above example by default?

I discovered that I actually had to create the Snippets directory myself before placing my generated XML file with your example content in it, this doesn't feel intuitive and I believe if you simply offered the above by default then the directory is created the xml exists and people like myself are not left guessing to then discover this thread.

I think you may have marked up an extra back slash in your source code on the edit flat file link:

doubleslash

Other than the above opinions I can now see an early use case in the example of building MEAN (Mongo Express Angular Node) web applications onto different operating systems and especially when you are moving between online and offline environments that require npmbox and unboxing, like bookmarking just the install npmbox command is going to save time.

Thanks again for the updated more specific information.

Cheers,

Bundy

Why not offer the above example by default?

This is a simple sample I wrote when I commented.

I have no intention at this time of creating or distributing snippets. I let users contribute.

I think you missed my point about it being not intuitive.

Without your explanation or example I simply had a disabled snippet button and a very lack luster description of what a snippet was meant to be, so really I just sat there curious as to what it was until I asked you to provide a more specific example. Then applying the example I was forced to have to create the directory myself and blah blah blah so yeah again that isn't exactly self explanatory where as if you supplied a generate example or just packaged a hello world by default it causes the user to investigate.

Just my opinion. ;P

Cheers,

Bundy

Then applying the example I was forced to have to create the directory myself and blah blah blah

馃槥

Work is in progress and I have a limited time.
Now that you are an expert at snippets, you can contribute to the documentation. :wink:

Documentation Done!!!

馃槣 馃憡

Was this page helpful?
0 / 5 - 0 ratings