mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-23 09:08:32 +02:00
Autocomplete URLs of other requests
This commit is contained in:
@@ -39,6 +39,8 @@ import { HeadersEditor } from './HeadersEditor';
|
|||||||
import { UrlBar } from './UrlBar';
|
import { UrlBar } from './UrlBar';
|
||||||
import { UrlParametersEditor } from './UrlParameterEditor';
|
import { UrlParametersEditor } from './UrlParameterEditor';
|
||||||
import { useImportCurl } from '../hooks/useImportCurl';
|
import { useImportCurl } from '../hooks/useImportCurl';
|
||||||
|
import { useRequests } from '../hooks/useRequests';
|
||||||
|
import type { GenericCompletionOption } from './core/Editor/genericCompletion';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
style: CSSProperties;
|
style: CSSProperties;
|
||||||
@@ -55,6 +57,7 @@ export const RequestPane = memo(function RequestPane({
|
|||||||
className,
|
className,
|
||||||
activeRequest,
|
activeRequest,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
|
const requests = useRequests();
|
||||||
const activeRequestId = activeRequest.id;
|
const activeRequestId = activeRequest.id;
|
||||||
const updateRequest = useUpdateHttpRequest(activeRequestId);
|
const updateRequest = useUpdateHttpRequest(activeRequestId);
|
||||||
const [activeTab, setActiveTab] = useActiveTab();
|
const [activeTab, setActiveTab] = useActiveTab();
|
||||||
@@ -250,6 +253,24 @@ export const RequestPane = memo(function RequestPane({
|
|||||||
}
|
}
|
||||||
importCurl.mutate({ requestId: activeRequestId, command });
|
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}
|
onSend={handleSend}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
onMethodChange={handleMethodChange}
|
onMethodChange={handleMethodChange}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { useHotKey } from '../hooks/useHotKey';
|
|||||||
import type { HttpRequest } from '../lib/models';
|
import type { HttpRequest } from '../lib/models';
|
||||||
import type { IconProps } from './core/Icon';
|
import type { IconProps } from './core/Icon';
|
||||||
import { IconButton } from './core/IconButton';
|
import { IconButton } from './core/IconButton';
|
||||||
|
import type { InputProps } from './core/Input';
|
||||||
import { Input } from './core/Input';
|
import { Input } from './core/Input';
|
||||||
import { RequestMethodDropdown } from './RequestMethodDropdown';
|
import { RequestMethodDropdown } from './RequestMethodDropdown';
|
||||||
|
|
||||||
@@ -21,6 +22,7 @@ type Props = Pick<HttpRequest, 'url'> & {
|
|||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
forceUpdateKey: string;
|
forceUpdateKey: string;
|
||||||
rightSlot?: ReactNode;
|
rightSlot?: ReactNode;
|
||||||
|
autocomplete?: InputProps['autocomplete'];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const UrlBar = memo(function UrlBar({
|
export const UrlBar = memo(function UrlBar({
|
||||||
@@ -35,6 +37,7 @@ export const UrlBar = memo(function UrlBar({
|
|||||||
onMethodChange,
|
onMethodChange,
|
||||||
onPaste,
|
onPaste,
|
||||||
submitIcon = 'sendHorizontal',
|
submitIcon = 'sendHorizontal',
|
||||||
|
autocomplete,
|
||||||
rightSlot,
|
rightSlot,
|
||||||
isLoading,
|
isLoading,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
@@ -67,6 +70,7 @@ export const UrlBar = memo(function UrlBar({
|
|||||||
className="pl-0 pr-1.5 py-0.5"
|
className="pl-0 pr-1.5 py-0.5"
|
||||||
name="url"
|
name="url"
|
||||||
label="Enter URL"
|
label="Enter URL"
|
||||||
|
autocomplete={autocomplete}
|
||||||
forceUpdateKey={forceUpdateKey}
|
forceUpdateKey={forceUpdateKey}
|
||||||
onFocus={() => setIsFocused(true)}
|
onFocus={() => setIsFocused(true)}
|
||||||
onBlur={() => setIsFocused(false)}
|
onBlur={() => setIsFocused(false)}
|
||||||
|
|||||||
@@ -17,9 +17,12 @@ export interface GenericCompletionConfig {
|
|||||||
options: GenericCompletionOption[];
|
options: GenericCompletionOption[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complete options, always matching until the start of the line
|
||||||
|
*/
|
||||||
export function genericCompletion({ options, minMatch = 1 }: GenericCompletionConfig) {
|
export function genericCompletion({ options, minMatch = 1 }: GenericCompletionConfig) {
|
||||||
return function completions(context: CompletionContext) {
|
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
|
// Only match if we're at the start of the line
|
||||||
if (toMatch === null || toMatch.from > 0) return null;
|
if (toMatch === null || toMatch.from > 0) return null;
|
||||||
|
|||||||
@@ -21,20 +21,12 @@ export function twig(
|
|||||||
const completions = twigCompletion({ options: variables });
|
const completions = twigCompletion({ options: variables });
|
||||||
|
|
||||||
const language = mixLanguage(base);
|
const language = mixLanguage(base);
|
||||||
const completion = language.data.of({ autocomplete: completions });
|
|
||||||
const completionBase = base.language.data.of({ autocomplete: completions });
|
const completionBase = base.language.data.of({ autocomplete: completions });
|
||||||
const additionalCompletion = autocomplete
|
const additionalCompletion = autocomplete
|
||||||
? [language.data.of({ autocomplete: genericCompletion(autocomplete) })]
|
? [base.language.data.of({ autocomplete: genericCompletion(autocomplete) })]
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
return [
|
return [language, completionBase, base.support, placeholders(variables), ...additionalCompletion];
|
||||||
language,
|
|
||||||
completion,
|
|
||||||
completionBase,
|
|
||||||
base.support,
|
|
||||||
placeholders(variables),
|
|
||||||
...additionalCompletion,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function mixLanguage(base: LanguageSupport): LRLanguage {
|
function mixLanguage(base: LanguageSupport): LRLanguage {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { LanguageSupport, LRLanguage } from '@codemirror/language';
|
import { LanguageSupport, LRLanguage } from '@codemirror/language';
|
||||||
import { completions } from './completion';
|
|
||||||
import { parser } from './url';
|
import { parser } from './url';
|
||||||
|
|
||||||
const urlLanguage = LRLanguage.define({
|
const urlLanguage = LRLanguage.define({
|
||||||
@@ -7,8 +6,6 @@ const urlLanguage = LRLanguage.define({
|
|||||||
languageData: {},
|
languageData: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const completion = urlLanguage.data.of({ autocomplete: completions });
|
|
||||||
|
|
||||||
export function url() {
|
export function url() {
|
||||||
return new LanguageSupport(urlLanguage, [completion]);
|
return new LanguageSupport(urlLanguage, []);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user