~ruther/qmk_firmware

803610a284ac886eaeb319b4a8d25ffbd2861152 — milestogo 5 years ago cd0edbb
[Keymap] initial user directory for milestogo + babblepaste  (#7698)

* initial user directory

* fix missing endif in vi mode

* fix includes per drashna and a few typos. I have not tested the userspace keymap, it is just there to help keep the user space and keymap in sync

* move babblepaste docs to md format

* clean up block quotes

* TIL clang-format - miles2go userspace
A users/miles2go/babblePaste.c => users/miles2go/babblePaste.c +125 -0
@@ 0,0 1,125 @@
/*  A library to output the right key shortcut in any common app.
Given a global variable babble_mode to show the environment and a
key that calls the paste macro, do the right type of paste.
Setting the context is done by another macro, or TBD interaction with the host.

Huge thanks to https://en.wikipedia.org/wiki/Table_of_keyboard_shortcuts
and https://github.com/qmk/qmk_firmware/blob/master/keyboards/planck/keymaps/jeebak/keymap.c
*/

#include QMK_KEYBOARD_H

#ifdef USE_BABBLEPASTE
#    include "babblePaste.h"

// small function that we might also want to call from a keymap.

// GLOBAL variable to determine mode.  Sets startup default if no eeppom
uint8_t babble_mode = 0;

// function to tell the user that the mode has changed
__attribute__((weak)) void babble_led_user(void) {}

void set_babble_mode(uint8_t id) { babble_mode = id; }

void babble_mode_increment() {
    babble_mode += 1;
    if (babble_mode >= BABL_MODEMAX) {
        babble_mode = 0;
    }
}

void babble_mode_decrement() {
    if (babble_mode >= 1) {
        babble_mode -= 1;
    } else {
        babble_mode = BABL_MODEMAX - 1;
    }
}

/* this function runs the appropriate babblepaste macro, given
the global babble_mode and a keycode defined in the babble_keycodes enum.

This could be made faster by splitting into two functions sorted by keycode range
But that makes for a *lot* of ifdefs.
*/
bool babblePaste(uint16_t keycode) {
    // handle the OS/mode  switching first

#    ifdef BABL_MAC
    if (keycode == BABL_DO_MAC) {
        set_babble_mode(BABL_MAC_MODE);
        babble_led_user();
        return true;
    }

    if (babble_mode == BABL_MAC_MODE) {
        babblePaste_mac(keycode);
    }
#    endif

#    ifdef BABL_VI
    if (keycode == BABL_DO_VI) {
        set_babble_mode(BABL_VI_MODE);
        babble_led_user();
        return true;
    }
    if (babble_mode == BABL_VI_MODE) {
        babblePaste_vi(keycode);
    }
#    endif
#    ifdef BABL_WINDOWS
    if (keycode == BABL_DO_WINDOWS) {
        set_babble_mode(BABL_WINDOWS_MODE);
        babble_led_user();
        return true;
    }
    if (babble_mode == BABL_WINDOWS_MODE) {
        babblePaste_win(keycode);
    }
#    endif
#    ifdef BABL_LINUX
    if (keycode == BABL_DO_LINUX) {
        set_babble_mode(BABL_LINUX_MODE);
        babble_led_user();
        return true;
    }
    if (babble_mode == BABL_LINUX_MODE) {
        babblePaste_linux(keycode);
    }
#    endif
#    ifdef BABL_EMACS
    if (keycode == BABL_DO_EMACS) {
        set_babble_mode(BABL_EMACS_MODE);
        babble_led_user();
        return true;
    }
    if (babble_mode == BABL_EMACS_MODE) {
        babblePaste_emacs(keycode);
    }
#    endif
#    ifdef BABL_CHROME
    if (keycode == BABL_DO_CHROMEOS) {
        set_babble_mode(BABL_CHROMEOS_MODE);
        babble_led_user();
        return true;
    }
    if (babble_mode == BABL_CHROMEOS_MODE) {
        babblePaste_readmux(keycode);
    }
#    endif
#    ifdef BABL_READMUX
    if (keycode == BABL_DO_READMUX) {
        set_babble_mode(BABL_READMUX_MODE);
        babble_led_user();
        return true;
    }
    if (babble_mode == BABL_READMUX_MODE) {
        babblePaste_readmux(keycode);
    }
#    endif

    return false;
}

#endif  // USE_BABBLEPASTE

A users/miles2go/babblePaste.h => users/miles2go/babblePaste.h +349 -0
@@ 0,0 1,349 @@
/*  A library to output the right key shortcut in any common app.
Given a global variable babble_mode to show the environment and a
key that calls the paste macro, do the right type of paste.

Setting the bable_mode is done by another macro, or TBD interaction with the host.

Huge thanks to https://en.wikipedia.org/wiki/Table_of_keyboard_shortcuts
and jeebak & algernon's keymap
*/

#pragma once
#include "quantum.h"

#ifdef USE_BABBLEPASTE

void set_babble_mode(uint8_t id);
void babble_mode_increment(void);
void babble_mode_decrement(void);
void babble_led_user(void);

// manually re-order these if you want to set the order or default.
enum babble_modes {
#    ifdef BABL_MAC
    BABL_MAC_MODE,
#    endif
#    ifdef BABL_READMUX
    BABL_READMUX_MODE,
#    endif
#    ifdef BABL_WINDOWS
    BABL_WINDOWS_MODE,
#    endif
#    ifdef BABL_VI
    BABL_VI_MODE,
#    endif
#    ifdef BABL_LINUX
    BABL_LINUX_MODE,
#    endif
#    ifdef BABL_EMACS
    BABL_EMACS_MODE,
#    endif
#    ifdef BABL_CHROMEOS
    BABL_CHROMEOS_MODE,
#    endif
    BABL_MODEMAX
};

// void babble_led_user( uint8_t id)

/// Hacks to make it easier to create sendstring macros

//"outer" versions wrap text
#    define OMCTL(arg) SS_DOWN(X_LCTRL) arg SS_UP(X_LCTRL)
#    define OMGUI(arg) SS_DOWN(X_LGUI) arg SS_UP(X_LGUI)
#    define OMALT(arg) SS_DOWN(X_LALT) arg SS_UP(X_LALT)
#    define OMSFT(...) SS_DOWN(X_LSHIFT) __VA_ARGS__ SS_UP(X_LSHIFT)
//"inner" versions wrap a key tap
#    define IMCTL(arg) SS_DOWN(X_LCTRL) SS_TAP(arg) SS_UP(X_LCTRL)
#    define IMGUI(arg) SS_DOWN(X_LGUI) SS_TAP(arg) SS_UP(X_LGUI)
#    define IMALT(arg) SS_DOWN(X_LALT) SS_TAP(arg) SS_UP(X_LALT)
#    define IMSFT(arg) SS_DOWN(X_LSHIFT) SS_TAP(arg) SS_UP(X_LSHIFT)

#    define BABLM(ent, ...)           \
        if (ent == keycode) {         \
            SEND_STRING(__VA_ARGS__); \
            return true;              \
        }

// BabblePaste should be loaded first (header in userspace .h file, before all else)
// if not,we'll do our best.
#    if defined(NEW_SAFE_RANGE)
#        define BABBLE_START NEW_SAFE_RANGE
#    else
#        if defined(KEYMAP_SAFE_RANGE)
#            define BABBLE_START KEYMAP_SAFE_RANGE
#        else
#            define BABBLE_START SAFE_RANGE
#        endif
#    endif

enum babble_keycodes {
    FIRST = BABBLE_START,
#    ifdef BABL_MOVE
    // Movement macros
    // left & right
    BABL_GO_LEFT_1C,
    BABL_GO_RIGHT_1C,
    BABL_GO_LEFT_WORD,
    BABL_GO_RIGHT_WORD,
    BABL_GO_START_LINE,
    BABL_GO_END_LINE,
    // now up & down
    BABL_GO_START_DOC,
    BABL_GO_END_DOC,
    BABL_GO_NEXT_LINE,
    BABL_GO_PREV_LINE,
    BABL_GO_PARA_START,
    BABL_GO_PARA_END,
    BABL_PGDN,
    BABL_PGUP,
    // And the delete options
    BABL_DEL_LEFT_1C,   // == backspace, so why bother?
    BABL_DEL_RIGHT_1C,  // usually = Del
    BABL_DEL_LEFT_WORD,
    BABL_DEL_RIGHT_WORD,
    BABL_DEL_TO_LINE_END,    // delete from cursor to end of line
    BABL_DEL_TO_LINE_START,  // delete from cursor to begining line
    BABL_MODE,               // print out string saying what mode we're in.
#    endif
#    ifdef BABL_OSKEYS
    BABL_UNDO,
    BABL_REDO,
    BABL_CUT,
    BABL_COPY,
    BABL_PASTE,
    BABL_SELECT_ALL,
    /* not yet implemented
    BABL_SWAP_LAST2C, // swap last characters before the cursor
    BABL_SWAP_LAST2W, // Swap the last two words before the cursor
    */
    // find & replace
    BABL_FIND,
    BABL_FIND_NEXT,
    BABL_FIND_PREV,
    BABL_FIND_REPLACE,
    // GUI or app
    BABL_RUNAPP,
    BABL_SWITCH_APP_NEXT,
    BABL_SWITCH_APP_LAST,  // previous
    BABL_WINDOW_NEXT,
    BABL_WINDOW_PREV,
    BABL_WINDOW_NEW,
    BABL_CLOSE_APP,
    BABL_HELP,
    BABL_LOCK,
    BABL_SCREENCAPTURE,
    BABL_SWITCH_KEYBOARD_LAYOUT,
#    endif
#    ifdef BABL_BROWSER
    BABL_BROWSER_NEW_TAB,
    BABL_BROWSER_CLOSE_TAB,
    BABL_BROWSER_REOPEN_LAST_TAB,
    BABL_BROWSER_NEXT_TAB,
    BABL_BROWSER_PREV_TAB,
    BABL_BROWSER_URL_BAR,
    BABL_BROWSER_FORWARD,
    BABL_BROWSER_BACK,
    BABL_BROWSER_FIND,
    BABL_BROWSER_BOOKMARK,
    BABL_BROWSER_DEV_TOOLS,  // hard one to remember
    BABL_BROWSER_RELOAD,
    BABL_BROWSER_FULLSCREEN,
    BABL_BROWSER_ZOOM_IN,
    BABL_BROWSER_ZOOM_OUT,
    BABL_BROWSER_VIEWSRC,
#    endif
#    ifdef BABL_APP
    BABL_APP_SAVE,                // save file blurs app & os. Move?
    BABL_APP_PASTE_VALUES,        // paste only values, or with some special formatting. ctrl shift v chrome, // Ctrl+Alt+V, excel
                                  // App hotkeys will be flawed, since you may use different spreadsheets across OSes.
#        ifdef BABL_APP_CELLS     // spreadsheets and tables
    BABL_APP_CENTER_ALIGN,        // Center align contents of a cell in table or spreadsheet.
    BABL_APP_CLEAR_FORMATTING,    //
    BABL_APP_SCROLL_ACTIVE_CELL,  // scroll to active cell.
    BABL_NEWLINE_IN_CELL,         // newline inside cell of table,
    BABL_INSERT_COMMENT,          // insert comment
    BABL_INSERT_COL_LEFT,         // insert columns to the left
    BABL_INSERT_ROW,              // insert row
    BABL_DELETE_ROW,              // delete row // excel ctrl minus // chrome ctrl alt minus
    BABL_SELECT_COL,              // select column - ctrl space //same in both
    BABL_SELECT_ROW,              // select row shift spaced // same in both.
#        endif                    // BABL_APP_CELLS
#        ifdef BABL_APP_EDITOR
    BABL_APP_MULTI_SELECT, /* www.sublimetext.com/docs/2/multiple_selection_with_the_keyboard.html */
#        endif             // BABL_APP_EDITOR
#        ifdef BABL_APP_WINDOWSPLITTING
    // These aren't useful on most oses.
    BABL_SPLIT_FRAME_VERT,
    BABL_UNSPLIT_FRAME_VERT,
    BABL_SPLIT_FRAME_HORIZONTAL,
    BABL_UNSPLIT_FRAME_HORIZONTAL,
    BABL_NEXT_FRAME,
    BABL_PREV_FRAME,
#        endif

#    endif

// Macros for mode switching
#    ifdef BABL_WINDOWS
    BABL_DO_WINDOWS,
#    endif
#    ifdef BABL_MAC
    BABL_DO_MAC,
#    endif
#    ifdef BABL_LINUX
    BABL_DO_LINUX,
#    endif
#    ifdef BABL_EMACS
    BABL_DO_EMACS,
#    endif
#    ifdef BABL_VI
    BABL_DO_VI,
#    endif
#    ifdef BABL_READMUX
    BABL_DO_READMUX,
#    endif
#    ifdef BABL_CHROMEOS
    BABL_DO_CHROMEOS,
#    endif
    BABBLE_END_RANGE
};

// primary function.
bool babblePaste(uint16_t keycode);

/****************************************************/
/* All per-os includes and short mode switch macros*/
#    ifdef BABL_WINDOWS
#        define B_WIN BABL_DO_WINDOWS
bool babblePaste_win(uint16_t keycode);
#    endif
#    ifdef BABL_MAC
#        define B_MAC BABL_DO_MAC
bool babblePaste_mac(uint16_t keycode);
#    endif
#    ifdef BABL_LINUX
#        define B_LINUX BABL_DO_LINUX
bool babblePaste_linux(uint16_t keycode);
#    endif
#    ifdef BABL_EMACS
#        define B_EMACS BABL_DO_EMACS
bool babblePaste_emacs(uint16_t keycode);
#    endif
#    ifdef BABL_VI
#        define B_VI BABL_DO_VI
bool babblePaste_vi(uint16_t keycode);
#    endif
#    ifdef BABL_READMUX
#        define B_READ BABL_DO_READMUX
bool babblePaste_readmux(uint16_t keycode);
#    endif
#    ifdef BABL_CHROMEOS
#        define B_CROM BABL_DO_CHROMEOS
bool babblePaste_chromeos(uint16_t keycode);
#    endif

#    define BABL_INC babble_mode_increment();
#    define BABL_DEC babble_mode_decrement();

/****************************************************
**    All keyboard macros for Babble Actions
*****************************************************/

#    ifdef BABL_MOVE
#        define B_L1C BABL_GO_LEFT_1C
#        define B_R1C BABL_GO_RIGHT_1C
#        define B_L1W BABL_GO_LEFT_WORD
#        define B_R1W BABL_GO_RIGHT_WORD
#        define B_GSOL BABL_GO_START_LINE
#        define B_GEOL BABL_GO_END_LINE
#        define B_GTOP BABL_GO_START_DOC
#        define B_GEND BABL_GO_END_DOC
#        define B_DOWN BABL_GO_NEXT_LINE
#        define B_UP BABL_GO_PREV_LINE
#        define B_PTOP BABL_GO_PARA_START
#        define B_PEND BABL_GO_PARA_END
#        define B_PGDN BABL_PGDN
#        define B_PGUP BABL_PGUP
//#define B_BKSP  BABL_DEL_LEFT_1C == backspace so why bother.
#        define B_DEL BABL_DEL_RIGHT_1C  // usually = Del
#        define B_DLW BABL_DEL_LEFT_WORD
#        define B_DRW BABL_DEL_RIGHT_WORD
#        define B_DEOL BABL_DEL_TO_LINE_END    // delete from cursor to end of line
#        define B_DSOL BABL_DEL_TO_LINE_START  // delete from cursor to begining line
#        define B_MODE BABL_MODE               // type out name of current mode.
#    endif

#    ifdef BABL_OSKEYS
#        define B_UNDO BABL_UNDO
#        define B_REDO BABL_REDO
#        define B_CUT BABL_CUT
#        define B_COPY BABL_COPY
#        define B_PASTE BABL_PASTE
#        define B_SELALL BABL_SELECT_ALL
#        define B_SELA BABL_SELECT_ALL
#        define B_FIND BABL_FIND
#        define B_FINDN BABL_FIND_NEXT
#        define B_FINDP BABL_FIND_PREV
#        define B_RPLACE BABL_FIND_REPLACE
#        define B_RUNAPP BABL_RUNAPP
#        define B_NAPP BABL_SWITCH_APP_NEXT
#        define B_PAPP BABL_SWITCH_APP_LAST  // previous
#        define B_NWIN BABL_WINDOW_NEXT
#        define B_PWIN BABL_WINDOW_PREV
#        define B_WINN BABL_WINDOW_NEW
#        define B_CAPP BABL_CLOSE_APP
#        define B_HELP BABL_HELP
#        define B_LOCK BABL_LOCK
#        define B_SCAP BABL_SCREENCAPTURE
#        define B_KEYB BABL_SWITCH_KEYBOARD_LAYOUT
#    endif

#    ifdef BABL_BROWSER
#        define B_NTAB BABL_BROWSER_NEW_TAB
#        define B_CTAB BABL_BROWSER_CLOSE_TAB
#        define B_ROTB BABL_BROWSER_REOPEN_LAST_TAB
#        define B_NXTB BABL_BROWSER_NEXT_TAB
#        define B_PTAB BABL_BROWSER_PREV_TAB
#        define B_NURL BABL_BROWSER_URL_BAR
#        define B_BFWD BABL_BROWSER_FORWARD
#        define B_BBAK BABL_BROWSER_BACK
#        define B_BFND BABL_BROWSER_FIND
#        define B_BOOK BABL_BROWSER_BOOKMARK
#        define B_BDEV BABL_BROWSER_DEV_TOOLS  // hard one to remember
#        define B_BRLD BABL_BROWSER_RELOAD
#        define B_BFULL BABL_BROWSER_FULLSCREEN
#        define B_ZIN BABL_BROWSER_ZOOM_IN
#        define B_ZOUT BABL_BROWSER_ZOOM_OUT
#    endif

#    ifdef BABL_APP
#        define B_SAVE BABL_APP_SAVE
#        ifdef BABL_APP_CELLS  // spreadsheets and tables
#            define B_PASTV BABL_APP_PASTE_VALUES
#            define B_CALN BABL_APP_CENTER_ALIGN
#            define B_CFMT BABL_APP_CLEAR_FORMATTING
#            define B_SCLA BABL_APP_SCROLL_ACTIVE_CELL
#            define B_NCEL BABL_NEWLINE_IN_CELL
#            define B_IPRW BABL_INSERT_ROW_ABOVE
#            define B_ICOL BABL_INSERT_COL_LEFT
#            define B_IROW BABL_INSERT_ROW
#            define B_DROW BABL_DELETE_ROW
#            define B_SELC BABL_SELECT_COL
#            define B_SELR BABL_SELECT_ROW
#        endif  // BABL_APP_CELLS
#        ifdef BABL_APP_EDITOR
#            define B_MSEL BABL_APP_MULTI_SELECT
/* www.sublimetext.com/docs/2/multiple_selection_with_the_keyboard.html */
#        endif  // BABL_APP_EDITOR
#        ifdef BABL_APP_WINDOWSPLITTING
#            define B_VSPLIT BABL_SPLIT_FRAME_VERT
#            define B_VUNSPT BABL_UNSPLIT_FRAME_VERT
#            define B_HSPLIT BABL_SPLIT_FRAME_HORIZONTAL
#            define B_HUNSPT BABL_UNSPLIT_FRAME_HORIZONTAL
#            define B_NXTFM BABL_NEXT_FRAME
#            define B_PRVFM BABL_PREV_FRAME
#        endif  // BABL_APP_WINDOWSPLITTING
#    endif      // BABL_APP

#endif

A users/miles2go/babblePaste.md => users/miles2go/babblePaste.md +207 -0
@@ 0,0 1,207 @@
## Babblepaste, a universal translator for keyboard shortcuts

The idea is to have one "paste" key do the right thing for any operating system.
Put the keyboard in Windows mode, and  "paste" means Ctrl-v.
Switch to Emacs and "Paste" means Ctrl-y.  Mac is GUI-v and so on.

Currently supported modes are Windows, OS X, Gnome/KDE, Emacs, VI , ChromeOS, and Readline, with 70+ common macro actions.

The babblepaste library looks for the current OS in the babble_mode global variable.
To switch modes, run the switch_babble_mode() function, or a pre defined BABL_DO_x macro.

**BE CAREFUL**
  * Not all actions are defined for all OSes. The default is to do nothing.
  * Not all actions are _TESTED_ on all OSes.
  * Keys can have very different meanings between windows in the same OS. If you switch apps without switching modes, bad things can happen.

###To use the library
#### Add #defines to your config.h.
```
    #define USE_BABBLEPASTE
    
    //// Uncomment the modes you want to enable
    #define BABL_WINDOWS
    #define BABL_READMUX
    #define BABL_VI
    #define BABL_MAC
    #define BABL_LINUX
    #define BABL_EMACS
    #define BABL_CHROMEOS
    
    //// These enable subsets of babble macros. Disable options to save space
    #define BABL_MOVE // Uncomment to add basic cursor movement
    #define BABL_OSKEYS // This adds Cut, paste, window movement and common OS shortcuts
    #define BABL_BROWSER // Browser shortcuts
    
    //// What Browser shortcuts?
    #define BABL_BROWSER_CHROME // Chrome browser, Google apps
    //#define BABL_BROWSER_MS
    //#define BABL_BROWSER_SAFARI // Safari, Apple defaults.
    
    //// applications vary even more between OSes. We'll do our best.
    #define BABL_APP
    // To enable specific App options.
    #define BABL_APP_CELLS // spreadsheets and tables
    #define BABL_APP_EDITOR // Fancy editor commands
    #define BABL_APP_WINDOWSPLITTING // splitting frames & windows
    
    //// What App keybinding is assumed?
    //#define BABL_APP_GOOGLE // Google office
    #define BABL_APP_MSOFFICE // MS office
    //#define BABL_APP_APPLE // Apple office
    #define BABL_APP_SUBLIME
```

#### Enable Babblepaste in your Keymap

Add the following to your keymap in process_record_user, before the main switch statement.
```
  #ifdef USE_BABBLEPASTE
       if( keycode > BABBLE_START && keycode < BABBLE_END_RANGE )  {
          if (record->event.pressed)  { // is there a case where this isn't desired?
            babblePaste ( keycode );
          } else{
            return true;
          }
        }
  #endif
```

#### Add makefile rules

Update your rules.mk to include the modes you want.

    `SRC += babblePaste.c babl_windows.c babl_mac.c babl_vi.c babl_readmux.c  babl_chromeos.c babl_emacs.c babl_linux.c`


#### Custom Keycodes

If you are using custom keycodes, update the safe range in your user.h
```
  #if defined(BABBLE_END_RANGE)
        #define USER_START BABBLE_END_RANGE
  #else
      #if defined(KEYMAP_SAFE_RANGE)
          #define USER_START KEYMAP_SAFE_RANGE
      #else
          #define USER_START SAFE_RANGE
      #endif
  #endif
```

#### Add Babblepaste actions to your keymap.
See the full list in babblePaste.h, or the list below
```
  B_WIN // switch babblepaste to  windows mode.
  B_MAC // Mac Mode
  B_LNX // switch to linux
  B_VI // switch to Vi mode
  B_EMAX //  switch mode to emacs
  B_READ // switch to readline /tmux mode
  B_CROM // switch to chromeos mode.

  #define B_L1C  BABL_GO_LEFT_1C
  #define B_R1C  BABL_GO_RIGHT_1C
  #define B_L1W  BABL_GO_LEFT_WORD
  #define B_R1W  BABL_GO_RIGHT_WORD
  #define B_GSOL  BABL_GO_START_LINE
  #define B_GEOL  BABL_GO_END_LINE
  #define B_GTOP  BABL_GO_START_DOC
  #define B_GEND  BABL_GO_END_DOC
  #define B_DOWN  BABL_GO_NEXT_LINE
  #define B_UP    BABL_GO_PREV_LINE
  #define B_PTOP  BABL_GO_PARA_START
  #define B_PEND  BABL_GO_PARA_END
  #define B_PGDN  BABL_PGDN
  #define B_PGUP  BABL_PGUP
  #define B_DEL    BABL_DEL_RIGHT_1C
  #define B_DLW    BABL_DEL_LEFT_WORD
  #define B_DRW    BABL_DEL_RIGHT_WORD
  #define B_DEOL  BABL_DEL_TO_LINE_END // delete from cursor to end of line
  #define B_DSOL  BABL_DEL_TO_LINE_START // delete from cursor to begining line
  #define B_MODE   BABL_MODE //type out name of current mode.

  #define B_UNDO    BABL_UNDO
  #define B_REDO    BABL_REDO
  #define B_CUT     BABL_CUT
  #define B_COPY    BABL_COPY
  #define B_PASTE    BABL_PASTE
  #define B_SELALL    BABL_SELECT_ALL
  #define B_SELA    BABL_SELECT_ALL
  #define B_FIND     BABL_FIND
  #define B_FINDN    BABL_FIND_NEXT
  #define B_FINDP    BABL_FIND_PREV
  #define B_RPLACE    BABL_FIND_REPLACE
  #define B_RUNAPP    BABL_RUNAPP
  #define B_NAPP  BABL_SWITCH_APP_NEXT
  #define B_PAPP  BABL_SWITCH_APP_LAST // previous
  #define B_CAPP  BABL_CLOSE_APP
  #define B_HELP  BABL_HELP

  #define B_NTAB  BABL_BROWSER_NEW_TAB
  #define B_CTAB  BABL_BROWSER_CLOSE_TAB
  #define B_ROTB  BABL_BROWSER_REOPEN_LAST_TAB
  #define B_NXTB  BABL_BROWSER_NEXT_TAB
  #define B_PTAB  BABL_BROWSER_PREV_TAB
  #define B_NURL  BABL_BROWSER_URL_BAR
  #define B_BFWD  BABL_BROWSER_FORWARD
  #define B_BBAK  BABL_BROWSER_BACK
  #define B_BFND  BABL_BROWSER_FIND
  #define B_BOOK  BABL_BROWSER_BOOKMARK
  #define B_BDEV  BABL_BROWSER_DEV_TOOLS // hard one to remember
  #define B_BRLD  BABL_BROWSER_RELOAD
  #define B_BFULL BABL_BROWSER_FULLSCREEN
  #define B_ZIN    BABL_BROWSER_ZOOM_IN
  #define B_ZOUT  BABL_BROWSER_ZOOM_OUT

  #define B_PASTV BABL_APP_PASTE_VALUES
  #define B_CALN  BABL_APP_CENTER_ALIGN
  #define B_CFMT  BABL_APP_CLEAR_FORMATTING
  #define B_SCLA  BABL_APP_SCROLL_ACTIVE_CELL
  #define B_NCEL  BABL_NEWLINE_IN_CELL
  #define B_IPRW  BABL_INSERT_ROW_ABOVE
  #define B_ICOL  BABL_INSERT_COL_LEFT
  #define B_IROW  BABL_INSERT_ROW
  #define B_DROW  BABL_DELETE_ROW
  #define B_SELC  BABL_SELECT_COL
  #define B_SELR  BABL_SELECT_ROW

  #define B_MSEL    BABL_APP_MULTI_SELECT
  #define B_VSPLIT  BABL_SPLIT_FRAME_VERT
  #define B_VUNSPT  BABL_UNSPLIT_FRAME_VERT
  #define B_HSPLIT  BABL_SPLIT_FRAME_HORIZONTAL
  #define B_HUNSPT  BABL_UNSPLIT_FRAME_HORIZONTAL
  #define B_NXTFM   BABL_NEXT_FRAME
  #define B_PRVFM   BABL_PREV_FRAME
```


## Development FAQs

**Todos**
eeprom store state of babble_mode? or update docs so that people can change the order of the enum in
babblespace.h?

**You have huge ifdef stanzas instead of functions**
This fails gracefully if you don't have all options defined. Patch if you can think how to use fewer defines.

** Why not an array of arrays as a lookup instead of a function?**
This would allow you to store the lookup table in PROGMEM.
True, but that takes more pre-processor skill than I have, and may be less portable to ARM or other flash mappings.

** Have you tested every key on every platform?**
No. Be careful, submit a patch.

** Why not update Apps at the same global level as the OS? **
This is only a good thing if it doesn't confuse the user. If you can show state of OS vs App, it's probably a good thing.

** Can the OS tell the keyboard what mode to use? **
The keyboard side is easy to do with virtser_recv & a function that updates babble_mode. It still needs a PC side app to track where the keyboard focus is.
One could use a keyboard macro to launch an app & switch modes for that app.

## Thanks

Thanks to [wikipedia shortcuts page](https://en.wikipedia.org/wiki/Table_of_keyboard_shortcuts)
and [Jeebak's keymap](https://github.com/qmk/qmk_firmware/blob/master/keyboards/planck/keymaps/jeebak/keymap.c)
this [howtogeek shortcuts page](https://www.howtogeek.com/115664/42-text-editing-keyboard-shortcuts-that-work-almost-everywhere/)
And of course QMK...

A users/miles2go/babl_chromeos.c => users/miles2go/babl_chromeos.c +103 -0
@@ 0,0 1,103 @@
/*  A library to output the right key shortcut in any common app.
Given a global variable babble_mode to show the environment and a
key that calls the paste macro, do the right type of paste.
Setting the context is done by another macro, or TBD interaction with the host.

https://support.google.com/docs/answer/181110?co=GENIE.Platform%3DDesktop&hl=en

*/

#include QMK_KEYBOARD_H

#ifdef USE_BABBLEPASTE
#    include "babblePaste.h"

#    ifdef BABL_CHROMEOS

bool babblepaste_chromeos(uint16_t keycode) {
#        ifdef BABL_MOVE
    BABLM(BABL_GO_LEFT_1C, SS_TAP(X_LEFT));
    BABLM(BABL_GO_RIGHT_1C, SS_TAP(X_RIGHT));
    BABLM(BABL_GO_LEFT_WORD, IMCTL(X_LEFT));
    BABLM(BABL_GO_RIGHT_WORD, IMCTL(X_RIGHT));
    BABLM(BABL_GO_START_LINE, SS_TAP(X_HOME));
    BABLM(BABL_GO_END_LINE, SS_TAP(X_END));
    BABLM(BABL_GO_START_DOC, IMCTL(X_HOME));
    BABLM(BABL_GO_END_DOC, IMCTL(X_END));
    BABLM(BABL_GO_NEXT_LINE, SS_TAP(X_DOWN));
    BABLM(BABL_GO_PREV_LINE, SS_TAP(X_UP));
    BABLM(BABL_GO_PARA_START, IMCTL(X_UP));  // untested
    BABLM(BABL_GO_PARA_END, IMCTL(X_DOWN));  // untested
    BABLM(BABL_PGDN, IMGUI(X_DOWN));
    BABLM(BABL_PGUP, IMGUI(X_UP));
    BABLM(BABL_DEL_RIGHT_1C, IMALT(X_BSPACE));
    BABLM(BABL_DEL_LEFT_WORD, IMCTL(X_BSPACE));
    BABLM(BABL_DEL_RIGHT_WORD, OMSFT(IMCTL(X_RIGHT)) SS_TAP(X_BSPACE));
    BABLM(BABL_DEL_TO_LINE_END, OMSFT(IMGUI(X_LEFT)) SS_TAP(X_BSPACE));
    BABLM(BABL_DEL_TO_LINE_START, OMSFT(IMGUI(X_RIGHT)) SS_TAP(X_BSPACE));
    BABLM(BABL_MODE, ("ChromeOS "));
#        endif
#        ifdef BABL_OSKEYS
    BABLM(BABL_UNDO, SS_LCTRL("z"));
    BABLM(BABL_REDO, OMSFT(IMCTL(X_Z)));
    BABLM(BABL_CUT, SS_LCTRL("x"));
    BABLM(BABL_COPY, SS_LCTRL("c"));
    BABLM(BABL_PASTE, SS_LCTRL("v"));
    BABLM(BABL_SELECT_ALL, SS_LCTRL("a"));
    BABLM(BABL_FIND, SS_LCTRL("f"));
    BABLM(BABL_FIND_NEXT, SS_LCTRL("g"));
    BABLM(BABL_FIND_PREV, OMSFT(IMCTL(X_G)));
    BABLM(BABL_WINDOW_NEW, IMCTL(X_N));
    //	BABLM( BABL_FIND_REPLACE,		() ); // not part of Chrome
    // BABLM( BABL_RUNAPP, 	SS_TAP(X_LGUI) ); // not sure of this
    BABLM(BABL_SWITCH_APP_NEXT, IMALT(X_TAB));
    BABLM(BABL_SWITCH_APP_LAST, OMSFT(IMALT(X_TAB)));
    BABLM(BABL_CLOSE_APP, OMSFT(IMCTL(X_W)));
    // BABLM( BABL_HELP,		OMCTL(IMALT(X_SLASH))	); // general help
    BABLM(BABL_HELP, IMCTL(X_SLASH));  // this is keyboard accelerator lookup
    BABLM(BABL_LOCK, SS_LGUI("l"));    // should be caps?
    BABLM(BABL_SCREENCAPTURE, OMSFT(IMCTL(X_F5)));
    BABLM(BABL_SWITCH_KEYBOARD_LAYOUT, IMCTL(X_SPACE));
#        endif
#        ifdef BABL_BROWSER
    BABLM(BABL_BROWSER_NEW_TAB, SS_LCTRL("t"));
    BABLM(BABL_BROWSER_CLOSE_TAB, SS_LCTRL("w"));
    BABLM(BABL_BROWSER_REOPEN_LAST_TAB, OMSFT(IMCTL(X_T)));
    BABLM(BABL_BROWSER_NEXT_TAB, IMCTL(X_TAB));
    BABLM(BABL_BROWSER_PREV_TAB, OMSFT(IMCTL(X_TAB)));
    BABLM(BABL_BROWSER_URL_BAR, SS_LCTRL("l"));
    BABLM(BABL_BROWSER_FORWARD, IMALT(X_RIGHT));
    BABLM(BABL_BROWSER_BACK, IMALT(X_LEFT));
    ;
    BABLM(BABL_BROWSER_FIND, SS_LCTRL("f"));
    BABLM(BABL_BROWSER_BOOKMARK, SS_LCTRL("d"));
    BABLM(BABL_BROWSER_DEV_TOOLS, OMSFT(IMCTL(X_I)));
    BABLM(BABL_BROWSER_RELOAD, OMSFT(IMCTL(X_R)));       // hard reload w/o cache
    BABLM(BABL_BROWSER_FULLSCREEN, SS_TAP(X_F4));        // untested
    BABLM(BABL_BROWSER_ZOOM_IN, OMSFT(IMCTL(X_EQUAL)));  // ctr+ +
    BABLM(BABL_BROWSER_ZOOM_OUT, IMCTL(X_MINUS));
    BABLM(BABL_BROWSER_VIEWSRC, SS_LCTRL("u"));  // Chrome or firefox
#        endif

#        ifdef BABL_APP
    BABLM(BABL_APP_SAVE, SS_LCTL("s"));
    //#ifdef BABL_APP_GOOGLE  -- we're going to make an assumption.
    BABLM(BABL_APP_CENTER_ALIGN, OMSFT(IMCTL(X_E)));
    BABLM(BABL_APP_SCROLL_ACTIVE_CELL, IMCTL(X_BSPACE));
    BABLM(BABL_NEWLINE_IN_CELL, IMALT(X_ENTER));
    BABLM(BABL_INSERT_COMMENT, OMALT(IMCTL(X_M)));
    BABLM(BABL_APP_CLEAR_FORMATTING, IMCTL(X_BSLASH));
    BABLM(BABL_DELETE_ROW, IMALT(X_E) "d");
    BABLM(BABL_INSERT_COL_LEFT, IMALT(X_I) "c");  // o for to the right.
    BABLM(BABL_INSERT_ROW, IMALT(X_I) "w");       // r for above.
    BABLM(BABL_SELECT_COL, IMCTL(X_SPACE));
    BABLM(BABL_SELECT_ROW, IMSFT(X_SPACE));
    BABLM(BABL_DELETE_ROW, OMALT(IMCTL(X_KP_MINUS)));  // once selected
//#endif // BABL_APP_CELLS
#        endif  // BABL_APP

    // Todo, ring bell, flash light, show user this isn't supported
    return false;
}
#    endif
#endif /* chromeos*/

A users/miles2go/babl_emacs.c => users/miles2go/babl_emacs.c +85 -0
@@ 0,0 1,85 @@
/*  A library to output the right key shortcut in any common app.
Given a global variable babble_mode to show the environment and a
key that calls the paste macro, do the right type of paste.
Setting the context is done by another macro, or TBD interaction with the host.

Emacs mode is probably most useful for people who don't usually use emacs

https://www.ast.cam.ac.uk/~vasily/idl/emacs_commands_list.html
*/

#include QMK_KEYBOARD_H

#ifdef USE_BABBLEPASTE
#    include "babblePaste.h"

#    ifdef BABL_EMACS

// probably should allow meta to not be ALT
#        define DMETA IMALT

bool babblePaste_emacs(uint16_t keycode) {
#        ifdef BABL_MOVE
    BABLM(BABL_GO_LEFT_1C, SS_TAP(X_LEFT));
    BABLM(BABL_GO_RIGHT_1C, SS_TAP(X_RIGHT));
    BABLM(BABL_GO_LEFT_WORD, IMALT(X_B));
    BABLM(BABL_GO_RIGHT_WORD, IMALT(X_F));
    BABLM(BABL_GO_START_LINE, SS_LCTRL("a"));
    BABLM(BABL_GO_END_LINE, SS_LCTRL("e"));
    BABLM(BABL_GO_START_DOC, OMALT(IMSFT(X_COMMA)));
    BABLM(BABL_GO_END_DOC, OMALT(IMSFT(X_DOT)));
    BABLM(BABL_GO_NEXT_LINE, SS_LCTRL("n"));
    BABLM(BABL_GO_PREV_LINE, SS_LCTRL("p"));
    BABLM(BABL_GO_PARA_START, OMALT(IMSFT(X_LBRACKET)));
    BABLM(BABL_GO_PARA_END, OMALT(IMSFT(X_RBRACKET)));
    BABLM(BABL_PGDN, SS_LCTRL("v"));
    BABLM(BABL_PGUP, IMALT(X_V));
    BABLM(BABL_DEL_RIGHT_1C, SS_LCTRL("d"));
    BABLM(BABL_DEL_LEFT_WORD, IMCTL(X_BSPACE));
    BABLM(BABL_DEL_RIGHT_WORD, IMALT(X_D));
    BABLM(BABL_DEL_TO_LINE_END, SS_LCTRL("k"));
    BABLM(BABL_DEL_TO_LINE_START, SS_TAP(X_ESCAPE) "0" SS_LCTRL("k"));
    BABLM(BABL_MODE, "Emacs ");
#        endif
#        ifdef BABL_OSKEYS
    BABLM(BABL_UNDO, SS_LCTRL("x") "c");
    BABLM(BABL_REDO, SS_LCTRL("x") "c");  // arguably
    BABLM(BABL_CUT, SS_LCTRL("w"));
    BABLM(BABL_COPY, SS_LALT("w"));  // really?
    BABLM(BABL_PASTE, SS_LCTRL("y"));
    BABLM(BABL_SELECT_ALL, SS_LCTRL("x") "h");
    BABLM(BABL_FIND, SS_LCTRL("s"));
    BABLM(BABL_FIND_NEXT, SS_LCTRL("s"));
    BABLM(BABL_FIND_PREV, SS_LCTRL("r"));
    BABLM(BABL_FIND_REPLACE, OMALT(IMSFT(X_5)));
    // BABLM( BABL_RUNAPP , 			//(SS_LALT("x") "shell")	 );// arguably
    BABLM(BABL_RUNAPP, IMALT(X_X) "split-window" SS_TAP(X_ENTER));  // arguably
    BABLM(BABL_WINDOW_NEXT, SS_LCTRL("x") "o");
    BABLM(BABL_WINDOW_PREV, SS_LCTRL("x") "o");  // arguably
    //	BABLM( BABL_WINDOW_NEW,		IMCTL(X_X)"n" ); //
    BABLM(BABL_CLOSE_APP, SS_LCTRL("x") "c");
    BABLM(BABL_HELP, SS_LCTRL("h") "a");  // start search in help
                                          // BABLM( BABL_LOCK,		()	); // lock buffer? Too many options.
    // BABLM( BABL_SCREENCAPTURE,		()	); // requires plugin?

#        endif
#        ifdef BABL_BROWSER
/* you get to figure w3 out */
#        endif

#        ifdef BABL_APP
    BABLM(BABL_APP_SAVE, SS_LCTL("x") SS_LCTL("s"));
    /// BABLM( BABL_APP_MULTI_SELECT, 	SS_LCTRL("x") "rt" ); // arguably
    BABLM(BABL_SPLIT_FRAME_VERT, SS_LCTRL("x") "3");
    BABLM(BABL_UNSPLIT_FRAME_VERT, SS_LCTRL("u") SS_LCTRL("x") "0");
    BABLM(BABL_SPLIT_FRAME_HORIZONTAL, SS_LCTRL("x") "2");
    BABLM(BABL_UNSPLIT_FRAME_HORIZONTAL, SS_LCTRL("u") SS_LCTRL("x") "0");
    BABLM(BABL_NEXT_FRAME, SS_LCTRL("x") "o");
    BABLM(BABL_PREV_FRAME, SS_LCTRL("u") "-1" SS_LCTRL("x") "o");
#        endif

    // Todo, ring bell, flash light, show user this isn't supported
    return false;
}
#    endif /* emacs mode*/
#endif

A users/miles2go/babl_linux.c => users/miles2go/babl_linux.c +102 -0
@@ 0,0 1,102 @@
/*  A library to output the right key shortcut in any common app.
Given a global variable babble_mode to show the environment and a
key that calls the paste macro, do the right type of paste.
Setting the context is done by another macro, or TBD interaction with the host.

Huge thanks to https://en.wikipedia.org/wiki/Table_of_keyboard_shortcuts
and
https://github.com/qmk/qmk_firmware/blob/master/keyboards/planck/keymaps/jeebak/keymap.c
*/

#include QMK_KEYBOARD_H

#ifdef USE_BABBLEPASTE
#    include "babblePaste.h"

#    ifdef BABL_LINUX

bool babblePaste_linux(uint16_t keycode) {
#        ifdef BABL_MOVE
    BABLM(BABL_GO_LEFT_1C, SS_TAP(X_LEFT));
    BABLM(BABL_GO_RIGHT_1C, SS_TAP(X_RIGHT));
    BABLM(BABL_GO_LEFT_WORD, IMCTL(X_LEFT));
    BABLM(BABL_GO_RIGHT_WORD, IMCTL(X_RIGHT));
    BABLM(BABL_GO_START_LINE, SS_TAP(X_HOME));
    BABLM(BABL_GO_END_LINE, SS_TAP(X_END));
    BABLM(BABL_GO_START_DOC, IMCTL(X_HOME));
    BABLM(BABL_GO_END_DOC, IMCTL(X_END));
    BABLM(BABL_GO_NEXT_LINE, SS_TAP(X_DOWN));
    BABLM(BABL_GO_PREV_LINE, SS_TAP(X_UP));
    BABLM(BABL_GO_PARA_START, IMCTL(X_UP));
    BABLM(BABL_GO_PARA_END, IMCTL(X_DOWN));
    BABLM(BABL_PGDN, SS_TAP(X_PGDOWN));
    BABLM(BABL_PGUP, SS_TAP(X_PGUP));
    BABLM(BABL_DEL_RIGHT_1C, SS_TAP(X_DELETE));
    BABLM(BABL_DEL_LEFT_WORD, IMCTL(X_BSPACE));
    BABLM(BABL_DEL_RIGHT_WORD, IMCTL(X_DELETE));
    BABLM(BABL_DEL_TO_LINE_END, IMSFT(X_HOME) SS_TAP(X_DELETE));
    BABLM(BABL_DEL_TO_LINE_START, IMSFT(X_END) SS_TAP(X_DELETE));
    BABLM(BABL_MODE, "Linux ");
#        endif
#        ifdef BABL_OSKEYS
    BABLM(BABL_UNDO, SS_LCTL("z"));
    BABLM(BABL_REDO, SS_LCTL("y"));
    BABLM(BABL_CUT, SS_LCTL("x"));
    BABLM(BABL_COPY, SS_LCTL("c"));
    BABLM(BABL_PASTE, SS_LCTL("v"));
    BABLM(BABL_SELECT_ALL, SS_LCTL("a"));
    BABLM(BABL_FIND, SS_LCTL("f"));
    BABLM(BABL_CLOSE_APP, IMALT(X_F4));
    BABLM(BABL_HELP, SS_TAP(X_F1));
    // BABLM(BABL_FIND_NEXT  (SS_LALT(X_F3))	); //KDE */
    BABLM(BABL_FIND_NEXT, SS_LCTL("g"));       // Gnome*/
    BABLM(BABL_FIND_PREV, OMSFT(IMCTL(X_G)));  // Gnome*/
    /* BABLM( BABL_FIND_REPLACE , (SS_LCTL("r"))	); // KDE */
    BABLM(BABL_FIND_REPLACE, SS_LCTL("h"));  // Gnome*/
    BABLM(BABL_RUNAPP, IMALT(X_F2));         // Gnome
    BABLM(BABL_SWITCH_APP_NEXT, IMALT(X_TAB));
    BABLM(BABL_SWITCH_APP_LAST, OMSFT(IMALT(X_TAB)));
    BABLM(BABL_WINDOW_NEXT, OMCTL(IMALT(X_PGUP)));  // Gnome, sometimes
    BABLM(BABL_WINDOW_PREV, OMCTL(IMALT(X_PGDOWN)));
    BABLM(BABL_WINDOW_NEW, IMCTL(X_N));
    // BABLM( BABL_HELP,		(SS_TAP(X_F1))	); // NA?
    BABLM(BABL_LOCK, OMCTL(IMALT(X_L)));
    BABLM(BABL_SCREENCAPTURE, IMSFT(X_PSCREEN));
#        endif
#        ifdef BABL_BROWSER
    BABLM(BABL_BROWSER_NEW_TAB, SS_LCTL("t"));
    BABLM(BABL_BROWSER_CLOSE_TAB, SS_LCTL("w"));
    BABLM(BABL_BROWSER_REOPEN_LAST_TAB, OMSFT(IMCTL(X_T)));
    BABLM(BABL_BROWSER_NEXT_TAB, SS_LCTL(SS_TAP(X_TAB)));
    BABLM(BABL_BROWSER_PREV_TAB, OMSFT(IMCTL(X_TAB)));
    BABLM(BABL_BROWSER_URL_BAR, SS_LCTL("l"));
    BABLM(BABL_BROWSER_FORWARD, IMALT(X_RIGHT));
    BABLM(BABL_BROWSER_BACK, IMALT(X_LEFT));
    BABLM(BABL_BROWSER_FIND, SS_LCTL("f"));
    BABLM(BABL_BROWSER_BOOKMARK, SS_LCTL("d"));
    BABLM(BABL_BROWSER_DEV_TOOLS, SS_LCTL("t"));  // Chrome
    // chrome
    BABLM(BABL_BROWSER_RELOAD, IMCTL(X_F5));             // hard reload w/o cache
    BABLM(BABL_BROWSER_FULLSCREEN, SS_TAP(X_F11));       // command shift F
    BABLM(BABL_BROWSER_ZOOM_IN, OMSFT(IMCTL(X_EQUAL)));  // ctr+ +
    BABLM(BABL_BROWSER_ZOOM_OUT, IMCTL(X_MINUS));
    BABLM(BABL_BROWSER_VIEWSRC, SS_LCTL("u"));  // Chrome or firefox
#        endif
#        ifdef BABL_APP
    BABLM(BABL_APP_SAVE, SS_LCTL("s"));
    // on linux we'd probably use tmux or screen. Some terminal software also
    // allows this.
    // BABLM( BABL_SPLIT_FRAME_VERT,		()  );
    // BABLM( BABL_UNSPLIT_FRAME_VERT,		()  );
    // BABLM( BABL_SPLIT_FRAME_HORIZONTAL, ()	);
    // BABLM( BABL_UNSPLIT_FRAME_HORIZONTAL, () );
    // BABLM( BABL_NEXT_FRAME, ()	);
    // BABLM( BABL_PREV_FRAME, ()	);
#        endif

    // Todo, ring bell, flash light, show user this isn't supported
    return false;
}

#    endif /* linux mode */
#endif

A users/miles2go/babl_mac.c => users/miles2go/babl_mac.c +152 -0
@@ 0,0 1,152 @@
/*  A library to output the right key shortcut in any common app.
Given a global variable babble_mode to show the environment and a
key that calls the paste macro, do the right type of paste.
Setting the context is done by another macro, or TBD interaction with the host.

Huge thanks to https://en.wikipedia.org/wiki/Table_of_keyboard_shortcuts
and https://github.com/qmk/qmk_firmware/blob/master/keyboards/planck/keymaps/jeebak/keymap.c
*/

#include QMK_KEYBOARD_H

#ifdef USE_BABBLEPASTE
#    include "babblePaste.h"

#    ifdef BABL_MAC

bool babblePaste_mac(uint16_t keycode) {
#        ifdef BABL_MOVE
    BABLM(BABL_GO_LEFT_1C, SS_TAP(X_LEFT));
    BABLM(BABL_GO_RIGHT_1C, SS_TAP(X_RIGHT));
    BABLM(BABL_GO_LEFT_WORD, IMALT(X_LEFT));
    BABLM(BABL_GO_RIGHT_WORD, IMALT(X_RIGHT));
    BABLM(BABL_GO_START_LINE, IMGUI(X_LEFT));
    BABLM(BABL_GO_END_LINE, IMGUI(X_RIGHT));
    BABLM(BABL_GO_START_DOC, IMGUI(X_UP));
    BABLM(BABL_GO_END_DOC, IMGUI(X_DOWN));
    BABLM(BABL_GO_NEXT_LINE, SS_TAP(X_DOWN));
    BABLM(BABL_GO_PREV_LINE, SS_TAP(X_UP));
    BABLM(BABL_GO_PARA_START, IMALT(X_UP));
    BABLM(BABL_DEL_RIGHT_1C, SS_TAP(X_DELETE));
    BABLM(BABL_GO_PARA_END, IMALT(X_DOWN));
    BABLM(BABL_PGDN, SS_TAP(X_PGDOWN));
    BABLM(BABL_PGUP, SS_TAP(X_PGUP));
    BABLM(BABL_DEL_LEFT_WORD, IMALT(X_BSPACE));
    BABLM(BABL_DEL_RIGHT_WORD, IMALT(X_DELETE));
    BABLM(BABL_DEL_TO_LINE_END, OMSFT(IMGUI(X_RIGHT)) SS_TAP(X_BSPACE));  // this is more app agnostic than ctrl-k
    BABLM(BABL_DEL_TO_LINE_START, OMSFT(IMGUI(X_LEFT)) SS_TAP(X_BSPACE));
    BABLM(BABL_MODE, "Mac ");
#        endif
#        ifdef BABL_OSKEYS
    BABLM(BABL_UNDO, SS_LGUI("z"));
    BABLM(BABL_REDO, SS_LGUI("y"));
    BABLM(BABL_CUT, SS_LGUI("x"));
    BABLM(BABL_COPY, SS_LGUI("c"));
    BABLM(BABL_PASTE, SS_LGUI("v"));
    BABLM(BABL_SELECT_ALL, SS_LGUI("a"));
    BABLM(BABL_FIND, SS_LGUI("f"));
    BABLM(BABL_FIND_NEXT, SS_LGUI("g"));
    // BABLM( BABL_FIND_NEXT, 	OMSFT(X_F4)) ); // Mac office
    BABLM(BABL_FIND_PREV, OMSFT(IMGUI(X_G)));  // Sublime, browser
    BABLM(BABL_FIND_PREV, SS_LGUI("g"));
    BABLM(BABL_FIND_REPLACE, SS_LGUI("f"));
    BABLM(BABL_RUNAPP, SS_LGUI(" "));
    BABLM(BABL_SWITCH_APP_NEXT, IMGUI(X_TAB));
    BABLM(BABL_SWITCH_APP_LAST, OMSFT(IMGUI(X_TAB)));
    // Apps vary, but this is  usually tab movement, same as B_NXTB
    /*
    BABLM( BABL_WINDOW_NEXT, OMSFT(IMGUI(X_RBRACKET)) ); // GUI Grav isn't everywhere
    BABLM( BABL_WINDOW_PREV, OMSFT(IMGUI(X_LBRACKET)) );
    */
    BABLM(BABL_WINDOW_NEXT, IMGUI(X_GRAVE));
    BABLM(BABL_WINDOW_PREV, OMSFT(IMGUI(X_GRAVE)));
    BABLM(BABL_WINDOW_NEW, IMGUI(X_N));
    BABLM(BABL_CLOSE_APP, SS_LGUI("q"));
    BABLM(BABL_HELP, OMSFT(IMGUI(X_SLASH)));
    // Locking screen from external keyboard requires automator https://apple.stackexchange.com/questions/73995
    BABLM(BABL_LOCK, OMCTL(IMALT(X_L)));
    BABLM(BABL_SCREENCAPTURE, OMSFT(OMGUI(IMALT(X_4))) IMGUI(X_SPACE) "preview" SS_LGUI("d"));
    BABLM(BABL_SWITCH_KEYBOARD_LAYOUT, IMCTL(X_SPACE));
#        endif
#        ifdef BABL_BROWSER
    BABLM(BABL_BROWSER_NEW_TAB, IMGUI(X_T));
    BABLM(BABL_BROWSER_CLOSE_TAB, SS_LGUI("w"));
    BABLM(BABL_BROWSER_REOPEN_LAST_TAB, OMSFT(SS_LGUI("t")));
    BABLM(BABL_BROWSER_NEXT_TAB, OMGUI(IMALT(X_RIGHT)));
    BABLM(BABL_BROWSER_PREV_TAB, OMGUI(IMALT(X_LEFT)));
    BABLM(BABL_BROWSER_URL_BAR, SS_LGUI("l"));
    BABLM(BABL_BROWSER_FORWARD, IMGUI(X_RIGHT));
    BABLM(BABL_BROWSER_BACK, IMGUI(X_LEFT));
    BABLM(BABL_BROWSER_FIND, SS_LGUI("f"));
    BABLM(BABL_BROWSER_BOOKMARK, SS_LGUI("d"));
    BABLM(BABL_BROWSER_RELOAD, OMGUI(SS_LSFT("r")));  // hard reload w/o cache
    BABLM(BABL_BROWSER_FULLSCREEN, OMGUI(SS_LCTRL("p")));
    BABLM(BABL_BROWSER_ZOOM_IN, IMGUI(X_KP_PLUS));  // ctr+ +
    BABLM(BABL_BROWSER_ZOOM_OUT, IMGUI(X_KP_MINUS));
#            ifdef BABL_BROWSER_CHROME
    BABLM(BABL_BROWSER_VIEWSRC, SS_LGUI("u"));           // Chrome or firefox
    BABLM(BABL_BROWSER_DEV_TOOLS, OMGUI(SS_LALT("i")));  // Chrome or Firefox
#            endif
#            ifdef BABL_BROWSER_SAFARI
    BABLM(BABL_BROWSER_VIEWSRC, OMGUI(IMALT(X_U)));  // Safari
                                                     // BABLM( BABL_BROWSER_DEV_TOOLS,	// No real equivalent for Safari
#            endif
#        endif  //  BABL_BROWSER

#        ifdef BABL_APP
    BABLM(BABL_APP_SAVE, SS_LGUI("s"));
#            ifdef BABL_APP_EDITOR
#                ifdef BABL_APP_SUBLIME
    BABLM(BABL_APP_MULTI_SELECT, OMCTL(IMGUI(X_G)));  // add all occurences of current word to select.
    BABLM(BABL_APP_PASTE_VALUES, OMSFT(IMGUI(X_V)));  // paste with proper indenting.
#                endif                                // sublime
#            endif                                    // editor

#            ifdef BABL_APP_CELLS
#                ifdef BABL_APP_MSOFFICE
    BABLM(BABL_APP_CENTER_ALIGN, IMGUI(X_E));
    // BABLM( BABL_APP_CLEAR_FORMATTING, 	OMCTL(IMGUI(X_G)) ); // this isn't native. https://support.office.com/en-us/article/Clear-all-text-formatting-C094C4DA-7F09-4CEA-9A8D-C166949C9C80#OfficeVersion=macOS
    BABLM(BABL_APP_SCROLL_ACTIVE_CELL, IMCTL(X_BSPACE));
    BABLM(BABL_NEWLINE_IN_CELL, IMALT(X_ENTER));
    BABLM(BABL_INSERT_COMMENT, IMSFT(X_F2));
    BABLM(BABL_INSERT_COL_LEFT, IMCTL(X_I));
    BABLM(BABL_INSERT_ROW, OMCTL(IMSFT(X_KP_PLUS)));
    BABLM(BABL_DELETE_ROW, IMCTL(X_KP_MINUS));
    BABLM(BABL_SELECT_COL, IMCTL(X_SPACE));
    BABLM(BABL_SELECT_ROW, IMSFT(X_SPACE));
#                endif  // BABL_APP_MSOFFICE

#                ifdef BABL_APP_GOOGLE
    BABLM(BABL_APP_CENTER_ALIGN, OMSFT(IMGUI(X_E)));
    BABLM(BABL_APP_SCROLL_ACTIVE_CELL, IMCTL(X_BSPACE));
    BABLM(BABL_NEWLINE_IN_CELL, IMALT(X_ENTER));
    BABLM(BABL_INSERT_COMMENT, IMSFT(X_F2));
    BABLM(BABL_APP_CLEAR_FORMATTING, IMGUI(X_BSLASH));
    BABLM(BABL_DELETE_ROW, OMCTL(IMGUI(X_G)));
    BABLM(BABL_INSERT_COL_LEFT, OMALT(IMCTL(X_I)) "c");  // o for to the right.
    BABLM(BABL_INSERT_ROW, OMALT(IMCTL(X_I)) "b");       // r for above.
    BABLM(BABL_SELECT_COL, IMCTL(X_SPACE));
    BABLM(BABL_SELECT_ROW, IMSFT(X_SPACE));
    BABLM(BABL_DELETE_ROW, OMALT(IMCTL(X_KP_MINUS)));  // once selected
#                endif                                 // BABL_APP_GOOGLE
/*
#ifdef BABL_APP_APPLE
    // you're on your own.
#endif
*/
#            endif  // BABL_APP_CELLS

#            ifdef BABL_APP_WINDOWSPLITTING
    // These are for os X terminal, and are pretty useless.
    BABLM(BABL_SPLIT_FRAME_HORIZONTAL, SS_LGUI("d"));
    BABLM(BABL_UNSPLIT_FRAME_HORIZONTAL, OMSFT(IMGUI(X_D)));
#            endif  // BABL_APP_WINDOWSPLITTING

#        endif  // BABL_APP

    // Todo, ring bell, flash light, show user this isn't supported
    return false;
}

#    endif /* mac mode*/
#endif     // Babblepaste

A users/miles2go/babl_readmux.c => users/miles2go/babl_readmux.c +86 -0
@@ 0,0 1,86 @@
// Readline command line editing + tmux windowing
// I haven't decided how much to do readline and how much tmux
// see https://tiswww.case.edu/php/chet/readline/rluserman.html for other possible
// keybindings.

#include QMK_KEYBOARD_H

#ifdef USE_BABBLEPASTE
#    include "babblePaste.h"

#    ifdef BABL_READMUX

// Redefine if you use something other than CTRL-B to activate tmux.
#        define TMUX SS_LCTL("b")

bool babblePaste_readmux(uint16_t keycode) {
#        ifdef BABL_MOVE
    BABLM(BABL_GO_LEFT_1C, SS_TAP(X_LEFT));
    BABLM(BABL_GO_RIGHT_1C, SS_TAP(X_RIGHT));
    BABLM(BABL_GO_LEFT_WORD, SS_LALT("b"));
    BABLM(BABL_GO_RIGHT_WORD, SS_LALT("f"));
    BABLM(BABL_GO_START_LINE, SS_LCTL("a"));
    BABLM(BABL_GO_END_LINE, SS_LCTL("e"));
    // BABLM( BABL_GO_START_DOC		,END );// tmux?
    // BABLM( BABL_GO_END_DOC		,END );  // tmux?
    BABLM(BABL_GO_NEXT_LINE, SS_LCTL("n"));
    BABLM(BABL_GO_PREV_LINE, SS_LCTL("p"));
    // BABLM( BABL_GO_PARA_START,	// undefined
    // BABLM( BABL_GO_PARA_END,	 	// undefinedBABLM( BABL_PGDN ,

    BABLM(BABL_PGUP, SS_TAP(X_PGUP));
    BABLM(BABL_PGDN, SS_TAP(X_PGDOWN));
    BABLM(BABL_DEL_RIGHT_1C, SS_LCTL("d"));
    BABLM(BABL_DEL_LEFT_WORD, SS_LCTL("w"));  // meta-DEL instead?
    BABLM(BABL_DEL_RIGHT_WORD, SS_LALT("d"));
    BABLM(BABL_DEL_TO_LINE_END, SS_LCTL("k"));
    BABLM(BABL_DEL_TO_LINE_START, SS_LCTL("u"));
    BABLM(BABL_MODE, "Readline ");
#        endif
#        ifdef BABL_OSKEYS
    BABLM(BABL_UNDO, SS_LALT("r"));
    BABLM(BABL_REDO, SS_LCTL("x") "c");  // arguably
    BABLM(BABL_CUT, SS_LCTL("k"));       // wrong half the time
    // BABLM( BABL_COPY		,END );
    BABLM(BABL_PASTE, SS_LCTL("y"));
    BABLM(BABL_SELECT_ALL, SS_LCTL("aky"));
    BABLM(BABL_FIND, SS_LCTL("r"));  // search history
    BABLM(BABL_FIND_NEXT, SS_LCTL("r"));
    BABLM(BABL_FIND_PREV, SS_LCTL("s"));
    // BABLM( BABL_FIND_REPLACE		,END ); // not offered in readline
    BABLM(BABL_RUNAPP, TMUX "c");           // tmux
    BABLM(BABL_SWITCH_APP_NEXT, TMUX "n");  // tmux
    BABLM(BABL_SWITCH_APP_LAST, TMUX "p");  // tmux
    BABLM(BABL_CLOSE_APP, TMUX "d");        // usually what I want
    BABLM(BABL_HELP, TMUX IMSFT(X_SLASH));
    BABLM(BABL_LOCK, TMUX "L");  // assuming you set up VLOCK yourself
    BABLM(BABL_SCREENCAPTURE, TMUX ":capture-pane");
#        endif
#        ifdef BABL_BROWSER
/* Add lynx shortcuts, brow.sh?
 */
#            ifdef BABL_MAC
    // this is stock OS X Terminal, alter for windows &etc.
    BABLM(BABL_BROWSER_NEW_TAB, IMGUI(X_T));
    BABLM(BABL_BROWSER_CLOSE_TAB, SS_LGUI("w"));
    BABLM(BABL_BROWSER_NEXT_TAB, IMCTL(X_TAB));
    BABLM(BABL_BROWSER_PREV_TAB, OMSFT(IMCTL(X_TAB)));
#            endif
#        endif
#        ifdef BABL_APP
    // Save makes no sense here
    BABLM(BABL_SPLIT_FRAME_VERT, TMUX IMSFT(X_5));
    // BUG - misleading. This is currently set to convert frame to a window.
    BABLM(BABL_UNSPLIT_FRAME_VERT, TMUX IMSFT(X_1));
    BABLM(BABL_SPLIT_FRAME_HORIZONTAL, TMUX IMSFT(X_QUOTE));
    // This one closes the current pane.
    BABLM(BABL_UNSPLIT_FRAME_HORIZONTAL, SS_LCTL("b") "x");
    BABLM(BABL_NEXT_FRAME, SS_LCTL("b") "o");
    BABLM(BABL_PREV_FRAME, SS_LCTL("w") SS_TAP(X_SCOLON));
#        endif

    // Todo, ring bell, flash light, show user this isn't supported
    return false;
}
#    endif /* readmux*/
#endif

A users/miles2go/babl_vi.c => users/miles2go/babl_vi.c +76 -0
@@ 0,0 1,76 @@
/*
Vi is stateful, so you have to track the modes yourself. Otherwise motion is awful (bell, bell, bell)

*/

#include QMK_KEYBOARD_H

#ifdef USE_BABBLEPASTE
#    include "babblePaste.h"

#    ifdef BABL_VI

bool babblePaste_vi(uint16_t keycode) {
#        ifdef BABL_MOVE
    BABLM(BABL_GO_LEFT_1C, "h");
    BABLM(BABL_GO_RIGHT_1C, "l");
    BABLM(BABL_GO_LEFT_WORD, "b");
    BABLM(BABL_GO_RIGHT_WORD, "w");
    BABLM(BABL_GO_START_LINE, IMSFT(X_6));
    BABLM(BABL_GO_END_LINE, IMSFT(X_4));
    BABLM(BABL_GO_START_DOC, "gg");
    BABLM(BABL_GO_END_DOC, IMSFT(X_G));
    BABLM(BABL_GO_NEXT_LINE, "j");
    BABLM(BABL_GO_PREV_LINE, "k");
    BABLM(BABL_GO_PARA_START, IMSFT(X_LBRACKET));
    BABLM(BABL_GO_PARA_END, IMSFT(X_RBRACKET));
    BABLM(BABL_PGDN, SS_LCTRL("f"));
    BABLM(BABL_PGUP, SS_LCTRL("b"));
    BABLM(BABL_DEL_RIGHT_1C, "x");
    BABLM(BABL_DEL_LEFT_WORD, "dge");
    BABLM(BABL_DEL_RIGHT_WORD, "dw");
    BABLM(BABL_DEL_TO_LINE_END, "d" IMSFT(X_4));
    BABLM(BABL_DEL_TO_LINE_START, "d" IMSFT(X_6));
    BABLM(BABL_MODE, "Vi ");
#        endif
#        ifdef BABL_OSKEYS
    BABLM(BABL_UNDO, "h");
    BABLM(BABL_REDO, SS_LCTRL("r"));
    BABLM(BABL_CUT, "x");
    BABLM(BABL_COPY, "y");
    BABLM(BABL_PASTE, "p");
    BABLM(BABL_SELECT_ALL, IMSFT(X_SCOLON) SS_TAP(X_5) "y");  // wrong but helpful?
    BABLM(BABL_FIND, SS_TAP(X_SLASH));
    BABLM(BABL_FIND_NEXT, "n");
    BABLM(BABL_FIND_PREV, IMSFT(X_N));
    BABLM(BABL_FIND_REPLACE, OMALT(IMSFT(X_5)));
    BABLM(BABL_RUNAPP, ":split");                // requires VIM, is vsplit better?
    BABLM(BABL_SWITCH_APP_NEXT, IMCTL(X_DOWN));  // Or Right?
    BABLM(BABL_SWITCH_APP_NEXT, IMCTL(X_UP));    // or Left?
    BABLM(BABL_CLOSE_APP, IMCTL(X_SCOLON) "q");
    BABLM(BABL_HELP, SS_LSFT(SS_TAP(X_SCOLON)) "h");  // start search in help
                                                      // BABLM( BABL_LOCK,		()	); Perhaps VI is not an OS?
                                                      // BABLM( BABL_SCREENCAPTURE,		()	); // capture a buffer?
#        endif

#        ifdef BABL_BROWSER
/* what _is_ the VI browser now that vimpirator is dead?*/
#        endif

#        ifdef BABL_APP
    BABLM(BABL_APP_SAVE, SS_TAP(X_ESCAPE) ":w");
#            ifdef BABL_APP_WINDOWSPLITTING
    BABLM(BABL_SPLIT_FRAME_VERT, SS_TAP(X_ESCAPE) ":vsplit");
    BABLM(BABL_UNSPLIT_FRAME_VERT, SS_TAP(X_ESCAPE) ":hide");  // debatable.
    BABLM(BABL_SPLIT_FRAME_HORIZONTAL, SS_TAP(X_ESCAPE) ":vsplit");
    BABLM(BABL_UNSPLIT_FRAME_HORIZONTAL, SS_TAP(X_ESCAPE) ":hide");
    BABLM(BABL_NEXT_FRAME, SS_LCTRL("w") "w");
    BABLM(BABL_PREV_FRAME, SS_LCTRL("w") SS_LSFT("w"));
#            endif
#        endif  // app
    // Todo, ring bell, flash light, show user this isn't supported
    return false;
}

#    endif  // VI
#endif      // Babblepaste

A users/miles2go/babl_windows.c => users/miles2go/babl_windows.c +151 -0
@@ 0,0 1,151 @@
/*  A library to output the right key shortcut in any common app.
Given a global variable babble_mode to show the environment and a
key that calls the paste macro, do the right type of paste.
Setting the context is done by another macro, or TBD interaction with the host.

Huge thanks to https://en.wikipedia.org/wiki/Table_of_keyboard_shortcuts
https://support.microsoft.com/en-gb/help/12445/windows-keyboard-shortcuts

Remember to check  https://github.com/qmk/qmk_firmware/blob/master/quantum/send_string_keycodes.h

*/

#include QMK_KEYBOARD_H

#ifdef USE_BABBLEPASTE
#    include "babblePaste.h"

#    ifdef BABL_WINDOWS

bool babblePaste_win(uint16_t keycode) {
#        ifdef BABL_MOVE
    BABLM(BABL_GO_LEFT_1C, SS_TAP(X_LEFT));
    BABLM(BABL_GO_RIGHT_1C, SS_TAP(X_RIGHT));
    BABLM(BABL_GO_LEFT_WORD, IMCTL(X_LEFT));
    BABLM(BABL_GO_RIGHT_WORD, IMCTL(X_RIGHT));
    BABLM(BABL_GO_START_LINE, IMGUI(X_LEFT));
    BABLM(BABL_GO_END_LINE, IMGUI(X_RIGHT));
    BABLM(BABL_GO_START_DOC, OMGUI(IMCTL(X_LEFT)));
    BABLM(BABL_GO_END_DOC, OMGUI(IMCTL(X_RIGHT)));
    BABLM(BABL_GO_NEXT_LINE, SS_TAP(X_DOWN));
    BABLM(BABL_GO_PREV_LINE, SS_TAP(X_UP));
    BABLM(BABL_GO_PARA_START, IMCTL(X_UP));
    BABLM(BABL_GO_PARA_END, IMCTL(X_DOWN));
    BABLM(BABL_PGDN, SS_TAP(X_PGDOWN));
    BABLM(BABL_PGUP, SS_TAP(X_PGUP));
    BABLM(BABL_DEL_RIGHT_1C, SS_TAP(X_DELETE));
    BABLM(BABL_DEL_LEFT_WORD, IMCTL(X_BSPACE));
    BABLM(BABL_DEL_RIGHT_WORD, IMCTL(X_DELETE));
    BABLM(BABL_DEL_TO_LINE_END, IMSFT(X_HOME) SS_TAP(X_DELETE));
    BABLM(BABL_DEL_TO_LINE_START, IMSFT(X_END) SS_TAP(X_DELETE));
    BABLM(BABL_MODE, "Windows ");
#        endif

#        ifdef BABL_OSKEYS
    BABLM(BABL_UNDO, SS_LCTRL("z"));
    BABLM(BABL_REDO, SS_LCTRL("y"));
    BABLM(BABL_CUT, SS_LCTRL("x"));
    BABLM(BABL_COPY, SS_LCTRL("c"));
    BABLM(BABL_PASTE, SS_LCTRL("v"));
    BABLM(BABL_SELECT_ALL, SS_LCTRL("a"));
    BABLM(BABL_FIND, SS_LCTRL("f"));
    BABLM(BABL_FIND_NEXT, SS_TAP(X_F3));
    // BABLM( BABL_FIND_PREV, 	SS_TAP(X_F3) ); // doesn't have a standard one?
    BABLM(BABL_FIND_REPLACE, SS_LCTRL("h"));
    BABLM(BABL_RUNAPP, SS_LGUI("r"));
    BABLM(BABL_SWITCH_APP_NEXT, IMALT(X_TAB));
    BABLM(BABL_SWITCH_APP_LAST, OMSFT(IMALT(X_TAB)));
    BABLM(BABL_WINDOW_NEXT, IMCTL(X_TAB));
    BABLM(BABL_WINDOW_PREV, OMSFT(IMCTL(X_TAB)));
    BABLM(BABL_WINDOW_NEW, IMCTL(X_N));
    BABLM(BABL_CLOSE_APP, IMALT(X_F4));
    BABLM(BABL_HELP, SS_TAP(X_F1));
    BABLM(BABL_LOCK, SS_LGUI("l"));
    BABLM(BABL_SCREENCAPTURE, OMSFT(SS_LGUI("s")));
    BABLM(BABL_SWITCH_KEYBOARD_LAYOUT, IMGUI(X_SPACE));

#        endif

#        ifdef BABL_BROWSER
    BABLM(BABL_BROWSER_NEW_TAB, SS_LCTRL("t"));
    BABLM(BABL_BROWSER_CLOSE_TAB, SS_LCTRL("w"));
    BABLM(BABL_BROWSER_REOPEN_LAST_TAB, OMSFT(IMCTL(X_T)));
    BABLM(BABL_BROWSER_NEXT_TAB, IMCTL(X_TAB));
    BABLM(BABL_BROWSER_PREV_TAB, OMSFT(IMCTL(X_TAB)));
    BABLM(BABL_BROWSER_URL_BAR, SS_LCTRL("l"));
    BABLM(BABL_BROWSER_FORWARD, IMALT(X_RIGHT));
    BABLM(BABL_BROWSER_BACK, OMSFT(IMALT(X_LEFT)));
    ;
    BABLM(BABL_BROWSER_FIND, SS_LCTRL("f"));
    BABLM(BABL_BROWSER_BOOKMARK, SS_LCTRL("d"));
#            ifdef BABL_BROWSER_MS
    BABLM(BABL_BROWSER_DEV_TOOLS, IMCTL(X_F12));  // EDGE
#            else
    BABLM(BABL_BROWSER_DEV_TOOLS, SS_LCTRL("t"));  // Chrome
    BABLM(BABL_BROWSER_VIEWSRC, SS_LCTRL("u"));    // Chrome or firefox
#            endif
    // chrome
    BABLM(BABL_BROWSER_RELOAD, IMCTL(X_F5));             // hard reload w/o cache
    BABLM(BABL_BROWSER_FULLSCREEN, SS_TAP(X_F11));       // command shift F
    BABLM(BABL_BROWSER_ZOOM_IN, OMSFT(IMCTL(X_EQUAL)));  // ctr+ +
    BABLM(BABL_BROWSER_ZOOM_OUT, IMCTL(X_MINUS));

#        endif

#        ifdef BABL_APP
    BABLM(BABL_APP_SAVE, SS_LCTL("s"));
#            ifdef BABL_APP_EDITOR
#                ifdef BABL_APP_SUBLIME
    // http://sweetme.at/2013/08/08/sublime-text-keyboard-shortcuts/
    BABLM(BABL_APP_MULTI_SELECT, IMALT(X_F3));        // add all occurences of current word to select.
    BABLM(BABL_APP_PASTE_VALUES, OMSFT(IMCTL(X_V)));  // paste with proper indenting.
#                endif                                // sublime
#            endif                                    // editor

#            ifdef BABL_APP_CELLS
#                ifdef BABL_APP_MSOFFICE
#                    ifndef BABL_APP_SUBLIME
    BABLM(BABL_APP_PASTE_VALUES, OMCTL(IMALT(X_V)) "v");
#                    endif
    BABLM(BABL_APP_CENTER_ALIGN, IMALT(X_H) "ac");
    // BABLM( BABL_APP_CLEAR_FORMATTING, 	OMCTL(IMGUI(X_G)) ); // this isn't native. https://support.office.com/en-us/article/Clear-all-text-formatting-C094C4DA-7F09-4CEA-9A8D-C166949C9C80#OfficeVersion=macOS
    BABLM(BABL_APP_SCROLL_ACTIVE_CELL, IMCTL(X_BSPACE));
    BABLM(BABL_NEWLINE_IN_CELL, IMALT(X_ENTER));
    BABLM(BABL_INSERT_COMMENT, IMSFT(X_F2));
    BABLM(BABL_INSERT_COL_LEFT, OMCTL(IMSFT(X_KP_PLUS)));
    BABLM(BABL_INSERT_ROW, OMCTL(IMSFT(X_KP_PLUS)));
    BABLM(BABL_DELETE_ROW, IMCTL(X_KP_MINUS));
    BABLM(BABL_SELECT_COL, IMCTL(X_SPACE));
    BABLM(BABL_SELECT_ROW, IMSFT(X_SPACE));
#                endif

#                ifdef BABL_APP_GOOGLE
    BABLM(BABL_APP_CENTER_ALIGN, OMSFT(IMCTL(X_E)));
    BABLM(BABL_APP_SCROLL_ACTIVE_CELL, IMCTL(X_BSPACE));
    BABLM(BABL_NEWLINE_IN_CELL, IMALT(X_ENTER));
    BABLM(BABL_INSERT_COMMENT, IMSFT(X_F2));
    BABLM(BABL_APP_CLEAR_FORMATTING, IMCTL(X_BSLASH));
    BABLM(BABL_DELETE_ROW, IMALT(X_E) "d");
    BABLM(BABL_INSERT_COL_LEFT, OMALT(IMCTL(X_I)) "c");  // o for to the right.
    BABLM(BABL_INSERT_ROW, IMALT(IMCTL(X_I)) "w");       // r for above.
    BABLM(BABL_SELECT_COL, IMCTL(X_SPACE));
    BABLM(BABL_SELECT_ROW, IMSFT(X_SPACE));
    BABLM(BABL_DELETE_ROW, OMALT(IMCTL(X_KP_MINUS)));  // once selected
#                endif

#            endif  // BABL_APP_CELLS

    // BABLM( BABL_SPLIT_FRAME_VERT,		()  );// no windows way?
    // BABLM( BABL_UNSPLIT_FRAME_VERT,		()  );
    BABLM(BABL_SPLIT_FRAME_HORIZONTAL, OMALT(IMCTL(X_S)));    // word only
    BABLM(BABL_UNSPLIT_FRAME_HORIZONTAL, OMSFT(IMALT(X_C)));  // word
    // BABLM( BABL_NEXT_FRAME, () );//no windows way?
    // BABLM( BABL_PREV_FRAME, () );// no windows way?
#        endif

    // Todo, ring bell, flash light, show user this isn't supported
    return false;
}

#    endif /* BABL_WINDOWS*/
#endif     /* babblepaste */
\ No newline at end of file

A users/miles2go/config.h => users/miles2go/config.h +53 -0
@@ 0,0 1,53 @@
#pragma once

#ifdef RGBLIGHT_ENABLE
#define RGBLIGHT_SLEEP
#undef RGBLIGHT_ANIMATIONS
#define RGBLIGHT_EFFECT_BREATHING
#endif // RGBLIGHT_ENABLE

#ifndef QMK_KEYS_PER_SCAN
#define QMK_KEYS_PER_SCAN 4
#endif // !QMK_KEYS_PER_SCAN

#undef FORCE_NKRO

#ifndef TAPPING_TOGGLE
#define TAPPING_TOGGLE  3
#endif

#ifdef TAPPING_TERM
	#undef TAPPING_TERM
#endif // TAPPING_TERM
#define TAPPING_TERM 200
//if no chord during tapping term, do the keystroke
#define RETRO_TAPPING

// Disable action_get_macro and fn_actions, since we don't use these
// and it saves on space in the firmware.
// LTO_ENABLE automatically enables these
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#define MACRO_TIMER 5



#define USE_BABBLEPASTE
// All options
#define BABL_MOVE // Uncomment to add basic cursor movement
#define BABL_OSKEYS // This adds Cut, paste, window movement and common OS shortcuts
#define BABL_BROWSER // Browser shortcuts, with Chrome/Firefox as the default. 
// edit the appropriate OS config file to enable Safari, Edge, vimpirator &etc. 
#define BABL_APP // Application specific settings this has sub-options.
#define BABL_APP_CELLS // spreadsheets and tables
#define BABL_APP_EDITOR // Fancy editor commands 
#define BABL_APP_WINDOWSPLITTING // splitting frames & windows

//All OSes
#define BABL_WINDOWS
#define BABL_READMUX
#define BABL_VI
#define BABL_MAC
#define BABL_LINUX
#define BABL_EMACS
#define BABL_CHROMEOS

A users/miles2go/keymaps/handwired/ms_sculpt_mobile/config.h => users/miles2go/keymaps/handwired/ms_sculpt_mobile/config.h +41 -0
@@ 0,0 1,41 @@
#pragma once

// Expect to get errors if you comment a feature out and leave it in your keymap.
#define USE_BABLPASTE

#ifdef USE_BABLPASTE

#ifdef RGBLIGHT_ENABLE
#define BABL_LED_INDEX 0 // set to 0 to set all LEDs , or set to # of LED to be used as BABL updaters
#define RGBLIGHT_COLOR_MS 0x00,0x27,0x88 // blue screen?
#define RGBLIGHT_COLOR_MAC 0xF0,0xF0,0xF0 // grey
#define RGBLIGHT_COLOR_LINUX 0xF4,0xAA,0x90 // ubuntu orange?
#define RGBLIGHT_COLOR_EMACS 0x00,0x00,0x00
#define RGBLIGHT_COLOR_VI 0x00,0x90,0x00
#define RGBLIGHT_COLOR_READMUX 0x33,0xFF,0x33 // green screen
#define RGBLIGHT_COLOR_CHROMEOS 0xf4,0xc2,0xd // google yellows
#endif 

#endif // bablpaste



// place overrides here
#define RGBLED_NUM 2
#define RGBLIGHT_LIMIT_VAL 200
#ifdef RGBLIGHT_ENABLE
#define RGBLIGHT_COLOR_LAYER_0 0x00, 0xFF, 0x00 // qwerty
#define RGBLIGHT_COLOR_LAYER_1 0x00, 0x99, 0x99 // cdh
#define RGBLIGHT_COLOR_LAYER_2 0xFF, 0x00, 0x00  // symbol
#define RGBLIGHT_COLOR_LAYER_3 0x00, 0xFF, 0xFF  // move
#define RGBLIGHT_COLOR_LAYER_4 0xFF, 0x00, 0xFF  // delmove
#define RGBLIGHT_COLOR_LAYER_5 0x00, 0xFF, 0xFF 
#define RGBLIGHT_ANIMATIONS
#define RGB_LIGHT_EFFECT_BREATHE_MAX 200
#define RGBLIGHT_RAINBOW_SWIRL_RANGE 127
#endif // rgblight

#define TAPPING_TERM 200
#define TAPPING_TERM_PER_KEY
#define RETRO_TAPPING
//#define PERMISSIVE_HOLD

A users/miles2go/keymaps/handwired/ms_sculpt_mobile/keymap.c => users/miles2go/keymaps/handwired/ms_sculpt_mobile/keymap.c +463 -0
@@ 0,0 1,463 @@
//placeholder until the new keymaps tree is built
//#include QMK_KEYBOARD_H


#include "virtser.h"
#include <print.h>
#include "milestogo.h"


#define LAYOUT_local LAYOUT_mobile_XUW
#define LAYOUT LAYOUT_mobile_XUW


#ifndef USERSPACE_ACTIVE
enum layer_keycodes {
    QWR = SAFE_RANGE,
    CDH,
    SYM,
    MOV,
    NUM,
    TRAN
};

enum layer_names {
_QWR,
_CDH,
_SYM,
_MOV,
_TRAN
};

#endif

// Shorter spacing
#define XXXX  KC_NO
#define ____  KC_TRNS

// Custom macros

/* Fn Keys */
#define TT_SYM MO(_SYM)
#define TT_NUM MO(_NUM)
#define SSFT ACTION_MODS_ONESHOT(MOD_LSFT)
#define SSYM LT(_SYM, KC_SPC)
#define MVTAB LT(_MOV,KC_TAB)
#define BKMV TT(_MOV)
#define MV2 LT(_MOV, KC_2)
#define MV3 LT(_MOV, KC_3)
#define MV4 LT(_MOV, KC_4)
#define MV8 LT(_MOV, KC_8)
#define MV9 LT(_MOV, KC_9)
#define MV0 LT(_MOV, KC_0)



const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/*  QWERTY
*
* |ESC | F1 | F2 | F3 | F4 | F5 | F6 | f7 | F8 | F9 | F10| F11| F12|Vol-|Vol+|_CDH|
*  -------------------------------------------------------------------------------'
* | ESC |  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8 |  9 |  0 |  - |  = |Bakspace| Del|
* ---------------------------------------------------------------------------
* | tab  |  q |  w |  e |  r |  t |  y |  u |  i |  o |  p |  [ |  ] |  \    |    |
*  -------------------------------------------------------------------------------'
* |Bak/Mov|  a |  s |  d |  f |  g |  h |  j |  k |  l |  ; |  ' | enter     |PgUp|
* --------------------------------------------------------------------------------
* |Lsft    |  z |  x |  c |  v |  b |  n |  m |  , |  . |  / |      Rsft| Up| PgDn|
* ---------------------------------------------------------------------------------
* |Lctl   |Lgui  |Lalt |       Space/Sym      | GUI |  Sym |  Rctl |Left|Down|Rght|
* ---------------------------------------------------------------------------------
*/

[_QWERTY] = LAYOUT_local( \
KC_ESC,   KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8,   KC_F9, KC_F10,    KC_F11,   KC_F12, KC_VOLD, KC_VOLU, TG(_CDH),\
KC_GRAVE, KC_1, KC_2, KC_3 ,KC_4, KC_5, KC_6, KC_7, KC_8,   KC_9, KC_0,     KC_MINS, KC_EQL, KC_BSPC, KC_DEL,\
KC_TAB,   KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I,   KC_O, KC_P,    KC_LBRC,  KC_RBRC,KC_BSLS,\
BKMV,    KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K,   KC_L, KC_SCLN, KC_QUOT,  KC_ENT, KC_PGUP,\
KC_LSFT,  KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM,KC_DOT,KC_SLSH,KC_RSFT,  KC_UP,  KC_PGDN,\
KC_LCTL,  KC_LGUI, KC_LALT, KC_SPC, KC_RGUI, TT_SYM,KC_CDH, KC_LEFT, KC_DOWN, KC_RIGHT
),


[_CDH] = LAYOUT_local(\
____,    ____, ____, ____, ____, ____,   ____, ____, ____,   ____,   ____,    ____,     ____,   ____,    ____,    ____,  \
KC_GRAVE, KC_1, KC_2, KC_3 ,KC_4, KC_5,   KC_6, KC_7, KC_8,   KC_9,   KC_0,    KC_MINUS, KC_EQL, KC_BSPC, KC_DEL,\
KC_TAB,  KC_Q, KC_W, KC_F, KC_P, KC_B,   KC_J, KC_L, KC_U,   KC_Y,   KC_SCLN, ____,    ____,    ____,\
KC_LCTL, KC_A, KC_R, KC_S, KC_T, KC_G,   KC_M, KC_N, KC_E,   KC_I,   KC_O,    KC_QUOT, KC_ENT,  KC_2,\
KC_LSFT, KC_Z, KC_X, KC_C, DHPASTE,KC_V, KC_K, KC_H, KC_COMM,KC_DOT, KC_SLSH, KC_RSFT, ____,    KC_1,\
TG(_MOV),     ____, ____ , ____, ____, ____, KC_QWERTY, ____, ____,   ____
),

/*  SYMBOL layer, several to chose from
*/

[_SYM] = LAYOUT_wrapper(\
____,     ____, ____, ____, ____, ____, ____, ____, ____,   ____, ____,    ____,     ____,   ____,    ____,     ____,  \
____,     ____, ____, ____, ____, ____, ____, ____, ____,   ____, ____,    ____,     ____,   ____,    ____,   \
____,  _________________EXCEL_L1__________________, _________________EXCEL_R1__________________,  ____,   ____,  ____,\
____,  _________________EXCEL_L2__________________, _________________EXCEL_R2__________________,  KC_GRV, ____,  ____,\
____,  _________________EXCEL_L3__________________, _________________EXCEL_R3__________________,  B_SAVE, ____,  ____,\
____,     ____, ____, ____, ____, ____, ____, ____, ____,   ____
),

#ifndef USE_BABLPASTE

[_MOV] = LAYOUT_local(\
____,     XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX,   XXXX, XXXX,    XXXX,     XXXX,   XXXX,    XXXX,   ____  ,  \
____,     XXXX, XXXX, XXXX, XXXX, XXXX,      XXXX, XXXX, XXXX, XXXX, XXXX,     XXXX, XXXX,   XXXX, XXXX,   \
____,     XXXX, XXXX, XXXX, XXXX, XXXX,      XXXX, XXXX, KC_UP, XXXX, XXXX,    XXXX, XXXX,   XXXX, \
____,     XXXX, XXXX, XXXX, XXXX, XXXX,      XXXX, KC_LEFT, KC_DOWN, KC_RIGHT,XXXX,   XXXX, XXXX,   XXXX, \
____,     XXXX, XXXX, XXXX, XXXX, XXXX,      XXXX, XXXX, XXXX, XXXX, XXXX,     XXXX, XXXX,   XXXX, \
____,     XXXX, XXXX, XXXX, XXXX, XXXX,      XXXX, XXXX, XXXX, XXXX
)

#else
/* MOVE babble version version

* |ESC   | MAC|Read|Linx| VI |    |    |    |    |    |    |    |   |    |   |    |
*  -------------------------------------------------------------------------------'
* |      |                                                 |  - | = |Bakspace| Del|
* ---------------------------------------------------------------------------
* | tab  |                                                 |  [ |  ] |  \    |    |
*  -------------------------------------------------------------------------------'
* |Bak/Mov|                                                |  ' |Launch App  |PgUp|
* ---------------------------------------------------------------------------------
* |Lsft    |                                                 |      Rsft| Up| PgDn|
* ---------------------------------------------------------------------------------
* |       |Lgui  |Lalt |   Exit Move Mode     | GUI |  Sym |  Rctl |Left|Down|Rght|
* ---------------------------------------------------------------------------------
*/
/*    ,--------------------------------------------.  ,--------------------------------------------.
 * 01 | ESC    |FindPrev|  Find  |FindNext| \n cell|  |ParStart|LineStrt|   Up   |  EOL   | ParEnd |
 *    |--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------|
 * 02 | SelA   | Do_DEL | Shift  |   Undo |Hsplit+ |  | WrdLft | Left   | Down   | Right  | WrdRght|
 *    |--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------|
 * 03 |Vspli+  | Cut    | Copy   | Paste  | Paste  |  | WinPrv | Tab--  | NewTab | Tab++  | WinNxt |
 *    `--------------------------------------------'  `--------------------------------------------'
 */

[_MOV] = LAYOUT_wrapper(\
  ____,    ____________BABBLE_SWITCH_L________________, ____________BABBLE_SWITCH_R________________,    XXXX,   XXXX,   XXXX,   XXXX,    ____,  \
  ____,    ____________BABBLE_MOV_LNUM________________, ____________BABBLE_MOV_RNUM________________,    XXXX,   XXXX,   XXXX,   XXXX,\
  ____,    ____________BABBLE_MOV_L1__________________, ____________BABBLE_MOV_R1__________________,    XXXX,   XXXX,   XXXX, \
  ____,    ____________BABBLE_MOV_L2__________________, ____________BABBLE_MOV_R2__________________,    XXXX, B_RUNAPP, XXXX,\
  ____,    ____________BABBLE_MOV_L3__________________, ____________BABBLE_MOV_R2__________________,   XXXX,  XXXX,   XXXX, \
  ____,    ____,   ____,  TG(_MOV), XXXX, XXXX, XXXX,  XXXX, XXXX,   XXXX
),
// Move in a direction, deleting as we go, or do opposite of Mov layer action */
/*    ,--------------------------------------------.  ,--------------------------------------------.
 * 01 |  Esc   |        |Replace |MultiSel|PasteVal|  |     .  |LineStrt|   .    |  EOL   |    .   |
 *    |--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------|
 * 02 |        | Do_Mov | Shift  | Redo   |Hsplit- |  | WrdLft | Left   |   .    | Right  | WrdRght|
 *    |--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------|
 * 03 |Vsplit- | Cut    | Copy   | Paste  |Paste   |  |  App-- | ZoomOut| NewWin | ZoomIn | App+   |
 *    `--------------------------------------------'  `--------------------------------------------'
 */ 
[_DMOV] = LAYOUT_wrapper(\
  ____,    ____________BABBLE_SWITCH_L________________,  ____________BABBLE_SWITCH_R________________,   XXXX,   XXXX,   XXXX,     ____,  \
  ____,    ____________BABBLE_MOV_LNUM________________,  ____________BABBLE_MOV_RNUM________________,   XXXX,   XXXX,   XXXX,    XXXX,   \
  ____,    _________BABBLE_DELMOV_L1__________________ , _________BABBLE_DELMOV_R1__________________ ,  XXXX,   XXXX,   XXXX, \
  ____,    _________BABBLE_DELMOV_L2__________________ , _________BABBLE_DELMOV_R2__________________ ,  XXXX,   XXXX,   XXXX,\
  ____,    _________BABBLE_DELMOV_L3__________________ , _________BABBLE_DELMOV_R3__________________ ,  XXXX,   XXXX,   XXXX, \
  ____,    XXXX,   XXXX,  XXXX, XXXX, XXXX, XXXX, XXXX, XXXX,  XXXX, XXXX
),

#endif // Bablepaste
/*
[_TRAN] = LAYOUT_local(\
  ____,     ____, ____, ____, ____, ____, ____, ____, ____,   ____, ____,    ____,     ____,   ____,    ____,     ____,  \
  ____,     ____, ____, ____, ____, ____,      ____, ____, ____, ____, ____,    ____, ____,   ____, ____,   \
  ____,     ____, ____, ____, ____, ____,      ____, ____, ____, ____, ____,    ____, ____,   ____, \
  ____,     ____, ____, ____, ____, ____,      ____, ____, ____, ____, ____,    ____, ____,   ____, \
  ____,     ____, ____, ____, ____, ____,      ____, ____, ____, ____, ____,    ____, ____,   ____, \
  ____,     ____, ____, ____, ____, ____,      ____, ____, ____, ____
)
*/
};

#ifndef USERSPACE_ACTIVE

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
        case QWR:
            if (record->event.pressed) {
                layer_off(_CDH);
            }
            return false;
            break;

        case CDH:
            if (record->event.pressed) {
                layer_on(_CDH);
            }
            return false;
            break;

        case SYM:
            if (record->event.pressed) {
                layer_on(_SYM);
            } else {
              layer_off(_SYM);
            }
            return false;
            break;

        case SAVE: 
             if (record->event.pressed) {
               SEND_STRING(SS_LCTL("s"));
            }
            return false;
            break;
        /* Colemak mod-dh moves the D key to the qwerty V position
            This hack makes apple-V_position do what I mean */
        case DHPASTE:
            if(get_mods() & MOD_BIT(KC_LGUI) ) {
                if (record->event.pressed) {
                    clear_keyboard_but_mods();
                    register_code(KC_V);
                } else {
                    unregister_code(KC_V);
                }
            } else {
                if (record->event.pressed) {
                    register_code(KC_D);
                } else {
                    unregister_code(KC_D);
                }
            }
            return false;
            break;

        return false;
        break;
    }

    return true;
}
#endif

void keyboard_post_init_user(void) {
  // Customise these values to desired behaviour
  // debug_enable=true;
  //debug_matrix=true;
  //debug_keyboard=true;
  //debug_mouse=true;
}


void matrix_init_user(void) {
    #ifdef RGBLIGHT_ENABLE
    #ifdef RGB_DI_PIN
        rgblight_setrgb(RGB_GREEN);
    #endif
    #endif //RGB_matrix  
}

// Runs whenever there is a layer state change.
layer_state_t layer_state_set_user(layer_state_t state) {
    uint8_t layer = get_highest_layer(state);
    switch (layer) {
        case 0:
            #ifdef RGBLIGHT_COLOR_LAYER_0
                rgblight_setrgb(RGBLIGHT_COLOR_LAYER_0);
            #else
                #ifdef RGBLIGHT_ENABLE
                    rgblight_init();
                #endif
            #endif
            break;

        case 1:
            #ifdef RGBLIGHT_COLOR_LAYER_1
                rgblight_setrgb(RGBLIGHT_COLOR_LAYER_1);
            #endif
            break;

        case 2: // symbol
            #ifdef RGBLIGHT_COLOR_LAYER_2
                rgblight_setrgb(RGBLIGHT_COLOR_LAYER_2);
            #endif
            break;

        case 3: // move
            #ifdef RGBLIGHT_COLOR_LAYER_3
                rgblight_setrgb(RGBLIGHT_COLOR_LAYER_3);
            #endif
            #ifdef USE_BABLPASTE
                babble_led_user(); // poke led to update
            #endif  // bablepaste
            break;

        case 4: //delmove ideally we'd turn on a red pixel in addition to the layer indicator. 
            #ifdef RGBLIGHT_COLOR_LAYER_4
                rgblight_setrgb(RGBLIGHT_COLOR_LAYER_4);
            #endif
            break;

        case 5:
            #ifdef RGBLIGHT_COLOR_LAYER_5
                rgblight_setrgb(RGBLIGHT_COLOR_LAYER_5);
            #endif
            break;

        default:
          break;
      }
    #ifdef VIRTSER_ENABLE
      //virtser_send(layer + 48); // ascii 0 is 48
    #endif
  return state;
};

// custom tapping term lengths. 
uint16_t get_tapping_term(uint16_t keycode) {
    switch (keycode) {
        case LT(_MOV, KC_TAB):
            return TAPPING_TERM ;
            break;
        default:
        return TAPPING_TERM;
    }
}



#ifdef VIRTSER_ENABLE
/* listen on serial for commands. Either a set of lower case letters mapped to colors, 
/  or upper case letters that change RGB mode. 
/  special command C takes 3 numbers as arguments, terminated with a newline or comma or excess digits.
Command C takes 3-5octets of RGB settings. Numbers can be terminated with a comma or period. 
3 octets = set all LED, 4th argument specfies specfic LED, 4+5 specify start and stop LEDs.
*/ 

uint8_t ser_rgbByte[18] ; //ascii string 
uint8_t ser_cmd_started =0 ; // are we in process
uint8_t ser_got_RGBbytes =0 ; // how many bytes we've recived. 
uint8_t rgb_r[6]; // R, g, b, P1, p2
uint8_t bs=0; // how many bytes into our rgbBytestring.

void virtser_recv(uint8_t serIn) { 
#ifdef RGBLIGHT_ENABLE 
    if ((serIn == 10 ) || (serIn ==  13) || ser_got_RGBbytes >=5) { //reached newline or max digits

        if (ser_cmd_started) {
            ser_cmd_started =0 ; // end loop at newline
            virtser_send('|');

            if (ser_got_RGBbytes==3) {
                rgblight_setrgb( rgb_r[0], rgb_r[1], rgb_r[2]);
            }

            if (ser_got_RGBbytes ==4) {
                if (( rgb_r[3] >=0)  && (rgb_r[3] <= RGBLED_NUM) ) { // is pos1 plausible
                    rgblight_setrgb_at ( rgb_r[0], rgb_r[1], rgb_r[2], rgb_r[3]);
                } else {
                        rgblight_setrgb( rgb_r[0], rgb_r[1], rgb_r[2]);
                }
            }

            if (ser_got_RGBbytes == 5) { // are start and end positions plausible? 
                if ( (rgb_r[4] >0)  && (rgb_r[4] <= RGBLED_NUM) && (rgb_r[4] > rgb_r[3]) && 
                 (rgb_r[3] >=0)  && (rgb_r[3] <= (RGBLED_NUM -1))  ) {
                    rgblight_setrgb_range(rgb_r[0], rgb_r[1], rgb_r[2], rgb_r[3], rgb_r[4]);
               } else {
                   rgblight_setrgb( rgb_r[0], rgb_r[1], rgb_r[2]);
               }
            }
        } else { // newline outside of command loop, or something that can be ignored. 
          //virtser_send('.');
        }
    } 

    if (1 == ser_cmd_started) { // collecting bytes. 
        if  (   // it is time to compute a byte
          ( ( (serIn == ',') || (serIn == '.') ) && (bs > 0) ) || // signal done with the byte. 
            (bs ==2 )){ //or we know this is last.
        
            if ( (serIn <= '9') && (serIn >='0') ) { //3rd asci digit 
                ser_rgbByte[bs] = serIn;
                bs++;
            //  virtser_send(serIn);
            }

            if (bs>3) {
                rgb_r[ser_got_RGBbytes]=255;
                ser_got_RGBbytes ++;
            }
            if (bs==3) {
              rgb_r[ser_got_RGBbytes] = (ser_rgbByte[0] -'0')*100 + (ser_rgbByte[1] -'0')*10 + (ser_rgbByte[2] -'0' );
              ser_got_RGBbytes ++;
            }
            if (bs ==2 ) {
               rgb_r[ser_got_RGBbytes] = (ser_rgbByte[0] -'0')*10 +  (ser_rgbByte[1] -'0' );
               ser_got_RGBbytes ++;
            }
            if (bs ==1) {
               rgb_r[ser_got_RGBbytes] = (ser_rgbByte[0] -'0');
               ser_got_RGBbytes ++;
            }  // {else wipe & start over}

          bs=0;
    //  virtser_send(ser_got_RGBbytes+'0');

        } else { // haven't got enough for our byte / no terminal marker
            if ( (serIn <= '9') && (serIn >='0') ) { //ascii only 
                ser_rgbByte[bs] = serIn;
                bs++;
            //    virtser_send(serIn);
            }
        }
    } else { //not in command loop - next is command w/o arguments, or start of one. 
        switch (serIn) {
            case 'C': // color switch
                ser_cmd_started=1;
                ser_got_RGBbytes = bs =0;
                virtser_send('/');
                break;
        
            case 'r': //red
                rgblight_setrgb(RGB_RED);
                break;
         
            case 'g': 
                rgblight_setrgb(RGB_GREEN);
                break;
   
            case 'b':  // color switch
                rgblight_setrgb(RGB_BLUE);
                break;

            case 'w':  // color switch
                rgblight_setrgb(RGB_WHITE);
                break;

            case 'o':  // color black/off
                rgblight_setrgb(0,0,0);
                break;
               
            case 'T':  // toggle
                rgblight_toggle();
                break;
            
            case 'P': // pulse led
                rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING);
                break; 
            case 'S':  // Static
                rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
                break;
           
            case 'U':  // Rainbow
                rgblight_mode_noeeprom(RGBLIGHT_MODE_RAINBOW_MOOD);
                break;
                   
            default: 
           //     virtser_send(serIn);
                break;

        }
    }
#endif // RGBLIGHT_ENABLE
}

