Compare commits
No commits in common. "d24c9bb89c6afb9030f3f5b2b9d467e82e9b6210" and "cc1565f3663bb637bed61fcb85be3c817a8d671d" have entirely different histories.
d24c9bb89c
...
cc1565f366
|
|
@ -41,7 +41,6 @@
|
||||||
"eslint": "^9.39.1",
|
"eslint": "^9.39.1",
|
||||||
"eslint-plugin-import": "^2.32.0",
|
"eslint-plugin-import": "^2.32.0",
|
||||||
"globals": "^16.5.0",
|
"globals": "^16.5.0",
|
||||||
"ignore": "^7.0.5",
|
|
||||||
"prettier": "^3.6.2",
|
"prettier": "^3.6.2",
|
||||||
"tailwindcss": "^4.1.17",
|
"tailwindcss": "^4.1.17",
|
||||||
"typescript": "~5.9.3",
|
"typescript": "~5.9.3",
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@
|
||||||
"license": "GPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@codemirror/language-data": "^6.5.2",
|
"@codemirror/language-data": "^6.5.2",
|
||||||
"@codemirror/lsp-client": "^6.2.0",
|
|
||||||
"@codemirror/theme-one-dark": "^6.1.3",
|
"@codemirror/theme-one-dark": "^6.1.3",
|
||||||
|
"@codemirror/lsp-client": "^6.2.0",
|
||||||
"@electron-forge/cli": "^7.10.2",
|
"@electron-forge/cli": "^7.10.2",
|
||||||
"@electron-forge/maker-deb": "^7.10.2",
|
"@electron-forge/maker-deb": "^7.10.2",
|
||||||
"@electron-forge/maker-rpm": "^7.10.2",
|
"@electron-forge/maker-rpm": "^7.10.2",
|
||||||
|
|
@ -46,7 +46,6 @@
|
||||||
"eslint": "^9.39.1",
|
"eslint": "^9.39.1",
|
||||||
"eslint-plugin-import": "^2.32.0",
|
"eslint-plugin-import": "^2.32.0",
|
||||||
"globals": "^16.5.0",
|
"globals": "^16.5.0",
|
||||||
"ignore": "^7.0.5",
|
|
||||||
"prettier": "^3.6.2",
|
"prettier": "^3.6.2",
|
||||||
"tailwindcss": "^4.1.17",
|
"tailwindcss": "^4.1.17",
|
||||||
"typescript": "~5.9.3",
|
"typescript": "~5.9.3",
|
||||||
|
|
@ -56,8 +55,8 @@
|
||||||
"vite": "^7.2.2"
|
"vite": "^7.2.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lydell/node-pty": "^1.1.0",
|
|
||||||
"chokidar": "^5.0.0",
|
"chokidar": "^5.0.0",
|
||||||
"electron-squirrel-startup": "^1.0.1"
|
"electron-squirrel-startup": "^1.0.1",
|
||||||
|
"@lydell/node-pty": "^1.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ const v = van.tags;
|
||||||
import type { FolderTree } from "../types/global";
|
import type { FolderTree } from "../types/global";
|
||||||
import { addEditor } from "./editorgrid";
|
import { addEditor } from "./editorgrid";
|
||||||
import { OpenFile } from "./filestate";
|
import { OpenFile } from "./filestate";
|
||||||
import ignore from "ignore";
|
|
||||||
|
|
||||||
import * as u from "./utils";
|
import * as u from "./utils";
|
||||||
|
|
||||||
|
|
@ -15,37 +14,6 @@ van.derive(() => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const ignoreInstance = van.state<ignore.Ignore | null>(null);
|
|
||||||
|
|
||||||
async function updateIgnoreInstance() {
|
|
||||||
const root = folderTreeState.val?.path;
|
|
||||||
if (!root) {
|
|
||||||
ignoreInstance.val = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ig = ignore();
|
|
||||||
const files = [".gitignore", ".ignore"];
|
|
||||||
for (const file of files) {
|
|
||||||
const data = await window.electronAPI.readFile(`${root}/${file}`).catch(() => (null as any));
|
|
||||||
if (data && data.content) {
|
|
||||||
ig.add(data.content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ignoreInstance.val = ig;
|
|
||||||
}
|
|
||||||
|
|
||||||
van.derive(updateIgnoreInstance);
|
|
||||||
|
|
||||||
export function shouldIgnore(filePath: string) {
|
|
||||||
const root = folderTreeState.val?.path;
|
|
||||||
if (!root || !ignoreInstance.val) return false;
|
|
||||||
if (!filePath.startsWith(root)) return false;
|
|
||||||
|
|
||||||
const relativePath = filePath.slice(root.length).replace(/^[/\\]/, "");
|
|
||||||
return ignoreInstance.val.ignores(relativePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function openFolder() {
|
async function openFolder() {
|
||||||
const folderTree = await window.electronAPI.openFolder().catch(alert);
|
const folderTree = await window.electronAPI.openFolder().catch(alert);
|
||||||
if (!folderTree) return;
|
if (!folderTree) return;
|
||||||
|
|
@ -82,11 +50,6 @@ window.electronAPI.onFsEvent(async (ev: { event: string; path: string }) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If ignore files are changed, update ignore instance
|
|
||||||
if (ev.event === "change" && (ev.path.endsWith(".gitignore") || ev.path.endsWith(".ignore"))) {
|
|
||||||
updateIgnoreInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a file changed on disk and it's open, show disk version panels
|
// If a file changed on disk and it's open, show disk version panels
|
||||||
if (ev.event === "change" || ev.event === "add" || ev.event === "unlink") {
|
if (ev.event === "change" || ev.event === "add" || ev.event === "unlink") {
|
||||||
const openFile = OpenFile.findOpenFile(ev.path);
|
const openFile = OpenFile.findOpenFile(ev.path);
|
||||||
|
|
@ -123,7 +86,7 @@ export const FolderTreeView = () => {
|
||||||
u.InlineButton(refreshFolder, "Refresh current folder", "⟳"),
|
u.InlineButton(refreshFolder, "Refresh current folder", "⟳"),
|
||||||
u.InlineButton(openFolder, "Open another folder", "📁"),
|
u.InlineButton(openFolder, "Open another folder", "📁"),
|
||||||
),
|
),
|
||||||
folderTreeState.val.children?.toSorted((a, b) => a.type.localeCompare(b.type)).map(FsItemView) || [],
|
folderTreeState.val.children?.map(FsItemView) || [],
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -141,11 +104,9 @@ const FsItemView = (tree: FolderTree): HTMLElement => {
|
||||||
tree.name,
|
tree.name,
|
||||||
);
|
);
|
||||||
const isOpen = van.state(false);
|
const isOpen = van.state(false);
|
||||||
const sorted = tree.children?.toSorted((a, b) =>
|
|
||||||
a.type.localeCompare(b.type));
|
|
||||||
const children = () =>
|
const children = () =>
|
||||||
isOpen.val
|
isOpen.val
|
||||||
? v.ul({ class: "pl-4" }, sorted.map(FsItemView))
|
? v.ul({ class: "pl-4" }, tree.children?.map(FsItemView))
|
||||||
: v.div({ ariaBusy: true });
|
: v.div({ ariaBusy: true });
|
||||||
const folder = v.details(
|
const folder = v.details(
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ function jumpToOrigin(view: EditorView, type: { get: typeof getDefinition, capab
|
||||||
: plugin.fromPosition(loc.range.start, target.view.state.doc);
|
: plugin.fromPosition(loc.range.start, target.view.state.doc);
|
||||||
target.view.dispatch({
|
target.view.dispatch({
|
||||||
selection: {anchor: pos},
|
selection: {anchor: pos},
|
||||||
effects: EditorView.scrollIntoView(pos, {y: "start"}),
|
scrollIntoView: true,
|
||||||
userEvent: "select.definition",
|
userEvent: "select.definition",
|
||||||
});
|
});
|
||||||
setTimeout(() => target.focus(), 0);
|
setTimeout(() => target.focus(), 0);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import van, { State } from "vanjs-core";
|
import van, { State } from "vanjs-core";
|
||||||
import { OpenFile } from "./filestate";
|
import { OpenFile } from "./filestate";
|
||||||
import { addEditor } from "./editorgrid";
|
import { addEditor } from "./editorgrid";
|
||||||
import { allFiles, shouldIgnore } from "./foldernav";
|
import { allFiles } from "./foldernav";
|
||||||
|
|
||||||
const v = van.tags;
|
const v = van.tags;
|
||||||
|
|
||||||
|
|
@ -10,15 +10,8 @@ export const QuickOpen = (() => {
|
||||||
const query = van.state("");
|
const query = van.state("");
|
||||||
const files = van.state([]);
|
const files = van.state([]);
|
||||||
const filteredFiles = van.derive(() => {
|
const filteredFiles = van.derive(() => {
|
||||||
let result = files.val;
|
if (!query.val) return files.val.slice(0, 100);
|
||||||
if (query.val) {
|
return files.val.filter(f => f.toLowerCase().includes(query.val.toLowerCase())).slice(0, 100);
|
||||||
result = result.filter(f => f.toLowerCase().includes(query.val.toLowerCase()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
.map(path => ({ path, ignored: shouldIgnore(path) }))
|
|
||||||
.sort((a, b) => (a.ignored === b.ignored ? 0 : a.ignored ? 1 : -1))
|
|
||||||
.slice(0, 100);
|
|
||||||
});
|
});
|
||||||
const selectedIndex = van.state(0);
|
const selectedIndex = van.state(0);
|
||||||
|
|
||||||
|
|
@ -35,9 +28,9 @@ export const QuickOpen = (() => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const openSelectedFile = async () => {
|
const openSelectedFile = async () => {
|
||||||
const item = filteredFiles.val[selectedIndex.val];
|
const path = filteredFiles.val[selectedIndex.val];
|
||||||
if (item) {
|
if (path) {
|
||||||
const file = await OpenFile.openFile(item.path);
|
const file = await OpenFile.openFile(path);
|
||||||
if (file) {
|
if (file) {
|
||||||
addEditor(file);
|
addEditor(file);
|
||||||
}
|
}
|
||||||
|
|
@ -66,6 +59,7 @@ export const QuickOpen = (() => {
|
||||||
const open = async () => {
|
const open = async () => {
|
||||||
query.val = "";
|
query.val = "";
|
||||||
files.val = allFiles.val;
|
files.val = allFiles.val;
|
||||||
|
console.log("setting allfiles to ", allFiles.val);
|
||||||
|
|
||||||
isOpen.val = true;
|
isOpen.val = true;
|
||||||
// Focus the input after the DOM is updated
|
// Focus the input after the DOM is updated
|
||||||
|
|
@ -103,11 +97,11 @@ export const QuickOpen = (() => {
|
||||||
v.div(
|
v.div(
|
||||||
{ class: "max-h-96 overflow-y-auto" },
|
{ class: "max-h-96 overflow-y-auto" },
|
||||||
() => v.ul(
|
() => v.ul(
|
||||||
filteredFiles.val.map(({ path, ignored }, i) => v.div(
|
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" : ""} ${ignored ? "opacity-50" : ""}`,
|
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: () => {
|
onclick: () => {
|
||||||
selectedIndex.val = i;
|
selectedIndex.val = filteredFiles.val.indexOf(path);
|
||||||
openSelectedFile();
|
openSelectedFile();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue