Skip to content

Commit b36b6a0

Browse files
committed
Initial commit
0 parents  commit b36b6a0

9 files changed

Lines changed: 247 additions & 0 deletions

File tree

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Non-source code files
2+
UnityCtrlBackspace/libs
3+
UnityCtrlBackspace/bin
4+
UnityCtrlBackspace/obj
5+
6+
# IDE-specific files and folders
7+
.vs/
8+
.idea/
9+
*.DotSettings.user

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 RandomGuyJCI
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

NuGet.Config

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<configuration>
3+
<packageSources>
4+
<add key="BepInEx" value="https://nuget.bepinex.dev/v3/index.json" />
5+
</packageSources>
6+
</configuration>

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# UnityCtrlBackspace
2+
A BepInEx plugin that adds ctrl-backspace functionality to Unity input fields

UnityCtrlBackspace.sln

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.32228.343
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnityCtrlBackspace", "UnityCtrlBackspace\UnityCtrlBackspace.csproj", "{2A0810EB-A360-41E8-AF26-1DB364DBD3A2}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{2A0810EB-A360-41E8-AF26-1DB364DBD3A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{2A0810EB-A360-41E8-AF26-1DB364DBD3A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{2A0810EB-A360-41E8-AF26-1DB364DBD3A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{2A0810EB-A360-41E8-AF26-1DB364DBD3A2}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {41E8FE91-F325-4508-A17E-6C9C9F16CC8C}
24+
EndGlobalSection
25+
EndGlobal

UnityCtrlBackspace/Plugin.cs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Reflection.Emit;
4+
using BepInEx;
5+
using HarmonyLib;
6+
using UnityEngine.UI;
7+
8+
namespace UnityCtrlBackspace
9+
{
10+
[BepInPlugin("com.randomguyjci.unityctrlbackspace", "Ctrl-Backspace For Unity", "1.0.0")]
11+
public class Plugin : BaseUnityPlugin
12+
{
13+
private void Awake()
14+
{
15+
Harmony.CreateAndPatchAll(typeof(PatchInputField));
16+
}
17+
18+
public static class PatchInputField
19+
{
20+
private static bool isCtrlHeld = false;
21+
22+
[HarmonyTranspiler]
23+
[HarmonyPatch(typeof(InputField), "KeyPressed")]
24+
public static IEnumerable<CodeInstruction> KeyPressedTranspiler(IEnumerable<CodeInstruction> instructions)
25+
{
26+
return new CodeMatcher(instructions)
27+
.MatchForward(false,
28+
new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(InputField), "Backspace")))
29+
.InsertAndAdvance(
30+
new CodeInstruction(OpCodes.Ldloc_S, 4),
31+
new CodeInstruction(OpCodes.Stsfld, AccessTools.Field(typeof(PatchInputField), nameof(isCtrlHeld))))
32+
.InstructionEnumeration();
33+
}
34+
35+
[HarmonyPrefix]
36+
[HarmonyPatch(typeof(InputField), "Backspace")]
37+
public static bool Prefix(InputField __instance)
38+
{
39+
if (!__instance.m_ReadOnly)
40+
{
41+
if (__instance.hasSelection)
42+
{
43+
__instance.Delete();
44+
__instance.UpdateTouchKeyboardFromEditChanges();
45+
__instance.SendOnValueChangedAndUpdateLabel();
46+
}
47+
else if (__instance.caretPositionInternal > 0 && __instance.caretPositionInternal - 1 < __instance.text.Length)
48+
{
49+
if (isCtrlHeld)
50+
{
51+
BackspaceWord(ref __instance);
52+
}
53+
else
54+
{
55+
__instance.m_Text = __instance.text.Remove(__instance.caretPositionInternal - 1, 1);
56+
__instance.caretSelectPositionInternal = --__instance.caretPositionInternal;
57+
}
58+
__instance.UpdateTouchKeyboardFromEditChanges();
59+
__instance.SendOnValueChangedAndUpdateLabel();
60+
}
61+
}
62+
return false;
63+
}
64+
65+
private static void BackspaceWord(ref InputField __instance)
66+
{
67+
var newCaretPosition = ModifiedFindPrevWordBegin(__instance.m_Text, __instance.caretPositionInternal);
68+
var moveLength = __instance.caretPositionInternal - newCaretPosition;
69+
70+
__instance.m_Text = __instance.text.Remove(newCaretPosition, moveLength);
71+
__instance.caretPositionInternal = __instance.caretSelectPositionInternal = newCaretPosition;
72+
}
73+
74+
private static int ModifiedFindPrevWordBegin(string text, int caretPosition)
75+
{
76+
var lastCaretPosition = caretPosition - 1;
77+
78+
if (char.IsWhiteSpace(text[lastCaretPosition]))
79+
{
80+
for (; lastCaretPosition > 0; lastCaretPosition--)
81+
if (!char.IsWhiteSpace(text[lastCaretPosition])) break;
82+
}
83+
84+
if (char.IsLetterOrDigit(text[lastCaretPosition]))
85+
{
86+
for (; lastCaretPosition > 0; lastCaretPosition--)
87+
if (!char.IsLetterOrDigit(text[lastCaretPosition - 1])) break;
88+
}
89+
else
90+
{
91+
for (; lastCaretPosition > 0; lastCaretPosition--)
92+
if (char.IsLetterOrDigit(text[lastCaretPosition - 1]) || char.IsWhiteSpace(text[lastCaretPosition - 1])) break;
93+
}
94+
95+
return lastCaretPosition;
96+
}
97+
}
98+
}
99+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System.Reflection;
2+
using System.Runtime.InteropServices;
3+
4+
// General Information about an assembly is controlled through the following
5+
// set of attributes. Change these attribute values to modify the information
6+
// associated with an assembly.
7+
[assembly: AssemblyTitle("UnityCtrlBackspace")]
8+
[assembly: AssemblyDescription("")]
9+
[assembly: AssemblyConfiguration("")]
10+
[assembly: AssemblyCompany("")]
11+
[assembly: AssemblyProduct("UnityCtrlBackspace")]
12+
[assembly: AssemblyCopyright("Copyright © 2022")]
13+
[assembly: AssemblyTrademark("")]
14+
[assembly: AssemblyCulture("")]
15+
16+
// Setting ComVisible to false makes the types in this assembly not visible
17+
// to COM components. If you need to access a type in this assembly from
18+
// COM, set the ComVisible attribute to true on that type.
19+
[assembly: ComVisible(false)]
20+
21+
// The following GUID is for the ID of the typelib if this project is exposed to COM
22+
[assembly: Guid("43845617-1EA1-4A3D-9349-60807D6911CC")]
23+
24+
// Version information for an assembly consists of the following four values:
25+
//
26+
// Major Version
27+
// Minor Version
28+
// Build Number
29+
// Revision
30+
//
31+
// You can specify all the values or you can default the Build and Revision Numbers
32+
// by using the '*' as shown below:
33+
// [assembly: AssemblyVersion("1.0.*")]
34+
[assembly: AssemblyVersion("1.0.0.0")]
35+
[assembly: AssemblyFileVersion("1.0.0.0")]
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{2A0810EB-A360-41E8-AF26-1DB364DBD3A2}</ProjectGuid>
8+
<OutputType>Library</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>UnityCtrlBackspace</RootNamespace>
11+
<AssemblyName>UnityCtrlBackspace</AssemblyName>
12+
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
<Deterministic>true</Deterministic>
15+
</PropertyGroup>
16+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17+
<DebugSymbols>true</DebugSymbols>
18+
<DebugType>full</DebugType>
19+
<Optimize>false</Optimize>
20+
<OutputPath>bin\Debug\</OutputPath>
21+
<DefineConstants>DEBUG;TRACE</DefineConstants>
22+
<ErrorReport>prompt</ErrorReport>
23+
<WarningLevel>4</WarningLevel>
24+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
25+
</PropertyGroup>
26+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
27+
<DebugType>pdbonly</DebugType>
28+
<Optimize>true</Optimize>
29+
<OutputPath>bin\Release\</OutputPath>
30+
<DefineConstants>TRACE</DefineConstants>
31+
<ErrorReport>prompt</ErrorReport>
32+
<WarningLevel>4</WarningLevel>
33+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
34+
</PropertyGroup>
35+
<ItemGroup>
36+
<PackageReference Include="BepInEx.Core" Version="5.*" />
37+
</ItemGroup>
38+
<ItemGroup>
39+
<Compile Include="Plugin.cs" />
40+
<Compile Include="Properties\AssemblyInfo.cs" />
41+
</ItemGroup>
42+
<ItemGroup>
43+
<Reference Include="UnityEngine.UI">
44+
<HintPath>Libs\UnityEngine.UI-nstrip.dll</HintPath>
45+
</Reference>
46+
</ItemGroup>
47+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
48+
</Project>

0 commit comments

Comments
 (0)