#endif // VirtSerial

A users/miles2go/keymaps/handwired/ms_sculpt_mobile/readme.md => users/miles2go/keymaps/handwired/ms_sculpt_mobile/readme.md +10 -0
@@ 0,0 1,10 @@
# keymap taking advantage of the STM32 storage & CPU. 
RGB LED is used to show layers
default bluepill LED is capslock.
there's a simple serial protocol for the keyboard to listen for color change commands from the PC. 
Useful for "do stuff && cat "green">/dev/ttyACM0"

lower case letters set pre-programmed colors
Upper case letters change RGB mode
Command C takes 3-5 octets of RGB settings. Numbers can be terminated with a comma or period. 
3 octets = set all LED, 4th argument specfies specfic LED, 4+5 specify start and stop LEDs.

A users/miles2go/keymaps/handwired/ms_sculpt_mobile/rules.mk => users/miles2go/keymaps/handwired/ms_sculpt_mobile/rules.mk +24 -0
@@ 0,0 1,24 @@
# Build Options
#   change to "no" to disable the options, or define them in the Makefile in 
#   the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = no       # Virtual DIP switch configuration
MOUSEKEY_ENABLE = yes       # Mouse keys
EXTRAKEY_ENABLE = yes       # Audio control and System control
CONSOLE_ENABLE = no         # Console for debug
COMMAND_ENABLE = no         # Commands for debug and configuration
NKRO_ENABLE = no            # Nkey Rollover 
BACKLIGHT_ENABLE = no       # Enable keyboard backlight functionality
MIDI_ENABLE = no            # MIDI controls
AUDIO_ENABLE = no           # Audio output on port C6
UNICODE_ENABLE = no         # Unicode
BLUETOOTH_ENABLE = no       # Enable Bluetooth with the Adafruit EZ-Key HID
ifeq ($(strip $(KEYBOARD)), handwired/ms_sculpt_mobile/8x18_arm)
	RGBLIGHT_ENABLE = yes       # Enable WS2812 RGB underlight. 
