]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Word replacement accent system (#15086)
authorKara <lunarautomaton6@gmail.com>
Tue, 4 Apr 2023 02:50:37 +0000 (19:50 -0700)
committerGitHub <noreply@github.com>
Tue, 4 Apr 2023 02:50:37 +0000 (19:50 -0700)
Content.Server/Speech/Components/DwarfAccentComponent.cs [deleted file]
Content.Server/Speech/Components/ReplacementAccentComponent.cs
Content.Server/Speech/EntitySystems/DwarfAccentSystem.cs [deleted file]
Content.Server/Speech/EntitySystems/MobsterAccentSystem.cs
Content.Server/Speech/EntitySystems/ReplacementAccentSystem.cs
Resources/Locale/en-US/accent/dwarf.ftl [new file with mode: 0644]
Resources/Locale/en-US/accent/mobster.ftl
Resources/Prototypes/Accents/full_replacements.yml [moved from Resources/Prototypes/accents.yml with 58% similarity]
Resources/Prototypes/Accents/word_replacements.yml [new file with mode: 0644]
Resources/Prototypes/Entities/Mobs/Species/dwarf.yml
Resources/keybinds.yml

diff --git a/Content.Server/Speech/Components/DwarfAccentComponent.cs b/Content.Server/Speech/Components/DwarfAccentComponent.cs
deleted file mode 100644 (file)
index 8760938..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Content.Server.Speech.Components;
-
-/// <summary>
-/// Used for replacing words for dwarves (pseudo-scottish)
-/// </summary>
-[RegisterComponent]
-public sealed class DwarfAccentComponent : Component
-{
-}
index d791675de4ee4e56142002890d5ee764367b24c7..ee3a102be3dd884e06aee224e83a9543003832c7 100644 (file)
@@ -10,12 +10,22 @@ namespace Content.Server.Speech.Components
         [IdDataField]
         public string ID { get; } = default!;
 
-        [DataField("words")]
-        public string[] Words = default!;
+        /// <summary>
+        ///     If this array is non-null, the full text of anything said will be randomly replaced with one of these words.
+        /// </summary>
+        [DataField("fullReplacements")]
+        public string[]? FullReplacements;
+
+        /// <summary>
+        ///     If this dictionary is non-null and <see cref="FullReplacements"/> is null, any keys surrounded by spaces
+        ///     (words) will be replaced by the value, attempting to intelligently keep capitalization.
+        /// </summary>
+        [DataField("wordReplacements")]
+        public Dictionary<string, string>? WordReplacements;
     }
 
     /// <summary>
-    /// Replaces any spoken sentences with a random word.
+    /// Replaces full sentences or words within sentences with new strings.
     /// </summary>
     [RegisterComponent]
     public sealed class ReplacementAccentComponent : Component
diff --git a/Content.Server/Speech/EntitySystems/DwarfAccentSystem.cs b/Content.Server/Speech/EntitySystems/DwarfAccentSystem.cs
deleted file mode 100644 (file)
index 4231f26..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-using System.Text.RegularExpressions;
-using Content.Server.Speech.Components;
-
-namespace Content.Server.Speech.EntitySystems;
-
-public sealed class DwarfAccentSystem : EntitySystem
-{
-    // TODO:
-    // these are pretty bad to have as static dicts in systems, ideally these all get moved to prototypes
-    // these can honestly stay unlocalized in prototypes? -- most of these word-replacers make zero sense to localize into other languages
-    // since they're so english-specific
-    // all of the 'word-replacers' should also probably respect capitalization when transformed, so all caps -> all caps
-    // and first letter capitalized -> first letter capitalized, at the very least
-
-    // these specifically mostly come from examples of specific scottish-english (not necessarily scots) verbiage
-    // https://en.wikipedia.org/wiki/Scotticism
-    // https://en.wikipedia.org/wiki/Scottish_English
-    // https://www.cs.stir.ac.uk/~kjt/general/scots.html
-    private static readonly Dictionary<string, string> DirectReplacements = new()
-    {
-        { "girl", "lassie" },
-        { "boy", "laddie" },
-        { "man", "lad" },
-        { "woman", "lass" },
-        { "do", "dae" },
-        { "don't", "dinnae" },
-        { "dont", "dinnae" },
-        { "i'm", "A'm" },
-        { "im", "am"},
-        { "going", "gaun" },
-        { "know", "ken"},
-        { "i", "Ah" },
-        { "you're", "ye're"},
-        { "youre", "yere"},
-        { "you", "ye" },
-        { "i'll", "A'll" },
-        { "ill", "all"},
-        { "of", "ae" },
-        { "was", "wis" },
-        { "can't", "cannae" },
-        { "cant", "cannae" },
-        { "yourself", "yersel" },
-        { "where", "whaur" },
-        { "oh", "ach" },
-        { "little", "wee" },
-        { "small", "wee" },
-        { "shit", "shite" },
-        { "yeah", "aye" },
-        { "yea", "aye"},
-        { "yes", "aye" },
-        { "too", "tae" },
-        { "my", "ma" },
-        { "not", "nae" },
-        { "dad", "da" },
-        { "mom", "maw" },
-    };
-
-    public override void Initialize()
-    {
-        base.Initialize();
-
-        SubscribeLocalEvent<DwarfAccentComponent, AccentGetEvent>(OnAccentGet);
-    }
-
-    public string Accentuate(string message)
-    {
-        // this is just word replacements right now,
-        // but leaving it open to more intelligent phonotactic manipulations at some point which are probably possible
-        var msg = message;
-
-        foreach (var (first, replace) in DirectReplacements)
-        {
-            msg = Regex.Replace(msg, $@"(?<!\w){first}(?!\w)", replace, RegexOptions.IgnoreCase);
-        }
-
-        return msg;
-    }
-
-    private void OnAccentGet(EntityUid uid, DwarfAccentComponent component, AccentGetEvent args)
-    {
-        args.Message = Accentuate(args.Message);
-    }
-}
index f7ff52d8243e38690e85c3a8cc6171b9f7ad0811..dfc3ab7e124ff04c97c09d3fe741d27148ee73c0 100644 (file)
@@ -8,6 +8,7 @@ namespace Content.Server.Speech.EntitySystems;
 public sealed class MobsterAccentSystem : EntitySystem
 {
     [Dependency] private readonly IRobustRandom _random = default!;
+    [Dependency] private readonly ReplacementAccentSystem _replacement = default!;
 
     private static readonly Dictionary<string, string> DirectReplacements = new()
     {
@@ -43,12 +44,8 @@ public sealed class MobsterAccentSystem : EntitySystem
         // Do text manipulations first
         // Then prefix/suffix funnyies
 
-        var msg = message;
-
-        foreach (var (first, replace) in DirectReplacements)
-        {
-            msg = Regex.Replace(msg, $@"(?<!\w){first}(?!\w)", replace, RegexOptions.IgnoreCase);
-        }
+        // direct word replacements
+        var msg = _replacement.ApplyReplacements(message, "mobster");
 
         // thinking -> thinkin'
         // king -> king
index 9834fba21bbc68251d9cb66020a7ebc97fc7899a..0671a25201f5d415a6d184e307c911aa28977ab9 100644 (file)
@@ -1,4 +1,7 @@
+using System.Linq;
+using System.Text.RegularExpressions;
 using Content.Server.Speech.Components;
+using JetBrains.Annotations;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Random;
 
@@ -6,12 +9,13 @@ namespace Content.Server.Speech.EntitySystems
 {
     // TODO: Code in-game languages and make this a language
     /// <summary>
-    /// Replaces any spoken sentences with a random word.
+    /// Replaces text in messages, either with full replacements or word replacements.
     /// </summary>
     public sealed class ReplacementAccentSystem : EntitySystem
     {
         [Dependency] private readonly IPrototypeManager _proto = default!;
         [Dependency] private readonly IRobustRandom _random = default!;
+        [Dependency] private readonly ILocalizationManager _loc = default!;
 
         public override void Initialize()
         {
@@ -20,9 +24,64 @@ namespace Content.Server.Speech.EntitySystems
 
         private void OnAccent(EntityUid uid, ReplacementAccentComponent component, AccentGetEvent args)
         {
-            var words = _proto.Index<ReplacementAccentPrototype>(component.Accent).Words;
+            args.Message = ApplyReplacements(args.Message, component.Accent);
+        }
+
+        /// <summary>
+        ///     Attempts to apply a given replacement accent prototype to a message.
+        /// </summary>
+        [PublicAPI]
+        public string ApplyReplacements(string message, string accent)
+        {
+            if (!_proto.TryIndex<ReplacementAccentPrototype>(accent, out var prototype))
+                return message;
+
+            // Prioritize fully replacing if that exists--
+            // ideally both aren't used at the same time (but we don't have a way to enforce that in serialization yet)
+            if (prototype.FullReplacements != null)
+            {
+                return prototype.FullReplacements.Length != 0 ? Loc.GetString(_random.Pick(prototype.FullReplacements)) : "";
+            }
+
+            if (prototype.WordReplacements == null)
+                return message;
+
+            foreach (var (first, replace) in prototype.WordReplacements)
+            {
+                var f = _loc.GetString(first);
+                var r = _loc.GetString(replace);
+                // this is kind of slow but its not that bad
+                // essentially: go over all matches, try to match capitalization where possible, then replace
+                // rather than using regex.replace
+                foreach (Match match in Regex.Matches(message, $@"(?<!\w){f}(?!\w)", RegexOptions.IgnoreCase))
+                {
+                    var replacement = r;
+
+                    // Intelligently replace capitalization
+                    // two cases where we will do so:
+                    // - the string is all upper case (just uppercase the replacement too)
+                    // - the first letter of the word is capitalized (common, just uppercase the first letter too)
+                    // any other cases are not really useful or not viable, since the match & replacement can be different
+                    // lengths
+
+                    // second expression here is weird--its specifically for single-word capitalization for I or A
+                    // dwarf expands I -> Ah, without that it would transform I -> AH
+                    // so that second case will only fully-uppercase if the replacement length is also 1
+                    if (!match.Value.Any(char.IsLower) && (match.Length > 1 || replacement.Length == 1))
+                    {
+                        replacement = replacement.ToUpperInvariant();
+                    }
+                    else if (match.Length >= 1 && replacement.Length >= 1 && char.IsUpper(match.Value[0]))
+                    {
+                        replacement = replacement[0].ToString().ToUpper() + replacement[1..];
+                    }
+
+                    // In-place replace the match with the transformed capitalization replacement
+                    message = message.Remove(match.Index, match.Length).Insert(match.Index, replacement);
+                }
+            }
 
-            args.Message = words.Length != 0 ? Loc.GetString(_random.Pick(words)) : "";
+            return message;
         }
     }
 }
diff --git a/Resources/Locale/en-US/accent/dwarf.ftl b/Resources/Locale/en-US/accent/dwarf.ftl
new file mode 100644 (file)
index 0000000..4467306
--- /dev/null
@@ -0,0 +1,109 @@
+# these specifically mostly come from examples of specific scottish-english (not necessarily scots) verbiage
+# https://en.wikipedia.org/wiki/Scotticism
+# https://en.wikipedia.org/wiki/Scottish_English
+# https://www.cs.stir.ac.uk/~kjt/general/scots.html
+
+accent-dwarf-words-1 = girl
+accent-dwarf-words-replace-1 = lassie
+
+accent-dwarf-words-2 = boy
+accent-dwarf-words-replace-2 = laddie
+
+accent-dwarf-words-3 = man
+accent-dwarf-words-replace-3 = lad
+
+accent-dwarf-words-4 = woman
+accent-dwarf-words-replace-4 = lass
+
+accent-dwarf-words-5 = do
+accent-dwarf-words-replace-5 = dae
+
+accent-dwarf-words-6 = don't
+accent-dwarf-words-replace-6 = dinnae
+
+accent-dwarf-words-7 = dont
+accent-dwarf-words-replace-7 = dinnae
+
+accent-dwarf-words-8 = i'm
+accent-dwarf-words-replace-8 = A'm
+
+accent-dwarf-words-9 = im
+accent-dwarf-words-replace-9 = am
+
+accent-dwarf-words-10 = going
+accent-dwarf-words-replace-10 = gaun
+
+accent-dwarf-words-11 = know
+accent-dwarf-words-replace-11 = ken
+
+accent-dwarf-words-12 = i
+accent-dwarf-words-replace-12 = Ah
+
+accent-dwarf-words-13 = you're
+accent-dwarf-words-replace-13 = ye're
+
+accent-dwarf-words-14 = youre
+accent-dwarf-words-replace-14 = yere
+
+accent-dwarf-words-15 = you
+accent-dwarf-words-replace-15 = ye
+
+accent-dwarf-words-16 = i'll
+accent-dwarf-words-replace-16 = A'll
+
+accent-dwarf-words-17 = ill
+accent-dwarf-words-replace-17 = all
+
+accent-dwarf-words-18 = of
+accent-dwarf-words-replace-18 = ae
+
+accent-dwarf-words-19 = was
+accent-dwarf-words-replace-19 = wis
+
+accent-dwarf-words-20 = can't
+accent-dwarf-words-replace-20 = cannae
+
+accent-dwarf-words-21 = cant
+accent-dwarf-words-replace-21 = cannae
+
+accent-dwarf-words-22 = yourself
+accent-dwarf-words-replace-22 = yersel
+
+accent-dwarf-words-23 = where
+accent-dwarf-words-replace-23 = whaur
+
+accent-dwarf-words-24 = oh
+accent-dwarf-words-replace-24 = ach
+
+accent-dwarf-words-25 = little
+accent-dwarf-words-replace-25 = wee
+
+accent-dwarf-words-26 = small
+accent-dwarf-words-replace-26 = wee
+
+accent-dwarf-words-27 = shit
+accent-dwarf-words-replace-27 = shite
+
+accent-dwarf-words-28 = yeah
+accent-dwarf-words-replace-28 = aye
+
+accent-dwarf-words-29 = yea
+accent-dwarf-words-replace-29 = aye
+
+accent-dwarf-words-30 = yes
+accent-dwarf-words-replace-30 = aye
+
+accent-dwarf-words-31 = too
+accent-dwarf-words-replace-31 = tae
+
+accent-dwarf-words-32 = my
+accent-dwarf-words-replace-32 = ma
+
+accent-dwarf-words-33 = not
+accent-dwarf-words-replace-33 = nae
+
+accent-dwarf-words-34 = dad
+accent-dwarf-words-replace-34 = da
+
+accent-dwarf-words-35 = mom
+accent-dwarf-words-replace-35 = maw
index 9aca97971bc40702bde54dc67cbae5b407df8ca4..d0f510453d2e74c9bc5bc03096fa80b7b3d4a81e 100644 (file)
@@ -6,3 +6,54 @@ accent-mobster-suffix-boss-3 = , capiche?
 
 accent-mobster-suffix-minion-1 = , yeah!
 accent-mobster-suffix-minion-2 = , boss says!
+
+accent-mobster-words-1 = let me
+accent-mobster-words-replace-1 = lemme
+
+accent-mobster-words-2 = should
+accent-mobster-words-replace-2 = oughta
+
+accent-mobster-words-3 = the
+accent-mobster-words-replace-3 = da
+
+accent-mobster-words-4 = them
+accent-mobster-words-replace-4 = dem
+
+accent-mobster-words-5 = attack
+accent-mobster-words-replace-5 = whack
+
+accent-mobster-words-6 = kill
+accent-mobster-words-replace-6 = whack
+
+accent-mobster-words-7 = murder
+accent-mobster-words-replace-7 = whack
+
+accent-mobster-words-8 = dead
+accent-mobster-words-replace-8 = sleepin' with da fishies
+
+accent-mobster-words-9 = hey
+accent-mobster-words-replace-9 = ey'o
+
+accent-mobster-words-10 = hi
+accent-mobster-words-replace-10 = ey'o
+
+accent-mobster-words-11 = hello
+accent-mobster-words-replace-11 = ey'o
+
+accent-mobster-words-12 = rules
+accent-mobster-words-replace-12 = roolz
+
+accent-mobster-words-13 = you
+accent-mobster-words-replace-13 = yous
+
+accent-mobster-words-14 = have to
+accent-mobster-words-replace-14 = gotta
+
+accent-mobster-words-15 = going to
+accent-mobster-words-replace-15 = boutta
+
+accent-mobster-words-16 = about to
+accent-mobster-words-replace-16 = boutta
+
+accent-mobster-words-17 = here
+accent-mobster-words-replace-17 = 'ere
similarity index 58%
rename from Resources/Prototypes/accents.yml
rename to Resources/Prototypes/Accents/full_replacements.yml
index b731559c89cdac949ac4e40d8af82147b27cff95..45ce49d6537e054c24f0221ef477ea4a0689776c 100644 (file)
@@ -1,6 +1,8 @@
+# Accents that work off of full replacements rather than word replacements.
+
 - type: accent
   id: cat
-  words:
+  fullReplacements:
   - accent-words-cat-1
   - accent-words-cat-2
   - accent-words-cat-3
@@ -9,7 +11,7 @@
 
 - type: accent
   id: dog
-  words:
+  fullReplacements:
   - accent-words-dog-1
   - accent-words-dog-2
   - accent-words-dog-3
@@ -18,7 +20,7 @@
 
 - type: accent
   id: mouse
-  words:
+  fullReplacements:
   - accent-words-mouse-1
   - accent-words-mouse-2
   - accent-words-mouse-3
 
 - type: accent
   id: mumble
-  words:
-    - accent-words-mumble-1
-    - accent-words-mumble-2
-    - accent-words-mumble-3
+  fullReplacements:
+  - accent-words-mumble-1
+  - accent-words-mumble-2
+  - accent-words-mumble-3
 
 - type: accent
   id: silicon
-  words:
-    - accent-words-silicon-1
-    - accent-words-silicon-2
-    - accent-words-silicon-3
-    - accent-words-silicon-4
+  fullReplacements:
+  - accent-words-silicon-1
+  - accent-words-silicon-2
+  - accent-words-silicon-3
+  - accent-words-silicon-4
 
 - type: accent
   id: xeno
-  words:
-    - accent-words-xeno-1
-    - accent-words-xeno-2
-    - accent-words-xeno-3
-    - accent-words-xeno-4
+  fullReplacements:
+  - accent-words-xeno-1
+  - accent-words-xeno-2
+  - accent-words-xeno-3
+  - accent-words-xeno-4
 
 - type: accent
   id: zombie
-  words:
-    - accent-words-zombie-1
-    - accent-words-zombie-2
-    - accent-words-zombie-3
-    - accent-words-zombie-4
-    - accent-words-zombie-5
-    - accent-words-zombie-6
-    - accent-words-zombie-7
+  fullReplacements:
+  - accent-words-zombie-1
+  - accent-words-zombie-2
+  - accent-words-zombie-3
+  - accent-words-zombie-4
+  - accent-words-zombie-5
+  - accent-words-zombie-6
+  - accent-words-zombie-7
 
 - type: accent
   id: genericAggressive
-  words:
+  fullReplacements:
   - accent-words-generic-aggressive-1
   - accent-words-generic-aggressive-2
   - accent-words-generic-aggressive-3
@@ -68,7 +70,7 @@
 
 - type: accent
   id: duck
-  words:
+  fullReplacements:
   - accent-words-duck-1
   - accent-words-duck-2
   - accent-words-duck-3
@@ -76,7 +78,7 @@
 
 - type: accent
   id: chicken
-  words:
+  fullReplacements:
   - accent-words-chicken-1
   - accent-words-chicken-2
   - accent-words-chicken-3
@@ -84,7 +86,7 @@
 
 - type: accent
   id: pig
-  words:
+  fullReplacements:
   - accent-words-pig-1
   - accent-words-pig-2
   - accent-words-pig-3
diff --git a/Resources/Prototypes/Accents/word_replacements.yml b/Resources/Prototypes/Accents/word_replacements.yml
new file mode 100644 (file)
index 0000000..2626bb0
--- /dev/null
@@ -0,0 +1,63 @@
+# Accents that work off of word replacements.
+
+# this is kind of dumb but localization demands it.
+# i guess you could just specify the prefix ('mobster') and count and let the system fill it
+- type: accent
+  id: mobster
+  wordReplacements:
+    accent-mobster-words-1: accent-mobster-words-replace-1
+    accent-mobster-words-2: accent-mobster-words-replace-2
+    accent-mobster-words-3: accent-mobster-words-replace-3
+    accent-mobster-words-4: accent-mobster-words-replace-4
+    accent-mobster-words-5: accent-mobster-words-replace-5
+    accent-mobster-words-6: accent-mobster-words-replace-6
+    accent-mobster-words-7: accent-mobster-words-replace-7
+    accent-mobster-words-8: accent-mobster-words-replace-8
+    accent-mobster-words-9: accent-mobster-words-replace-9
+    accent-mobster-words-10: accent-mobster-words-replace-10
+    accent-mobster-words-11: accent-mobster-words-replace-11
+    accent-mobster-words-12: accent-mobster-words-replace-12
+    accent-mobster-words-13: accent-mobster-words-replace-13
+    accent-mobster-words-14: accent-mobster-words-replace-14
+    accent-mobster-words-15: accent-mobster-words-replace-15
+    accent-mobster-words-16: accent-mobster-words-replace-16
+    accent-mobster-words-17: accent-mobster-words-replace-17
+
+- type: accent
+  id: dwarf
+  wordReplacements:
+    accent-dwarf-words-1: accent-dwarf-words-replace-1
+    accent-dwarf-words-2: accent-dwarf-words-replace-2
+    accent-dwarf-words-3: accent-dwarf-words-replace-3
+    accent-dwarf-words-4: accent-dwarf-words-replace-4
+    accent-dwarf-words-5: accent-dwarf-words-replace-5
+    accent-dwarf-words-6: accent-dwarf-words-replace-6
+    accent-dwarf-words-7: accent-dwarf-words-replace-7
+    accent-dwarf-words-8: accent-dwarf-words-replace-8
+    accent-dwarf-words-9: accent-dwarf-words-replace-9
+    accent-dwarf-words-10: accent-dwarf-words-replace-10
+    accent-dwarf-words-11: accent-dwarf-words-replace-11
+    accent-dwarf-words-12: accent-dwarf-words-replace-12
+    accent-dwarf-words-13: accent-dwarf-words-replace-13
+    accent-dwarf-words-14: accent-dwarf-words-replace-14
+    accent-dwarf-words-15: accent-dwarf-words-replace-15
+    accent-dwarf-words-16: accent-dwarf-words-replace-16
+    accent-dwarf-words-17: accent-dwarf-words-replace-17
+    accent-dwarf-words-18: accent-dwarf-words-replace-18
+    accent-dwarf-words-19: accent-dwarf-words-replace-19
+    accent-dwarf-words-20: accent-dwarf-words-replace-20
+    accent-dwarf-words-21: accent-dwarf-words-replace-21
+    accent-dwarf-words-22: accent-dwarf-words-replace-22
+    accent-dwarf-words-23: accent-dwarf-words-replace-23
+    accent-dwarf-words-24: accent-dwarf-words-replace-24
+    accent-dwarf-words-25: accent-dwarf-words-replace-25
+    accent-dwarf-words-26: accent-dwarf-words-replace-26
+    accent-dwarf-words-27: accent-dwarf-words-replace-27
+    accent-dwarf-words-28: accent-dwarf-words-replace-28
+    accent-dwarf-words-29: accent-dwarf-words-replace-29
+    accent-dwarf-words-30: accent-dwarf-words-replace-30
+    accent-dwarf-words-31: accent-dwarf-words-replace-31
+    accent-dwarf-words-32: accent-dwarf-words-replace-32
+    accent-dwarf-words-33: accent-dwarf-words-replace-33
+    accent-dwarf-words-34: accent-dwarf-words-replace-34
+    accent-dwarf-words-35: accent-dwarf-words-replace-35
index 15b226ded57066309a10adad6e5494559e4af808..e909368124be6c27469d197c2b8dc9231855b490 100644 (file)
@@ -42,7 +42,8 @@
       Male: UnisexDwarf
       Female: UnisexDwarf
       Unsexed: UnisexDwarf
-  - type: DwarfAccent
+  - type: ReplacementAccent
+    accent: dwarf
   - type: Speech
     speechSounds: Bass
 
index a4611f62f9014562d3fd8a24294d911e664efbc0..8fa3d13de68b9cdf797433ec7fba96457f36db66 100644 (file)
@@ -311,22 +311,6 @@ binds:
   type: State
   key: BackSpace
   canRepeat: true
-- function: TextDelete
-  type: State
-  key: Delete
-  canRepeat: true
-- function: TextWordBackspace
-  type: State
-  key: BackSpace
-  mod1: Control
-  canRepeat: true
-  allowSubCombs: true
-- function: TextWordDelete
-  type: State
-  key: Delete
-  mod1: Control
-  canRepeat: true
-  allowSubCombs: true
 - function: TextNewline
   type: State
   key: Return
@@ -384,6 +368,10 @@ binds:
 - function: TextScrollToBottom
   type: State
   key: PageDown
+- function: TextDelete
+  type: State
+  key: Delete
+  canRepeat: true
 - function: TextTabComplete
   type: State
   key: Tab