Skip to content

Commit e06e93e

Browse files
authored
Merge pull request #4826 from gitbutlerapp/improve-commit-text-input
Improve the commit text content experience
2 parents 9ca174e + ee238fd commit e06e93e

File tree

2 files changed

+59
-23
lines changed

2 files changed

+59
-23
lines changed

apps/desktop/src/lib/commit/CommitMessageInput.svelte

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@
1616
import { autoHeight } from '$lib/utils/autoHeight';
1717
import { splitMessage } from '$lib/utils/commitMessage';
1818
import { getContext, getContextStore } from '$lib/utils/context';
19+
import { KeyName } from '$lib/utils/hotkeys';
1920
import { resizeObserver } from '$lib/utils/resizeObserver';
21+
import { isWhiteSpaceString } from '$lib/utils/string';
2022
import { Ownership } from '$lib/vbranches/ownership';
2123
import { VirtualBranch, LocalFile } from '$lib/vbranches/types';
2224
import Checkbox from '@gitbutler/ui/Checkbox.svelte';
2325
import Icon from '@gitbutler/ui/Icon.svelte';
2426
import Tooltip from '@gitbutler/ui/Tooltip.svelte';
25-
import { createEventDispatcher, onMount } from 'svelte';
27+
import { createEventDispatcher, onMount, tick } from 'svelte';
2628
import { fly } from 'svelte/transition';
2729
2830
export let isExpanded: boolean;
@@ -119,6 +121,56 @@
119121
onMount(async () => {
120122
aiConfigurationValid = await aiService.validateConfiguration($user?.access_token);
121123
});
124+
125+
function handleDescriptionKeyDown(e: KeyboardEvent & { currentTarget: HTMLTextAreaElement }) {
126+
const value = e.currentTarget.value;
127+
128+
if (e.key === KeyName.Delete && value.length === 0) {
129+
e.preventDefault();
130+
if (titleTextArea) {
131+
titleTextArea?.focus();
132+
titleTextArea.selectionStart = titleTextArea.textLength;
133+
}
134+
autoHeight(e.currentTarget);
135+
return;
136+
}
137+
138+
if (e.key === 'a' && (e.metaKey || e.ctrlKey) && value.length === 0) {
139+
// select previous textarea on cmd+a if this textarea is empty
140+
e.preventDefault();
141+
titleTextArea?.select();
142+
return;
143+
}
144+
}
145+
146+
function handleSummaryKeyDown(e: KeyboardEvent & { currentTarget: HTMLTextAreaElement }) {
147+
if (commit && (e.ctrlKey || e.metaKey) && e.key === KeyName.Enter) commit();
148+
if (e.key === KeyName.Enter) {
149+
e.preventDefault();
150+
151+
const caretStart = e.currentTarget.selectionStart;
152+
const caretEnd = e.currentTarget.selectionEnd;
153+
const value = e.currentTarget.value;
154+
155+
// if the caret is not at the end of the text, move the rest of the text to the description
156+
// get rid of the selected text
157+
if (caretStart < value.length || caretEnd < value.length) {
158+
const toKeep = value.slice(0, caretStart);
159+
const toMove = value.slice(caretEnd);
160+
const newDescription = isWhiteSpaceString(description)
161+
? toMove
162+
: `${toMove}\n${description}`;
163+
commitMessage = concatMessage(toKeep, newDescription);
164+
tick().then(() => {
165+
descriptionTextArea?.focus();
166+
descriptionTextArea.setSelectionRange(0, 0);
167+
autoHeight(descriptionTextArea);
168+
});
169+
}
170+
171+
descriptionTextArea?.focus();
172+
}
173+
}
122174
</script>
123175

124176
{#if isExpanded}
@@ -137,13 +189,7 @@
137189
commitMessage = concatMessage(e.currentTarget.value, description);
138190
autoHeight(e.currentTarget);
139191
}}
140-
on:keydown={(e) => {
141-
if (commit && (e.ctrlKey || e.metaKey) && e.key === 'Enter') commit();
142-
if (e.key === 'Enter') {
143-
e.preventDefault();
144-
descriptionTextArea?.focus();
145-
}
146-
}}
192+
on:keydown={handleSummaryKeyDown}
147193
></textarea>
148194

149195
{#if title.length > 0 || description}
@@ -160,21 +206,7 @@
160206
commitMessage = concatMessage(title, e.currentTarget.value);
161207
autoHeight(e.currentTarget);
162208
}}
163-
on:keydown={(e) => {
164-
const value = e.currentTarget.value;
165-
if (e.key === 'Backspace' && value.length === 0) {
166-
e.preventDefault();
167-
if (titleTextArea) {
168-
titleTextArea?.focus();
169-
titleTextArea.selectionStart = titleTextArea.textLength;
170-
}
171-
autoHeight(e.currentTarget);
172-
} else if (e.key === 'a' && (e.metaKey || e.ctrlKey) && value.length === 0) {
173-
// select previous textarea on cmd+a if this textarea is empty
174-
e.preventDefault();
175-
titleTextArea?.select();
176-
}
177-
}}
209+
on:keydown={handleDescriptionKeyDown}
178210
></textarea>
179211
{/if}
180212

apps/desktop/src/lib/utils/string.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,7 @@ export function isChar(char: string) {
1919
export function isStr(s: unknown): s is string {
2020
return typeof s === 'string';
2121
}
22+
23+
export function isWhiteSpaceString(s: string) {
24+
return s.trim() === '';
25+
}

0 commit comments

Comments
 (0)