endif
SLEEP_LED_ENABLE = no       # Breathing sleep LED during USB suspend

#enable RAW in keymap config, since it can hang machines
RAW_ENABLE = no
# virtual serial port
VIRTSER_ENABLE = yes

A users/miles2go/milestogo.c => users/miles2go/milestogo.c +142 -0
@@ 0,0 1,142 @@
// based on drashna's but I think at this point it's a new axe

#include QMK_KEYBOARD_H
#include "milestogo.h"
#include <print.h>

__attribute__((weak)) bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { return true; }

bool move_is_on = false;  // track if we are in _MOV layer
bool sym_is_on  = false;  // track if we are in _SYM layer

// Defines actions for global custom keycodes
// Then runs the _keymap's record handier if not processed here
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    // static uint16_t spcmov_timer; // timer for spcmov key

#ifdef USE_BABBLEPASTE
    if (keycode > BABBLE_START && keycode < BABBLE_END_RANGE) {
        if (record->event.pressed) {  // is there a case where this isn't desired?
            babblePaste(keycode);
        } else {
            return true;
        }
    }
#endif

    switch (keycode) {
        case _QWERTY:
            if (record->event.pressed) {
                set_single_persistent_default_layer(_QWERTY);
            }
            break;

        case _CDH:
            if (record->event.pressed) {
                set_single_persistent_default_layer(_CDH);
            }
            break;

        case TMUX:  // ctl-B
            if (record->event.pressed) {
                tap_code16(C(KC_B));
            }
            break;

            /* Colemak mod-dh moves the D key to the qwerty V position
                        This hack makes apple-V_position do what I mean */
        case DHPASTE:
            if (get_mods() & MOD_BIT(KC_LGUI)) {
                if (record->event.pressed) {
                    clear_keyboard_but_mods();
                    register_code(KC_V);
                } else {
                    unregister_code(KC_V);
                }
            } else {
                if (record->event.pressed) {
                    register_code(KC_D);
                } else {
                    unregister_code(KC_D);
                }
            }
            return false;
            break;

        default:
            return true;
    }

    // normal keycode
    return process_record_keymap(keycode, record);
}

void babble_led_user(void) {
#ifdef USE_BABLPASTE
    extern uint8_t babble_mode;

#    ifdef BABL_WINDOWS
    if (babble_mode == BABL_WINDOWS_MODE) {
        if (BABL_LED_INDEX > 0) {
            rgblight_setrgb_at(RGBLIGHT_COLOR_MS, BABL_LED_INDEX);
        } else {
            rgblight_setrgb(RGBLIGHT_COLOR_MS);
        }
    }
#    endif
#    ifdef BABL_READMUX
    if (babble_mode == BABL_READMUX_MODE) {
        if (BABL_LED_INDEX > 0) {
            rgblight_setrgb_at(RGBLIGHT_COLOR_READMUX, BABL_LED_INDEX);
        } else {
            rgblight_setrgb(RGBLIGHT_COLOR_READMUX);
        }
    }
#    endif
#    ifdef BABL_MAC
    if (babble_mode == BABL_MAC_MODE) {
        if (BABL_LED_INDEX > 0) {
            rgblight_setrgb_at(RGBLIGHT_COLOR_MAC, BABL_LED_INDEX);
        } else {
            rgblight_setrgb(RGBLIGHT_COLOR_MAC);
        }
    }
#    endif
#    ifdef BABL_VI
    if (babble_mode == BABL_VI_MODE) {
        if (BABL_LED_INDEX > 0) {
            rgblight_setrgb_at(RGBLIGHT_COLOR_VI, BABL_LED_INDEX);
        } else {
            rgblight_setrgb(RGBLIGHT_COLOR_VI);
        }
    }
#    endif
#    ifdef BABL_EMACS
    if (babble_mode == BABL_EMACS_MODE) {
        if (BABL_LED_INDEX > 0) {
            rgblight_setrgb_at(RGBLIGHT_COLOR_EMACS, BABL_LED_INDEX);
        } else {
            rgblight_setrgb(RGBLIGHT_COLOR_EMACS);
        }
    }
#    endif
#    ifdef BABL_CHROMEOS
    if (babble_mode == BABL_CHROMEOS_MODE) {
        if (BABL_LED_INDEX > 0) {
            rgblight_setrgb_at(RGBLIGHT_COLOR_CHROMEOS, BABL_LED_INDEX);
        } else {
            rgblight_setrgb(RGBLIGHT_COLOR_CHROMEOS);
        }
    }
#    endif
#    ifdef BABL_LINUX
    if (babble_mode == BABL_LINUX_MODE) {
        if (BABL_LED_INDEX > 0) {
            rgblight_setrgb_at(RGBLIGHT_COLOR_LINUX, BABL_LED_INDEX);
        } else {
            rgblight_setrgb(RGBLIGHT_COLOR_LINUX);
        }
    }
#    endif
#endif  // bablepaste
}

