The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

JSON::Karabiner - easy JSON code generation for Karabiner-Elements

SYNOPSIS

Below is an example of an executable perl script for generating a json file for use by Karabiner-Elements. You can copy and paste this code to your local machine and execute it. Feel free to modify it to your liking. Note that you must first install the JSON::Karabiner package (see the "INSTALLATION" section below).

This script is easy to understand even if you have no experience with Perl or any programming langauge, for that matter. Read through the code below and see if you can determine what it will do. Don't hesitate to file an issue if you need asssistance.

  #!/usr/bin/env perl                # shebang line so this program is opened with perl interpreter
  use JSON::Karabiner::Manipulator;  # The JSON::Karabiner Perl package must be installed on your machine

  # Create a new manipulator object with a description and the file you want to save it to
  new_manipulator('a-s-d to show character viewer', 'my_awesome_karabiner_mod.json');

  # Add a from action to the manipulator:
  add_action 'from';

  # Add behaviors to the action:
  add_simultaneous 'a', 's', 'd';
  add_optional_modifiers 'any';

  # Add a "to" action to the manipulator:
  add_action 'to';

  # Tell the "to" action what to do
  add_key_code('spacebar');
  add_modifiers('control', 'command');

  # Done! Now it's time to write the file and give the rule a title:
  write_file('Emoji Character Viewer');

Save this above code to a file on your computer and be sure to make the script executable with:

  chmod 744 your_file_name.pl

Then execute this script with:

  ./your_file_name.pl

from the same directory where this script is saved.

After this script is run, a json file called my_awesome_karabiner_mod.json should now be sitting in the assets/complex_modifications directory. Open the Karabiner-Elements app on your Mac to install the new rule.

Ready to give is try? Follow the "INSTALLATION" instructions to get started.

DESCRIPTION

Karabiner stores rules for its modifications in a file using a data format known as JSON which is painstaking to edit and create. JSON::Karabiner eases the pain by letting Perl write the JSON for you. If you aren't familar with Perl, or programming at all, don't worry. There are examples provided that you can follow so no programming knowledge is necessary. The 10 or 20 minutes you spend learning how to install and use this module will pay off in spades.

A Karabiner JSON complex modification file stores the rules for modifying the keyboard in a data structure called the "manipulators." Therefore, most of methods you write will add data to the manipulator data structure. JSON::Karabiner can then write the JSON to a file and then you can load the rules you've written using the Kabrabiner-Elements program.

Below are descriptions of the methods used on manipulators.

add_action method

for adding the from/to actions to the manipulator

add_condition method

for adding manipulator conditions

add_parameter method

for adding maniplator parameters

add_description method

for adding a description to the manipulator

After running one of the four methods, the next step is to run additional methods that will be applied to the last action or condition you added.

It will be very helpful if you have a basic familiarity with the Karabiner manipulator definition to gain an understanding of which methods to run. See the Karabiner complex_modification manipulator documentation for more information.

DSL Interface

As of version 0.011, JSON::Karabiner moved to a DSL (domain specific language) interface to make writing scripts exceedingly easy. Please see the "SYNOPSIS" for an example of how to use the DSL. Full documention of the DSL will be available shortly. The older, object-oriented interface is still available below so it can be referred until the new documentation is releases. Note that the older object-oriented interface is still fully funcitonal (or should be, in theory).

How to Use the DSL Interface

There are two parts to the inteface: the method and the list of arguments you are passing to the method. Methods that add data to the Karabiner json file begin with add_ followed by a string of characters that corresponds to properties outlined in the Karabiner documentation. For example, to add a key_code property, you write:

  add_key_code('t');

It bears repeating that methods that apply to actions (or condtions) are automatically assigned to the last action (or condition) that was created. In other words, if your have:

  add_action 'to';
  add_action 'from';
  add_key_code 'x';

The key code will be added to the from action. If you wish apply it to the to action, simply move the add_key_code line immediately after the to action. This same rule applies for condtions as well as actions. Any method that adds data to a condtion will get added to the last condition created.

List of Methods for Actions

The following methods apply to actions (e.g. from, to, to_if_alone etc.)

From methods

The following methods are for the from action:

add_any
add_consumer_key_code
add_key_code
add_mandatory_modifiers
add_optional_modifiers
add_pointing_button
add_simultaneous
add_simultaneous_options

To methods

The following methods are for the to action (includes to_if_alone, to_if_held_down to_after_key_up, to_delayed_if_invoked, to_delayed_if_canceled):

