Archived
1
0

Merge branch 'master' into dev

This commit is contained in:
Jacob Alexander 2016-09-11 11:10:00 -07:00
commit 44addcf031
6 changed files with 517 additions and 589 deletions

View File

@ -1,6 +1,12 @@
kll - keyboard layout language kll - keyboard layout language
============================== ==============================
[![https://travis-ci.org/kiibohd/kll](https://travis-ci.org/kiibohd/kll.svg?branch=master)](https://travis-ci.org/kiibohd/kll)
[![Visit our IRC channel](https://kiwiirc.com/buttons/irc.freenode.net/input.club.png)](https://kiwiirc.com/client/irc.freenode.net/#input.club)
## If you're trying to compile keyboard firmware, you want [THIS](https://github.com/kiibohd/controller/)
KLL Compiler KLL Compiler
------------ ------------
@ -31,11 +37,3 @@ Patches/Features/Backends
------------------------- -------------------------
Completely welcome :D Completely welcome :D
Spec Additions/Fixes
--------------------
Contact HaaTa via IRC (#geekhack@irc.freenode.net or #deskthority).
Or by email -> haata@kiibohd.com

View File

@ -1,9 +1,10 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# KLL Compiler - Kiibohd Backend '''
# KLL Compiler - Kiibohd Backend
# Backend code generator for the Kiibohd Controller firmware.
# Backend code generator for the Kiibohd Controller firmware.
# Copyright (C) 2014-2015 by Jacob Alexander '''
# Copyright (C) 2014-2016 by Jacob Alexander
# #
# This file is free software: you can redistribute it and/or modify # This file is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -37,6 +38,11 @@ from kll_lib.hid_dict import *
### Classes ### ### Classes ###
class Backend( BackendBase ): class Backend( BackendBase ):
'''
Kiibohd Code-Generation Backend
Kiibohd specific code generation.
'''
# Default templates and output files # Default templates and output files
templatePaths = ["templates/kiibohdKeymap.h", "templates/kiibohdDefs.h"] templatePaths = ["templates/kiibohdKeymap.h", "templates/kiibohdDefs.h"]
outputPaths = ["generatedKeymap.h", "kll_defs.h"] outputPaths = ["generatedKeymap.h", "kll_defs.h"]
@ -119,11 +125,14 @@ class Backend( BackendBase ):
## Defines ## ## Defines ##
self.fill_dict['Defines'] = "" self.fill_dict['Defines'] = ""
stateWordSize = ""
# Iterate through defines and lookup the variables # Iterate through defines and lookup the variables
for define in variables.defines.keys(): for define in variables.defines.keys():
if define in variables.overallVariables.keys(): if define in variables.overallVariables.keys():
self.fill_dict['Defines'] += "\n#define {0} {1}".format( variables.defines[ define ], variables.overallVariables[ define ].replace( '\n', ' \\\n' ) ) self.fill_dict['Defines'] += "\n#define {0} {1}".format( variables.defines[ define ], variables.overallVariables[ define ].replace( '\n', ' \\\n' ) )
if define == "stateWordSize":
stateWordSize = variables.overallVariables[ define ]
else: else:
print( "{0} '{1}' not defined...".format( WARNING, define ) ) print( "{0} '{1}' not defined...".format( WARNING, define ) )
@ -144,6 +153,9 @@ class Backend( BackendBase ):
self.fill_dict['CapabilitiesList'] += "};" self.fill_dict['CapabilitiesList'] += "};"
self.fill_dict['CapabilitiesIndices'] += "} CapabilityIndex;" self.fill_dict['CapabilitiesIndices'] += "} CapabilityIndex;"
# Define for total number of capabilities
self.fill_dict['Defines'] += "\n#define CapabilitiesNum_KLL {0}".format( len( capabilities.keys() ) )
## Results Macros ## ## Results Macros ##
self.fill_dict['ResultMacros'] = "" self.fill_dict['ResultMacros'] = ""
@ -215,15 +227,21 @@ class Backend( BackendBase ):
self.fill_dict['ResultMacroList'] += "\tDefine_RM( {0} ),\n".format( result ) self.fill_dict['ResultMacroList'] += "\tDefine_RM( {0} ),\n".format( result )
self.fill_dict['ResultMacroList'] += "};" self.fill_dict['ResultMacroList'] += "};"
results_count = len( macros.resultsIndexSorted )
## Result Macro Record ## ## Result Macro Record ##
self.fill_dict['ResultMacroRecord'] = "ResultMacroRecord ResultMacroRecordList[ ResultMacroNum ];" self.fill_dict['ResultMacroRecord'] = "ResultMacroRecord ResultMacroRecordList[ ResultMacroNum ];"
# Define for total number of Result Macros
self.fill_dict['Defines'] += "\n#define ResultMacroNum_KLL {0}".format( len( macros.resultsIndexSorted ) )
## Trigger Macros ## ## Trigger Macros ##
self.fill_dict['TriggerMacros'] = "" self.fill_dict['TriggerMacros'] = ""
# Iterate through each of the trigger macros # Iterate through each of the trigger macros
triggers_count = len( macros.triggersIndexSorted );
for trigger in range( 0, len( macros.triggersIndexSorted ) ): for trigger in range( 0, len( macros.triggersIndexSorted ) ):
self.fill_dict['TriggerMacros'] += "Guide_TM( {0} ) = {{ ".format( trigger ) self.fill_dict['TriggerMacros'] += "Guide_TM( {0} ) = {{ ".format( trigger )
@ -249,6 +267,13 @@ class Backend( BackendBase ):
self.fill_dict['TriggerMacros'] += "0 };\n" self.fill_dict['TriggerMacros'] += "0 };\n"
self.fill_dict['TriggerMacros'] = self.fill_dict['TriggerMacros'][ :-1 ] # Remove last newline self.fill_dict['TriggerMacros'] = self.fill_dict['TriggerMacros'][ :-1 ] # Remove last newline
# check for too small stateWordSize
if stateWordSize == "8" and (triggers_count > 255 or results_count > 255):
print ("{0} Over 255 trigger or result macros, changing stateWordSize from {1} to 16.".format( WARNING, stateWordSize ) )
print( "Results count: ", results_count )
print( "Triggers count: ", triggers_count )
stateWordSize == "16"
self.fill_dict['Defines'] = self.fill_dict['Defines'].replace("StateWordSize_define 8", "StateWordSize_define 16")
## Trigger Macro List ## ## Trigger Macro List ##
self.fill_dict['TriggerMacroList'] = "const TriggerMacro TriggerMacroList[] = {\n" self.fill_dict['TriggerMacroList'] = "const TriggerMacro TriggerMacroList[] = {\n"
@ -263,6 +288,9 @@ class Backend( BackendBase ):
## Trigger Macro Record ## ## Trigger Macro Record ##
self.fill_dict['TriggerMacroRecord'] = "TriggerMacroRecord TriggerMacroRecordList[ TriggerMacroNum ];" self.fill_dict['TriggerMacroRecord'] = "TriggerMacroRecord TriggerMacroRecordList[ TriggerMacroNum ];"
# Define for total number of Trigger Macros
self.fill_dict['Defines'] += "\n#define TriggerMacroNum_KLL {0}".format( len( macros.triggersIndexSorted ) )
## Max Scan Code ## ## Max Scan Code ##
self.fill_dict['MaxScanCode'] = "#define MaxScanCode 0x{0:X}".format( macros.overallMaxScanCode ) self.fill_dict['MaxScanCode'] = "#define MaxScanCode 0x{0:X}".format( macros.overallMaxScanCode )
@ -354,6 +382,9 @@ class Backend( BackendBase ):
self.fill_dict['LayerIndexList'] += '\tLayer_IN( layer{0}_scanMap, "{0}: {2}", 0x{1:02X} ),\n'.format( layer, firstScanCode, stackName ) self.fill_dict['LayerIndexList'] += '\tLayer_IN( layer{0}_scanMap, "{0}: {2}", 0x{1:02X} ),\n'.format( layer, firstScanCode, stackName )
self.fill_dict['LayerIndexList'] += "};" self.fill_dict['LayerIndexList'] += "};"
# Define for total number of Trigger Macros
self.fill_dict['Defines'] += "\n#define LayerNum_KLL {0}".format( len( macros.triggerList ) )
## Layer State ## ## Layer State ##
self.fill_dict['LayerState'] = "uint8_t LayerState[ LayerNum ];" self.fill_dict['LayerState'] = "uint8_t LayerState[ LayerNum ];"

520
kll.py
View File

@ -1,7 +1,9 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# KLL Compiler '''
# Keyboard Layout Langauge KLL Compiler
# Keyboard Layout Langauge
'''
# Copyright (C) 2014-2016 by Jacob Alexander # Copyright (C) 2014-2016 by Jacob Alexander
# #
# This file is free software: you can redistribute it and/or modify # This file is free software: you can redistribute it and/or modify
@ -21,21 +23,16 @@
import argparse import argparse
import importlib import importlib
import io
import os import os
import re
import sys import sys
import token
from pprint import pformat
from re import VERBOSE from re import VERBOSE
from tokenize import generate_tokens
from kll_lib.containers import * from kll_lib.containers import *
from kll_lib.hid_dict import * from kll_lib.hid_dict import *
from funcparserlib.lexer import make_tokenizer, Token, LexerError from funcparserlib.lexer import make_tokenizer, Token, LexerError
from funcparserlib.parser import (some, a, many, oneplus, skip, finished, maybe, skip, forward_decl, NoParseError) from funcparserlib.parser import (some, a, many, oneplus, finished, maybe, skip, NoParseError)
@ -84,7 +81,7 @@ def processCommandLineArgs():
pArgs.add_argument( '-b', '--backend', type=str, default="kiibohd", pArgs.add_argument( '-b', '--backend', type=str, default="kiibohd",
help="Specify target backend for the KLL compiler.\n" help="Specify target backend for the KLL compiler.\n"
"Default: kiibohd\n" "Default: kiibohd\n"
"Options: kiibohd" ) "Options: kiibohd, json" )
pArgs.add_argument( '-d', '--default', type=str, nargs='+', pArgs.add_argument( '-d', '--default', type=str, nargs='+',
help="Specify .kll files to layer on top of the default map to create a combined map." ) help="Specify .kll files to layer on top of the default map to create a combined map." )
pArgs.add_argument( '-p', '--partial', type=str, nargs='+', action='append', pArgs.add_argument( '-p', '--partial', type=str, nargs='+', action='append',
@ -142,30 +139,20 @@ def tokenize( string ):
( 'ConsCodeStart', ( r'CONS\[', ) ), ( 'ConsCodeStart', ( r'CONS\[', ) ),
( 'SysCode', ( r'SYS(("[^"]+")|(0x[0-9a-fA-F]+)|([0-9]+))', ) ), ( 'SysCode', ( r'SYS(("[^"]+")|(0x[0-9a-fA-F]+)|([0-9]+))', ) ),
( 'SysCodeStart', ( r'SYS\[', ) ), ( 'SysCodeStart', ( r'SYS\[', ) ),
( 'LedCode', ( r'LED(("[^"]+")|(0x[0-9a-fA-F]+)|([0-9]+))', ) ),
( 'LedCodeStart', ( r'LED\[', ) ),
( 'ScanCode', ( r'S((0x[0-9a-fA-F]+)|([0-9]+))', ) ), ( 'ScanCode', ( r'S((0x[0-9a-fA-F]+)|([0-9]+))', ) ),
( 'ScanCodeStart', ( r'S\[', ) ), ( 'ScanCodeStart', ( r'S\[', ) ),
( 'Indicator', ( r'I(("[^"]+")|(0x[0-9a-fA-F]+)|([0-9]+))', ) ),
( 'IndicatorStart', ( r'I\[', ) ),
( 'Pixel', ( r'P"[^"]+"', ) ),
( 'PixelStart', ( r'P\[', ) ),
( 'PixelLayer', ( r'PL"[^"]+"', ) ),
( 'PixelLayerStart', ( r'PL\[', ) ),
( 'Animation', ( r'A"[^"]+"', ) ),
( 'AnimationStart', ( r'A\[', ) ),
( 'CodeBegin', ( r'\[', ) ),
( 'CodeEnd', ( r'\]', ) ), ( 'CodeEnd', ( r'\]', ) ),
( 'Position', ( r'r?[xyz]:[0-9]+(.[0-9]+)?', ) ),
( 'String', ( r'"[^"]*"', ) ), ( 'String', ( r'"[^"]*"', ) ),
( 'SequenceString', ( r"'[^']*'", ) ), ( 'SequenceString', ( r"'[^']*'", ) ),
( 'PixelOperator', ( r'(\+:|-:|>>|<<)', ) ), ( 'Operator', ( r'=>|:\+|:-|::|:|=', ) ),
( 'Operator', ( r'=>|<=|:\+|:-|::|:|=', ) ), ( 'Number', ( r'(-[ \t]*)?((0x[0-9a-fA-F]+)|(0|([1-9][0-9]*)))', VERBOSE ) ),
( 'Comma', ( r',', ) ), ( 'Comma', ( r',', ) ),
( 'Dash', ( r'-', ) ), ( 'Dash', ( r'-', ) ),
( 'Plus', ( r'\+', ) ), ( 'Plus', ( r'\+', ) ),
( 'Parenthesis', ( r'\(|\)', ) ), ( 'Parenthesis', ( r'\(|\)', ) ),
( 'None', ( r'None', ) ), ( 'None', ( r'None', ) ),
( 'Timing', ( r'[0-9]+(.[0-9]+)?((s)|(ms)|(us))', ) ),
( 'Number', ( r'-?(0x[0-9a-fA-F]+)|(0|([1-9][0-9]*))', VERBOSE ) ),
( 'Name', ( r'[A-Za-z_][A-Za-z_0-9]*', ) ), ( 'Name', ( r'[A-Za-z_][A-Za-z_0-9]*', ) ),
( 'VariableContents', ( r'''[^"' ;:=>()]+''', ) ), ( 'VariableContents', ( r'''[^"' ;:=>()]+''', ) ),
( 'EndOfLine', ( r';', ) ), ( 'EndOfLine', ( r';', ) ),
@ -189,8 +176,7 @@ capabilities_dict = Capabilities()
## Parsing Functions ## Parsing Functions
class Make: def make_scanCode( token ):
def scanCode( token ):
scanCode = int( token[1:], 0 ) scanCode = int( token[1:], 0 )
# Check size, to make sure it's valid # Check size, to make sure it's valid
# XXX Add better check that takes symbolic names into account (i.e. U"Latch5") # XXX Add better check that takes symbolic names into account (i.e. U"Latch5")
@ -199,9 +185,9 @@ class Make:
# raise # raise
return scanCode return scanCode
def hidCode( type, token ): def make_hidCode( type, token ):
# If first character is a U or I, strip # If first character is a U, strip
if token[0] == "U" or token[0] == "I": if token[0] == "U":
token = token[1:] token = token[1:]
# CONS specifier # CONS specifier
elif 'CONS' in token: elif 'CONS' in token:
@ -233,111 +219,46 @@ class Make:
# Return a tuple, identifying which type it is # Return a tuple, identifying which type it is
if type == 'USBCode': if type == 'USBCode':
return Make.usbCode_number( hidCode ) return make_usbCode_number( hidCode )
elif type == 'ConsCode': elif type == 'ConsCode':
return Make.consCode_number( hidCode ) return make_consCode_number( hidCode )
elif type == 'SysCode': elif type == 'SysCode':
return Make.sysCode_number( hidCode ) return make_sysCode_number( hidCode )
elif type == 'IndCode':
return Make.indCode_number( hidCode )
print ( "{0} Unknown HID Specifier '{1}'".format( ERROR, type ) ) print ( "{0} Unknown HID Specifier '{1}'".format( ERROR, type ) )
raise raise
def usbCode( token ): def make_usbCode( token ):
return Make.hidCode( 'USBCode', token ) return make_hidCode( 'USBCode', token )
def consCode( token ): def make_consCode( token ):
return Make.hidCode( 'ConsCode', token ) return make_hidCode( 'ConsCode', token )
def sysCode( token ): def make_sysCode( token ):
return Make.hidCode( 'SysCode', token ) return make_hidCode( 'SysCode', token )
def indCode( token ): def make_hidCode_number( type, token ):
return Make.hidCode( 'IndCode', token )
def animation( token ):
# TODO
print( token )
return "NULL"
def animationCapability( token ):
# TODO
print( token )
return "DIS"
def pixelCapability( token ):
# TODO
print( token )
return "DAT"
def pixel( token ):
# TODO
print( token )
return "PNULL"
def pixelLayer( token ):
# TODO
print( token )
return "PLNULL"
def pixelchans( token ):
# Create dictionary list
channel_widths = []
for elem in token:
channel_widths.append( {
'chan' : elem[0],
'width' : elem[1],
} )
print(channel_widths)
return channel_widths
def pixelchan_elem( token ):
channel_config = {
'pixels' : token[0],
'chans' : token[1],
}
return channel_config
def pixelmods( token ):
# TODO
print( token )
return "PMOD"
def pixellayer( token ):
# TODO
print( token )
return "PL"
def position( token ):
return token.split(':')
def hidCode_number( type, token ):
lookup = { lookup = {
'ConsCode' : 'CONS', 'ConsCode' : 'CONS',
'SysCode' : 'SYS', 'SysCode' : 'SYS',
'USBCode' : 'USB', 'USBCode' : 'USB',
'IndCode' : 'LED',
} }
return ( lookup[ type ], token ) return ( lookup[ type ], token )
def usbCode_number( token ): def make_usbCode_number( token ):
return Make.hidCode_number( 'USBCode', token ) return make_hidCode_number( 'USBCode', token )
def consCode_number( token ): def make_consCode_number( token ):
return Make.hidCode_number( 'ConsCode', token ) return make_hidCode_number( 'ConsCode', token )
def sysCode_number( token ): def make_sysCode_number( token ):
return Make.hidCode_number( 'SysCode', token ) return make_hidCode_number( 'SysCode', token )
def indCode_number( token ):
return Make.hidCode_number( 'IndCode', token )
# Replace key-word with None specifier (which indicates a noneOut capability) # Replace key-word with None specifier (which indicates a noneOut capability)
def none( token ): def make_none( token ):
return [[[('NONE', 0)]]] return [[[('NONE', 0)]]]
def seqString( token ): def make_seqString( token ):
# Shifted Characters, and amount to move by to get non-shifted version # Shifted Characters, and amount to move by to get non-shifted version
# US ANSI # US ANSI
shiftCharacters = ( shiftCharacters = (
@ -389,55 +310,17 @@ class Make:
return listOfLists return listOfLists
def string( token ): def make_string( token ):
return token[1:-1] return token[1:-1]
def unseqString( token ): def make_unseqString( token ):
return token[1:-1] return token[1:-1]
def number( token ): def make_number( token ):
return int( token, 0 ) return int( token, 0 )
def timing( token ): # Range can go from high to low or low to high
# Find ms, us, or s def make_scanCode_range( rangeVals ):
if 'ms' in token:
unit = 'ms'
num = token.split('m')[0]
print (token.split('m'))
elif 'us' in token:
unit = 'us'
num = token.split('u')[0]
elif 's' in token:
unit = 's'
num = token.split('s')[0]
else:
print ( "{0} cannot find timing unit in token '{1}'".format( ERROR, token ) )
return "NULL"
print ( num, unit )
ret = {
'time' : float( num ),
'unit' : unit,
}
return ret
def specifierState( values ):
# TODO
print ( values )
return "SPECSTATE"
def specifierAnalog( value ):
# TODO
print( value )
return "SPECANALOG"
def specifierUnroll( value ):
# TODO
print( value )
return [ value[0] ]
# Range can go from high to low or low to high
def scanCode_range( rangeVals ):
start = rangeVals[0] start = rangeVals[0]
end = rangeVals[1] end = rangeVals[1]
@ -448,20 +331,20 @@ class Make:
# Iterate from start to end, and generate the range # Iterate from start to end, and generate the range
return list( range( start, end + 1 ) ) return list( range( start, end + 1 ) )
# Range can go from high to low or low to high # Range can go from high to low or low to high
# Warn on 0-9 for USBCodes (as this does not do what one would expect) TODO # Warn on 0-9 for USBCodes (as this does not do what one would expect) TODO
# Lookup USB HID tags and convert to a number # Lookup USB HID tags and convert to a number
def hidCode_range( type, rangeVals ): def make_hidCode_range( type, rangeVals ):
# Check if already integers # Check if already integers
if isinstance( rangeVals[0], int ): if isinstance( rangeVals[0], int ):
start = rangeVals[0] start = rangeVals[0]
else: else:
start = Make.hidCode( type, rangeVals[0] )[1] start = make_hidCode( type, rangeVals[0] )[1]
if isinstance( rangeVals[1], int ): if isinstance( rangeVals[1], int ):
end = rangeVals[1] end = rangeVals[1]
else: else:
end = Make.hidCode( type, rangeVals[1] )[1] end = make_hidCode( type, rangeVals[1] )[1]
# Swap start, end if start is greater than end # Swap start, end if start is greater than end
if start > end: if start > end:
@ -472,25 +355,17 @@ class Make:
# Convert each item in the list to a tuple # Convert each item in the list to a tuple
for item in range( len( listRange ) ): for item in range( len( listRange ) ):
listRange[ item ] = Make.hidCode_number( type, listRange[ item ] ) listRange[ item ] = make_hidCode_number( type, listRange[ item ] )
return listRange return listRange
def usbCode_range( rangeVals ): def make_usbCode_range( rangeVals ):
return Make.hidCode_range( 'USBCode', rangeVals ) return make_hidCode_range( 'USBCode', rangeVals )
def sysCode_range( rangeVals ): def make_sysCode_range( rangeVals ):
return Make.hidCode_range( 'SysCode', rangeVals ) return make_hidCode_range( 'SysCode', rangeVals )
def consCode_range( rangeVals ): def make_consCode_range( rangeVals ):
return Make.hidCode_range( 'ConsCode', rangeVals ) return make_hidCode_range( 'ConsCode', rangeVals )
def indCode_range( rangeVals ):
return Make.hidCode_range( 'IndCode', rangeVals )
def range( rangeVals ):
# TODO
print (rangeVals)
return ""
## Base Rules ## Base Rules
@ -503,7 +378,6 @@ tokenValue = lambda x: x.value
tokenType = lambda t: some( lambda x: x.type == t ) >> tokenValue tokenType = lambda t: some( lambda x: x.type == t ) >> tokenValue
operator = lambda s: a( Token( 'Operator', s ) ) >> tokenValue operator = lambda s: a( Token( 'Operator', s ) ) >> tokenValue
parenthesis = lambda s: a( Token( 'Parenthesis', s ) ) >> tokenValue parenthesis = lambda s: a( Token( 'Parenthesis', s ) ) >> tokenValue
bracket = lambda s: a( Token( 'Bracket', s ) ) >> tokenValue
eol = a( Token( 'EndOfLine', ';' ) ) eol = a( Token( 'EndOfLine', ';' ) )
def listElem( item ): def listElem( item ):
@ -521,14 +395,27 @@ def oneLayerFlatten( items ):
return mainList return mainList
# Capability arguments may need to be expanded (e.g. 1 16 bit argument needs to be 2 8 bit arguments for the state machine)
def capArgExpander( items ): def capArgExpander( items ):
'''
Capability arguments may need to be expanded
(e.g. 1 16 bit argument needs to be 2 8 bit arguments for the state machine)
If the number is negative, determine width of the final value, mask to max, subtract,
then convert to multiple bytes
'''
newArgs = [] newArgs = []
# For each defined argument in the capability definition # For each defined argument in the capability definition
for arg in range( 0, len( capabilities_dict[ items[0] ][1] ) ): for arg in range( 0, len( capabilities_dict[ items[0] ][1] ) ):
argLen = capabilities_dict[ items[0] ][1][ arg ][1] argLen = capabilities_dict[ items[0] ][1][ arg ][1]
num = items[1][ arg ] num = items[1][ arg ]
byteForm = num.to_bytes( argLen, byteorder='little' ) # XXX Yes, little endian from how the uC structs work
# Set last bit if value is negative
if num < 0:
max_val = 2 ** (argLen * 8)
num += max_val
# XXX Yes, little endian from how the uC structs work
byteForm = num.to_bytes( argLen, byteorder='little' )
# For each sub-argument, split into byte-sized chunks # For each sub-argument, split into byte-sized chunks
for byte in range( 0, argLen ): for byte in range( 0, argLen ):
@ -614,9 +501,7 @@ def tupleit( t ):
## Evaluation Rules ## Evaluation Rules
class Eval: def eval_scanCode( triggers, operator, results ):
def scanCode( triggers, operator, results ):
print ( triggers, operator, results )
# Convert to lists of lists of lists to tuples of tuples of tuples # Convert to lists of lists of lists to tuples of tuples of tuples
# Tuples are non-mutable, and can be used has index items # Tuples are non-mutable, and can be used has index items
triggers = tuple( tuple( tuple( sequence ) for sequence in variant ) for variant in triggers ) triggers = tuple( tuple( tuple( sequence ) for sequence in variant ) for variant in triggers )
@ -656,9 +541,7 @@ class Eval:
elif operator == ":" or operator == "::": elif operator == ":" or operator == "::":
macros_map.replaceScanCode( trigger, result ) macros_map.replaceScanCode( trigger, result )
def usbCode( triggers, operator, results ): def eval_usbCode( triggers, operator, results ):
# TODO
return
# Convert to lists of lists of lists to tuples of tuples of tuples # Convert to lists of lists of lists to tuples of tuples of tuples
# Tuples are non-mutable, and can be used has index items # Tuples are non-mutable, and can be used has index items
triggers = tuple( tuple( tuple( sequence ) for sequence in variant ) for variant in triggers ) triggers = tuple( tuple( tuple( sequence ) for sequence in variant ) for variant in triggers )
@ -676,7 +559,7 @@ class Eval:
# Cache assignment until file finishes processing # Cache assignment until file finishes processing
macros_map.cacheAssignment( operator, scanCode, result ) macros_map.cacheAssignment( operator, scanCode, result )
def variable( name, content ): def eval_variable( name, content ):
# Content might be a concatenation of multiple data types, convert everything into a single string # Content might be a concatenation of multiple data types, convert everything into a single string
assigned_content = "" assigned_content = ""
for item in content: for item in content:
@ -684,209 +567,90 @@ class Eval:
variables_dict.assignVariable( name, assigned_content ) variables_dict.assignVariable( name, assigned_content )
def capability( name, function, args ): def eval_capability( name, function, args ):
capabilities_dict[ name ] = [ function, args ] capabilities_dict[ name ] = [ function, args ]
def define( name, cdefine_name ): def eval_define( name, cdefine_name ):
variables_dict.defines[ name ] = cdefine_name variables_dict.defines[ name ] = cdefine_name
def scanCodePosition( scanCode, positions ): map_scanCode = unarg( eval_scanCode )
print (scanCode) map_usbCode = unarg( eval_usbCode )
# Re-organize position lists into a dictionary first
pos_dict = dict()
for pos in positions:
pos_dict[ pos[0] ] = pos[1]
print (pos_dict)
# TODO Create datastructure for positions set_variable = unarg( eval_variable )
set_capability = unarg( eval_capability )
def pixelPosition( pixel, position ): set_define = unarg( eval_define )
# TODO
print (pixel, position)
def pixelChannels( channel, scanCode ):
# TODO
print (channel, scanCode )
def animation( animation, modifiers ):
# TODO
print( animation, modifiers )
def animationFrame( animation, frame, modifiers ):
# TODO
print( frame, modifiers )
def animationTrigger( animation, operator, results ):
# TODO
print ( animation, operator, results )
def animationTriggerFrame( animation, frame, operator, results ):
# TODO
print ( animation, frame, operator, results )
def array( name, index, content ):
# TODO
print (name, index, content)
class Map:
scanCode = unarg( Eval.scanCode )
usbCode = unarg( Eval.usbCode )
animationTrigger = unarg( Eval.animationTrigger )
animationTriggerFrame = unarg( Eval.animationTriggerFrame )
class Set:
animation = unarg( Eval.animation )
animationFrame = unarg( Eval.animationFrame )
array = unarg( Eval.array )
capability = unarg( Eval.capability )
define = unarg( Eval.define )
pixelChannels = unarg( Eval.pixelChannels )
pixelPosition = unarg( Eval.pixelPosition )
scanCodePosition = unarg( Eval.scanCodePosition )
variable = unarg( Eval.variable )
## Sub Rules ## Sub Rules
usbCode = tokenType('USBCode') >> Make.usbCode usbCode = tokenType('USBCode') >> make_usbCode
scanCode = tokenType('ScanCode') >> Make.scanCode scanCode = tokenType('ScanCode') >> make_scanCode
consCode = tokenType('ConsCode') >> Make.consCode consCode = tokenType('ConsCode') >> make_consCode
sysCode = tokenType('SysCode') >> Make.sysCode sysCode = tokenType('SysCode') >> make_sysCode
indCode = tokenType('Indicator') >> Make.indCode none = tokenType('None') >> make_none
animation = tokenType('Animation') >> Make.animation
pixel = tokenType('Pixel') >> Make.pixel
pixelLayer = tokenType('PixelLayer') >> Make.pixelLayer
none = tokenType('None') >> Make.none
position = tokenType('Position') >> Make.position
name = tokenType('Name') name = tokenType('Name')
number = tokenType('Number') >> Make.number number = tokenType('Number') >> make_number
timing = tokenType('Timing') >> Make.timing
comma = tokenType('Comma') comma = tokenType('Comma')
dash = tokenType('Dash') dash = tokenType('Dash')
plus = tokenType('Plus') plus = tokenType('Plus')
content = tokenType('VariableContents') content = tokenType('VariableContents')
string = tokenType('String') >> Make.string string = tokenType('String') >> make_string
unString = tokenType('String') # When the double quotes are still needed for internal processing unString = tokenType('String') # When the double quotes are still needed for internal processing
seqString = tokenType('SequenceString') >> Make.seqString seqString = tokenType('SequenceString') >> make_seqString
unseqString = tokenType('SequenceString') >> Make.unseqString # For use with variables unseqString = tokenType('SequenceString') >> make_unseqString # For use with variables
pixelOperator = tokenType('PixelOperator')
# Code variants # Code variants
code_begin = tokenType('CodeBegin')
code_end = tokenType('CodeEnd') code_end = tokenType('CodeEnd')
# Specifier
specifier_state = ( name + skip( operator(':') ) + timing ) | ( name + skip( operator(':') ) + timing ) | timing | name >> Make.specifierState
specifier_analog = number >> Make.specifierAnalog
specifier_list = skip( parenthesis('(') ) + many( ( specifier_state | specifier_analog ) + skip( maybe( comma ) ) ) + skip( parenthesis(')') )
# Scan Codes # Scan Codes
scanCode_start = tokenType('ScanCodeStart') scanCode_start = tokenType('ScanCodeStart')
scanCode_range = number + skip( dash ) + number >> Make.scanCode_range scanCode_range = number + skip( dash ) + number >> make_scanCode_range
scanCode_listElem = number >> listElem scanCode_listElem = number >> listElem
scanCode_specifier = ( scanCode_range | scanCode_listElem ) + maybe( specifier_list ) >> Make.specifierUnroll >> flatten scanCode_innerList = oneplus( ( scanCode_range | scanCode_listElem ) + skip( maybe( comma ) ) ) >> flatten
scanCode_innerList = many( scanCode_specifier + skip( maybe( comma ) ) ) >> flatten
scanCode_expanded = skip( scanCode_start ) + scanCode_innerList + skip( code_end ) scanCode_expanded = skip( scanCode_start ) + scanCode_innerList + skip( code_end )
scanCode_elem = scanCode + maybe( specifier_list ) >> Make.specifierUnroll >> listElem scanCode_elem = scanCode >> listElem
scanCode_combo = oneplus( ( scanCode_expanded | scanCode_elem ) + skip( maybe( plus ) ) ) scanCode_combo = oneplus( ( scanCode_expanded | scanCode_elem ) + skip( maybe( plus ) ) )
scanCode_sequence = oneplus( scanCode_combo + skip( maybe( comma ) ) ) scanCode_sequence = oneplus( scanCode_combo + skip( maybe( comma ) ) )
# USB Codes
usbCode_start = tokenType('USBCodeStart')
usbCode_number = number >> make_usbCode_number
usbCode_range = ( usbCode_number | unString ) + skip( dash ) + ( number | unString ) >> make_usbCode_range
usbCode_listElemTag = unString >> make_usbCode
usbCode_listElem = ( usbCode_number | usbCode_listElemTag ) >> listElem
usbCode_innerList = oneplus( ( usbCode_range | usbCode_listElem ) + skip( maybe( comma ) ) ) >> flatten
usbCode_expanded = skip( usbCode_start ) + usbCode_innerList + skip( code_end )
usbCode_elem = usbCode >> listElem
usbCode_combo = oneplus( ( usbCode_expanded | usbCode_elem ) + skip( maybe( plus ) ) ) >> listElem
usbCode_sequence = oneplus( ( usbCode_combo | seqString ) + skip( maybe( comma ) ) ) >> oneLayerFlatten
# Cons Codes # Cons Codes
consCode_start = tokenType('ConsCodeStart') consCode_start = tokenType('ConsCodeStart')
consCode_number = number >> Make.consCode_number consCode_number = number >> make_consCode_number
consCode_range = ( consCode_number | unString ) + skip( dash ) + ( number | unString ) >> Make.consCode_range consCode_range = ( consCode_number | unString ) + skip( dash ) + ( number | unString ) >> make_consCode_range
consCode_listElemTag = unString >> Make.consCode consCode_listElemTag = unString >> make_consCode
consCode_listElem = ( consCode_number | consCode_listElemTag ) >> listElem consCode_listElem = ( consCode_number | consCode_listElemTag ) >> listElem
consCode_specifier = ( consCode_range | consCode_listElem ) + maybe( specifier_list ) >> Make.specifierUnroll >> flatten consCode_innerList = oneplus( ( consCode_range | consCode_listElem ) + skip( maybe( comma ) ) ) >> flatten
consCode_innerList = oneplus( consCode_specifier + skip( maybe( comma ) ) ) >> flatten
consCode_expanded = skip( consCode_start ) + consCode_innerList + skip( code_end ) consCode_expanded = skip( consCode_start ) + consCode_innerList + skip( code_end )
consCode_elem = consCode + maybe( specifier_list ) >> Make.specifierUnroll >> listElem consCode_elem = consCode >> listElem
# Sys Codes # Sys Codes
sysCode_start = tokenType('SysCodeStart') sysCode_start = tokenType('SysCodeStart')
sysCode_number = number >> Make.sysCode_number sysCode_number = number >> make_sysCode_number
sysCode_range = ( sysCode_number | unString ) + skip( dash ) + ( number | unString ) >> Make.sysCode_range sysCode_range = ( sysCode_number | unString ) + skip( dash ) + ( number | unString ) >> make_sysCode_range
sysCode_listElemTag = unString >> Make.sysCode sysCode_listElemTag = unString >> make_sysCode
sysCode_listElem = ( sysCode_number | sysCode_listElemTag ) >> listElem sysCode_listElem = ( sysCode_number | sysCode_listElemTag ) >> listElem
sysCode_specifier = ( sysCode_range | sysCode_listElem ) + maybe( specifier_list ) >> Make.specifierUnroll >> flatten sysCode_innerList = oneplus( ( sysCode_range | sysCode_listElem ) + skip( maybe( comma ) ) ) >> flatten
sysCode_innerList = oneplus( sysCode_specifier + skip( maybe( comma ) ) ) >> flatten
sysCode_expanded = skip( sysCode_start ) + sysCode_innerList + skip( code_end ) sysCode_expanded = skip( sysCode_start ) + sysCode_innerList + skip( code_end )
sysCode_elem = sysCode + maybe( specifier_list ) >> Make.specifierUnroll >> listElem sysCode_elem = sysCode >> listElem
# Indicator Codes
indCode_start = tokenType('IndicatorStart')
indCode_number = number >> Make.indCode_number
indCode_range = ( indCode_number | unString ) + skip( dash ) + ( number | unString ) >> Make.indCode_range
indCode_listElemTag = unString >> Make.indCode
indCode_listElem = ( indCode_number | indCode_listElemTag ) >> listElem
indCode_specifier = ( indCode_range | indCode_listElem ) + maybe( specifier_list ) >> Make.specifierUnroll >> flatten
indCode_innerList = oneplus( indCode_specifier + skip( maybe( comma ) ) ) >> flatten
indCode_expanded = skip( indCode_start ) + indCode_innerList + skip( code_end )
indCode_elem = indCode + maybe( specifier_list ) >> Make.specifierUnroll >> listElem
# USB Codes
usbCode_start = tokenType('USBCodeStart')
usbCode_number = number >> Make.usbCode_number
usbCode_range = ( usbCode_number | unString ) + skip( dash ) + ( number | unString ) >> Make.usbCode_range
usbCode_listElemTag = unString >> Make.usbCode
usbCode_listElem = ( usbCode_number | usbCode_listElemTag ) >> listElem
usbCode_specifier = ( usbCode_range | usbCode_listElem ) + maybe( specifier_list ) >> Make.specifierUnroll >> flatten
usbCode_innerList = oneplus( usbCode_specifier + skip( maybe( comma ) ) ) >> flatten
usbCode_expanded = skip( usbCode_start ) + usbCode_innerList + skip( code_end )
usbCode_elem = usbCode + maybe( specifier_list ) >> Make.specifierUnroll >> listElem
# HID Codes # HID Codes
hidCode_elem = usbCode_expanded | usbCode_elem | sysCode_expanded | sysCode_elem | consCode_expanded | consCode_elem | indCode_expanded | indCode_elem hidCode_elem = usbCode_expanded | usbCode_elem | sysCode_expanded | sysCode_elem | consCode_expanded | consCode_elem
usbCode_combo = oneplus( hidCode_elem + skip( maybe( plus ) ) ) >> listElem
usbCode_sequence = oneplus( ( usbCode_combo | seqString ) + skip( maybe( comma ) ) ) >> oneLayerFlatten
# Pixels
pixel_start = tokenType('PixelStart')
pixel_number = number
pixel_range = ( pixel_number ) + skip( dash ) + ( number ) >> Make.range
pixel_listElem = pixel_number >> listElem
pixel_innerList = many( ( pixel_range | pixel_listElem ) + skip( maybe( comma ) ) )
pixel_expanded = skip( pixel_start ) + pixel_innerList + skip( code_end )
pixel_elem = pixel >> listElem
# Pixel Layer
pixellayer_start = tokenType('PixelLayerStart')
pixellayer_number = number
pixellayer_expanded = skip( pixellayer_start ) + pixellayer_number + skip( code_end )
pixellayer_elem = pixelLayer >> listElem
# Pixel Channels
pixelchan_chans = many( number + skip( operator(':') ) + number + skip( maybe( comma ) ) ) >> Make.pixelchans
pixelchan_elem = ( pixel_expanded | pixel_elem ) + skip( parenthesis('(') ) + pixelchan_chans + skip( parenthesis(')') ) >> Make.pixelchan_elem
# Pixel Mods
pixelmod_mods = many( maybe( pixelOperator | plus | dash ) + number + skip( maybe( comma ) ) ) >> Make.pixelmods
pixelmod_layer = ( pixellayer_expanded | pixellayer_elem ) >> Make.pixellayer
pixelmod_elem = ( pixel_expanded | pixel_elem | pixelmod_layer ) + skip( parenthesis('(') ) + pixelmod_mods + skip( parenthesis(')') )
# Pixel Capability
pixel_capability = pixelmod_elem >> Make.pixelCapability
# Animations
animation_start = tokenType('AnimationStart')
animation_name = name
animation_frame_range = ( number ) + skip( dash ) + ( number ) >> Make.range
animation_name_frame = many( ( number | animation_frame_range ) + skip( maybe( comma ) ) )
animation_def = skip( animation_start ) + animation_name + skip( code_end )
animation_expanded = skip( animation_start ) + animation_name + skip( comma ) + animation_name_frame + skip( code_end )
animation_elem = animation >> listElem
# Animation Modifier
animation_modifier = many( ( name | number ) + maybe( skip( operator(':') ) + number ) + skip( maybe( comma ) ) )
# Animation Capability
animation_capability = ( animation_def | animation_elem ) + maybe( skip( parenthesis('(') + animation_modifier + skip( parenthesis(')') ) ) ) >> Make.animationCapability
# Capabilities # Capabilities
capFunc_arguments = many( number + skip( maybe( comma ) ) ) >> listToTuple capFunc_arguments = many( number + skip( maybe( comma ) ) ) >> listToTuple
capFunc_elem = name + skip( parenthesis('(') ) + capFunc_arguments + skip( parenthesis(')') ) >> capArgExpander >> listElem capFunc_elem = name + skip( parenthesis('(') ) + capFunc_arguments + skip( parenthesis(')') ) >> capArgExpander >> listElem
capFunc_combo = oneplus( ( hidCode_elem | capFunc_elem | animation_capability | pixel_capability ) + skip( maybe( plus ) ) ) >> listElem capFunc_combo = oneplus( ( hidCode_elem | capFunc_elem ) + skip( maybe( plus ) ) ) >> listElem
capFunc_sequence = oneplus( ( capFunc_combo | seqString ) + skip( maybe( comma ) ) ) >> oneLayerFlatten capFunc_sequence = oneplus( ( capFunc_combo | seqString ) + skip( maybe( comma ) ) ) >> oneLayerFlatten
# Trigger / Result Codes # Trigger / Result Codes
@ -894,76 +658,30 @@ triggerCode_outerList = scanCode_sequence >> optionExpansion
triggerUSBCode_outerList = usbCode_sequence >> optionExpansion >> hidCodeToCapability triggerUSBCode_outerList = usbCode_sequence >> optionExpansion >> hidCodeToCapability
resultCode_outerList = ( ( capFunc_sequence >> optionExpansion ) | none ) >> hidCodeToCapability resultCode_outerList = ( ( capFunc_sequence >> optionExpansion ) | none ) >> hidCodeToCapability
# Positions
position_list = oneplus( position + skip( maybe( comma ) ) )
## Main Rules ## Main Rules
#| Assignment
#| <variable> = <variable contents>; #| <variable> = <variable contents>;
variable_contents = name | content | string | number | comma | dash | unseqString variable_contents = name | content | string | number | comma | dash | unseqString
variable_expression = name + skip( operator('=') ) + oneplus( variable_contents ) + skip( eol ) >> Set.variable variable_expression = name + skip( operator('=') ) + oneplus( variable_contents ) + skip( eol ) >> set_variable
#| Array Assignment
#| <variable>[] = <space> <separated> <list>;
#| <variable>[<index>] = <index element>;
array_expression = name + skip( code_begin ) + maybe( number ) + skip( code_end ) + skip( operator('=') ) + oneplus( variable_contents ) + skip( eol ) >> Set.array
#| Name Association
#| <capability name> => <c function>; #| <capability name> => <c function>;
capability_arguments = name + skip( operator(':') ) + number + skip( maybe( comma ) ) capability_arguments = name + skip( operator(':') ) + number + skip( maybe( comma ) )
capability_expression = name + skip( operator('=>') ) + name + skip( parenthesis('(') ) + many( capability_arguments ) + skip( parenthesis(')') ) + skip( eol ) >> Set.capability capability_expression = name + skip( operator('=>') ) + name + skip( parenthesis('(') ) + many( capability_arguments ) + skip( parenthesis(')') ) + skip( eol ) >> set_capability
#| Name Association
#| <define name> => <c define>; #| <define name> => <c define>;
define_expression = name + skip( operator('=>') ) + name + skip( eol ) >> Set.define define_expression = name + skip( operator('=>') ) + name + skip( eol ) >> set_define
#| Data Association
#| <animation> <= <modifiers>;
#| <animation frame> <= <modifiers>;
animation_expression = ( animation_elem | animation_def ) + skip( operator('<=') ) + animation_modifier + skip( eol ) >> Set.animation
animationFrame_expression = animation_expanded + skip( operator('<=') ) + many( pixelmod_elem + skip( maybe( comma ) ) ) + skip( eol ) >> Set.animationFrame
#| Data Association
#| <pixel> <= <position>;
pixelPosition_expression = ( pixel_expanded | pixel_elem ) + skip( operator('<=') ) + position_list + skip( eol ) >> Set.pixelPosition
#| Data Association
#| <pixel chan> <= <scanCode>;
pixelChan_expression = pixelchan_elem + skip( operator(':') ) + ( scanCode_expanded | scanCode_elem | none ) + skip( eol ) >> Set.pixelChannels
#| Data Association
#| <scancode> <= <position>;
scanCodePosition_expression = triggerCode_outerList + skip( operator('<=') ) + position_list + skip( eol ) >> Set.scanCodePosition
#| Mapping
#| <trigger> : <result>; #| <trigger> : <result>;
operatorTriggerResult = operator(':') | operator(':+') | operator(':-') | operator('::') operatorTriggerResult = operator(':') | operator(':+') | operator(':-') | operator('::')
scanCode_expression = triggerCode_outerList + operatorTriggerResult + resultCode_outerList + skip( eol ) >> Map.scanCode scanCode_expression = triggerCode_outerList + operatorTriggerResult + resultCode_outerList + skip( eol ) >> map_scanCode
usbCode_expression = triggerUSBCode_outerList + operatorTriggerResult + resultCode_outerList + skip( eol ) >> Map.usbCode usbCode_expression = triggerUSBCode_outerList + operatorTriggerResult + resultCode_outerList + skip( eol ) >> map_usbCode
animation_trigger = ( animation_elem | animation_def ) + operatorTriggerResult + resultCode_outerList + skip( eol ) >> Map.animationTrigger
animation_triggerFrame = animation_expanded + operatorTriggerResult + resultCode_outerList + skip( eol ) >> Map.animationTriggerFrame
def parse( tokenSequence ): def parse( tokenSequence ):
"""Sequence(Token) -> object""" """Sequence(Token) -> object"""
# Top-level Parser # Top-level Parser
expression = ( expression = scanCode_expression | usbCode_expression | variable_expression | capability_expression | define_expression
scanCode_expression |
scanCodePosition_expression |
usbCode_expression |
animation_trigger |
animation_triggerFrame |
pixelPosition_expression |
pixelChan_expression |
animation_expression |
animationFrame_expression |
array_expression |
variable_expression |
capability_expression |
define_expression
)
kll_text = many( expression ) kll_text = many( expression )
kll_file = maybe( kll_text ) + skip( finished ) kll_file = maybe( kll_text ) + skip( finished )
@ -973,7 +691,7 @@ def parse( tokenSequence ):
def processKLLFile( filename ): def processKLLFile( filename ):
with open( filename ) as file: with open( filename, encoding='utf-8' ) as file:
data = file.read() data = file.read()
try: try:
tokenSequence = tokenize( data ) tokenSequence = tokenize( data )

40
layouts/mouseTest.kll Normal file
View File

@ -0,0 +1,40 @@
Name = mouseTest;
Version = 0.2;
Author = "HaaTa (Jacob Alexander) 2016";
KLL = 0.3d;
# Modified Date
Date = 2016-03-21;
# mouseOut
# Arg1, button, 1-16
# Arg2, mouse x relative axis -32 767 to 32 767
# Arg3, mouse y relative axis -32 767 to 32 767
U"1" : mouseOut( 1, 0, 0 );
U"2" : mouseOut( 2, 0, 0 );
U"3" : mouseOut( 3, 0, 0 );
U"4" : mouseOut( 4, 0, 0 );
U"5" : mouseOut( 5, 0, 0 );
U"6" : mouseOut( 6, 0, 0 );
U"7" : mouseOut( 7, 0, 0 );
U"8" : mouseOut( 8, 0, 0 );
U"Z" : mouseOut( 9, 0, 0 );
U"X" : mouseOut( 10, 0, 0 );
U"C" : mouseOut( 11, 0, 0 );
U"V" : mouseOut( 12, 0, 0 );
U"B" : mouseOut( 13, 0, 0 );
U"N" : mouseOut( 14, 0, 0 );
U"M" : mouseOut( 15, 0, 0 );
U"Comma" : mouseOut( 16, 0, 0 );
U"Up" : mouseOut( 0, 0, 1 );
U"Down" : mouseOut( 0, 0, -1 );
U"Left" : mouseOut( 0, -1, 0 );
U"Right" : mouseOut( 0, 1, 0 );
U"W" : mouseOut( 0, 0, 5 );
U"S" : mouseOut( 0, 0, -5 );
U"A" : mouseOut( 0, -5, 0 );
U"D" : mouseOut( 0, 5, 0 );

View File

@ -0,0 +1,93 @@
Name = programmers dvorak default layer;
Version = 0.1;
Author = "HaaTa (Jacob Alexander) 2016";
KLL = 0.3d;
# Modified Date
Date = 2016-08-06;
# This the default layer for programmers dvorak
# http://www.kaufmann.no/roland/dvorak/
#
# CAVEATS;
# 1) Assumes US ANSI locale set on the host OS
# 2) No AltGr layer (future enhancement, will require a different locale)
# 3) Some shortcuts may not behave correctly
# Shift Keys are masked in some situations
#
# USAGE:
# This layer must be set on the defaultMap
# programmers_dvorak_shift must be set as Layer1 (first PartialMap)
# Attempt to force the host OS to use US ANSI
# (Not guaranteed)
keyboardLocale = 33;
### Mapping ###
# Top Row
U"BackTick" : '$';
U"1" : '&';
U"2" : '[';
U"3" : '{';
U"4" : '}';
U"5" : '(';
U"6" : '=';
U"7" : '*';
U"8" : ')';
U"9" : '+';
U"0" : ']';
U"-" : '!';
U"=" : '#';
# Top-Middle Row
U"Q" : ';';
U"W" : ',';
U"E" : '.';
U"R" : 'p';
U"T" : 'y';
U"Y" : 'f';
U"U" : 'g';
U"I" : 'c';
U"O" : 'r';
U"P" : 'l';
U"[" : '/';
U"]" : '@';
### / is in the same place
# Middle Row
### A is in the same place
U"S" : 'o';
U"D" : 'e';
U"F" : 'u';
U"G" : 'i';
U"H" : 'd';
U"J" : 'h';
U"K" : 't';
U"L" : 'n';
U"Semicolon" : 's';
U"Quote" : '-';
# Bottom-Middle Row
U"LShift" :+ U"Function1"; # Do not replace LShift, just trigger Function1 in addition to LShift
### XXX Not sure what the square key is (-HaaTa)
U"Z" : U"Quote"; # ' is hard to do using the single quote syntax
U"X" : 'q';
U"C" : 'j';
U"V" : 'k';
U"B" : 'x';
### M is in the same place
U"N" : 'b';
U"Comma" : 'w';
#U"Period" : 'v';
U"Slash" : 'z';
U"RShift" :+ U"Function1"; # Do not replace RShift, just trigger Function1 in addition to RShift
# Bottom Row
# N/A

View File

@ -0,0 +1,48 @@
Name = programmers dvorak shift layer;
Version = 0.1;
Author = "HaaTa (Jacob Alexander) 2016";
KLL = 0.3d;
#
# NOTE: See programmers_dvorak_default.kll for more details on how to use this layout
# It relies on the semantics of the US ANSI layout
#
# This file relies heavily on the blockKey capability for LShift (0xE1) and RShift (0xE5)
# However, it is only used in the cases where it's necessary
#
# We also rely on "fall-through" to the previous layer
# This means any normally shifted keys do not need to be redefined here
#
# Modified Date
Date = 2016-08-06;
### Mapping ###
# Top Row
U"BackTick" : '~';
U"1" : '%';
U"2" : U"7" + blockKey( 0xE1 ) + blockKey( 0xE5 );
U"3" : U"5" + blockKey( 0xE1 ) + blockKey( 0xE5 );
U"4" : U"3" + blockKey( 0xE1 ) + blockKey( 0xE5 );
U"5" : U"1" + blockKey( 0xE1 ) + blockKey( 0xE5 );
U"6" : U"9" + blockKey( 0xE1 ) + blockKey( 0xE5 );
U"7" : U"0" + blockKey( 0xE1 ) + blockKey( 0xE5 );
U"8" : U"2" + blockKey( 0xE1 ) + blockKey( 0xE5 );
U"9" : U"4" + blockKey( 0xE1 ) + blockKey( 0xE5 );
U"0" : U"6" + blockKey( 0xE1 ) + blockKey( 0xE5 );
U"-" : U"8" + blockKey( 0xE1 ) + blockKey( 0xE5 );
U"=" : U"Backtick" + blockKey( 0xE1 ) + blockKey( 0xE5 );
# Top-Middle Row
U"]" : '^';
# Middle Row
# N/A
# Bottom-Middle Row
# N/A
# Bottom Row
# N/A