Skip to content

Command Line Interface #213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
fleischie opened this issue Jan 9, 2016 · 11 comments
Closed

Command Line Interface #213

fleischie opened this issue Jan 9, 2016 · 11 comments

Comments

@fleischie
Copy link

As was mentioned in Issue #80 there was the intention to implement a command line interface for ckb? ckb-cli maybe?

Are there any specific plans already in the making? Is there something in particular that can be done (by me for example)? :)

I would like to help and ... you know, help me help you. ;)

@SicVolo
Copy link
Contributor

SicVolo commented Jan 9, 2016

A lot of scripted control of the keyboard can already be done by echoing into the ckb device. Other functions for controlling the ckb itself from a command line (like start/stop animation, change profile etc) could be implemented through ckb command line options, just like you done with the pull #211, and could be a nice addition

@ccMSC
Copy link
Owner

ccMSC commented Jan 11, 2016

What I'm planning is that there will eventually be a way to pass commands to the GUI, like ckb --cmd <commands here> and then you'll have a fully scriptable interface that does the same things as the UI. I'm going to do a fairly heavy rewrite to the device/profile system for v0.3 which should make this easier to implement.

@fleischie
Copy link
Author

I tried to write out the grammar for the CLI analogously to the ip command. Because of the inherently differnet approach of the GUI/CLI, this is a very flat and thus verbose grouping:

Top Level Command

<cmd> ::= "global" <global-cmd>
        | "keyboard" [<device-id>] <device-cmd>
        | "mouse" [<device-id>] <device-cmd>
<device-id> ::= <str>

<direction> ::= "up" | "down"
<color> ::= "#" <int>
          | "(" <int> "," <int> "," <int> ")"

Global Commands

<global-cmd> ::= "info"
               | "layout" <global-layout-cmd>
               | "modifier" <global-modifier-cmd>
               | "framerate" <input-int>
               | "animation-dir" <global-animation-dir-cmd>
               | "brightness-per-mode" <input-bool>
               | "spatial-dithering" <input-bool>
               | "firmware-autocheck" <input-bool>
               | "tray-icon" <input-bool>
               | "mouse-acceleration" <input-bool>
               | "scroll-acceleration" <input-bool>
               | "scroll-acceleration-speed" <input-int>

<input-int> ::= "show" | "set" <int>
<input-float> ::= "show" | "set" <float>
<input-str> ::= "show" | "set" <str>
<input-bool> ::= "show" | "enable" | "disable"

<global-layout-cmd> ::= "list" | "set" <layout>
<layout> ::= "EU" | "EU_DVORAK"
           | "GB" | "GB_DVORAK"
           | "US" | "US_DVORAK"
           | "FR" | "DE" | "IT" | "PL" | "MX" | "ES" | "SE"

<global-modifier-cmd> ::= "list" | "set <modifier-key> <modifier-name>" | "reset"
<modifier-key> ::= "caps" | "lshift" | "lctrl" | "lwin" | "lalt"
<modifier-name> ::= "caps" | "shift" | "ctrl" | "option" | "cmd" | "alt" | "super"

<global-animation-dir-cmd> ::= <input-str> | "scan"

Device Commands

<device-cmd> ::= "device" <device-device-cmd>
               | "profile" <profile-cmd>

<device-device-cmd> ::= "" | "info"
                      | "firmware" <device-firmware-cmd>

<device-firmware-cmd> ::= "show"
                        | "update" [<input-str>]

<profile-cmd> ::= "" | "list"
                | "create" <profile-name>
                | "duplicate" <profile-name>
                | "rename" <profile-name> <profile-name>
                | "move" <profile-name> <direction>
                | <profile-name> "mode" <mode-cmd>
<profile-name> ::= <str>

<mode-cmd> ::= "list"
             | "create" <mode-name>
             | "duplicate" <mode-name>
             | "rename" <mode-name>
             | "move" <direction>
             | "animation" <animation-cmd>
             | "lighting" <lighting-cmd>
             | "bind" <bind-cmd>
             | "performance" <performance-cmd>

<animation-cmd> ::= "list"
                  | "show"
                  | "delete" <animation-id>
                  | "set" <animation-id> <animation-specs>

<lighting-cmd> ::= "brightness" <lighting-brightness-cmd>
                 | "color" <key-id> <lighting-color-cmd>
                 | "animation" <key-id> <lighting-animation-cmd>
<lighting-brightness-cmd> ::= "show" | "set" <indicator-mode>
<lighting-color-cmd> ::= "show" | "set" <color>
<lighting-animation-cmd> ::= "show" | "set" <animation-id>

<bind-cmd> ::= "list"
             | "show" <key-id>
             | "set" <key-id> <key-code>
             | "copy" <mode-name>
             | "reset"

<performance-cmd> ::= "copy" <mode-name>
                    | "intensity" <input-int>
                    | "indicator" <performance-indicator-cmd>
                    | "lock" <performance-lock-cmd>
                    | "dpi" <dpi-cmd>

<performance-indicator-cmd> ::= <indicator-key-name> <indicator-cmd>
<indicator-key-name> ::= "brightness" | "windows-lock" | "mute"
<indicator-cmd> ::= "show" | "enable" | "disable" | set <indicator-mode> <color>
<indicator-mode> ::= "0" | "1" | "2"

<dpi-cmd> ::= "list"
            | "indicator" <dpi-indicator-cmd>
            | "independent-axes" <input-bool>
            | "stage" <stage> "set" "x" <int> ["y" <int>]
            | "angle-snap" <input-bool>
            | "lift-height" <input-int>