A users/miles2go/milestogo.h => users/miles2go/milestogo.h +289 -0
@@ 0,0 1,289 @@
/* Modified from 
Copyright 2017 Christopher Courtney <drashna@live.com> @drashna

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


#pragma once
#include "quantum.h"
#include "version.h"
#include "eeprom.h"


#ifdef USE_BABBLEPASTE
#include "babblePaste.h"
#endif 

#ifdef RGB_MATRIX_ENABLE
#include "rgb_matrix.h"
#endif

#define USERSPACE_ACTIVE

/* Define layer names */
enum userspace_layers {
    _QWERTY=0, 
    _CDH,
    _SYM,
    _MOV,
    _DMOV,
    _NUM
};


/*
define modifiers here, since MOD_* doesn't seem to work for these
 */
#define MODS_SHIFT_MASK  (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT))
#define MODS_CTRL_MASK  (MOD_BIT(KC_LCTL)|MOD_BIT(KC_RCTRL))
#define MODS_ALT_MASK  (MOD_BIT(KC_LALT)|MOD_BIT(KC_RALT))
#define MODS_GUI_MASK  (MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI))

#if defined(BABBLE_END_RANGE)
      #define USER_START BABBLE_END_RANGE
#else
    #if defined(KEYMAP_SAFE_RANGE)
        #define USER_START KEYMAP_SAFE_RANGE
    #else
        #define USER_START SAFE_RANGE
    #endif
#endif

enum userspace_custom_keycodes {
    EPRM = BABBLE_END_RANGE, // Resets EEPROM do defaults (as in eeconfig_init)
    VRSN,              // Prints QMK Firmware and board info
    KC_QWERTY,         // Sets default layer to QWERTY
    KC_CDH,        // Sets default layer to COLEMAK DH
    KC_MAKE,
    VIBRK,  // escape :
    DHPASTE, // allow pasting via qwerty V,not colemak V
    TMUX, // TMUX Ctrl-b
    ALTSYM, // Alt when held, toggle MOV when tapped
    GUISYM,
    SPCMOV,
    SAVE, // placeholder for CTRL-S while I get babble working again.
    NEW_SAFE_RANGE     //Keymap specific codes come AFTER this
};
    
#define QWERTY KC_QWERTY
#define COLEMAK KC_CDH
#define KC_RESET RESET



#if (!defined(LAYOUT) && defined(KEYMAP))
#define LAYOUT KEYMAP
#endif

#define LAYOUT_wrapper(...)                  LAYOUT(__VA_ARGS__)


#define _________________QWERTY_L1_________________        KC_Q,    KC_W,    KC_E,    KC_R,    KC_T
#define _________________QWERTY_L2_________________        KC_A,    KC_S,    KC_D,    KC_F,    KC_G
#define _________________QWERTY_L3_________________        KC_Z,    KC_X,    KC_C,    KC_V,    KC_B

#define _________________QWERTY_R1_________________        KC_Y,    KC_U,    KC_I,    KC_O,    KC_P
#define _________________QWERTY_R2_________________        KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN
#define _________________QWERTY_R3_________________        KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLASH


#define ______________COLEMAK_MOD_DH_L1____________       KC_Q,    KC_W,    KC_F,    KC_P,    KC_B
#define ______________COLEMAK_MOD_DH_L2____________       KC_A,    KC_R,    KC_S,    KC_T,    KC_G
#define ______________COLEMAK_MOD_DH_L3____________       KC_Z,    KC_X,    KC_C,    KC_D,    KC_V

#define ______________COLEMAK_MOD_DH_R1____________       KC_J,    KC_L,    KC_U,    KC_Y,    KC_SCLN
#define ______________COLEMAK_MOD_DH_R2____________       KC_M,    KC_N,    KC_E,    KC_I,    KC_O
#define ______________COLEMAK_MOD_DH_R3____________       KC_K,    KC_H,    KC_COMM, KC_DOT,  KC_SLASH


#define ________________NUMBER_LEFT________________       KC_1,    KC_2,    KC_3,    KC_4,    KC_5
#define ________________NUMBER_RIGHT_______________       KC_6,    KC_7,    KC_8,    KC_9,    KC_0