add_consumer_key_code
add_key_code
add_modifiers
add_mouse_key
add_pointing_button
add_select_input_source
add_set_variable
add_shell_command

Condition methods

add_bundle_identifiers
add_description
add_file_path
add_identifier
add_input_source
add_keyboard_types
add_value
add_variable

For further details on each these methods, including the arguments they take, please see that appropriate perl doc page:

from action
to action
conditions

Multiple manipulators

The DSL interface makes it easy to include multiple manipulator in a single rule. Follow this patter:

  new_manipulator('Turn x key into y key', 'name_of_file.json');

  ... Run methods for above manipulator here ...

  write_file('Name of Rule');

  new_manipulator('Turn a key into by key', 'name_of_file.json');

  ... Run methods for the second manipulator here ...

  write_file('');

  ... Add N more manipulators here ...

Just be sure the manipulators all have the same file name so they will be included in the same file.

Notice that only the first write_file method requires the name of the rule to be passed. Subsequent calls to write_file will inherit the title from the first manipulator written.

Writing the JSON

As shown in the example above, a write_file call must be made for each manipulator in your script to have it included in the JSON file. The title is required to be supplied to the first manipulator. Subsequent write_file calls will use the first title.

METHODS

Below are the methods for the Karabiner, Rule, and Manipulator classes. The classes are used to create objects that you then run methods on.

Together, these methods create one large data structure that gets written to the json file. A good way to get a feel for how this works is to write just a little bit of Perl code, write it to a file, and then look at the file. Then add a little bit more Perl code, run the script again, and see what happens. You can also add the undocumented _dump_json method to your script to spit out the current state of your json without writing it to a file.

The new DSL Interface, as demonstrated in the "SYNOPSIS", should be used instead of the old object-oriented interface.

DEPRECATED Object-Oriented Interface

Karabiner Object Methods DEPRECATED

new($title, $file, [ { mod_file_dir => $path_to_dir } ] )

  my $kb_obj = JSON::Karabiner->new('title', 'file.json');

The new method creates the Karabiner object that holds the entire data structure. This should be the first command you issue in your scipt.

The $title and $file arguments are required. An optional third argument, set inside curly braces, can be passed to change the default Karabiner directory which is set to:

  ~/.config/karabiner/assets/complex_modifications/

You must pass this third argument inside the curly brackes as shown in this example:

  my $kb_obj = JSON::Karabiner->new('title', 'file.json', { mod_file_dir => '/path/to/dir' } ));

If you are using a non-standard location for your Karabiner install, you must change this directory to where Karabiner stores its modifications on your local machine by setting mod_file_dir option to the correct path on your drive.

Note: Thie method is DEPRECATED in favor of the new DSL approach (see the exmaple in SYNOPSI).

write_file() DEPRECATED

This will generally be the last command in your script:

  $kb_obj->write_file();

Once the file is written, you should be able to add the rules from your script using the Karabiner-Elements program. If it does not appear there, first check to make sure the file is saving to the right directory. If it still doesn't work, please open an issue on GitHub and post your perl script as it may be a bug.

Note: Thie method is DEPRECATED in favor of the new DSL approach (see the example in the SYNOPSIS).

add_rule($rule_title) DEPRECATED

Every Karabiner json file has a rules data structure which contains all the modifications. Add it to your object like so:

  my $rule = $kb_obj->add_rule('My Cool Rule Title');

Set the title of the rule by passing it a string set in quotes.

Note: Thie method is DEPRECATED in favor of the new DSL approach (see the example in the SYNOPSIS).

Rule Methods DEPRECATED

add_manipulator() DEPRECATED

A manipulator must be added to the Rule object to do anything useful:

  my $manip = $rule->add_manipulator

Once done, you can add actions, conditions, and parameters to your manipulator. See below for more information.

Manipulator Methods DEPRECATED

add_action($type) DEPRECATED

There are seven different types of actions you can add:

  my $from        = $manip->add_action('from');
  my $to          = $manip->add_action('to');
  my $to_alone    = $manip->add_action('to_if_alone');
  my $to_down     = $manip->add_action('to_if_held_down');
  my $to_up       = $manip->add_action('to_after_key_up');
  my $to_invoked  = $manip->add_action('to_delayed_if_invoked');
  my $to_canceled = $manip->add_action('to_delayed_if_canceled');

The major ones are the first four listed above. You must create a from action to your manipulator. This the actions that contains the keystrokes you want to change. The other to actions describe what the from keystroke actions will be changed into. See the Karabiner documentation for more information on these actions.

