Compare commits
No commits in common. "84bef709724a4fd3a0660fd29c8a2f9f05000fab" and "7bd021e23615b32e172d453cc65232afec576be0" have entirely different histories.
84bef70972
...
7bd021e236
|
|
@ -3,6 +3,7 @@ import { MakerSquirrel } from "@electron-forge/maker-squirrel";
|
||||||
import { MakerZIP } from "@electron-forge/maker-zip";
|
import { MakerZIP } from "@electron-forge/maker-zip";
|
||||||
import { MakerDeb } from "@electron-forge/maker-deb";
|
import { MakerDeb } from "@electron-forge/maker-deb";
|
||||||
import { MakerRpm } from "@electron-forge/maker-rpm";
|
import { MakerRpm } from "@electron-forge/maker-rpm";
|
||||||
|
import { MakerFlatpak } from "@electron-forge/maker-flatpak";
|
||||||
import { VitePlugin } from "@electron-forge/plugin-vite";
|
import { VitePlugin } from "@electron-forge/plugin-vite";
|
||||||
import { FusesPlugin } from "@electron-forge/plugin-fuses";
|
import { FusesPlugin } from "@electron-forge/plugin-fuses";
|
||||||
import { FuseV1Options, FuseVersion } from "@electron/fuses";
|
import { FuseV1Options, FuseVersion } from "@electron/fuses";
|
||||||
|
|
@ -21,8 +22,8 @@ const config: ForgeConfig = {
|
||||||
makers: [
|
makers: [
|
||||||
new MakerSquirrel({}),
|
new MakerSquirrel({}),
|
||||||
new MakerZIP({}),
|
new MakerZIP({}),
|
||||||
new MakerRpm({ options: { icon: "res/icon.png", categories: ["Development"], name: "miller-ide" } }),
|
new MakerRpm({ options: { icon: "res/icon.png", categories: ["Development"] } }),
|
||||||
new MakerDeb({ options: { icon: "res/icon.png", categories: ["Development"], name: "miller-ide" } }),
|
new MakerDeb({ options: { icon: "res/icon.png", categories: ["Development"] } }),
|
||||||
],
|
],
|
||||||
plugins: [
|
plugins: [
|
||||||
new VitePlugin({
|
new VitePlugin({
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "miller",
|
"name": "miller",
|
||||||
"productName": "miller",
|
"productName": "miller",
|
||||||
"version": "0.2.5",
|
"version": "0.2.4",
|
||||||
"description": "Column-based code editor",
|
"description": "Column-based code editor",
|
||||||
"main": ".vite/build/main.js",
|
"main": ".vite/build/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ const fixedHeightEditor = EditorView.theme({
|
||||||
minHeight: "1em",
|
minHeight: "1em",
|
||||||
resize: "horizontal",
|
resize: "horizontal",
|
||||||
overflow: "auto",
|
overflow: "auto",
|
||||||
width: "864px",
|
width: "768px",
|
||||||
minWidth: "8em",
|
minWidth: "8em",
|
||||||
flex: "none",
|
flex: "none",
|
||||||
fontSize: "16px",
|
fontSize: "16px",
|
||||||
|
|
@ -184,7 +184,7 @@ export class Editor extends Displayable {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn("Failed to apply LSP extension:", err);
|
console.warn("Failed to apply LSP extension:", err);
|
||||||
}
|
}
|
||||||
}).catch((err) => console.warn("Failed to create LSP extension:",err));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
van.derive(() => {
|
van.derive(() => {
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@ import * as u from "./utils";
|
||||||
import { Editor } from "./editor";
|
import { Editor } from "./editor";
|
||||||
import { Terminal } from "./terminal";
|
import { Terminal } from "./terminal";
|
||||||
import { Displayable } from "./displayable";
|
import { Displayable } from "./displayable";
|
||||||
import { QuickOpen } from "./quickopen";
|
|
||||||
import { toggleSidebar } from "./renderer";
|
|
||||||
|
|
||||||
const EditorWrapper = (
|
const EditorWrapper = (
|
||||||
editor: State<Displayable>,
|
editor: State<Displayable>,
|
||||||
|
|
@ -137,15 +135,6 @@ function shortcutHandler(e: KeyboardEvent) {
|
||||||
addTerminal();
|
addTerminal();
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
} else if (e.key === "p" && e.ctrlKey) {
|
|
||||||
if (e.type === "keydown") {
|
|
||||||
QuickOpen.open();
|
|
||||||
}
|
|
||||||
e.preventDefault();
|
|
||||||
} else if (e.key === "b" && e.ctrlKey) {
|
|
||||||
if (e.type === "keydown") {
|
|
||||||
toggleSidebar();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ window.electronAPI.onFsEvent(async (ev: { event: string; path: string }) => {
|
||||||
// Read latest contents from disk
|
// Read latest contents from disk
|
||||||
const data = await window.electronAPI
|
const data = await window.electronAPI
|
||||||
.readFile(ev.path)
|
.readFile(ev.path)
|
||||||
.catch((): any => null);
|
.catch(() => null);
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
if (ev.event === "unlink") {
|
if (ev.event === "unlink") {
|
||||||
openFile.knownDiskContent.val = null;
|
openFile.knownDiskContent.val = null;
|
||||||
|
|
@ -125,19 +125,3 @@ const FsItemView = (tree: FolderTree): HTMLElement => {
|
||||||
|
|
||||||
return folder;
|
return folder;
|
||||||
};
|
};
|
||||||
|
|
||||||
function allFilesFromTree(t: FolderTree): string[] {
|
|
||||||
if (t.type == "directory") {
|
|
||||||
return t.children.flatMap(allFilesFromTree);
|
|
||||||
} else if (t.type == "file") {
|
|
||||||
return [t.path];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const allFiles = van.derive(() => {
|
|
||||||
if (folderTreeState.val) {
|
|
||||||
return allFilesFromTree(folderTreeState.val);
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
@ -1,119 +0,0 @@
|
||||||
import van, { State } from "vanjs-core";
|
|
||||||
import { OpenFile } from "./filestate";
|
|
||||||
import { addEditor } from "./editorgrid";
|
|
||||||
import { allFiles } from "./foldernav";
|
|
||||||
|
|
||||||
const v = van.tags;
|
|
||||||
|
|
||||||
export const QuickOpen = (() => {
|
|
||||||
const isOpen = van.state(false);
|
|
||||||
const query = van.state("");
|
|
||||||
const files = van.state([]);
|
|
||||||
const filteredFiles = van.derive(() => {
|
|
||||||
if (!query.val) return files.val.slice(0, 100);
|
|
||||||
return files.val.filter(f => f.toLowerCase().includes(query.val.toLowerCase())).slice(0, 100);
|
|
||||||
});
|
|
||||||
const selectedIndex = van.state(0);
|
|
||||||
|
|
||||||
// Update selectedIndex when filteredFiles changes
|
|
||||||
van.derive(() => {
|
|
||||||
filteredFiles.val; // track dependency
|
|
||||||
selectedIndex.val = 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
const close = () => {
|
|
||||||
isOpen.val = false;
|
|
||||||
query.val = "";
|
|
||||||
selectedIndex.val = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
const openSelectedFile = async () => {
|
|
||||||
const path = filteredFiles.val[selectedIndex.val];
|
|
||||||
if (path) {
|
|
||||||
const file = await OpenFile.openFile(path);
|
|
||||||
if (file) {
|
|
||||||
addEditor(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close();
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleKeyDown = (e: KeyboardEvent) => {
|
|
||||||
if (!isOpen.val) return;
|
|
||||||
|
|
||||||
if (e.key === "Escape") {
|
|
||||||
close();
|
|
||||||
e.preventDefault();
|
|
||||||
} else if (e.key === "Enter") {
|
|
||||||
openSelectedFile();
|
|
||||||
e.preventDefault();
|
|
||||||
} else if (e.key === "ArrowDown") {
|
|
||||||
selectedIndex.val = (selectedIndex.val + 1) % filteredFiles.val.length;
|
|
||||||
e.preventDefault();
|
|
||||||
} else if (e.key === "ArrowUp") {
|
|
||||||
selectedIndex.val = (selectedIndex.val - 1 + filteredFiles.val.length) % filteredFiles.val.length;
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const open = async () => {
|
|
||||||
query.val = "";
|
|
||||||
files.val = allFiles.val;
|
|
||||||
console.log("setting allfiles to ", allFiles.val);
|
|
||||||
|
|
||||||
isOpen.val = true;
|
|
||||||
// Focus the input after the DOM is updated
|
|
||||||
setTimeout(() => {
|
|
||||||
const input = document.getElementById("quick-open-input") as HTMLInputElement;
|
|
||||||
input?.focus();
|
|
||||||
}, 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener("keydown", handleKeyDown, { capture: true });
|
|
||||||
|
|
||||||
const modal = v.div(
|
|
||||||
{
|
|
||||||
class: () => isOpen.val ? "fixed inset-0 z-50 flex items-start justify-center pt-20 bg-black bg-opacity-50" : "hidden",
|
|
||||||
onclick: (e: MouseEvent) => {
|
|
||||||
if ((e.target as HTMLElement).id === "quick-open-overlay") {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
v.div(
|
|
||||||
{
|
|
||||||
id: "quick-open-overlay",
|
|
||||||
class: "bg-white dark:bg-gray-800 w-1/2 max-w-2xl rounded shadow-lg overflow-hidden flex flex-col",
|
|
||||||
},
|
|
||||||
v.input(
|
|
||||||
{
|
|
||||||
id: "quick-open-input",
|
|
||||||
class: "w-full p-4 text-lg border-b dark:border-gray-700 dark:bg-gray-800 dark:text-white outline-none",
|
|
||||||
placeholder: "Quick Open...",
|
|
||||||
value: query,
|
|
||||||
oninput: (e: any) => (query.val = e.target.value),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
v.div(
|
|
||||||
{ class: "max-h-96 overflow-y-auto" },
|
|
||||||
() => v.ul(
|
|
||||||
filteredFiles.val.map((path, i) => v.div(
|
|
||||||
{
|
|
||||||
class: () => `p-2 cursor-pointer hover:bg-blue-100 dark:hover:bg-blue-900 ${selectedIndex.val === i ? "bg-blue-200 dark:bg-blue-800" : ""}`,
|
|
||||||
onclick: () => {
|
|
||||||
selectedIndex.val = filteredFiles.val.indexOf(path);
|
|
||||||
openSelectedFile();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
path
|
|
||||||
)
|
|
||||||
))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
dom: modal,
|
|
||||||
open,
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
@ -6,7 +6,6 @@ const v = van.tags;
|
||||||
|
|
||||||
import { FolderTreeView } from "./foldernav";
|
import { FolderTreeView } from "./foldernav";
|
||||||
import { EditorTabs, addTab, addEditor } from "./editorgrid";
|
import { EditorTabs, addTab, addEditor } from "./editorgrid";
|
||||||
import { QuickOpen } from "./quickopen";
|
|
||||||
import * as u from "./utils";
|
import * as u from "./utils";
|
||||||
import { OpenFile } from "./filestate";
|
import { OpenFile } from "./filestate";
|
||||||
|
|
||||||
|
|
@ -15,29 +14,17 @@ function newFile() {
|
||||||
addEditor(file);
|
addEditor(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function toggleSidebar() {
|
|
||||||
if (sidebar.val == "none") {
|
|
||||||
sidebar.val = "tree";
|
|
||||||
} else if (sidebar.val == "tree") {
|
|
||||||
sidebar.val = "none";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const sidebar = van.state<"tree" | "none">("tree");
|
|
||||||
|
|
||||||
const app = v.div(
|
const app = v.div(
|
||||||
{ class: "h-screen max-h-screen w-screen max-w-screen flex" },
|
{ class: "h-screen max-h-screen w-screen max-w-screen flex" },
|
||||||
v.aside(
|
v.aside(
|
||||||
{
|
{
|
||||||
class: "flex-none resize-x overflow-x-hidden overflow-y-scroll w-3xs min-w-32",
|
class: "flex-none resize-x overflow-x-hidden overflow-y-scroll w-3xs min-w-32",
|
||||||
hidden: () => sidebar.val != "tree",
|
|
||||||
},
|
},
|
||||||
u.InlineButton(addTab, "Add Tab", "+Tab"),
|
u.InlineButton(addTab, "Add Tab", "+Tab"),
|
||||||
u.InlineButton(newFile, "Add Editor", "+File"),
|
u.InlineButton(newFile, "Add Editor", "+File"),
|
||||||
FolderTreeView,
|
FolderTreeView,
|
||||||
),
|
),
|
||||||
EditorTabs,
|
EditorTabs,
|
||||||
QuickOpen.dom,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
van.add(document.body, app);
|
van.add(document.body, app);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue