plover 5.0.0.dev2__py3-none-any.whl → 5.0.0.dev3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. plover/__init__.py +8 -7
  2. plover/__main__.py +1 -1
  3. plover/command/set_config.py +7 -4
  4. plover/config.py +177 -74
  5. plover/dictionary/base.py +21 -9
  6. plover/dictionary/helpers.py +6 -4
  7. plover/dictionary/json_dict.py +10 -12
  8. plover/dictionary/loading_manager.py +8 -10
  9. plover/dictionary/rtfcre_dict.py +46 -43
  10. plover/dictionary/rtfcre_parse.py +116 -100
  11. plover/engine.py +112 -96
  12. plover/exception.py +4 -1
  13. plover/formatting.py +198 -140
  14. plover/gui_none/add_translation.py +17 -16
  15. plover/gui_none/engine.py +1 -3
  16. plover/gui_none/main.py +2 -2
  17. plover/gui_qt/about_dialog.py +17 -17
  18. plover/gui_qt/add_translation_dialog.py +8 -9
  19. plover/gui_qt/add_translation_widget.py +66 -63
  20. plover/gui_qt/config_window.py +274 -154
  21. plover/gui_qt/console_widget.py +9 -13
  22. plover/gui_qt/dictionaries_widget.py +140 -119
  23. plover/gui_qt/dictionary_editor.py +60 -61
  24. plover/gui_qt/engine.py +3 -3
  25. plover/gui_qt/info_browser.py +50 -4
  26. plover/gui_qt/log_qt.py +3 -2
  27. plover/gui_qt/lookup_dialog.py +9 -9
  28. plover/gui_qt/machine_options.py +38 -37
  29. plover/gui_qt/main.py +19 -19
  30. plover/gui_qt/main_window.py +88 -71
  31. plover/gui_qt/paper_tape.py +69 -52
  32. plover/gui_qt/paper_tape_ui.py +0 -3
  33. plover/gui_qt/plugins_manager.py +47 -43
  34. plover/gui_qt/resources_rc.py +28 -28
  35. plover/gui_qt/run_dialog.py +7 -6
  36. plover/gui_qt/steno_validator.py +2 -3
  37. plover/gui_qt/suggestions_dialog.py +34 -38
  38. plover/gui_qt/suggestions_widget.py +22 -16
  39. plover/gui_qt/tool.py +1 -3
  40. plover/gui_qt/trayicon.py +19 -19
  41. plover/gui_qt/utils.py +19 -9
  42. plover/i18n.py +9 -8
  43. plover/key_combo.py +130 -130
  44. plover/log.py +26 -26
  45. plover/machine/base.py +40 -35
  46. plover/machine/geminipr.py +7 -7
  47. plover/machine/keyboard.py +16 -14
  48. plover/machine/keyboard_capture/__init__.py +0 -1
  49. plover/machine/keymap.py +24 -20
  50. plover/machine/passport.py +6 -5
  51. plover/machine/procat.py +12 -16
  52. plover/machine/stentura.py +45 -29
  53. plover/machine/txbolt.py +5 -3
  54. plover/macro/repeat.py +0 -1
  55. plover/macro/retro.py +9 -9
  56. plover/macro/undo.py +4 -3
  57. plover/meta/attach.py +12 -10
  58. plover/meta/case.py +2 -1
  59. plover/meta/conditional.py +3 -3
  60. plover/meta/currency.py +4 -4
  61. plover/meta/mode.py +15 -15
  62. plover/meta/punctuation.py +1 -0
  63. plover/misc.py +21 -17
  64. plover/orthography.py +12 -10
  65. plover/oslayer/__init__.py +7 -5
  66. plover/oslayer/config.py +16 -15
  67. plover/oslayer/controller.py +13 -13
  68. plover/oslayer/linux/i18n.py +2 -1
  69. plover/oslayer/linux/keyboardcontrol.py +2 -2
  70. plover/oslayer/linux/keyboardcontrol_uinput.py +48 -3
  71. plover/oslayer/linux/keyboardcontrol_x11.py +860 -851
  72. plover/oslayer/linux/log.py +1 -1
  73. plover/oslayer/linux/log_dbus.py +97 -65
  74. plover/oslayer/linux/serial.py +2 -2
  75. plover/oslayer/linux/wmctrl_x11.py +11 -15
  76. plover/oslayer/osx/keyboardcontrol.py +194 -99
  77. plover/oslayer/osx/keyboardlayout.py +138 -119
  78. plover/oslayer/osx/log.py +14 -8
  79. plover/oslayer/osx/serial.py +1 -1
  80. plover/oslayer/osx/wmctrl.py +6 -1
  81. plover/oslayer/windows/keyboardcontrol.py +195 -89
  82. plover/oslayer/windows/keyboardlayout.py +367 -334
  83. plover/oslayer/windows/log.py +5 -3
  84. plover/oslayer/windows/serial.py +4 -5
  85. plover/oslayer/windows/wmctrl.py +1 -1
  86. plover/output/__init__.py +1 -2
  87. plover/output/keyboard.py +15 -15
  88. plover/plugins_manager/__main__.py +42 -39
  89. plover/plugins_manager/global_registry.py +2 -5
  90. plover/plugins_manager/local_registry.py +11 -13
  91. plover/plugins_manager/package_index.py +12 -18
  92. plover/plugins_manager/pip_wrapper.py +5 -5
  93. plover/plugins_manager/plugin_metadata.py +17 -9
  94. plover/plugins_manager/registry.py +39 -28
  95. plover/plugins_manager/requests.py +2 -4
  96. plover/plugins_manager/utils.py +9 -7
  97. plover/registry.py +28 -26
  98. plover/resource.py +13 -10
  99. plover/scripts/dist_main.py +7 -7
  100. plover/scripts/main.py +57 -34
  101. plover/scripts/send_command.py +13 -7
  102. plover/steno.py +16 -9
  103. plover/steno_dictionary.py +47 -21
  104. plover/suggestions.py +11 -11
  105. plover/system/__init__.py +39 -23
  106. plover/system/english_stenotype.py +231 -229
  107. plover/translation.py +67 -51
  108. {plover-5.0.0.dev2.dist-info → plover-5.0.0.dev3.dist-info}/METADATA +1 -1
  109. plover-5.0.0.dev3.dist-info/RECORD +216 -0
  110. plover_build_utils/check_requirements.py +5 -6
  111. plover_build_utils/download.py +10 -8
  112. plover_build_utils/get_pip.py +10 -5
  113. plover_build_utils/install_wheels.py +33 -31
  114. plover_build_utils/pyqt.py +24 -22
  115. plover_build_utils/setup.py +64 -54
  116. plover_build_utils/source_less.py +6 -6
  117. plover_build_utils/testing/blackbox.py +31 -31
  118. plover_build_utils/testing/dict.py +3 -3
  119. plover_build_utils/testing/output.py +5 -6
  120. plover_build_utils/testing/parametrize.py +5 -3
  121. plover_build_utils/testing/steno_dictionary.py +145 -124
  122. plover_build_utils/tree.py +21 -19
  123. plover_build_utils/trim.py +5 -5
  124. plover_build_utils/zipdir.py +3 -3
  125. plover-5.0.0.dev2.dist-info/RECORD +0 -216
  126. {plover-5.0.0.dev2.dist-info → plover-5.0.0.dev3.dist-info}/WHEEL +0 -0
  127. {plover-5.0.0.dev2.dist-info → plover-5.0.0.dev3.dist-info}/entry_points.txt +0 -0
  128. {plover-5.0.0.dev2.dist-info → plover-5.0.0.dev3.dist-info}/licenses/LICENSE.txt +0 -0
  129. {plover-5.0.0.dev2.dist-info → plover-5.0.0.dev3.dist-info}/top_level.txt +0 -0
  130. {plover-5.0.0.dev2.dist-info → plover-5.0.0.dev3.dist-info}/zip-safe +0 -0
