Stop last pressed character from getting consumed

This might have a simple answer, but I can’t for the life of me figure out how to do this. Let me explain.

Say I have a list of ‘stop characters’ that I want to terminate a word:

store(stopChar) ' .?!'

I would like to replace a series of keystrokes with a single glyph, so I write something like this:

group(main) using keys
  'smile' + any(stopChar) > '😊'

Consequently, this also consumes the stop character, so the input “smile!” becomes just “:blush:” instead of “😊!” which I’d like it to do.

How do I avoid this issue? Am I going about this the right way? I’d like to do this programmatically since I have a number of these substitutions and I fear my code would become quite unruly were the list of glyphs or stop characters to grow.

Thank you!

I think your rule needs to be:
'smile' + any(stopChar) > '😊' index(stopChar,6)

The index statement uses the position corresponding to the any(stopChar) match as an index to pick the character at that position from the stopChar store (thereby giving you the same character back again).

Why the ‘6’? This tells the index statement where to look for the corresponding any statement. Because there are five characters in the context (the ‘smile’ characters before the ‘+’), the any(stopChar) is the sixth item on the left-hand side of the rule, so the corresponding index statement needs a ‘6’.

In this case, the same store is used for both any and index, but that isn’t always the case. For more details on the index statement, see index statement

1 Like

@drowe’s suggestion is a good one.

Here’s another, which may be an even better fit for your use case: include a final ‘using keys’ group to emit the original key:

group(main) using keys
  'smile' + any(stopChar) > '😊' use(emit)

group(emit) using keys
  c empty group that will force the original keystroke to be output

This has two advantages:

  1. No need to calculate the index value for each rule (the 6 in @drowe’s example)
  2. You can include other key types such as [K_ENTER] in the stopChar store and have them handled cleanly

You can optimise this even further with a match rule, so you don’t have to repeat the use(emit) statement:

group(main) using keys
  'smile' + any(stopChar) > '😊'
  c ... many other rules here
  match > use(emit)

group(emit) using keys
  c empty group that will force the original keystroke to be output

There is one more optimisation you could do with a separate group just for processing the emoji rules (note that this emoji group is not a using keys group because you’ve already matched the key in the main group):

group(main) using keys
  + any(stopChar) > use(emoji)

group(emoji)
  'smile' > '😊'
  c ... many other rules here
  match > use(emit)
  nomatch > use(emit)  c or, you might want to do some other processing here

group(emit) using keys
  c empty group that will force the original keystroke to be output
1 Like

Thank you for your reply, this is exactly what I needed! I didn’t mention this in my original post, but handling other key types was another problem I was trying to overcome. I’m more than happy to ditch the hacky script I was using to generate rules with index().

1 Like