#define ________________FKEYS__LEFT________________       KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5
#define ________________FKEYS__RIGHT_______________       KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10
#define ________________FKEYS__FAR_RIGHT___________       KC_F11,  KC_F12,  KC_PSCR, KC_HOME, KC_END

#define ________________NAV_NUMBER_LEFT____________       KC_LSFT, KC_LCTL, KC_LALT, KC_LGUI, XXXXXXX

#define ___________________BLANK___________________       _______, _______, _______, _______, _______
#define ___________________BLOCK___________________       XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX



// BabblePaste 
#define ____________BABBLE_SWITCH_L________________       B_MAC , B_READ , B_LINUX, B_VI, _______
#define ____________BABBLE_SWITCH_R________________       B_CROM, B_LINUX, B_WIN  , QWERTY,  COLEMAK


/////////MOVE  - Full size  keyboard version

/*    ,--------------------------------------------.  ,--------------------------------------------.
 * N  |Lock    |PrevApp |NextApp |PasteVal|        |  |        |        |SwitchKB|Devtools| Lock   |
 *    |--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------|
 * 01 | ESC    |FindPrev|  Find  |FindNext| \n cell|  |ParStart|LineStrt|   Up   |  EOL   | ParEnd |
 *    |--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------|
 * 02 | SelA   | Do_DEL | Shift  |   Undo |Hsplit+ |  | WrdLft | Left   | Down   | Right  | WrdRght|
 *    |--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------|
 * 03 |Vspli+  | Cut    | Copy   | Paste  | Paste  |  | WinPrv | Tab--  | NewTab | Tab++  | WinNxt |
 *    `--------------------------------------------'  `--------------------------------------------'
 */
/* Movement layer  similar to Extend, but fully enriched with babblepaste */
#define ____________BABBLE_MOV_LNUM________________     B_LOCK, B_PAPP,   B_NAPP,   B_PASTV,    XXXX    

#define ____________BABBLE_MOV_L1__________________     KC_ESC, B_FINDP,  B_FIND,  B_FINDN, B_NCEL
#define ____________BABBLE_MOV_L2__________________     B_SELA , MO(_DMOV),KC_LSFT,B_UNDO, B_HSPLIT
#define ____________BABBLE_MOV_L3__________________     B_VSPLIT, B_CUT,  B_COPY,  B_PASTE, B_PASTE

#define ____________BABBLE_MOV_RNUM________________     XXXX,    XXXX,     B_KEYB,  B_BDEV,  B_LOCK
#define ____________BABBLE_MOV_R1__________________     B_PTOP,  B_GSOL,   B_UP,    B_GEOL,  B_PEND
#define ____________BABBLE_MOV_R2__________________     B_L1W,   B_L1C,    B_DOWN,  B_R1C,   B_R1W
#define ____________BABBLE_MOV_R3__________________     B_PWIN,  B_PTAB,   B_NTAB,  B_NXTB,  B_NWIN


// Move in a direction, deleting as we go, or do opposite of Mov layer action */
/*    ,--------------------------------------------.  ,--------------------------------------------.
 * 01 |  Esc   |        |Replace |MultiSel|PasteVal|  |     .  |LineStrt|   .    |  EOL   |    .   |
 *    |--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------|
 * 02 |        | Do_Mov | Shift  | Redo   |Hsplit- |  | WrdLft | Left   |   .    | Right  | WrdRght|
 *    |--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------|
 * 03 |Vsplit- | Cut    | Copy   | Paste  |Paste   |  |  App-- | ZoomOut| NewWin | ZoomIn | App+   |
 *    `--------------------------------------------'  `--------------------------------------------'
 */ 
#define _________BABBLE_DELMOV_L1__________________       KC_ESC,  _______, B_RPLACE, B_MSEL,  B_PASTV
#define _________BABBLE_DELMOV_L2__________________       XXXXXXX, _______, _______,  B_REDO,  B_HUNSPT
#define _________BABBLE_DELMOV_L3__________________	      B_VUNSPT,B_CUT,   B_COPY,   B_PASTE, B_PRVFM

#define _________BABBLE_DELMOV_R1__________________       XXXXXXX, B_DSOL,  _______, B_DEOL,  XXXXXXX
#define _________BABBLE_DELMOV_R2__________________       B_DLW,   KC_BSPC, _______, B_DEL,  B_DRW 
#define _________BABBLE_DELMOV_R3__________________       B_NAPP,  B_ZOUT,  B_WINN,  B_ZIN,   B_PAPP

/* SYM  / excel / programming logic +=1 optimization*/
/*    ,----------------------------------.  ,----------------------------------.
 * 01 |      |   [  |  ]   |  {   |      |  |      |  }   | (    | )    |      |
 *    |------+------+------+------+------|  |------+------+------+------+------|
 * 02 |  ^   |   !  |  =   |   0  | $    |  |   #  |  1   | -    |  +   |  `   |
 *    |------+------+------+------+------|  |------+------+------+------+------|
 * 03 |  \   |   %  |   @  |  |   |  _   |  |   *  |  &   |  ~   |  .   |  /   |
 *    `----------------------------------'  `----------------------------------'
 Memnonics
 ^begining end$ .   &&/|| on strong finger.  #at start of line.  
 * (multiply) opposite /  
 Minus is left of plus as normal. 
 ` is a shifted ''
 ~/ is an outwards roll. / .* is a roll. !=0 is a roll , ++1 --1 roll. 
 _ is hard to get to. 

 */
#define ___________________SYM_L1__________________       XXXXXXX, KC_LBRC, KC_RBRC, KC_LCBR, XXXXXXX
#define ___________________SYM_L2__________________       KC_CIRC,  KC_EXLM, KC_EQL,  KC_0,    KC_DLR 
#define ___________________SYM_L3__________________       KC_BSLS,  KC_PERC, KC_AT,   KC_PIPE, KC_UNDS
  
#define ___________________SYM_R1__________________       XXXXXXX,  KC_RCBR, KC_LPRN, KC_RPRN, XXXXXXX
#define ___________________SYM_R2__________________       KC_HASH,  KC_KP_1, KC_MINS, KC_PLUS, KC_GRAVE
#define ___________________SYM_R3__________________       KC_PERC,  KC_TILDE,KC_AMPR, KC_DOT,  KC_SLASH



/* excel centric symbol layer*/
 /*    ,--------------------------------------------.  ,--------------------------------------------.
 * 01 |  DelRow|InsCol  | SelCol |PasteVal|        |  |     .  |   1    |  2     |   3    |        |
 *    |--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------|
 * 02 |   -    |InsRow  | SelRow | Undo   | +      |  |    *   |   4    |  5     |   6    |   -    |
 *    |--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------|
 * 03 | Undo   |  Cut   | Copy   | Paste  |Paste   |  |    /   |   7    |  8     |   9    | Paste  |
 *    `--------------------------------------------'  `--------------------------------------------'
 
 */
#define _________________EXCEL_L1__________________       B_DROW,   B_ICOL, B_SELC, B_PASTV,    XXXX
#define _________________EXCEL_L2__________________       KC_MINS,   B_ICOL, B_SELC,  B_UNDO,   KC_PLUS
#define _________________EXCEL_L3__________________       B_UNDO,   B_CUT,  B_COPY, B_PASTE,    B_PASTE
  
#define _________________EXCEL_R1__________________       XXXXXXX,  KC_1, KC_2, KC_3, XXXXXXX
#define _________________EXCEL_R2__________________       KC_ASTR,  KC_4, KC_5, KC_6, KC_MINS
#define _________________EXCEL_R3__________________       KC_SLASH, KC_7, KC_8, KC_8, B_PASTE


/* Based on BEKL 15 punctuation
*     ,----------------------------------.  ,----------------------------------.
 * 01 |      |   <  |  $   |  >   |      |  |      |  [   |  _   |  ]   |      |
 *    |------+------+------+------+------|  |------+------+------+------+------|
 * 02 |  \   |   (  |  ""  |  )   |  #   |  |   %  |  {   |  =   |  }   |  "|" |
 *    |------+------+------+------+------|  |------+------+------+------+------|
 * 03 |      |   :  |   *  |  +   |      |  |      |  &   |  ^   |  ~   |      |
 *    `----------------------------------'  `----------------------------------'
 Memnonics

 */
#define ______________BEKL_SYM_L1__________________       XXXXXXX, KC_LBRC, KC_RBRC, KC_LCBR, XXXXXXX
#define ______________BEKL_SYM_L2__________________       KC_CIRC,  KC_EXLM, KC_EQL,  KC_0,    KC_DLR 
#define ______________BEKL_SYM_L3__________________       KC_BSLS,  KC_PERC, KC_AT,   KC_PIPE, KC_UNDS
  
#define ______________BEKL_SYM_R1__________________       XXXXXXX,  KC_RCBR, KC_LPRN, KC_RPRN, XXXXXXX
#define ______________BEKL_SYM_R2__________________       KC_HASH,  KC_KP_1, KC_MINS, KC_PLUS, KC_GRAVE
#define ______________BEKL_SYM_R3__________________       KC_PERC,  KC_TILDE,KC_AMPR, KC_DOT,  KC_SLASH
 
// NUM  
/*    ,----------------------------------.  ,----------------------------------.
 * 01 |   1  |   2  |  3   |  4   |  5   |  |   6  |  7   |  8   |   9  |  0   |
 *    |------+------+------+------+------|  |------+------+------+------+------|
 * 02 |  F1  |  F2  |  F3  |  F4  |  F5  |  |  F6  |  F7  |  F8  |  F9  |  F10 |
 *    |------+------+------+------+------|  |------+------+------+------+------|
 * 03 |  F11 |  F12 |      |      | QWERT|  | CDH  |      |      |      |      |
 *    `----------------------------------'  `----------------------------------'
 */
 
#define ___________________NUM_L1__________________      ________________NUMBER_LEFT________________ 
#define ___________________NUM_L2__________________      ________________FKEYS__LEFT________________ 
#define ___________________NUM_L3__________________      KC_F11,  KC_F11,  XXXXXXX,    XXXXXXX, QWERTY
  
#define ___________________NUM_R1__________________      ________________NUMBER_RIGHT_______________
#define ___________________NUM_R2__________________      ________________FKEYS__RIGHT_______________
#define ___________________NUM_R3__________________      COLEMAK,   XXXXXXX,  XXXXXXX, XXXXXXX,   XXXXXXX
 


/* NUM  / excel / programming logic +=1 optimization*/
/*    ,----------------------------------.  ,----------------------------------.
 * 01 |   1  |   2  |  3   |  4   |  5   |  | 6    | 7    | 8    | 9    | 0    |
 *    |------+------+------+------+------|  |------+------+------+------+------|
 * 02 |  ^   |   !  |  =   |   0  | $    |  |   #  |  1   | -    |  +   |  `   |
 *    |------+------+------+------+------|  |------+------+------+------+------|
 * 03 |  \   |   %  |   @  |  |   |  _   |  |   *  |  &   |  ~   |  .   |  /   |
 *    `----------------------------------'  `----------------------------------'
 Memnonics
 ^begining end$ .   &&/|| on strong finger.  #at start of line.  * missing? 
 Minus is left of plus as normal. ` is a shifted ''
 ~/ is an outwards roll. / * is a roll. 
 _ is hard to get to. 

 */
#define __________40_______NUM_L1__________________       ________________NUMBER_LEFT________________
#define __________40_______NUM_L2__________________       KC_CIRC,  KC_EXLM, KC_EQL,  KC_0,    KC_DLR 
#define __________40_______NUM_L3__________________       KC_BSLS,  KC_PERC, KC_AT,   KC_PIPE, KC_UNDS
  
#define __________40_______NUM_R1__________________       ________________NUMBER_RIGHT_______________
#define __________40_______NUM_R2__________________       KC_HASH,  KC_KP_1, KC_MINS, KC_PLUS, KC_GRAVE
#define __________40_______NUM_R3__________________       KC_PERC,  KC_TILDE, KC_AMPR,KC_DOT,  KC_SLASH
 

#define _________________ADJUST_L1_________________        RGB_MOD, RGB_HUI, RGB_SAI, RGB_VAI, RGB_TOG
#define _________________ADJUST_L2_________________        MU_TOG , CK_TOGG, AU_ON,   AU_OFF,  AG_NORM
#define _________________ADJUST_L3_________________        RGB_RMOD,RGB_HUD,RGB_SAD, RGB_VAD, KC_RGB_T

#define _________________ADJUST_R1_________________        KC_SEC1, KC_SEC2, KC_SEC3, KC_SEC4, KC_SEC5
#define _________________ADJUST_R2_________________        AG_SWAP, QWERTY,  COLEMAK, DVORAK,  WORKMAN
#define _________________ADJUST_R3_________________        MG_NKRO, KC_MUTE, KC_VOLD, KC_VOLU, KC_MNXT



A users/miles2go/readme.md => users/miles2go/readme.md +10 -0
@@ 0,0 1,10 @@
# Overview

This is my personal userspace file.  Most of my code exists here, as it's heavily shared.

## Custom Keycodes
See the babblepaste.txt readme 

## Layer Indication

This uses the `layer_state_set_*` command to change the layer color, to indicate which layer it is on.  This includes the default keymap, as well.
\ No newline at end of file

A users/miles2go/rules.mk => users/miles2go/rules.mk +10 -0
@@ 0,0 1,10 @@
SRC += milestogo.c  babblePaste.c babl_windows.c babl_mac.c babl_vi.c babl_readmux.c  babl_chromeos.c babl_emacs.c babl_linux.c
LTO_ENABLE = yes

ifeq ($(strip $(MACROS_ENABLED)), yes)
    OPT_DEFS += -DMACROS_ENABLED
endif

ifeq ($(strip $(USE_BABBLEPASTE)), yes)
	SRC += babblePaste.c
endif