Location of dictionaries

I have created 2 macros which are dictionary based, these automatically have synced to my laptop. Unfortunately neither dictionary accompanied the macro. Are dictionaries kept separately and if so where are they?

I can easily write an Applescript to export them to a text file and another to read them back but it seems a waste of time if I can just copy a file.

The data files are generally in the folder: ~/Libary/Application\ Support/Keyboard\ Maestro

In particular, there is a Keyboard\ Maestro\ Dictionaries.sqlite file in that location.

I had checked both Dictionaries.sqlite and variables.sqlite with Valentina Studio without sucess. I tried another sql browser this morning and found the data for both of my dictionaries in Dictionaries.sqlite.

Unfortunately I would not recommend drag and dropping this file to move Dictionaries as that would wipe existing data.

The browser I used is DB Browser for SQLite and can be installed from -
https://github.com/sqlitebrowser/sqlitebrowser/releases

or with

Homebrew Cask: https://caskroom.github.io/ using the
shell command: brew cask install db-browser-for-sqlite

It allows for import/export of sqlite databases in various formats.

Not sure whether this helps, but you can also read .sqlite files from JavaScript for Automation:

(() => {
    'use strict';

    ObjC.import('sqlite3');

    // GENERIC FUNCTIONS -----------------------------------------------------

    // Just :: a -> Just a
    const Just = x => ({
        type: 'Maybe',
        Nothing: false,
        Just: x
    });

    // Left :: a -> Either a b
    const Left = x => ({
        type: 'Either',
        Left: x
    });

    // Nothing :: () -> Nothing
    const Nothing = () => ({
        type: 'Maybe',
        Nothing: true,
    });

    // Right :: b -> Either a b
    const Right = x => ({
        type: 'Either',
        Right: x
    });

    // Tuple (,) :: a -> b -> (a, b)
    const Tuple = (a, b) => ({
        type: 'Tuple',
        '0': a,
        '1': b
    });

    // bindEither (>>=) :: Either a -> (a -> Either b) -> Either b
    const bindEither = (m, mf) =>
        m.Right !== undefined ? (
            mf(m.Right)
        ) : m;

    // filePath :: String -> FilePath
    const filePath = s =>
        ObjC.unwrap(ObjC.wrap(s)
            .stringByStandardizingPath);

    // showJSON :: a -> String
    const showJSON = x => JSON.stringify(x, null, 2);

    // (x => Maybe [value, remainder] -> initial value -> values
    // unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
    const unfoldr = (f, v) => {
        let xs = [];
        return (
            until(
                mb => mb.Nothing,
                mb => (
                    xs.push(mb.Just[0]),
                    f(mb.Just[1])
                ), Just(Tuple(v, v))
            ),
            xs.slice(1)
        );
    };

    // until :: (a -> Bool) -> (a -> a) -> a -> a
    const until = (p, f, x) => {
        let v = x;
        while (!p(v)) v = f(v);
        return v;
    };

    //------------------------------------------------------------------------
    // MAIN: SIMPLE EXAMPLE OF TABLE-READING FROM JAVASCRIPT FOR AUTOMATION

    const
        strPath = '~/Library/Application Support/Keyboard Maestro/' +
        'Keyboard Maestro Dictionaries.sqlite',

        strSQL = 'SELECT dictionary, key, value FROM dictionaries';

    const
        SQLITE_OK = parseInt($.SQLITE_OK, 10),
        SQLITE_ROW = parseInt($.SQLITE_ROW, 10),
        ppDb = Ref();

    const lrRows = (
        bindEither(
            bindEither(
                $.sqlite3_open(filePath(strPath), ppDb) !== SQLITE_OK ? (
                    Left($.sqlite3_errmsg(ppDb[0]))
                ) : Right(ppDb[0]),

                db => {
                    const ppStmt = Ref();
                    return $.sqlite3_prepare_v2(
                        db, strSQL, -1, ppStmt, Ref()
                    ) !== SQLITE_OK ? (
                        Left($.sqlite3_errmsg(db))
                    ) : Right(Tuple(db, ppStmt[0]));
                }
            ),

            tpl => Right(unfoldr(
                stmt => SQLITE_ROW === $.sqlite3_step(stmt) ? (
                    Just(Tuple(
                        [0, 1, 2].map(i => $.sqlite3_column_text(stmt, i)),
                        stmt
                    ))
                ) : (
                    $.sqlite3_finalize(stmt),
                    $.sqlite3_close(tpl[0]),
                    Nothing()
                ),
                tpl[1]
            ))
        )
    );

    return showJSON(
        lrRows.Right || lrRows.Left
    );
})();

As noted, the dictionaries are stored in sqlite files in the Keyboard Maestro preferences folder. I would definitely not recommend copying it to another Mac - in general, you should not make any changes to files in that folder while Keyboard Maestro Engine or Keyboard Maestro editor is running.

Also, as noted, only macros are synced, not data.

So if you want to sync the dictionaries, I would suggest you copy them from/to a text file in Dropbox (or maybe iCloud Drive or whatever). At the start of your macro, clear your dictionary, copy the entries from the text sync file, and then at the end, copy from your dictionary to the text sync file. There is, of course, a problem if you run macros on both Macs without allowing the sync to complete first.

There are many other plausible solutions to this problem. For example, you could set up some sort of database server. Or, whenever you want to change a dictionary, you could just a remote trigger that both Macs here and so both Macs change their dictionary (presuming both Macs are always awake).

Certainly it helps, thank you!

I have completed an Applescript that will dump a dictionary to a CSV file on the Desktop. It isn’t quite finished yet, still needs a few bells and whistles.

As an aside, does anyone have a good resource for learning JXA?

p.s. Thank you Peter For your response

See my list of JXA Resources


KM Dictionaries vs JavaScript

If you are open to learning a bit of JavaScript, then I’d suggest you investigate the use of JSON in JavaScript.

KM provides a good, but basic, implementation of dictionaries. They work well for simple use cases with limited data. But if your needs are more complex and/or you have a lot of data, then using JXA makes a lot of sense to me.

JavaScript makes the handling of arrays, objects, and a combination of the two very easy, and very powerful. Then you can easily use JSON to output these as text files that make sharing with other apps and devices very easy.

Good luck, and let us know how it goes.

Just pulled it up, many thanks!