feat(nvim): navigate to file and open in editor

This commit is contained in:
Pihkaal
2024-05-31 00:46:26 +02:00
parent 66785d425e
commit a4038ae294
3 changed files with 71 additions and 8 deletions

View File

@@ -1 +1,3 @@
export const NvimEditor = () => <div className="h-full">editor</div>; export const NvimEditor = (props: { data: string }) => (
<div className="h-full">{props.data}</div>
);

View File

@@ -3,6 +3,7 @@ import { CHAR_HEIGHT, CHAR_WIDTH } from "../Kitty";
import { type ReactNode, useEffect, useState } from "react"; import { type ReactNode, useEffect, useState } from "react";
import { type InnerKittyProps } from "~/utils/types"; import { type InnerKittyProps } from "~/utils/types";
import { type Nvim } from "."; import { type Nvim } from ".";
import { useNavigate } from "react-router-dom";
type FileIcon = { type FileIcon = {
char: string; char: string;
@@ -12,7 +13,7 @@ type FileIcon = {
type File = { type File = {
name: string; name: string;
} & ( } & (
| { type: "file" } | { type: "file"; directory?: File & { type: "directory" } }
| { type: "directory"; files: Array<string>; folded: boolean } | { type: "directory"; files: Array<string>; folded: boolean }
); );
@@ -41,19 +42,20 @@ const sortFiles = (files: Array<File>) =>
export const NvimTree = (props: InnerKittyProps<typeof Nvim>) => { export const NvimTree = (props: InnerKittyProps<typeof Nvim>) => {
const { rootManifest, activeKitty } = useApp(); const { rootManifest, activeKitty } = useApp();
const navigate = useNavigate();
const [selected, setSelected] = useState(0);
const [files, setFiles] = useState<Array<File>>( const [files, setFiles] = useState<Array<File>>(
sortFiles([ sortFiles([
{ {
type: "directory", type: "directory",
name: "projects", name: "projects",
files: rootManifest.projects, files: rootManifest.projects,
folded: false, folded: true,
}, },
...rootManifest.files.map((name) => ({ type: "file" as const, name })), ...rootManifest.files.map((name) => ({ type: "file" as const, name })),
]), ]),
); );
const [selected, setSelected] = useState(files.length - 1);
const tree: Array<ReactNode> = []; const tree: Array<ReactNode> = [];
let y = 0; let y = 0;
@@ -87,7 +89,11 @@ export const NvimTree = (props: InnerKittyProps<typeof Nvim>) => {
for (let i = 0; i < fileOrDir.files.length; i++) { for (let i = 0; i < fileOrDir.files.length; i++) {
y++; y++;
if (y === selected) if (y === selected)
selectedFile = { type: "file", name: fileOrDir.files[i] }; selectedFile = {
type: "file",
name: fileOrDir.files[i],
directory: fileOrDir,
};
const icon = FILE_ICONS.UNKNOWN; const icon = FILE_ICONS.UNKNOWN;
const fy = y; const fy = y;
@@ -150,7 +156,12 @@ export const NvimTree = (props: InnerKittyProps<typeof Nvim>) => {
if (selectedFile.type === "directory") { if (selectedFile.type === "directory") {
selectedFile.folded = !selectedFile.folded; selectedFile.folded = !selectedFile.folded;
} else { } else {
console.log(`navigate to ${selectedFile.name}`); let filePath = "";
if (selectedFile.directory) {
filePath += `${selectedFile.directory.name}/`;
}
navigate(`?view=${filePath}${selectedFile.name}`);
} }
setFiles([...files]); setFiles([...files]);

View File

@@ -4,9 +4,59 @@ import { NvimEditor } from "./NvimEditor";
import { NvimInput } from "./NvimInput"; import { NvimInput } from "./NvimInput";
import { NvimStatusBar } from "./NvimStatusBar"; import { NvimStatusBar } from "./NvimStatusBar";
import { NvimTree } from "./NvimTree"; import { NvimTree } from "./NvimTree";
import { useLocation, useNavigate } from "react-router-dom";
import { useEffect, useState } from "react";
import axios from "axios";
const fetchData = async (
branch: string,
repo: string,
file: string,
): Promise<string | null> => {
try {
const response = await axios.get<string>(
`https://raw.githubusercontent.com/pihkaal/${repo}/${branch}/${file}`,
);
return response.data;
} catch {
return null;
}
};
export const Nvim = (_props: {}) => { export const Nvim = (_props: {}) => {
const kitty = useKitty(); const kitty = useKitty();
const location = useLocation();
const navigate = useNavigate();
const [data, setData] = useState<string>();
useEffect(() => {
const params = new URLSearchParams(location.search);
const view = params.get("view");
if (!view) {
navigate("?view=README.md");
return;
}
const path = view.split("/");
if (path.length === 1) {
path.splice(0, 0, "pihkaal");
}
const repo = path[0]!;
const file = path[1]!;
void (async () => {
const data =
(await fetchData("main", repo, file)) ??
(await fetchData("dev", repo, file));
if (!data) {
navigate("?view=README.md");
return;
}
setData(data);
})();
}, [location, navigate]);
return ( return (
<div <div
@@ -21,8 +71,8 @@ export const Nvim = (_props: {}) => {
<div style={{ gridArea: "1 / 1 / 1 / 2" }}> <div style={{ gridArea: "1 / 1 / 1 / 2" }}>
<NvimTree {...kitty} /> <NvimTree {...kitty} />
</div> </div>
<div style={{ gridArea: "1 / 2 / 1 / 3" }}> <div style={{ gridArea: "1 / 2 / 1 / 3", overflow: "scroll" }}>
<NvimEditor /> <NvimEditor data={data ?? ""} />
</div> </div>
<div style={{ gridArea: "2 / 1 / 2 / 3" }}> <div style={{ gridArea: "2 / 1 / 2 / 3" }}>
<NvimStatusBar <NvimStatusBar