@@ -6,8 +6,7 @@
6
6
  # is a connection error.
7
7
  # TODO: Address any generic exceptions still left.
8
8
 
9
- """Thread-based monitoring of a stenotype machine using the stentura protocol.
10
- """
9
+ """Thread-based monitoring of a stenotype machine using the stentura protocol."""
11
10
 
12
11
  """
13
12
  The stentura protocol uses packets to communicate with the machine. A
@@ -157,8 +156,8 @@ def buffer(object, offset=None, size=None):
157
156
  if offset is None:
158
157
  offset = 0
159
158
  if size is None:
160
- size = len(object)-offset
161
- return memoryview(object)[offset:offset+size]
159
+ size = len(object) - offset
160
+ return memoryview(object)[offset : offset + size]
162
161
 
163
162
 
164
163
  def _allocate_buffer():
@@ -167,24 +166,29 @@ def _allocate_buffer():
167
166
 
168
167
  class _ProtocolViolationException(Exception):
169
168
  """Something has happened that is doesn't follow the protocol."""
169
+
170
170
  pass
171
171
 
172
172
 
173
173
  class _StopException(Exception):
174
174
  """The thread was asked to stop."""
175
+
175
176
  pass
176
177
 
177
178
 
178
179
  class _TimeoutException(Exception):
179
180
  """An operation has timed out."""
181
+
180
182
  pass
181
183
 
182
184
 
183
185
  class _ConnectionLostException(Exception):
184
186
  """Cannot communicate with the machine."""
187
+
185
188
  pass
186
189
 
187
190
 
191
+ # fmt: off
188
192
  _CRC_TABLE = [
189
193
  0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
190
194
  0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
@@ -219,6 +223,7 @@ _CRC_TABLE = [
219
223
  0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
220
224
  0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
221
225
  ]
226
+ # fmt: on
222
227
 
223
228
 
224
229
  def _crc(data, offset=None, size=None):
@@ -250,8 +255,7 @@ def _crc(data, offset=None, size=None):
250
255
  checksum = 0
251
256
  for n in range(offset, offset + size):
252
257
  b = data[n]
253
- checksum = (_CRC_TABLE[(checksum ^ b) & 0xff] ^
254
- ((checksum >> 8) & 0xff))
258
+ checksum = _CRC_TABLE[(checksum ^ b) & 0xFF] ^ ((checksum >> 8) & 0xFF)
255
259
  return checksum
256
260
 
257
261
 
@@ -265,14 +269,17 @@ def _write_to_buffer(buf, offset, data):
265
269
  - offset. The offset at which to start writing.
266
270
  - data: An iterable containing the data to write.
267
271
  """
268
- buf[offset:offset+len(data)] = data
272
+ buf[offset : offset + len(data)] = data
273
+
269
274
 
270
275
  # Helper table for parsing strokes of the form:
271
276
  # 11^#STKP 11WHRAO* 11EUFRPB 11LGTSDZ
272
- _STENO_KEY_CHART = ('^', '#', 'S-', 'T-', 'K-', 'P-', # Byte #1
273
- 'W-', 'H-', 'R-', 'A-', 'O-', '*', # Byte #2
274
- '-E', '-U', '-F', '-R', '-P', '-B', # Byte #3
275
- '-L', '-G', '-T', '-S', '-D', '-Z') # Byte #4
277
+ # fmt: off
278
+ _STENO_KEY_CHART = ("^", "#", "S-", "T-", "K-", "P-", # Byte #1
279
+ "W-", "H-", "R-", "A-", "O-", "*", # Byte #2
280
+ "-E", "-U", "-F", "-R", "-P", "-B", # Byte #3
281
+ "-L", "-G", "-T", "-S", "-D", "-Z") # Byte #4
282
+ # fmt: on
276
283
 
277
284
 
278
285
  def _parse_stroke(a, b, c, d):
@@ -288,10 +295,8 @@ def _parse_stroke(a, b, c, d):
288
295
  e.g. ['S-', 'A-', '-T']
289
296
 
290
297
  """
291
- fullstroke = (((a & 0x3f) << 18) | ((b & 0x3f) << 12) |
292
- ((c & 0x3f) << 6) | d & 0x3f)
293
- return [_STENO_KEY_CHART[i] for i in range(24)
294
- if (fullstroke & (1 << (23 - i)))]
298
+ fullstroke = ((a & 0x3F) << 18) | ((b & 0x3F) << 12) | ((c & 0x3F) << 6) | d & 0x3F
299
+ return [_STENO_KEY_CHART[i] for i in range(24) if (fullstroke & (1 << (23 - i)))]
295
300
 
296
301
 
297
302
  def _parse_strokes(data):
@@ -309,7 +314,8 @@ def _parse_strokes(data):
309
314
  strokes = []
310
315
  if (len(data) % 4) != 0:
311
316
  raise _ProtocolViolationException(
312
- "Data size is not divisible by 4: %d" % (len(data)))
317
+ "Data size is not divisible by 4: %d" % (len(data))
318
+ )
313
319
  for b in data:
314
320
  if (b & 0b11000000) != 0b11000000:
315
321
  raise _ProtocolViolationException("Data is not stroke: 0x%X" % (b))
@@ -317,6 +323,7 @@ def _parse_strokes(data):
317
323
  strokes.append(_parse_stroke(a, b, c, d))
318
324
  return strokes
319
325
 
326
+
320
327
  # Actions
321
328
  _CLOSE = 0x2
322
329
  _DELETE = 0x3
@@ -329,8 +336,8 @@ _RESET = 0x14
329
336
  _TERM = 0x15
330
337
 
331
338
  # Compiled struct for writing request headers.
332
- _REQUEST_STRUCT = struct.Struct('<2B7H')
333
- _SHORT_STRUCT = struct.Struct('<H')
339
+ _REQUEST_STRUCT = struct.Struct("<2B7H")
340
+ _SHORT_STRUCT = struct.Struct("<H")
334
341
 
335
342
 
336
343
  def _make_request(buf, action, seq, p1=0, p2=0, p3=0, p4=0, p5=0, data=None):
@@ -351,8 +358,7 @@ def _make_request(buf, action, seq, p1=0, p2=0, p3=0, p4=0, p5=0, data=None):
351
358
  length = 18
352
359
  if data:
353
360
  length += len(data) + 2 # +2 for the data CRC.
354
- _REQUEST_STRUCT.pack_into(buf, 0, 1, seq, length, action,
355
- p1, p2, p3, p4, p5)
361
+ _REQUEST_STRUCT.pack_into(buf, 0, 1, seq, length, action, p1, p2, p3, p4, p5)
356
362
  crc = _crc(buf, 1, 15)
357
363
  _SHORT_STRUCT.pack_into(buf, 16, crc)
358
364
  if data:
@@ -460,7 +466,10 @@ def _read_data(port, stop, buf, offset, num_bytes):
460
466
  _write_to_buffer(buf, offset, read_bytes)
461
467
  return len(read_bytes)
462
468
 
469
+
463
470
  MINIMUM_PACKET_LENGTH = 14
471
+
472
+
464
473
  def _read_packet(port, stop, buf):
465
474
  """Read a full packet from the port.
466
475
 
@@ -487,8 +496,7 @@ def _read_packet(port, stop, buf):
487
496
  # Packet length should always be at least 14 bytes long
488
497
  if packet_length < MINIMUM_PACKET_LENGTH:
489
498
  raise _ProtocolViolationException()
490
- bytes_read += _read_data(port, stop, buf, bytes_read,
491
- packet_length - bytes_read)
499
+ bytes_read += _read_data(port, stop, buf, bytes_read, packet_length - bytes_read)
492
500
  packet = buffer(buf, 0, bytes_read)
493
501
  if not _validate_response(packet):
494
502
  raise _ProtocolViolationException()
@@ -548,6 +556,7 @@ def _send_receive(port, stop, packet, buf, max_tries=3):
548
556
 
549
557
  class _SequenceCounter:
550
558
  """A mod 256 counter."""
559
+
551
560
  def __init__(self, seq=0):
552
561
  """Init a new counter starting at seq."""
553
562
  self.seq = seq
@@ -582,8 +591,10 @@ def _read(port, stop, seq, request_buf, response_buf, stroke_buf, block, byte):
582
591
  packet = _make_read(request_buf, seq(), block, byte, length=512)
583
592
  response = _send_receive(port, stop, packet, response_buf)
584
593
  p1 = _SHORT_STRUCT.unpack(response[8:10])[0]
585
- if not ((p1 == 0 and len(response) == 14) or # No data.
586
- (p1 == len(response) - 16)): # Data.
594
+ if not (
595
+ (p1 == 0 and len(response) == 14) # No data.
596
+ or (p1 == len(response) - 16)
597
+ ): # Data.
587
598
  raise _ProtocolViolationException()
588
599
  if p1 == 0:
589
600
  return block, byte, buffer(stroke_buf, 0, bytes_read)
@@ -595,6 +606,7 @@ def _read(port, stop, seq, request_buf, response_buf, stroke_buf, block, byte):
595
606
  block += 1
596
607
  byte -= 512
597
608
 
609
+
598
610
  def _loop(port, stop, callback, ready_callback, timeout=1):
599
611
  """Enter into a loop talking to the machine and returning strokes.
600
612
 
@@ -628,15 +640,19 @@ def _loop(port, stop, callback, ready_callback, timeout=1):
628
640
  request_buf, response_buf = _allocate_buffer(), _allocate_buffer()
629
641
  stroke_buf = _allocate_buffer()
630
642
  seq = _SequenceCounter()
631
- request = _make_open(request_buf, seq(), b'A', b'REALTIME.000')
643
+ request = _make_open(request_buf, seq(), b"A", b"REALTIME.000")
632
644
  # Any checking needed on the response packet?
633
645
  _send_receive(port, stop, request, response_buf)
634
646
  # Do a full read to get to the current position in the realtime file.
635
647
  block, byte = 0, 0
636
- block, byte, _ = _read(port, stop, seq, request_buf, response_buf, stroke_buf, block, byte)
648
+ block, byte, _ = _read(
649
+ port, stop, seq, request_buf, response_buf, stroke_buf, block, byte
650
+ )
637
651
  ready_callback()
638
652
  while True:
639
- block, byte, data = _read(port, stop, seq, request_buf, response_buf, stroke_buf, block, byte)
653
+ block, byte, data = _read(
654
+ port, stop, seq, request_buf, response_buf, stroke_buf, block, byte
655
+ )
640
656
  strokes = _parse_strokes(data)
641
657
  for stroke in strokes:
642
658
  callback(stroke)
@@ -650,13 +666,13 @@ class Stentura(plover.machine.base.SerialStenotypeBase):
650
666
  add_callback.
651
667
  """
652
668
 
653
- KEYS_LAYOUT = '''
669
+ KEYS_LAYOUT = """
654
670
  # # # # # # # # # #
655
671
  S- T- P- H- * -F -P -L -T -D
