diff --git a/packages/altair-app/src/app/modules/altair/components/x-input/x-input.component.ts b/packages/altair-app/src/app/modules/altair/components/x-input/x-input.component.ts index 218731e686..e68a1a8e97 100644 --- a/packages/altair-app/src/app/modules/altair/components/x-input/x-input.component.ts +++ b/packages/altair-app/src/app/modules/altair/components/x-input/x-input.component.ts @@ -15,7 +15,13 @@ import { CompletionContext, completionKeymap, } from '@codemirror/autocomplete'; -import { EditorState, Extension, StateEffect, StateField } from '@codemirror/state'; +import { + ChangeSpec, + EditorState, + Extension, + StateEffect, + StateField, +} from '@codemirror/state'; import { Decoration, DecorationSet, @@ -126,7 +132,22 @@ export class XInputComponent implements AfterViewInit, ControlValueAccessor { }, }, }); + const filterNewLine = EditorState.transactionFilter.of((tr) => { + if (tr.changes.empty) return tr; + + if (tr.isUserEvent('input.paste')) { + // For paste events, replace newlines with spaces + const changes = [ + { + from: 0, + insert: tr.newDoc.toString().replace(/\n/g, ' '), + }, + ]; + return [{ changes }]; + } + + // Block multi-line input from other sources return tr.newDoc.lines > 1 ? [] : [tr]; });