Once these actions are created, you may apply methods to them to add additional data. Consult the documentation for the different actions for a listing and description of those methods:

JSON::Karabiner::Manipulator::Actions::From
JSON::Karabiner::Manipulator::Actions::To

add_condition($type) DEPRECATED

Conditions make the modification conditional upon some other bit of data. You can add the following types of conditions:

  $manip->add_condition('device_if');
  $mainp->add_condition('device_unless')
  $manip->add_condition('event_changed_if')
  $manip->add_condition('frontmost_application_if')
  $manip->add_condition('frontmost_application_unless')
  $manip->add_condition('input_source_if')
  $manip->add_condition('input_source_unless')
  $manip->add_condition('keyboard_type_if')
  $manip->add_condition('variable_if')
  $manip->add_condition('variable_unless')

Consult the Karabiner documenation for more information on conditions. Once the conditions are created, you can add data to them using methods. See the documenation for each of the type of conditions and the types of methods they use:

JSON::Karabiner::Manipulator::Conditions

add_parameter($name, $value) DEPRECATED

Parameters are used by Karabiner to change various timing aspects of the actions. Four different parameters may be set:

  $manip->add_parameter('to_if_alone_timeout_milliseconds', 500);
  $manip->add_parameter('to_if_held_down_threshold_milliseconds, 500);
  $manip->add_parameter('to_delayed_action_delay_milliseconds, 250);
  $manip->add_parameter('simultaneous_threshold_milliseconds, 50);

See the Karabiner documentation for more details.

add_description($description) DEPRECATED

Adds a description to the manipulator data structure:

  $manip->add_description('This turns a period into a hyper key.');

INSTALLATION

This software is written in Perl and bundled as a package called JSON::Karabiner. If you are not familiar with installing Perl packages, don't worry. Just follow this simple two-step process:

Step 1: Ensure the cpanm command is installed:

Run the following command from a terminal window:

  C<which cpanm>

If the terminal reponds with the path to cpanm, proceed to Step 2.

If the cpanm command is not installed, copy and paste one of the following three commands into your terminal window to install it:

  # Option 1: Install to system Perl
  curl -L https://cpanmin.us | perl - --sudo App::cpanminus

  # Option 2: Install to local Perl (you must have a local version of Perl already installed)
  curl -L https://cpanmin.us | perl - App::cpanminus

  # Option 3: Install as standalone executable
  cd ~/bin && curl -L https://cpanmin.us/ -o cpanm && chmod +x cpanm

If you are unsure what the best option is for installing cpanm, consult its documentation for more help..

Step 2: Install the JSON::Karabiner package

Now issue the following comamdn to install the software:

  cpanm JSON::Karabiner

After issuing the cpanm command above, you should see a success message. If so, you can start using cpanm JSON::Karabiner and start using it in local Perl scripts you write. If you get errors about lack of permissions, try running:

  sudo cpanm JSON::Karabiner

If you still get weird errors, it may be a bug. Please report your issue to the issue queue.

Other install methods

This module can also be installed using the older cpan command that is already on your Mac. See how to install CPAN modules for more information.

VERSION

version 0.014

Development Status

This module is currently in alpha release and is actively supported and maintained. Suggestion for improvement are welcome. It is known to generate valid JSON that allow Karabiner to import rules from the file generated for at least simple cases and probably more advanced cases as well.

Many improvements are in the works. Please watch us on GitHub.

SUPPORT

Perldoc

You can find documentation for this module with the perldoc command.

  perldoc JSON::Karabiner

Websites

The following websites have more information about this module, and may be of help to you. As always, in addition to those websites please use your favorite search engine to discover more resources.

Source Code

The code is open to the world, and available for you to hack on. Please feel free to browse it and play with it, or whatever. If you want to contribute patches, please send me a diff or prod me to pull from your repository :)

https://github.com/sdondley/JSON-Karabiner

  git clone git://github.com/sdondley/JSON-Karabiner.git

BUGS AND LIMITATIONS

Though this software is still in an alpha state, it should be able to generate code for any property with the exception of the to_after_key_up key/value use for the simultaneous options behavior due to uncertainty in how this should be implemented. If you need this feature, generate your json code using this script as you normally would and then manually edit it to insert the necessary json code.

SEE ALSO

Karabiner Elements Home Page
Karabiner Elements Reference Manual

AUTHOR

Steve Dondley <s@dondley.com>

COPYRIGHT AND LICENSE

This software is copyright (c) 2020 by Steve Dondley.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.