656
672
  S- K- W- R- * -R -B -G -S -Z
657
673
  A- O- -E -U
658
674
  ^
659
- '''
675
+ """
660
676
 
661
677
  def run(self):
662
678
  """Overrides base class run method. Do not call directly."""
plover/machine/txbolt.py CHANGED
@@ -24,10 +24,12 @@ import plover.machine.base
24
24
  # seen. Additionally, if there is no activity then the machine will
25
25
  # send a zero byte every few seconds.
26
26
 
27
+ # fmt: off
27
28
  STENO_KEY_CHART = ("S-", "T-", "K-", "P-", "W-", "H-", # 00
28
29
  "R-", "A-", "O-", "*", "-E", "-U", # 01
29
30
  "-F", "-R", "-P", "-B", "-L", "-G", # 10
30
31
  "-T", "-S", "-D", "-Z", "#") # 11
32
+ # fmt: on
31
33
 
32
34
 
33
35
  class TxBolt(plover.machine.base.SerialStenotypeBase):
@@ -39,12 +41,12 @@ class TxBolt(plover.machine.base.SerialStenotypeBase):
39
41
 
40
42
  """
41
43
 
42
- KEYS_LAYOUT = '''
44
+ KEYS_LAYOUT = """
43
45
  # # # # # # # # # #
44
46
  S- T- P- H- * -F -P -L -T -D
45
47
  S- K- W- R- * -R -B -G -S -Z
46
48
  A- O- -E -U
47
- '''
49
+ """
48
50
 
49
51
  def __init__(self, params):
50
52
  super().__init__(params)
@@ -63,7 +65,7 @@ class TxBolt(plover.machine.base.SerialStenotypeBase):
63
65
  def run(self):
64
66
  """Overrides base class run method. Do not call directly."""
65
67
  settings = self.serial_port.getSettingsDict()
66
- settings['timeout'] = 0.1 # seconds
68
+ settings["timeout"] = 0.1 # seconds
67
69
  self.serial_port.applySettingsDict(settings)
68
70
  self._ready()
69
71
  while not self.finished.is_set():
plover/macro/repeat.py CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  from plover.steno import Stroke
3
2
 
4
3
 
plover/macro/retro.py CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  from plover.translation import Translation
3
2
  from plover.steno import Stroke
4
3
  from plover import system
@@ -13,12 +12,13 @@ def toggle_asterisk(translator, stroke, cmdline):
13
12
  t = translations[-1]
14
13
  translator.untranslate_translation(t)
15
14
  keys = set(t.strokes[-1].steno_keys)
16
- if '*' in keys:
17
- keys.remove('*')
15
+ if "*" in keys:
16
+ keys.remove("*")
18
17
  else:
19
- keys.add('*')
18
+ keys.add("*")
20
19
  translator.translate_stroke(Stroke(keys))
21
20
 
21
+
22
22
  def delete_space(translator, stroke, cmdline):
23
23
  assert not cmdline
24
24
  # Retrospective delete space
@@ -33,13 +33,14 @@ def delete_space(translator, stroke, cmdline):
33
33
  if t.english is not None:
34
34
  english.append(t.english)
35
35
  elif len(t.rtfcre) == 1 and t.rtfcre[0].isdigit():
36
- english.append('{&%s}' % t.rtfcre[0])
36
+ english.append("{&%s}" % t.rtfcre[0])
37
37
  if len(english) > 1:
38
- t = Translation([stroke], '{^~|^}'.join(english))
38
+ t = Translation([stroke], "{^~|^}".join(english))
39
39
  t.replaced = replaced
40
40
  t.is_retrospective_command = True
41
41
  translator.translate_translation(t)
42
42
 
43
+
43
44
  def insert_space(translator, stroke, cmdline):
44
45
  assert not cmdline
45
46
  # Retrospective insert space
@@ -50,14 +51,13 @@ def insert_space(translator, stroke, cmdline):
50
51
  if replaced.is_retrospective_command:
51
52
  return
52
53
  lookup_stroke = replaced.strokes[-1]
53
- english = [t.english or '/'.join(t.rtfcre)
54
- for t in replaced.replaced]
54
+ english = [t.english or "/".join(t.rtfcre) for t in replaced.replaced]
55
55
  if english:
56
56
  english.append(
57
57
  translator.lookup([lookup_stroke], system.SUFFIX_KEYS)
58
58
  or lookup_stroke.rtfcre
59
59
  )
60
- t = Translation([stroke], ' '.join(english))
60
+ t = Translation([stroke], " ".join(english))
61
61
  t.replaced = [replaced]
62
62
  t.is_retrospective_command = True
63
63
  translator.translate_translation(t)
plover/macro/undo.py CHANGED
@@ -2,10 +2,11 @@ from plover.translation import Translation
2
2
  from plover.oslayer.config import PLATFORM
