~ecs/madeline

54dcf14b67f34da392be837d01889e2956905d68 — Ember Sawady 4 months ago a84a4ff
implement numeric prefixes

extensible enough to be able to handle custom repetition handling
4 files changed, 69 insertions(+), 12 deletions(-)

M made/actions.ha
M made/default_config.ha
M made/line.ha
M made/types.ha
M made/actions.ha => made/actions.ha +24 -0
@@ 28,9 28,19 @@ let action_noargstr: [_](str, *action_noarg) = [
	("mode-normal", &mode_normal),
	("mode-search", &mode_search),
	("mode-vi-normal", &mode_vi_normal),
	("number1", &number1),
	("number2", &number2),
	("number3", &number3),
	("number4", &number4),
	("number5", &number5),
	("number6", &number6),
	("number7", &number7),
	("number8", &number8),
	("number9", &number9),
	("reset-hidx", &reset_hidx),
	("unkill", &unkill),
	("unkill-pop", &unkill_pop),
	("zero-or-home", &zero_or_home),
];

export type action_arg = fn(s: *state, m: *motion) (void | error);


@@ 296,3 306,17 @@ case let r: rune =>
};

fn append_newline(s: *state) (void | error) = appendstr(s, "\n");

fn zero_or_home(s: *state) (void | error) = {
	if (s.reps == 0) move(s, &home);
	s.new_reps = s.reps * 10;
};
fn number1(s: *state) (void | error) = s.new_reps = s.reps * 10 + 1;
fn number2(s: *state) (void | error) = s.new_reps = s.reps * 10 + 2;
fn number3(s: *state) (void | error) = s.new_reps = s.reps * 10 + 3;
fn number4(s: *state) (void | error) = s.new_reps = s.reps * 10 + 4;
fn number5(s: *state) (void | error) = s.new_reps = s.reps * 10 + 5;
fn number6(s: *state) (void | error) = s.new_reps = s.reps * 10 + 6;
fn number7(s: *state) (void | error) = s.new_reps = s.reps * 10 + 7;
fn number8(s: *state) (void | error) = s.new_reps = s.reps * 10 + 8;
fn number9(s: *state) (void | error) = s.new_reps = s.reps * 10 + 9;

M made/default_config.ha => made/default_config.ha +13 -1
@@ 83,7 83,16 @@ ctrl right = next-word
left = prev-char
alt left = prev-word
ctrl left = prev-word
0 = home
0 = zero-or-home
1 = number1
2 = number2
3 = number3
4 = number4
5 = number5
6 = number6
7 = number7
8 = number8
9 = number9
_ = home next-word prev-word
^ = home next-word prev-word
$ = end


@@ 120,4 129,7 @@ S = end kill-push home mode-normal
g I = home mode-normal
g $ = end
g _ = end prev-word next-word
delete = kill next-char
ctrl h = prev-char
backspace = prev-char
`;

M made/line.ha => made/line.ha +29 -11
@@ 86,19 86,37 @@ fn handle_events(s: *state) (void | signal | error) = for :loop (true) {
		};

		let a = b[i].action;
		for (let j = 0z; j < len(a); j += 1) match (a[j]) {
		case let m: *motion =>
			match (s.action) {
			case void =>
				move(s, m);
		for (let j = 0z; j < len(a); j += 1) {
			let reps = if (s.reps == 0) 1u64 else s.reps;
			s.new_reps = -1;
			defer if (s.new_reps != -1) s.reps = s.new_reps;
			defer s.reps = 0;

			match (a[j]) {
			case let m: *motion =>
				match (s.action) {
				case void =>
					for (reps > 0 && s.new_reps == -1;
							reps -= 1) {
						move(s, m);
					};
				case let a: *action_arg =>
					reps *= s.areps;
					for (reps > 0 && s.new_reps == -1;
							reps -= 1) {
						a(s, m)?;
					};
					s.action = void;
					s.areps = 0;
				};
			case let a: *action_noarg =>
				for (reps > 0 && s.new_reps == -1; reps -= 1) {
					a(s)?;
				};
			case let a: *action_arg =>
				a(s, m)?;
				s.action = void;
				s.action = a;
				s.areps = reps;
			};
		case let a: *action_noarg =>
			a(s)?;
		case let a: *action_arg =>
			s.action = a;
		};
		match (s.signal) {
		case void => void;

M made/types.ha => made/types.ha +3 -0
@@ 48,6 48,9 @@ export type state = struct {
	// XXX: might be able to integrate this with ret?
	signal: (signal | void),

	reps: u64,
	new_reps: u64,
	areps: u64,
	queued: []event,
	action: (*action_arg | void),
};