mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-07-09 06:15:08 +02:00
Vim/emacs/vscode keybindings
This commit is contained in:
Generated
+44
@@ -1782,6 +1782,47 @@
|
|||||||
"integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==",
|
"integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@replit/codemirror-emacs": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@replit/codemirror-emacs/-/codemirror-emacs-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-74DITnht6Cs6sHg02PQ169IKb1XgtyhI9sLD0JeOFco6Ds18PT+dkD8+DgXBDokne9UIFKsBbKPnpFRAz60/Lw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@codemirror/autocomplete": "^6.0.2",
|
||||||
|
"@codemirror/commands": "^6.0.0",
|
||||||
|
"@codemirror/search": "^6.0.0",
|
||||||
|
"@codemirror/state": "^6.0.1",
|
||||||
|
"@codemirror/view": "^6.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@replit/codemirror-vim": {
|
||||||
|
"version": "6.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@replit/codemirror-vim/-/codemirror-vim-6.2.1.tgz",
|
||||||
|
"integrity": "sha512-qDAcGSHBYU5RrdO//qCmD8K9t6vbP327iCj/iqrkVnjbrpFhrjOt92weGXGHmTNRh16cUtkUZ7Xq7rZf+8HVow==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@codemirror/commands": "^6.0.0",
|
||||||
|
"@codemirror/language": "^6.1.0",
|
||||||
|
"@codemirror/search": "^6.2.0",
|
||||||
|
"@codemirror/state": "^6.0.1",
|
||||||
|
"@codemirror/view": "^6.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@replit/codemirror-vscode-keymap": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@replit/codemirror-vscode-keymap/-/codemirror-vscode-keymap-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-j45qTwGxzpsv82lMD/NreGDORFKSctMDVkGRopaP+OrzSzv+pXDQuU3LnFvKpasyjVT0lf+PKG1v2DSCn/vxxg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@codemirror/autocomplete": "^6.0.0",
|
||||||
|
"@codemirror/commands": "^6.0.0",
|
||||||
|
"@codemirror/language": "^6.0.0",
|
||||||
|
"@codemirror/lint": "^6.0.0",
|
||||||
|
"@codemirror/search": "^6.0.0",
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"@codemirror/view": "^6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rollup/plugin-virtual": {
|
"node_modules/@rollup/plugin-virtual": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.2.tgz",
|
||||||
@@ -15878,6 +15919,9 @@
|
|||||||
"@gilbarbara/deep-equal": "^0.3.1",
|
"@gilbarbara/deep-equal": "^0.3.1",
|
||||||
"@lezer/highlight": "^1.1.3",
|
"@lezer/highlight": "^1.1.3",
|
||||||
"@lezer/lr": "^1.3.3",
|
"@lezer/lr": "^1.3.3",
|
||||||
|
"@replit/codemirror-emacs": "^6.1.0",
|
||||||
|
"@replit/codemirror-vim": "^6.2.1",
|
||||||
|
"@replit/codemirror-vscode-keymap": "^6.0.2",
|
||||||
"@tailwindcss/container-queries": "^0.1.1",
|
"@tailwindcss/container-queries": "^0.1.1",
|
||||||
"@tanstack/react-query": "^5.62.16",
|
"@tanstack/react-query": "^5.62.16",
|
||||||
"@tanstack/react-router": "^1.95.1",
|
"@tanstack/react-router": "^1.95.1",
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE settings
|
||||||
|
ADD COLUMN editor_keymap TEXT DEFAULT 'codemirror' NOT NULL;
|
||||||
@@ -1,250 +1,61 @@
|
|||||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||||
|
|
||||||
export type AnyModel =
|
export type AnyModel = CookieJar | Environment | Folder | GrpcConnection | GrpcEvent | GrpcRequest | HttpRequest | HttpResponse | Plugin | Settings | KeyValue | Workspace;
|
||||||
| CookieJar
|
|
||||||
| Environment
|
|
||||||
| Folder
|
|
||||||
| GrpcConnection
|
|
||||||
| GrpcEvent
|
|
||||||
| GrpcRequest
|
|
||||||
| HttpRequest
|
|
||||||
| HttpResponse
|
|
||||||
| Plugin
|
|
||||||
| Settings
|
|
||||||
| KeyValue
|
|
||||||
| Workspace;
|
|
||||||
|
|
||||||
export type Cookie = {
|
export type Cookie = { raw_cookie: string, domain: CookieDomain, expires: CookieExpires, path: [string, boolean], };
|
||||||
raw_cookie: string;
|
|
||||||
domain: CookieDomain;
|
|
||||||
expires: CookieExpires;
|
|
||||||
path: [string, boolean];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type CookieDomain = { HostOnly: string } | { Suffix: string } | 'NotPresent' | 'Empty';
|
export type CookieDomain = { "HostOnly": string } | { "Suffix": string } | "NotPresent" | "Empty";
|
||||||
|
|
||||||
export type CookieExpires = { AtUtc: string } | 'SessionEnd';
|
export type CookieExpires = { "AtUtc": string } | "SessionEnd";
|
||||||
|
|
||||||
export type CookieJar = {
|
export type CookieJar = { model: "cookie_jar", id: string, createdAt: string, updatedAt: string, workspaceId: string, cookies: Array<Cookie>, name: string, };
|
||||||
model: 'cookie_jar';
|
|
||||||
id: string;
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
workspaceId: string;
|
|
||||||
cookies: Array<Cookie>;
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Environment = {
|
export type EditorKeymap = "default" | "vim" | "vscode" | "emacs";
|
||||||
model: 'environment';
|
|
||||||
id: string;
|
|
||||||
workspaceId: string;
|
|
||||||
environmentId: string | null;
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
name: string;
|
|
||||||
variables: Array<EnvironmentVariable>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type EnvironmentVariable = { enabled?: boolean; name: string; value: string; id: string };
|
export type Environment = { model: "environment", id: string, workspaceId: string, environmentId: string | null, createdAt: string, updatedAt: string, name: string, variables: Array<EnvironmentVariable>, };
|
||||||
|
|
||||||
export type Folder = {
|
export type EnvironmentVariable = { enabled?: boolean, name: string, value: string, id: string, };
|
||||||
model: 'folder';
|
|
||||||
id: string;
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
workspaceId: string;
|
|
||||||
folderId: string | null;
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
sortPriority: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type GrpcConnection = {
|
export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, name: string, description: string, sortPriority: number, };
|
||||||
model: 'grpc_connection';
|
|
||||||
id: string;
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
workspaceId: string;
|
|
||||||
requestId: string;
|
|
||||||
elapsed: number;
|
|
||||||
error: string | null;
|
|
||||||
method: string;
|
|
||||||
service: string;
|
|
||||||
status: number;
|
|
||||||
state: GrpcConnectionState;
|
|
||||||
trailers: { [key in string]?: string };
|
|
||||||
url: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type GrpcConnectionState = 'initialized' | 'connected' | 'closed';
|
export type GrpcConnection = { model: "grpc_connection", id: string, createdAt: string, updatedAt: string, workspaceId: string, requestId: string, elapsed: number, error: string | null, method: string, service: string, status: number, state: GrpcConnectionState, trailers: { [key in string]?: string }, url: string, };
|
||||||
|
|
||||||
export type GrpcEvent = {
|
export type GrpcConnectionState = "initialized" | "connected" | "closed";
|
||||||
model: 'grpc_event';
|
|
||||||
id: string;
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
workspaceId: string;
|
|
||||||
requestId: string;
|
|
||||||
connectionId: string;
|
|
||||||
content: string;
|
|
||||||
error: string | null;
|
|
||||||
eventType: GrpcEventType;
|
|
||||||
metadata: { [key in string]?: string };
|
|
||||||
status: number | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type GrpcEventType =
|
export type GrpcEvent = { model: "grpc_event", id: string, createdAt: string, updatedAt: string, workspaceId: string, requestId: string, connectionId: string, content: string, error: string | null, eventType: GrpcEventType, metadata: { [key in string]?: string }, status: number | null, };
|
||||||
| 'info'
|
|
||||||
| 'error'
|
|
||||||
| 'client_message'
|
|
||||||
| 'server_message'
|
|
||||||
| 'connection_start'
|
|
||||||
| 'connection_end';
|
|
||||||
|
|
||||||
export type GrpcMetadataEntry = { enabled?: boolean; name: string; value: string; id: string };
|
export type GrpcEventType = "info" | "error" | "client_message" | "server_message" | "connection_start" | "connection_end";
|
||||||
|
|
||||||
export type GrpcRequest = {
|
export type GrpcMetadataEntry = { enabled?: boolean, name: string, value: string, id: string, };
|
||||||
model: 'grpc_request';
|
|
||||||
id: string;
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
workspaceId: string;
|
|
||||||
folderId: string | null;
|
|
||||||
authenticationType: string | null;
|
|
||||||
authentication: Record<string, any>;
|
|
||||||
description: string;
|
|
||||||
message: string;
|
|
||||||
metadata: Array<GrpcMetadataEntry>;
|
|
||||||
method: string | null;
|
|
||||||
name: string;
|
|
||||||
service: string | null;
|
|
||||||
sortPriority: number;
|
|
||||||
url: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type HttpRequest = {
|
export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record<string, any>, description: string, message: string, metadata: Array<GrpcMetadataEntry>, method: string | null, name: string, service: string | null, sortPriority: number, url: string, };
|
||||||
model: 'http_request';
|
|
||||||
id: string;
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
workspaceId: string;
|
|
||||||
folderId: string | null;
|
|
||||||
authentication: Record<string, any>;
|
|
||||||
authenticationType: string | null;
|
|
||||||
body: Record<string, any>;
|
|
||||||
bodyType: string | null;
|
|
||||||
description: string;
|
|
||||||
headers: Array<HttpRequestHeader>;
|
|
||||||
method: string;
|
|
||||||
name: string;
|
|
||||||
sortPriority: number;
|
|
||||||
url: string;
|
|
||||||
urlParameters: Array<HttpUrlParameter>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type HttpRequestHeader = { enabled?: boolean; name: string; value: string; id: string };
|
export type HttpRequest = { model: "http_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record<string, any>, authenticationType: string | null, body: Record<string, any>, bodyType: string | null, description: string, headers: Array<HttpRequestHeader>, method: string, name: string, sortPriority: number, url: string, urlParameters: Array<HttpUrlParameter>, };
|
||||||
|
|
||||||
export type HttpResponse = {
|
export type HttpRequestHeader = { enabled?: boolean, name: string, value: string, id: string, };
|
||||||
model: 'http_response';
|
|
||||||
id: string;
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
workspaceId: string;
|
|
||||||
requestId: string;
|
|
||||||
bodyPath: string | null;
|
|
||||||
contentLength: number | null;
|
|
||||||
elapsed: number;
|
|
||||||
elapsedHeaders: number;
|
|
||||||
error: string | null;
|
|
||||||
headers: Array<HttpResponseHeader>;
|
|
||||||
remoteAddr: string | null;
|
|
||||||
status: number;
|
|
||||||
statusReason: string | null;
|
|
||||||
state: HttpResponseState;
|
|
||||||
url: string;
|
|
||||||
version: string | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type HttpResponseHeader = { name: string; value: string };
|
export type HttpResponse = { model: "http_response", id: string, createdAt: string, updatedAt: string, workspaceId: string, requestId: string, bodyPath: string | null, contentLength: number | null, elapsed: number, elapsedHeaders: number, error: string | null, headers: Array<HttpResponseHeader>, remoteAddr: string | null, status: number, statusReason: string | null, state: HttpResponseState, url: string, version: string | null, };
|
||||||
|
|
||||||
export type HttpResponseState = 'initialized' | 'connected' | 'closed';
|
export type HttpResponseHeader = { name: string, value: string, };
|
||||||
|
|
||||||
export type HttpUrlParameter = { enabled?: boolean; name: string; value: string; id: string };
|
export type HttpResponseState = "initialized" | "connected" | "closed";
|
||||||
|
|
||||||
export type KeyValue = {
|
export type HttpUrlParameter = { enabled?: boolean, name: string, value: string, id: string, };
|
||||||
model: 'key_value';
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
key: string;
|
|
||||||
namespace: string;
|
|
||||||
value: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ModelPayload = { model: AnyModel; windowLabel: string; updateSource: UpdateSource };
|
export type KeyValue = { model: "key_value", createdAt: string, updatedAt: string, key: string, namespace: string, value: string, };
|
||||||
|
|
||||||
export type Plugin = {
|
export type ModelPayload = { model: AnyModel, windowLabel: string, updateSource: UpdateSource, };
|
||||||
model: 'plugin';
|
|
||||||
id: string;
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
checkedAt: string | null;
|
|
||||||
directory: string;
|
|
||||||
enabled: boolean;
|
|
||||||
url: string | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ProxySetting =
|
export type Plugin = { model: "plugin", id: string, createdAt: string, updatedAt: string, checkedAt: string | null, directory: string, enabled: boolean, url: string | null, };
|
||||||
| { type: 'enabled'; http: string; https: string; auth: ProxySettingAuth | null }
|
|
||||||
| {
|
|
||||||
type: 'disabled';
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ProxySettingAuth = { user: string; password: string };
|
export type ProxySetting = { "type": "enabled", http: string, https: string, auth: ProxySettingAuth | null, } | { "type": "disabled" };
|
||||||
|
|
||||||
export type Settings = {
|
export type ProxySettingAuth = { user: string, password: string, };
|
||||||
model: 'settings';
|
|
||||||
id: string;
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
appearance: string;
|
|
||||||
editorFontSize: number;
|
|
||||||
editorSoftWrap: boolean;
|
|
||||||
interfaceFontSize: number;
|
|
||||||
interfaceScale: number;
|
|
||||||
openWorkspaceNewWindow: boolean | null;
|
|
||||||
telemetry: boolean;
|
|
||||||
theme: string;
|
|
||||||
themeDark: string;
|
|
||||||
themeLight: string;
|
|
||||||
updateChannel: string;
|
|
||||||
proxy: ProxySetting | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type SyncState = {
|
export type Settings = { model: "settings", id: string, createdAt: string, updatedAt: string, appearance: string, editorFontSize: number, editorSoftWrap: boolean, interfaceFontSize: number, interfaceScale: number, openWorkspaceNewWindow: boolean | null, proxy: ProxySetting | null, telemetry: boolean, theme: string, themeDark: string, themeLight: string, updateChannel: string, editorKeymap: EditorKeymap, };
|
||||||
model: 'sync_state';
|
|
||||||
id: string;
|
|
||||||
workspaceId: string;
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
flushedAt: string;
|
|
||||||
modelId: string;
|
|
||||||
checksum: string;
|
|
||||||
relPath: string;
|
|
||||||
syncDir: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type UpdateSource = 'sync' | 'window' | 'plugin' | 'background';
|
export type SyncState = { model: "sync_state", id: string, workspaceId: string, createdAt: string, updatedAt: string, flushedAt: string, modelId: string, checksum: string, relPath: string, syncDir: string, };
|
||||||
|
|
||||||
export type Workspace = {
|
export type UpdateSource = "sync" | "window" | "plugin" | "background";
|
||||||
model: 'workspace';
|
|
||||||
id: string;
|
export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, settingSyncDir: string | null, };
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
settingValidateCertificates: boolean;
|
|
||||||
settingFollowRedirects: boolean;
|
|
||||||
settingRequestTimeout: number;
|
|
||||||
settingSyncDir: string | null;
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ use sea_query::Iden;
|
|||||||
use serde::{Deserialize, Deserializer, Serialize};
|
use serde::{Deserialize, Deserializer, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use std::fmt::Display;
|
||||||
|
use std::str::FromStr;
|
||||||
use ts_rs::TS;
|
use ts_rs::TS;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||||
@@ -26,6 +28,48 @@ pub struct ProxySettingAuth {
|
|||||||
pub password: String,
|
pub password: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
#[ts(export, export_to = "models.ts")]
|
||||||
|
pub enum EditorKeymap {
|
||||||
|
Default,
|
||||||
|
Vim,
|
||||||
|
Vscode,
|
||||||
|
Emacs,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for EditorKeymap {
|
||||||
|
type Err = ();
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
match s {
|
||||||
|
"default" => Ok(Self::Default),
|
||||||
|
"vscode" => Ok(Self::Vscode),
|
||||||
|
"vim" => Ok(Self::Vim),
|
||||||
|
"emacs" => Ok(Self::Emacs),
|
||||||
|
_ => Ok(Self::default()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for EditorKeymap {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let str = match self {
|
||||||
|
EditorKeymap::Default => "default".to_string(),
|
||||||
|
EditorKeymap::Vscode => "vscode".to_string(),
|
||||||
|
EditorKeymap::Vim => "vim".to_string(),
|
||||||
|
EditorKeymap::Emacs => "emacs".to_string(),
|
||||||
|
};
|
||||||
|
write!(f, "{}", str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for EditorKeymap {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to = "models.ts")]
|
#[ts(export, export_to = "models.ts")]
|
||||||
@@ -42,12 +86,13 @@ pub struct Settings {
|
|||||||
pub interface_font_size: i32,
|
pub interface_font_size: i32,
|
||||||
pub interface_scale: f32,
|
pub interface_scale: f32,
|
||||||
pub open_workspace_new_window: Option<bool>,
|
pub open_workspace_new_window: Option<bool>,
|
||||||
|
pub proxy: Option<ProxySetting>,
|
||||||
pub telemetry: bool,
|
pub telemetry: bool,
|
||||||
pub theme: String,
|
pub theme: String,
|
||||||
pub theme_dark: String,
|
pub theme_dark: String,
|
||||||
pub theme_light: String,
|
pub theme_light: String,
|
||||||
pub update_channel: String,
|
pub update_channel: String,
|
||||||
pub proxy: Option<ProxySetting>,
|
pub editor_keymap: EditorKeymap,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Iden)]
|
#[derive(Iden)]
|
||||||
@@ -61,6 +106,7 @@ pub enum SettingsIden {
|
|||||||
|
|
||||||
Appearance,
|
Appearance,
|
||||||
EditorFontSize,
|
EditorFontSize,
|
||||||
|
EditorKeymap,
|
||||||
EditorSoftWrap,
|
EditorSoftWrap,
|
||||||
InterfaceFontSize,
|
InterfaceFontSize,
|
||||||
InterfaceScale,
|
InterfaceScale,
|
||||||
@@ -78,6 +124,7 @@ impl<'s> TryFrom<&Row<'s>> for Settings {
|
|||||||
|
|
||||||
fn try_from(r: &Row<'s>) -> Result<Self, Self::Error> {
|
fn try_from(r: &Row<'s>) -> Result<Self, Self::Error> {
|
||||||
let proxy: Option<String> = r.get("proxy")?;
|
let proxy: Option<String> = r.get("proxy")?;
|
||||||
|
let editor_keymap: String = r.get("editor_keymap")?;
|
||||||
Ok(Settings {
|
Ok(Settings {
|
||||||
id: r.get("id")?,
|
id: r.get("id")?,
|
||||||
model: r.get("model")?,
|
model: r.get("model")?,
|
||||||
@@ -85,6 +132,7 @@ impl<'s> TryFrom<&Row<'s>> for Settings {
|
|||||||
updated_at: r.get("updated_at")?,
|
updated_at: r.get("updated_at")?,
|
||||||
appearance: r.get("appearance")?,
|
appearance: r.get("appearance")?,
|
||||||
editor_font_size: r.get("editor_font_size")?,
|
editor_font_size: r.get("editor_font_size")?,
|
||||||
|
editor_keymap: EditorKeymap::from_str(editor_keymap.as_str()).unwrap(),
|
||||||
editor_soft_wrap: r.get("editor_soft_wrap")?,
|
editor_soft_wrap: r.get("editor_soft_wrap")?,
|
||||||
interface_font_size: r.get("interface_font_size")?,
|
interface_font_size: r.get("interface_font_size")?,
|
||||||
interface_scale: r.get("interface_scale")?,
|
interface_scale: r.get("interface_scale")?,
|
||||||
@@ -1043,9 +1091,7 @@ impl<'de> Deserialize<'de> for AnyModel {
|
|||||||
Some(m) if m == "environment" => {
|
Some(m) if m == "environment" => {
|
||||||
AnyModel::Environment(serde_json::from_value(value).unwrap())
|
AnyModel::Environment(serde_json::from_value(value).unwrap())
|
||||||
}
|
}
|
||||||
Some(m) if m == "folder" => {
|
Some(m) if m == "folder" => AnyModel::Folder(serde_json::from_value(value).unwrap()),
|
||||||
AnyModel::Folder(serde_json::from_value(value).unwrap())
|
|
||||||
}
|
|
||||||
Some(m) if m == "key_value" => {
|
Some(m) if m == "key_value" => {
|
||||||
AnyModel::KeyValue(serde_json::from_value(value).unwrap())
|
AnyModel::KeyValue(serde_json::from_value(value).unwrap())
|
||||||
}
|
}
|
||||||
@@ -1058,9 +1104,7 @@ impl<'de> Deserialize<'de> for AnyModel {
|
|||||||
Some(m) if m == "cookie_jar" => {
|
Some(m) if m == "cookie_jar" => {
|
||||||
AnyModel::CookieJar(serde_json::from_value(value).unwrap())
|
AnyModel::CookieJar(serde_json::from_value(value).unwrap())
|
||||||
}
|
}
|
||||||
Some(m) if m == "plugin" => {
|
Some(m) if m == "plugin" => AnyModel::Plugin(serde_json::from_value(value).unwrap()),
|
||||||
AnyModel::Plugin(serde_json::from_value(value).unwrap())
|
|
||||||
}
|
|
||||||
Some(m) => {
|
Some(m) => {
|
||||||
return Err(serde::de::Error::custom(format!("Unknown model {}", m)));
|
return Err(serde::de::Error::custom(format!("Unknown model {}", m)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -914,6 +914,7 @@ pub async fn update_settings<R: Runtime>(
|
|||||||
(SettingsIden::InterfaceFontSize, settings.interface_font_size.into()),
|
(SettingsIden::InterfaceFontSize, settings.interface_font_size.into()),
|
||||||
(SettingsIden::InterfaceScale, settings.interface_scale.into()),
|
(SettingsIden::InterfaceScale, settings.interface_scale.into()),
|
||||||
(SettingsIden::EditorFontSize, settings.editor_font_size.into()),
|
(SettingsIden::EditorFontSize, settings.editor_font_size.into()),
|
||||||
|
(SettingsIden::EditorKeymap, settings.editor_keymap.to_string().into()),
|
||||||
(SettingsIden::EditorSoftWrap, settings.editor_soft_wrap.into()),
|
(SettingsIden::EditorSoftWrap, settings.editor_soft_wrap.into()),
|
||||||
(SettingsIden::Telemetry, settings.telemetry.into()),
|
(SettingsIden::Telemetry, settings.telemetry.into()),
|
||||||
(SettingsIden::OpenWorkspaceNewWindow, settings.open_workspace_new_window.into()),
|
(SettingsIden::OpenWorkspaceNewWindow, settings.open_workspace_new_window.into()),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useFolders } from '../hooks/useFolders';
|
import { useFolders } from '../hooks/useFolders';
|
||||||
import { useUpdateAnyFolder } from '../hooks/useUpdateAnyFolder';
|
import { useUpdateAnyFolder } from '../hooks/useUpdateAnyFolder';
|
||||||
import { PlainInput } from './core/PlainInput';
|
import { Input } from './core/Input';
|
||||||
import { VStack } from './core/Stacks';
|
import { VStack } from './core/Stacks';
|
||||||
import { MarkdownEditor } from './MarkdownEditor';
|
import { MarkdownEditor } from './MarkdownEditor';
|
||||||
|
|
||||||
@@ -17,13 +17,14 @@ export function FolderSettingsDialog({ folderId }: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<VStack space={3} className="pb-3">
|
<VStack space={3} className="pb-3">
|
||||||
<PlainInput
|
<Input
|
||||||
label="Folder Name"
|
label="Folder Name"
|
||||||
defaultValue={folder.name}
|
defaultValue={folder.name}
|
||||||
onChange={(name) => {
|
onChange={(name) => {
|
||||||
if (folderId == null) return;
|
if (folderId == null) return;
|
||||||
updateFolder({ id: folderId, update: (folder) => ({ ...folder, name }) });
|
updateFolder({ id: folderId, update: (folder) => ({ ...folder, name }) });
|
||||||
}}
|
}}
|
||||||
|
stateKey={`name.${folder.id}`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<MarkdownEditor
|
<MarkdownEditor
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ import type {
|
|||||||
GenericCompletionOption,
|
GenericCompletionOption,
|
||||||
} from './core/Editor/genericCompletion';
|
} from './core/Editor/genericCompletion';
|
||||||
import { InlineCode } from './core/InlineCode';
|
import { InlineCode } from './core/InlineCode';
|
||||||
|
import { Input } from './core/Input';
|
||||||
import type { Pair } from './core/PairEditor';
|
import type { Pair } from './core/PairEditor';
|
||||||
import { PlainInput } from './core/PlainInput';
|
|
||||||
import type { TabItem } from './core/Tabs/Tabs';
|
import type { TabItem } from './core/Tabs/Tabs';
|
||||||
import { TabContent, Tabs } from './core/Tabs/Tabs';
|
import { TabContent, Tabs } from './core/Tabs/Tabs';
|
||||||
import { EmptyStateText } from './EmptyStateText';
|
import { EmptyStateText } from './EmptyStateText';
|
||||||
@@ -481,7 +481,7 @@ export const RequestPane = memo(function RequestPane({
|
|||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value={TAB_DESCRIPTION}>
|
<TabContent value={TAB_DESCRIPTION}>
|
||||||
<div className="grid grid-rows-[auto_minmax(0,1fr)] h-full">
|
<div className="grid grid-rows-[auto_minmax(0,1fr)] h-full">
|
||||||
<PlainInput
|
<Input
|
||||||
label="Request Name"
|
label="Request Name"
|
||||||
hideLabel
|
hideLabel
|
||||||
forceUpdateKey={forceUpdateKey}
|
forceUpdateKey={forceUpdateKey}
|
||||||
@@ -490,6 +490,7 @@ export const RequestPane = memo(function RequestPane({
|
|||||||
containerClassName="border-0"
|
containerClassName="border-0"
|
||||||
placeholder="Request Name"
|
placeholder="Request Name"
|
||||||
onChange={(name) => updateRequest({ id: activeRequestId, update: { name } })}
|
onChange={(name) => updateRequest({ id: activeRequestId, update: { name } })}
|
||||||
|
stateKey={`name.${activeRequest.id}`}
|
||||||
/>
|
/>
|
||||||
<MarkdownEditor
|
<MarkdownEditor
|
||||||
name="request-description"
|
name="request-description"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import type { EditorKeymap } from '@yaakapp-internal/models';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useActiveWorkspace } from '../../hooks/useActiveWorkspace';
|
import { useActiveWorkspace } from '../../hooks/useActiveWorkspace';
|
||||||
import { useResolvedAppearance } from '../../hooks/useResolvedAppearance';
|
import { useResolvedAppearance } from '../../hooks/useResolvedAppearance';
|
||||||
@@ -9,7 +10,7 @@ import { getThemes } from '../../lib/theme/themes';
|
|||||||
import { isThemeDark } from '../../lib/theme/window';
|
import { isThemeDark } from '../../lib/theme/window';
|
||||||
import type { ButtonProps } from '../core/Button';
|
import type { ButtonProps } from '../core/Button';
|
||||||
import { Checkbox } from '../core/Checkbox';
|
import { Checkbox } from '../core/Checkbox';
|
||||||
import {Editor} from "../core/Editor/Editor";
|
import { Editor } from '../core/Editor/Editor';
|
||||||
import type { IconProps } from '../core/Icon';
|
import type { IconProps } from '../core/Icon';
|
||||||
import { Icon } from '../core/Icon';
|
import { Icon } from '../core/Icon';
|
||||||
import { IconButton } from '../core/IconButton';
|
import { IconButton } from '../core/IconButton';
|
||||||
@@ -18,10 +19,13 @@ import { Select } from '../core/Select';
|
|||||||
import { Separator } from '../core/Separator';
|
import { Separator } from '../core/Separator';
|
||||||
import { HStack, VStack } from '../core/Stacks';
|
import { HStack, VStack } from '../core/Stacks';
|
||||||
|
|
||||||
const fontSizes = [
|
const fontSizeOptions = [
|
||||||
8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
|
8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
|
||||||
].map((n) => ({ label: `${n}`, value: `${n}` }));
|
].map((n) => ({ label: `${n}`, value: `${n}` }));
|
||||||
|
|
||||||
|
const keymaps: EditorKeymap[] = ['default', 'vim', 'vscode', 'emacs'];
|
||||||
|
const keymapOptions = keymaps.map((n) => ({ label: n, value: n }));
|
||||||
|
|
||||||
const buttonColors: ButtonProps['color'][] = [
|
const buttonColors: ButtonProps['color'][] = [
|
||||||
'primary',
|
'primary',
|
||||||
'info',
|
'info',
|
||||||
@@ -86,9 +90,9 @@ export function SettingsAppearance() {
|
|||||||
label="Font Size"
|
label="Font Size"
|
||||||
labelPosition="left"
|
labelPosition="left"
|
||||||
value={`${settings.interfaceFontSize}`}
|
value={`${settings.interfaceFontSize}`}
|
||||||
options={fontSizes}
|
options={fontSizeOptions}
|
||||||
onChange={(v) => updateSettings.mutate({ interfaceFontSize: parseInt(v) })}
|
onChange={(v) => updateSettings.mutate({ interfaceFontSize: parseInt(v) })}
|
||||||
event="font-size.interface"
|
event="ui-font-size"
|
||||||
/>
|
/>
|
||||||
<Select
|
<Select
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -96,15 +100,25 @@ export function SettingsAppearance() {
|
|||||||
label="Editor Font Size"
|
label="Editor Font Size"
|
||||||
labelPosition="left"
|
labelPosition="left"
|
||||||
value={`${settings.editorFontSize}`}
|
value={`${settings.editorFontSize}`}
|
||||||
options={fontSizes}
|
options={fontSizeOptions}
|
||||||
onChange={(v) => updateSettings.mutate({ editorFontSize: clamp(parseInt(v) || 14, 8, 30) })}
|
onChange={(v) => updateSettings.mutate({ editorFontSize: clamp(parseInt(v) || 14, 8, 30) })}
|
||||||
event="font-size.editor"
|
event="editor-font-size"
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={settings.editorSoftWrap}
|
checked={settings.editorSoftWrap}
|
||||||
title="Wrap Editor Lines"
|
title="Wrap Editor Lines"
|
||||||
onChange={(editorSoftWrap) => updateSettings.mutate({ editorSoftWrap })}
|
onChange={(editorSoftWrap) => updateSettings.mutate({ editorSoftWrap })}
|
||||||
event="wrap-lines"
|
event="editor-wrap-lines"
|
||||||
|
/>
|
||||||
|
<Select
|
||||||
|
size="sm"
|
||||||
|
name="editorKeymap"
|
||||||
|
label="Editor Key Map"
|
||||||
|
labelPosition="left"
|
||||||
|
value={`${settings.editorKeymap}`}
|
||||||
|
options={keymapOptions}
|
||||||
|
onChange={(v) => updateSettings.mutate({ editorKeymap: v })}
|
||||||
|
event="editor-keymap"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Separator className="my-4" />
|
<Separator className="my-4" />
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useDeleteActiveWorkspace } from '../hooks/useDeleteActiveWorkspace';
|
|||||||
import { useUpdateWorkspace } from '../hooks/useUpdateWorkspace';
|
import { useUpdateWorkspace } from '../hooks/useUpdateWorkspace';
|
||||||
import { useWorkspaces } from '../hooks/useWorkspaces';
|
import { useWorkspaces } from '../hooks/useWorkspaces';
|
||||||
import { Button } from './core/Button';
|
import { Button } from './core/Button';
|
||||||
import { PlainInput } from './core/PlainInput';
|
import { Input } from './core/Input';
|
||||||
import { VStack } from './core/Stacks';
|
import { VStack } from './core/Stacks';
|
||||||
import { MarkdownEditor } from './MarkdownEditor';
|
import { MarkdownEditor } from './MarkdownEditor';
|
||||||
import { SelectFile } from './SelectFile';
|
import { SelectFile } from './SelectFile';
|
||||||
@@ -22,10 +22,11 @@ export function WorkspaceSettingsDialog({ workspaceId, hide }: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<VStack space={3} alignItems="start" className="pb-3 max-h-[50vh]">
|
<VStack space={3} alignItems="start" className="pb-3 max-h-[50vh]">
|
||||||
<PlainInput
|
<Input
|
||||||
label="Workspace Name"
|
label="Workspace Name"
|
||||||
defaultValue={workspace.name}
|
defaultValue={workspace.name}
|
||||||
onChange={(name) => updateWorkspace({ name })}
|
onChange={(name) => updateWorkspace({ name })}
|
||||||
|
stateKey={`name.${workspace.id}`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<MarkdownEditor
|
<MarkdownEditor
|
||||||
|
|||||||
@@ -4,16 +4,28 @@
|
|||||||
.cm-editor {
|
.cm-editor {
|
||||||
@apply w-full block text-base;
|
@apply w-full block text-base;
|
||||||
|
|
||||||
|
/* Regular cursor */
|
||||||
.cm-cursor {
|
.cm-cursor {
|
||||||
@apply border-text !important;
|
@apply border-text !important;
|
||||||
/* Widen the cursor */
|
/* Widen the cursor a bit */
|
||||||
@apply border-l-[2px];
|
@apply border-l-[2px];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Vim-mode cursor */
|
||||||
|
.cm-fat-cursor {
|
||||||
|
@apply bg-text opacity-60;
|
||||||
|
}
|
||||||
|
|
||||||
&.cm-focused {
|
&.cm-focused {
|
||||||
outline: none !important;
|
outline: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:not(.cm-focused) {
|
||||||
|
.cm-cursor, .cm-fat-cursor {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.cm-content {
|
.cm-content {
|
||||||
@apply py-0;
|
@apply py-0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ import { foldState, forceParsing } from '@codemirror/language';
|
|||||||
import type { EditorStateConfig, Extension } from '@codemirror/state';
|
import type { EditorStateConfig, Extension } from '@codemirror/state';
|
||||||
import { Compartment, EditorState } from '@codemirror/state';
|
import { Compartment, EditorState } from '@codemirror/state';
|
||||||
import { keymap, placeholder as placeholderExt, tooltips } from '@codemirror/view';
|
import { keymap, placeholder as placeholderExt, tooltips } from '@codemirror/view';
|
||||||
import type { EnvironmentVariable } from '@yaakapp-internal/models';
|
import { emacs } from '@replit/codemirror-emacs';
|
||||||
|
import { vim } from '@replit/codemirror-vim';
|
||||||
|
import { vscodeKeymap } from '@replit/codemirror-vscode-keymap';
|
||||||
|
import type { EditorKeymap, EnvironmentVariable } from '@yaakapp-internal/models';
|
||||||
import type { TemplateFunction } from '@yaakapp-internal/plugins';
|
import type { TemplateFunction } from '@yaakapp-internal/plugins';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { EditorView } from 'codemirror';
|
import { EditorView } from 'codemirror';
|
||||||
@@ -33,15 +36,17 @@ import { TemplateVariableDialog } from '../../TemplateVariableDialog';
|
|||||||
import { IconButton } from '../IconButton';
|
import { IconButton } from '../IconButton';
|
||||||
import { HStack } from '../Stacks';
|
import { HStack } from '../Stacks';
|
||||||
import './Editor.css';
|
import './Editor.css';
|
||||||
import {
|
import { baseExtensions, getLanguageExtension, multiLineExtensions } from './extensions';
|
||||||
baseExtensions,
|
|
||||||
emptyExtension,
|
|
||||||
getLanguageExtension,
|
|
||||||
multiLineExtensions,
|
|
||||||
} from './extensions';
|
|
||||||
import type { GenericCompletionConfig } from './genericCompletion';
|
import type { GenericCompletionConfig } from './genericCompletion';
|
||||||
import { singleLineExtensions } from './singleLine';
|
import { singleLineExtensions } from './singleLine';
|
||||||
|
|
||||||
|
const keymapExtensions: Record<EditorKeymap, Extension> = {
|
||||||
|
vim: vim(),
|
||||||
|
emacs: emacs(),
|
||||||
|
vscode: keymap.of(vscodeKeymap),
|
||||||
|
default: [],
|
||||||
|
};
|
||||||
|
|
||||||
export interface EditorProps {
|
export interface EditorProps {
|
||||||
id?: string;
|
id?: string;
|
||||||
readOnly?: boolean;
|
readOnly?: boolean;
|
||||||
@@ -86,6 +91,7 @@ export interface EditorProps {
|
|||||||
const stateFields = { history: historyField, folds: foldState };
|
const stateFields = { history: historyField, folds: foldState };
|
||||||
|
|
||||||
const emptyVariables: EnvironmentVariable[] = [];
|
const emptyVariables: EnvironmentVariable[] = [];
|
||||||
|
const emptyExtension: Extension = [];
|
||||||
|
|
||||||
export const Editor = forwardRef<EditorView | undefined, EditorProps>(function Editor(
|
export const Editor = forwardRef<EditorView | undefined, EditorProps>(function Editor(
|
||||||
{
|
{
|
||||||
@@ -119,6 +125,7 @@ export const Editor = forwardRef<EditorView | undefined, EditorProps>(function E
|
|||||||
ref,
|
ref,
|
||||||
) {
|
) {
|
||||||
const settings = useSettings();
|
const settings = useSettings();
|
||||||
|
|
||||||
const templateFunctions = useTemplateFunctions();
|
const templateFunctions = useTemplateFunctions();
|
||||||
const allEnvironmentVariables = useActiveEnvironmentVariables();
|
const allEnvironmentVariables = useActiveEnvironmentVariables();
|
||||||
const environmentVariables = autocompleteVariables ? allEnvironmentVariables : emptyVariables;
|
const environmentVariables = autocompleteVariables ? allEnvironmentVariables : emptyVariables;
|
||||||
@@ -178,6 +185,25 @@ export const Editor = forwardRef<EditorView | undefined, EditorProps>(function E
|
|||||||
[placeholder],
|
[placeholder],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Update vim
|
||||||
|
const keymapCompartment = useRef(new Compartment());
|
||||||
|
useEffect(
|
||||||
|
function configureKeymap() {
|
||||||
|
if (cm.current === null) return;
|
||||||
|
const current = keymapCompartment.current.get(cm.current.view.state) ?? [];
|
||||||
|
// PERF: This is expensive with hundreds of editors on screen, so only do it when necessary
|
||||||
|
if (settings.editorKeymap === 'default' && current === keymapExtensions['default']) return; // Nothing to do
|
||||||
|
if (settings.editorKeymap === 'vim' && current === keymapExtensions['vim']) return; // Nothing to do
|
||||||
|
if (settings.editorKeymap === 'vscode' && current === keymapExtensions['vscode']) return; // Nothing to do
|
||||||
|
if (settings.editorKeymap === 'emacs' && current === keymapExtensions['emacs']) return; // Nothing to do
|
||||||
|
|
||||||
|
const ext = keymapExtensions[settings.editorKeymap] ?? keymapExtensions['default'];
|
||||||
|
const effect = keymapCompartment.current.reconfigure(ext);
|
||||||
|
cm.current.view.dispatch({ effects: effect });
|
||||||
|
},
|
||||||
|
[settings.editorKeymap],
|
||||||
|
);
|
||||||
|
|
||||||
// Update wrap lines
|
// Update wrap lines
|
||||||
const wrapLinesCompartment = useRef(new Compartment());
|
const wrapLinesCompartment = useRef(new Compartment());
|
||||||
useEffect(
|
useEffect(
|
||||||
@@ -188,7 +214,7 @@ export const Editor = forwardRef<EditorView | undefined, EditorProps>(function E
|
|||||||
if (wrapLines && current !== emptyExtension) return; // Nothing to do
|
if (wrapLines && current !== emptyExtension) return; // Nothing to do
|
||||||
if (!wrapLines && current === emptyExtension) return; // Nothing to do
|
if (!wrapLines && current === emptyExtension) return; // Nothing to do
|
||||||
|
|
||||||
const ext = wrapLines ? EditorView.lineWrapping : emptyExtension;
|
const ext = wrapLines ? EditorView.lineWrapping : [];
|
||||||
const effect = wrapLinesCompartment.current.reconfigure(ext);
|
const effect = wrapLinesCompartment.current.reconfigure(ext);
|
||||||
cm.current?.view.dispatch({ effects: effect });
|
cm.current?.view.dispatch({ effects: effect });
|
||||||
},
|
},
|
||||||
@@ -331,7 +357,10 @@ export const Editor = forwardRef<EditorView | undefined, EditorProps>(function E
|
|||||||
placeholderCompartment.current.of(
|
placeholderCompartment.current.of(
|
||||||
placeholderExt(placeholderElFromText(placeholder ?? '')),
|
placeholderExt(placeholderElFromText(placeholder ?? '')),
|
||||||
),
|
),
|
||||||
wrapLinesCompartment.current.of(wrapLines ? EditorView.lineWrapping : emptyExtension),
|
wrapLinesCompartment.current.of(wrapLines ? EditorView.lineWrapping : []),
|
||||||
|
keymapCompartment.current.of(
|
||||||
|
keymapExtensions[settings.editorKeymap] ?? keymapExtensions['default'],
|
||||||
|
),
|
||||||
...getExtensions({
|
...getExtensions({
|
||||||
container,
|
container,
|
||||||
readOnly,
|
readOnly,
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import {
|
|||||||
import { lintKeymap } from '@codemirror/lint';
|
import { lintKeymap } from '@codemirror/lint';
|
||||||
|
|
||||||
import { searchKeymap } from '@codemirror/search';
|
import { searchKeymap } from '@codemirror/search';
|
||||||
import type { Extension } from '@codemirror/state';
|
|
||||||
import { EditorState } from '@codemirror/state';
|
import { EditorState } from '@codemirror/state';
|
||||||
import {
|
import {
|
||||||
crosshairCursor,
|
crosshairCursor,
|
||||||
@@ -86,8 +85,6 @@ const syntaxExtensions: Record<NonNullable<EditorProps['language']>, LanguageSup
|
|||||||
markdown: markdown(),
|
markdown: markdown(),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const emptyExtension: Extension = [];
|
|
||||||
|
|
||||||
export function getLanguageExtension({
|
export function getLanguageExtension({
|
||||||
language,
|
language,
|
||||||
useTemplating = false,
|
useTemplating = false,
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import type { PromptTextRequest } from '@yaakapp-internal/plugins';
|
import type { PromptTextRequest } from '@yaakapp-internal/plugins';
|
||||||
import type { FormEvent, ReactNode } from 'react';
|
import type { FormEvent, ReactNode } from 'react';
|
||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import {PlainInput} from "./PlainInput";
|
|
||||||
import { HStack } from './Stacks';
|
|
||||||
import { Button } from './Button';
|
import { Button } from './Button';
|
||||||
|
import { Input } from './Input';
|
||||||
|
import { HStack } from './Stacks';
|
||||||
|
|
||||||
export type PromptProps = Omit<PromptTextRequest, 'id' | 'title' | 'description'> & {
|
export type PromptProps = Omit<PromptTextRequest, 'id' | 'title' | 'description'> & {
|
||||||
description?: ReactNode;
|
description?: ReactNode;
|
||||||
@@ -35,7 +35,7 @@ export function Prompt({
|
|||||||
className="grid grid-rows-[auto_auto] grid-cols-[minmax(0,1fr)] gap-4 mb-4"
|
className="grid grid-rows-[auto_auto] grid-cols-[minmax(0,1fr)] gap-4 mb-4"
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
>
|
>
|
||||||
<PlainInput
|
<Input
|
||||||
hideLabel
|
hideLabel
|
||||||
autoSelect
|
autoSelect
|
||||||
require={require}
|
require={require}
|
||||||
@@ -43,6 +43,7 @@ export function Prompt({
|
|||||||
label={label}
|
label={label}
|
||||||
defaultValue={defaultValue}
|
defaultValue={defaultValue}
|
||||||
onChange={setValue}
|
onChange={setValue}
|
||||||
|
stateKey={null}
|
||||||
/>
|
/>
|
||||||
<HStack space={2} justifyContent="end">
|
<HStack space={2} justifyContent="end">
|
||||||
<Button onClick={onCancel} variant="border" color="secondary">
|
<Button onClick={onCancel} variant="border" color="secondary">
|
||||||
|
|||||||
@@ -19,6 +19,9 @@
|
|||||||
"@gilbarbara/deep-equal": "^0.3.1",
|
"@gilbarbara/deep-equal": "^0.3.1",
|
||||||
"@lezer/highlight": "^1.1.3",
|
"@lezer/highlight": "^1.1.3",
|
||||||
"@lezer/lr": "^1.3.3",
|
"@lezer/lr": "^1.3.3",
|
||||||
|
"@replit/codemirror-emacs": "^6.1.0",
|
||||||
|
"@replit/codemirror-vim": "^6.2.1",
|
||||||
|
"@replit/codemirror-vscode-keymap": "^6.0.2",
|
||||||
"@tailwindcss/container-queries": "^0.1.1",
|
"@tailwindcss/container-queries": "^0.1.1",
|
||||||
"@tanstack/react-query": "^5.62.16",
|
"@tanstack/react-query": "^5.62.16",
|
||||||
"@tanstack/react-router": "^1.95.1",
|
"@tanstack/react-router": "^1.95.1",
|
||||||
|
|||||||
Reference in New Issue
Block a user