Skip to content

Commit

Permalink
Merge pull request #1 from t33chong/t33chong
Browse files Browse the repository at this point in the history
Add s/S/x/X actions, various synonyms, mode hooks, userspace docs; optionally differentiate w & e motions; fix process hooks & redo on Mac; automate updating firmware size table in readme
  • Loading branch information
andrewjrae authored Jun 21, 2021
2 parents f668203 + 206ffb3 commit aeaf460
Show file tree
Hide file tree
Showing 9 changed files with 244 additions and 49 deletions.
124 changes: 81 additions & 43 deletions README.org

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions src/actions.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,23 @@
// This should be used whenever using one of these shortcuts
#ifdef VIM_FOR_MAC
#define VCMD LCMD
#define VIM_REDO VCMD(LSFT(KC_Z))
#else
#define VCMD LCTL
#define VIM_REDO VCMD(KC_Y)
#endif

// These are the main keys for each vim core vim action
// These + VIM_REDO (defined above) are the main keys for each vim core vim action
#define VIM_CHANGE KC_DEL
#define VIM_DELETE VCMD(KC_X) // note that you may prefer a simple delete here since we only are using one clipboard
#define VIM_YANK VCMD(KC_C)
// Other commands
#define VIM_PASTE VCMD(KC_V)
#define VIM_UNDO VCMD(KC_Z)
#define VIM_REDO VCMD(KC_Y)
#define VIM_FIND VCMD(KC_F)
#define VIM_SAVE VCMD(KC_S)
#define VIM_X KC_DEL
#define VIM_SHIFT_X KC_BSPC

// Process function to handle text objects ie in or around word
bool process_text_objects(uint16_t keycode, const keyrecord_t *record);
Expand Down
58 changes: 57 additions & 1 deletion src/modes.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ bool process_normal_mode_user(uint16_t keycode, const keyrecord_t *record) {

// The function that handles normal mode keycode inputs
bool process_normal_mode(uint16_t keycode, const keyrecord_t *record) {
if (!process_normal_mode_user(keycode, record)) {
return false;
}
#ifdef VIM_DOT_REPEAT
bool should_record_action = true;
#define NO_RECORD_ACTION() should_record_action = false;
Expand Down Expand Up @@ -120,6 +123,15 @@ bool process_normal_mode(uint16_t keycode, const keyrecord_t *record) {
case KC_D:
start_delete_action();
break;
case LSFT(KC_S):
VIM_HOME();
VIM_SHIFT_END();
change_action();
break;
case KC_S:
tap_code16(LSFT(KC_RIGHT));
change_action();
break;
case LSFT(KC_Y):
VIM_SHIFT_END();
yank_action();
Expand Down Expand Up @@ -169,6 +181,9 @@ bool process_normal_mode(uint16_t keycode, const keyrecord_t *record) {
case KC_X:
tap_code16(VIM_X);
break;
case LSFT(KC_X):
tap_code16(VIM_SHIFT_X);
break;
#ifdef VIM_COLON_CMDS
case KC_COLON:
process_func = process_colon_cmd;
Expand Down Expand Up @@ -211,7 +226,7 @@ bool process_normal_mode(uint16_t keycode, const keyrecord_t *record) {
return false;
}

// Allow the user to add their own bindings to both visual modes
// Allow the user to add their own bindings to visual mode
// Note, this should be optimized away unless there is a user definition
__attribute__ ((weak))
bool process_visual_mode_user(uint16_t keycode, const keyrecord_t *record) {
Expand All @@ -220,6 +235,9 @@ bool process_visual_mode_user(uint16_t keycode, const keyrecord_t *record) {

// The function that handles visual mode keycode inputs
bool process_visual_mode(uint16_t keycode, const keyrecord_t *record) {
if (!process_visual_mode_user(keycode, record)) {
return false;
}
// handle motions on their own so they can be pressed and held
if (!process_motions(keycode, record, QK_LSFT)) {
return false;
Expand All @@ -232,9 +250,11 @@ bool process_visual_mode(uint16_t keycode, const keyrecord_t *record) {
if (record->event.pressed) {
switch (keycode) {
case KC_C:
case KC_S:
change_action();
return false;
case KC_D:
case KC_X:
delete_action();
return false;
case KC_Y:
Expand Down Expand Up @@ -265,8 +285,18 @@ bool process_visual_mode(uint16_t keycode, const keyrecord_t *record) {
return false;
}

// Allow the user to add their own bindings to visual line mode
// Note, this should be optimized away unless there is a user definition
__attribute__ ((weak))
bool process_visual_line_mode_user(uint16_t keycode, const keyrecord_t *record) {
return true;
}

// The function that handles visual line mode keycode inputs
bool process_visual_line_mode(uint16_t keycode, const keyrecord_t *record) {
if (!process_visual_line_mode_user(keycode, record)) {
return false;
}
// handle motions on their own so they can be pressed and held
switch (keycode) {
case KC_J:
Expand All @@ -289,10 +319,12 @@ bool process_visual_line_mode(uint16_t keycode, const keyrecord_t *record) {
if (record->event.pressed) {
switch (keycode) {
case KC_C:
case KC_S:
tap_code16(LSFT(KC_LEFT));
change_action();
return false;
case KC_D:
case KC_X:
delete_line_action();
return false;
case KC_Y:
Expand Down Expand Up @@ -350,22 +382,40 @@ bool process_insert_mode(uint16_t keycode, const keyrecord_t *record) {
}


// Allow the user to set custom state when normal mode is entered
__attribute__ ((weak))
void normal_mode_user(void) {
}

// Function to enter into normal mode
void normal_mode(void) {
normal_mode_user();
vim_current_mode = NORMAL_MODE;
process_func = process_normal_mode;
}

// Allow the user to set custom state when insert mode is entered
__attribute__ ((weak))
void insert_mode_user(void) {
}

// Function to enter into insert mode
void insert_mode(void) {
insert_mode_user();
vim_current_mode = INSERT_MODE;
// need to clear motion keys if they are currently pressed
clear_keyboard();
process_func = process_insert_mode;
}

// Allow the user to set custom state when visual mode is entered
__attribute__ ((weak))
void visual_mode_user(void) {
}

// Function to enter into visual mode
void visual_mode(void) {
visual_mode_user();
vim_current_mode = VISUAL_MODE;
#ifndef NO_VISUAL_MODE
#ifdef BETTER_VISUAL_MODE
Expand All @@ -378,8 +428,14 @@ void visual_mode(void) {
}


// Allow the user to set custom state when visual line mode is entered
__attribute__ ((weak))
void visual_line_mode_user(void) {
}

// Function to enter into visual line mode
void visual_line_mode(void) {
visual_line_mode_user();
vim_current_mode = VISUAL_LINE_MODE;
#ifndef NO_VISUAL_LINE_MODE
#ifdef BETTER_VISUAL_MODE
Expand Down
21 changes: 18 additions & 3 deletions src/motions.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,36 @@ bool process_motions(uint16_t keycode, const keyrecord_t *record, uint16_t qk_mo
return false;
case KC_B:
case VIM_B:
case LSFT(KC_B):
set_visual_direction(V_BACKWARD);
register_motion(qk_mods | VIM_B, record);
return false;
case KC_E: // currently this doesn't do much
case KC_W:
case VIM_W:
case LSFT(KC_W):
#ifdef VIM_W_BEGINNING_OF_WORD
set_visual_direction(V_FORWARD);
register_motion(qk_mods | VIM_W, record);
if (record->event.pressed) {
register_code16(qk_mods | VIM_W);
} else {
unregister_code16(qk_mods | VIM_W);
tap_code16(qk_mods | VIM_W);
tap_code16(qk_mods | VIM_B);
}
return false;
#endif
case KC_E:
case LSFT(KC_E):
set_visual_direction(V_FORWARD);
register_motion(qk_mods | VIM_E, record);
return false;
case KC_0:
case VIM_0:
case KC_CIRC: // ^
set_visual_direction(V_BACKWARD);
register_motion(qk_mods | VIM_0, record);
return false;
case KC_DLR:
case KC_DLR: // $
case VIM_DLR:
set_visual_direction(V_FORWARD);
register_motion(qk_mods | VIM_DLR, record);
Expand Down
10 changes: 10 additions & 0 deletions update-readme/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM qmkfm/qmk_firmware:latest

ENV MY_KEYMAP_PATH=/qmk_firmware/keyboards/uno/keymaps/qmk-vim-update-readme

WORKDIR /qmk_firmware

COPY keymap $MY_KEYMAP_PATH
COPY run.py /qmk_firmware/qmk_vim_update_readme.py

CMD python3 qmk_vim_update_readme.py
Empty file added update-readme/keymap/config.h
Empty file.
21 changes: 21 additions & 0 deletions update-readme/keymap/keymap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include QMK_KEYBOARD_H
#include "qmk-vim/src/vim.h"

enum keycodes {
QMK_VIM = SAFE_RANGE
};

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT(QMK_VIM)
};

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!process_vim_mode(keycode, record)) {
return false;
}
if (keycode == QMK_VIM && record->event.pressed) {
toggle_vim_mode();
return false;
}
return true;
}
1 change: 1 addition & 0 deletions update-readme/keymap/rules.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include keyboards/uno/keymaps/qmk-vim-update-readme/qmk-vim/rules.mk
52 changes: 52 additions & 0 deletions update-readme/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import os
import re
import subprocess

# Path to QMK keymap used for firmware size calculations
MY_KEYMAP_PATH = os.getenv('MY_KEYMAP_PATH')
README_PATH = os.path.join(MY_KEYMAP_PATH, 'qmk-vim/README.org')

# Split readme into sections: before feature macros table, table itself, and after table
BEFORE, MACROS, AFTER = 0, 1, 2
lines = [[], [], []]
position = BEFORE
with open(README_PATH) as f:
for line in f:
if ((position == BEFORE and line.startswith('| ='))
or (position == MACROS and not line.startswith('|'))):
position += 1
lines[position].append(line)

# Compile and parse output for firmware size
def get_firmware_size():
process = subprocess.run(
['qmk', 'compile', '-kb', 'uno', '-km', 'qmk-vim-update-readme'], capture_output=True)
matches = re.search(r'The firmware size is fine - (\d+)', process.stdout.decode('utf-8'))
return int(matches[1])

# Determine firmware size without any macros defined
baseline = get_firmware_size()

# Iterate over rows in table
for i in range(len(lines[MACROS])):
# Parse macro name
line = lines[MACROS][i]
cells = line.split('|')
macro = cells[1].strip('= ')
# Add macro to config
with open(os.path.join(MY_KEYMAP_PATH, 'config.h'), 'w') as f:
f.write(f'#define {macro}')
# Determine firmware size difference
size = get_firmware_size()
size_diff = baseline - size
if size_diff >= 0:
new_val_str = f' +{size_diff} B'
else:
new_val_str = f' {size_diff} B'
# Update table
cells[3] = new_val_str.ljust(len(cells[3]), ' ')
lines[MACROS][i] = '|'.join(cells)

# Overwrite readme with new values
with open(README_PATH, 'w') as f:
f.write(''.join(line for section in lines for line in section))

0 comments on commit aeaf460

Please sign in to comment.