3
3
 
4
4
 
5
- if PLATFORM == 'mac':
6
- BACK_STRING = '{#Alt_L(BackSpace)}{^}'
5
+ if PLATFORM == "mac":
6
+ BACK_STRING = "{#Alt_L(BackSpace)}{^}"
7
7
  else:
8
- BACK_STRING = '{#Control_L(BackSpace)}{^}'
8
+ BACK_STRING = "{#Control_L(BackSpace)}{^}"
9
+
9
10
 
10
11
  def undo(translator, stroke, cmdline):
11
12
  assert not cmdline
plover/meta/attach.py CHANGED
@@ -19,23 +19,24 @@ def meta_attach(ctx, meta):
19
19
  meta = META_ATTACH_FLAG + meta + META_ATTACH_FLAG
20
20
  begin = end = True
21
21
  if begin:
22
- meta = meta[len(META_ATTACH_FLAG):]
22
+ meta = meta[len(META_ATTACH_FLAG) :]
23
23
  action.prev_attach = True
24
24
  if end:
25
- meta = meta[:-len(META_ATTACH_FLAG)]
25
+ meta = meta[: -len(META_ATTACH_FLAG)]
26
26
  action.next_attach = True
27
27
  action.word_is_finished = False
28
- last_word = ctx.last_action.word or ''
28
+ last_word = ctx.last_action.word or ""
29
29
  if not meta:
30
30
  # We use an empty connection to indicate a "break" in the
31
31
  # application of orthography rules. This allows the
32
32
  # stenographer to tell Plover not to auto-correct a word.
33
33
  action.orthography = False
34
34
  elif (
35
- last_word and
36
- not meta.isspace() and
37
- ctx.last_action.orthography and
38
- begin and (not end or has_word_boundary(meta))
35
+ last_word
36
+ and not meta.isspace()
37
+ and ctx.last_action.orthography
38
+ and begin
39
+ and (not end or has_word_boundary(meta))
39
40
  ):
40
41
  new_word = add_suffix(last_word, meta)
41
42
  common_len = len(commonprefix([last_word, new_word]))
@@ -49,6 +50,7 @@ def meta_attach(ctx, meta):
49
50
  action.word = rightmost_word(last_word + meta)
50
51
  return action
51
52
 
53
+
52
54
  def meta_carry_capitalize(ctx, meta):
53
55
  # Meta format: ^~|content^ (attach flags are optional)
54
56
  action = ctx.new_action()
@@ -56,12 +58,12 @@ def meta_carry_capitalize(ctx, meta):
56
58
  action.next_case = Case.CAP_FIRST_WORD
57
59
  begin = meta.startswith(META_ATTACH_FLAG)
58
60
  if begin:
59
- meta = meta[len(META_ATTACH_FLAG):]
61
+ meta = meta[len(META_ATTACH_FLAG) :]
60
62
  action.prev_attach = True
61
- meta = meta[len(META_CARRY_CAPITALIZATION):]
63
+ meta = meta[len(META_CARRY_CAPITALIZATION) :]
62
64
  end = meta.endswith(META_ATTACH_FLAG)
63
65
  if end:
64
- meta = meta[:-len(META_ATTACH_FLAG)]
66
+ meta = meta[: -len(META_ATTACH_FLAG)]
65
67
  action.next_attach = True
66
68
  action.word_is_finished = False
67
69
  if meta or begin or end:
plover/meta/case.py CHANGED
@@ -7,6 +7,7 @@ def meta_case(ctx, case):
7
7
  action.next_case = case
8
8
  return action
9
9
 
10
+
10
11
  def meta_retro_case(ctx, case):
11
12
  case = Case(case.lower())
12
13
  action = ctx.copy_last_action()
@@ -16,5 +17,5 @@ def meta_retro_case(ctx, case):
16
17
  action.prev_replace = last_words[0]
17
18
  action.text = apply_case(last_words[0], case)
18
19
  else:
19
- action.text = ''
20
+ action.text = ""
20
21
  return action
@@ -3,13 +3,13 @@ import re
3
3
  from plover.formatting import _LookAheadAction
4
4
 
5
5
 
6
- IF_NEXT_META_RX = re.compile(r'((?:[^\\/]|\\\\|\\/)*)/?')
7
- IF_NEXT_ESCAPE_RX = re.compile(r'\\([\\/])')
6
+ IF_NEXT_META_RX = re.compile(r"((?:[^\\/]|\\\\|\\/)*)/?")
7
+ IF_NEXT_ESCAPE_RX = re.compile(r"\\([\\/])")
8
8
 
9
9
 
10
10
  def meta_if_next_matches(ctx, meta):
11
11
  pattern, result1, result2 = [
12
- IF_NEXT_ESCAPE_RX.sub(r'\1', s)
12
+ IF_NEXT_ESCAPE_RX.sub(r"\1", s)
13
13
  for s in filter(None, IF_NEXT_META_RX.split(meta, 2))
14
14
  ]
15
15
  action_list = []
plover/meta/currency.py CHANGED
@@ -3,16 +3,16 @@ def meta_retro_currency(ctx, dict_format):
3
3
  last_words = ctx.last_words(count=1)
4
4
  if not last_words:
5
5
  return action
6
- currency = last_words[0].replace(',', '')
6
+ currency = last_words[0].replace(",", "")
7
7
  for cast, fmt in (
8
- (int, '{:,}' ),
9
- (float, '{:,.2f}'),
8
+ (int, "{:,}"),
9
+ (float, "{:,.2f}"),
10
10
  ):
11
11
  try:
12
12
  cast_input = cast(currency)
13
13
  except ValueError:
14
14
  continue
15
- currency_format = dict_format.replace('c', fmt)
15
+ currency_format = dict_format.replace("c", fmt)
16
16
  action.prev_attach = True
17
17
  action.prev_replace = last_words[0]
18
18
  action.text = currency_format.format(cast_input)
plover/meta/mode.py CHANGED
@@ -15,34 +15,34 @@ def meta_mode(ctx, cmdline):
15
15
  set_space:xy: Set space to xy
16
16
  reset: Reset to normal case, space resets to ' '
17
17
  """
18
- args = cmdline.split(':', 1)
18
+ args = cmdline.split(":", 1)
19
19
  mode = args.pop(0).lower()
20
20
  action = ctx.copy_last_action()
21
- if mode == 'set_space':
22
- action.space_char = args[0] if args else ''
21
+ if mode == "set_space":
22
+ action.space_char = args[0] if args else ""
23
23
  return action
24
24
  # No argument allowed for other mode directives.
25
25
  if args:
26
- raise ValueError('%r is not a valid mode' % cmdline)
27
- if mode == 'caps':
26
+ raise ValueError("%r is not a valid mode" % cmdline)
27
+ if mode == "caps":
28
28
  action.case = Case.UPPER
29
- elif mode == 'title':
29
+ elif mode == "title":
30
30
  action.case = Case.TITLE
31
- elif mode == 'lower':
31
+ elif mode == "lower":
32
32
  action.case = Case.LOWER
33
- elif mode == 'snake':
34
- action.space_char = '_'
35
- elif mode == 'camel':
33
+ elif mode == "snake":
34
+ action.space_char = "_"
35
+ elif mode == "camel":
36
36
  action.case = Case.TITLE
37
- action.space_char = ''
37
+ action.space_char = ""
38
38
  action.next_case = Case.LOWER_FIRST_CHAR
39
- elif mode == 'reset':
39
+ elif mode == "reset":
40
40
  action.space_char = SPACE
41
41
  action.case = None
42
- elif mode == 'reset_space':
42
+ elif mode == "reset_space":
43
43
  action.space_char = SPACE
44
- elif mode == 'reset_case':
44
+ elif mode == "reset_case":
45
45
  action.case = None
46
46
  else:
47
- raise ValueError('%r is not a valid mode' % cmdline)
47
+ raise ValueError("%r is not a valid mode" % cmdline)
48
48
  return action
@@ -7,6 +7,7 @@ def meta_comma(ctx, text):
7
7
  action.prev_attach = True
8
8
  return action
9
9
 
10
+
10
11
  def meta_stop(ctx, text):
11
12
  action = ctx.new_action()
12
13
  action.prev_attach = True
plover/misc.py CHANGED
@@ -10,30 +10,32 @@ from plover.resource import ASSET_SCHEME
10
10
  def popcount_8(v):
11
11
  """Population count for an 8 bit integer"""
12
12
  assert 0 <= v <= 255
13
- v -= ((v >> 1) & 0x55555555)
13
+ v -= (v >> 1) & 0x55555555
14
14
  v = (v & 0x33333333) + ((v >> 2) & 0x33333333)
15
15
  return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24
16
16
 
17
+
17
18
  def expand_path(path):
18
- ''' Expand path.
19
+ """Expand path.
19
20
 
20
- - if starting with "~/", it is substituted with the user home directory
21
- - if relative, it is resolved relative to CONFIG_DIR
22
- '''
21
+ - if starting with "~/", it is substituted with the user home directory
22
+ - if relative, it is resolved relative to CONFIG_DIR
23
+ """
23
24
  if path.startswith(ASSET_SCHEME):
24
25
  return path
25
26
  path = os.path.expanduser(path)
26
27
  path = normalize_path(os.path.join(CONFIG_DIR, path))
27
28
  return path
28
29
 
30
+
29
31
  def shorten_path(path):
30
- ''' Shorten path.
32
+ """Shorten path.
31
33
 
32
- - if the path is below CONFIG_DIR, a relative path to it is returned
33
- - if path is below the user home directory, "~/" is substituted to it
34
+ - if the path is below CONFIG_DIR, a relative path to it is returned
35
+ - if path is below the user home directory, "~/" is substituted to it
34
36
 
35
- Note: relative path are automatically assumed to be relative to CONFIG_DIR.
36
- '''
37
+ Note: relative path are automatically assumed to be relative to CONFIG_DIR.
38
+ """
37
39
  if path.startswith(ASSET_SCHEME):
38
40
  return path
39
41
  path = normalize_path(os.path.join(CONFIG_DIR, path))
@@ -41,31 +43,33 @@ def shorten_path(path):
41
43
  if not config_dir.endswith(os.sep):
42
44
  config_dir += os.sep
43
45
  if path.startswith(config_dir):
44
- return path[len(config_dir):]
45
- home_dir = normalize_path(os.path.expanduser('~'))
46
+ return path[len(config_dir) :]
47
+ home_dir = normalize_path(os.path.expanduser("~"))
46
48
  if not home_dir.endswith(os.sep):
47
49
  home_dir += os.sep
48
50
  if path.startswith(home_dir):
49
- return os.path.join('~', path[len(home_dir):])
51
+ return os.path.join("~", path[len(home_dir) :])
50
52
  return path
51
53
 
54
+
52
55
  def normalize_path(path):
53
- ''' Normalize path: return canonical path, normalizing case on Windows.
54
- '''
56
+ """Normalize path: return canonical path, normalizing case on Windows."""
55
57
  if path.startswith(ASSET_SCHEME):
56
58
  return path
57
59
  return os.path.normcase(os.path.realpath(path))
58
60
 
61
+
59
62
  def boolean(value):
60
63
  if isinstance(value, str):
61
64
  v = value.lower()
62
- if v in ('1', 'yes', 'true', 'on'):
65
+ if v in ("1", "yes", "true", "on"):
63
66
  return True
64
- if v in ('0', 'no', 'false', 'off'):
67
+ if v in ("0", "no", "false", "off"):
65
68
  return False
66
69
  raise ValueError(value)
67
70
  return bool(value)
68
71
 
72
+
69
73
  def to_surrogate_pair(char):
70
74
  pairs = []
71
75
  for code in char:
plover/orthography.py CHANGED
@@ -10,26 +10,27 @@ def make_candidates_from_rules(word, suffix, check=lambda x: True):
10
10
  candidates = []
11
11
  for r in system.ORTHOGRAPHY_RULES:
12
12
  m = r[0].match(word + " ^ " + suffix)
13
- if m:
13
+ if m:
14
14
  expanded = m.expand(r[1])
15
15
  if check(expanded):
16
16
  candidates.append(expanded)
17
17
  return candidates
18
18
 
19
+
19
20
  def _add_suffix(word, suffix):
20
21
  in_dict_f = lambda x: x in system.ORTHOGRAPHY_WORDS
21
22
 
22
23
  candidates = []
23
-
24
+
24
25
  alias = system.ORTHOGRAPHY_RULES_ALIASES.get(suffix, None)
25
26
  if alias is not None:
26
27
  candidates.extend(make_candidates_from_rules(word, alias, in_dict_f))
27
-
28
+
28
29
  # Try a simple join if it is in the dictionary.
29
30
  simple = word + suffix
30
31
  if in_dict_f(simple):
31
32
  candidates.append(simple)
32
-
33
+
33
34
  # Try rules with dict lookup.
34
35
  candidates.extend(make_candidates_from_rules(word, suffix, in_dict_f))
35
36
 
@@ -38,24 +39,25 @@ def _add_suffix(word, suffix):
38
39
  if candidates:
39
40
  candidates.sort(key=lambda x: system.ORTHOGRAPHY_WORDS[x])
40
41
  return candidates[0]
41
-
42
+
42
43
  # Try rules without dict lookup.
43
44
  candidates = make_candidates_from_rules(word, suffix)
44
45
  if candidates:
45
46
  return candidates[0]
46
-
47
+
47
48
  # If all else fails then just do a simple join.
48
49
  return simple
49
50
 
51
+
50
52
  def add_suffix(word, suffix):
51
53
  """Add a suffix to a word by applying the rules above
52
-
54
+
53
55
  Arguments:
54
-
56
+
55
57
  word -- A word
56
58
  suffix -- The suffix to add
57
-
59
+
58
60
  """
59
- suffix, sep, rest = suffix.partition(' ')
61
+ suffix, sep, rest = suffix.partition(" ")
60
62
  expanded = _add_suffix(word, suffix)
61
63
  return expanded + sep + rest