diff --git a/src-web/components/RequestPane.tsx b/src-web/components/RequestPane.tsx index 72bcb92d..cd9829ec 100644 --- a/src-web/components/RequestPane.tsx +++ b/src-web/components/RequestPane.tsx @@ -39,6 +39,8 @@ import { HeadersEditor } from './HeadersEditor'; import { UrlBar } from './UrlBar'; import { UrlParametersEditor } from './UrlParameterEditor'; import { useImportCurl } from '../hooks/useImportCurl'; +import { useRequests } from '../hooks/useRequests'; +import type { GenericCompletionOption } from './core/Editor/genericCompletion'; interface Props { style: CSSProperties; @@ -55,6 +57,7 @@ export const RequestPane = memo(function RequestPane({ className, activeRequest, }: Props) { + const requests = useRequests(); const activeRequestId = activeRequest.id; const updateRequest = useUpdateHttpRequest(activeRequestId); const [activeTab, setActiveTab] = useActiveTab(); @@ -250,6 +253,24 @@ export const RequestPane = memo(function RequestPane({ } importCurl.mutate({ requestId: activeRequestId, command }); }} + autocomplete={{ + minMatch: 3, + options: + requests.length > 0 + ? [ + ...requests.map( + (r) => + ({ + type: 'constant', + label: r.url, + } as GenericCompletionOption), + ), + ] + : [ + { label: 'http://', type: 'constant' }, + { label: 'https://', type: 'constant' }, + ], + }} onSend={handleSend} onCancel={handleCancel} onMethodChange={handleMethodChange} diff --git a/src-web/components/UrlBar.tsx b/src-web/components/UrlBar.tsx index e765d462..52f04ec1 100644 --- a/src-web/components/UrlBar.tsx +++ b/src-web/components/UrlBar.tsx @@ -5,6 +5,7 @@ import { useHotKey } from '../hooks/useHotKey'; import type { HttpRequest } from '../lib/models'; import type { IconProps } from './core/Icon'; import { IconButton } from './core/IconButton'; +import type { InputProps } from './core/Input'; import { Input } from './core/Input'; import { RequestMethodDropdown } from './RequestMethodDropdown'; @@ -21,6 +22,7 @@ type Props = Pick & { isLoading: boolean; forceUpdateKey: string; rightSlot?: ReactNode; + autocomplete?: InputProps['autocomplete']; }; export const UrlBar = memo(function UrlBar({ @@ -35,6 +37,7 @@ export const UrlBar = memo(function UrlBar({ onMethodChange, onPaste, submitIcon = 'sendHorizontal', + autocomplete, rightSlot, isLoading, }: Props) { @@ -67,6 +70,7 @@ export const UrlBar = memo(function UrlBar({ className="pl-0 pr-1.5 py-0.5" name="url" label="Enter URL" + autocomplete={autocomplete} forceUpdateKey={forceUpdateKey} onFocus={() => setIsFocused(true)} onBlur={() => setIsFocused(false)} diff --git a/src-web/components/core/Editor/genericCompletion.ts b/src-web/components/core/Editor/genericCompletion.ts index 81464e34..fa6b4056 100644 --- a/src-web/components/core/Editor/genericCompletion.ts +++ b/src-web/components/core/Editor/genericCompletion.ts @@ -17,9 +17,12 @@ export interface GenericCompletionConfig { options: GenericCompletionOption[]; } +/** + * Complete options, always matching until the start of the line + */ export function genericCompletion({ options, minMatch = 1 }: GenericCompletionConfig) { return function completions(context: CompletionContext) { - const toMatch = context.matchBefore(/\w*/); + const toMatch = context.matchBefore(/.*/); // Only match if we're at the start of the line if (toMatch === null || toMatch.from > 0) return null; diff --git a/src-web/components/core/Editor/twig/extension.ts b/src-web/components/core/Editor/twig/extension.ts index 49fbaccd..4aa28166 100644 --- a/src-web/components/core/Editor/twig/extension.ts +++ b/src-web/components/core/Editor/twig/extension.ts @@ -21,20 +21,12 @@ export function twig( const completions = twigCompletion({ options: variables }); const language = mixLanguage(base); - const completion = language.data.of({ autocomplete: completions }); const completionBase = base.language.data.of({ autocomplete: completions }); const additionalCompletion = autocomplete - ? [language.data.of({ autocomplete: genericCompletion(autocomplete) })] + ? [base.language.data.of({ autocomplete: genericCompletion(autocomplete) })] : []; - return [ - language, - completion, - completionBase, - base.support, - placeholders(variables), - ...additionalCompletion, - ]; + return [language, completionBase, base.support, placeholders(variables), ...additionalCompletion]; } function mixLanguage(base: LanguageSupport): LRLanguage { diff --git a/src-web/components/core/Editor/url/extension.ts b/src-web/components/core/Editor/url/extension.ts index 0e40bf37..14aa10da 100644 --- a/src-web/components/core/Editor/url/extension.ts +++ b/src-web/components/core/Editor/url/extension.ts @@ -1,5 +1,4 @@ import { LanguageSupport, LRLanguage } from '@codemirror/language'; -import { completions } from './completion'; import { parser } from './url'; const urlLanguage = LRLanguage.define({ @@ -7,8 +6,6 @@ const urlLanguage = LRLanguage.define({ languageData: {}, }); -const completion = urlLanguage.data.of({ autocomplete: completions }); - export function url() { - return new LanguageSupport(urlLanguage, [completion]); + return new LanguageSupport(urlLanguage, []); }