<dpi-indicator-cmd> ::= <input-bool> | "set" <int>
<dpi-stage> ::= "0" | "1" | "2" | "3" | "4" | "5" | "other"

<performance-lock-cmd> ::= "show" | <lock-key> <lock-cmd>
<lock-key> ::= "num" | "caps" | "scroll"
<lock-cmd> ::= "set" <lock-mode> | "set" <lock-setting> <color>
<lock-mode> ::= "normal" | "always-on" | "always-off" | "RGB" | "normal-rgb"
<lock-setting> ::= "0" | "1"

I hope I didn't miss any. :)
Furthermore I'm looking forward for that rewrite, maybe the grammar will become more simple this way. :)

@frickler24
Copy link
Contributor

@fleischie Thanks for the BNF.
Because in the current testing stage the macro key definition is integrated, I did some additions to your def.


// Added a special configuration item
<global-cmd> ::= "info"
               | "layout" <global-layout-cmd>
               | "modifier" <global-modifier-cmd>
               | "framerate" <input-int>
               | "animation-dir" <global-animation-dir-cmd>
               | "brightness-per-mode" <input-bool>
               | "spatial-dithering" <input-bool>
               | "firmware-autocheck" <input-bool>
               | "tray-icon" <input-bool>
               | "mouse-acceleration" <input-bool>
               | "scroll-acceleration" <input-bool>
               | "scroll-acceleration-speed" <input-int>

               | "macro-delay" <input-bool>

// Added some modifier keys 
// (pls double check, I thought it should be 13 keys, 
// but I could remember 12 only):
<modifier-key> ::= "caps" | "lshift" | "lctrl" | "lwin" | "lalt"
           | "rshift" | "ralt" | "rwin" | "fn" | "altgr" | "menu" | "rcontrol"

// Is the following really needed?
<modifier-name> ::= "caps" | "shift" | "ctrl" | "option" | "cmd" | "alt" | "super"

// added macro definition as it is added now to the bind tabs (testing stage)
<bind-cmd> ::= "list"
             | "show" <key-id>
             | "set" <key-id> <key-code>
             | "copy" <mode-name>
             | "reset"

             | "macro" <macro-definition>

// Here is the BNF for the macro definiton
<macro-definition> ::= <key-def> <macro-action> <macro-text> <macro-comment>

// There should be no space between <modifier-list> and <key-list> or the CLI must check it.
// Same is for all modifier/key combinations
<key-def> ::= <modifier-list><key-list>

<modifier-list> ::= ""
                  | <modifier-key>"+"
                  | <modifier-key><modifier-list>

<key-list> ::= <key>
             | <key>"+"<key-list>

// Assuming that <str> may not be empty.
<key>           ::= <str>
<macro-action>  ::= "" | <str>
<macro-text>    ::= "" | <str>
<macro-comment> ::= "" | <str>

// <macro-action> has an internal syntax definition 
// (list of valid keys with +/-, each should appear as pairs with +key before -key).
// Same is for <key>, because this means only valid key names.
// I do not think the CLI should implement a syntax check for that.
// If one does not know what string to send to the CL-interface, he should use the GUI.

@ccMSC
Copy link
Owner

ccMSC commented Apr 8, 2016

Looks good overall. Only part I'd change is this:

<cmd> ::= "global" <global-cmd>
        | "keyboard" [<device-id>] <device-cmd>
        | "mouse" [<device-id>] <device-cmd>

The current device-based profile system is going away. In future versions you'll be able to use the same profile for the keyboard and mouse simultaneously. So, for instance, you could bind a key on the keyboard to change DPI (which is currently impossible) and the mouse would update accordingly. It also means there won't really be a distinction between keyboards and mice; they'll simply be different devices with different properties.

That being the case, what I think we should have:

<cmd> ::= "global" <global-cmd>
        | "device" [<device-id>] <device-device-cmd>
        | "profile" [<profile-id>] <profile-cmd>

and the device commands would include a command to get/set the current profile, by profile-id. Other than that I really like it :)

@fleischie
Copy link
Author

OK, sounds legit. @ccMSC Do you have an estimate on when v0.3 is to be expected?

I can start on the syntax implementation, make it allow the current profile system and adapt, when v0.3 is out.

@fleischie
Copy link
Author

I am wondering how to approach this task. Should there be an --cmd parameter to the GUI command? Would this be best implemented with a separated ckb-cli command? Would it be best to separate the functionality of the GUI into an own library, which the GUI and the CLI utilizes separately but as the same command?

I would like to have some feedback, because I am not decisive enough. :(

@ccMSC
Copy link
Owner

ccMSC commented Apr 13, 2016

I think ckb --cmd [commands] would be the way to go. Unambiguous and won't conflict with anything. It's also worth noting that this should cause the GUI to launch itself in the background, if it wasn't running already.

I've considered splitting the actual UI into a separate module, but we already have two daemons (one root, one non-root) and I really don't want to make it three :P

@fleischie
Copy link
Author

This is very helpful. I'll try to figure out a way to allow this workflow and report back. :)

@fleischie
Copy link
Author

Hey,

I am trying to manipulate the state of the keyboard (specifically I am trying to set the keyboard layout via Kb::layout(KeyMap::layout)). I am able to set it temporarily, but it is always KeyMap::NO_LAYOUT (or -1) when I am querrying for it.

So my question is: Do I use the static KbManager class to globally modify the data? If yes, how? If not, why are calls to Kb::layout(KeyMap::layout) not persistent?

Note: I have the ckb-daemon and the ckb-gui running, while trying to manipulate the data.

@fleischie
Copy link
Author

Nevermind. I have found the CkbSettings class and was able to implement setting the layout persistently. 😃 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants