Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ updates:
open-pull-requests-limit: 5
reviewers:
- Docyrus/system
# The SDK is patched by scripts/patch-native-sdk-pointer.mjs and Monaco is
# vendored under frontend/dist/vs, so both need a human upgrade, not a bump.
# The SDK is patched by the scripts/patch-native-sdk-*.mjs files and Monaco
# is vendored under frontend/dist/vs, so both need a human upgrade, not a bump.
ignore:
- dependency-name: "@native-sdk/cli"
- dependency-name: "@native-sdk/core"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The installer places `Docyrus Open IDE.app` in `/Applications`, clears the downl
- Keep a completely independent pane layout, tabs, split mode, explorer state, and terminal pair for each open project.
- Reorder tabs or move them between panes with drag and drop.
- Edit local code, text, and Markdown files in Monaco; Markdown updates its native preview after save.
- Open code and text documents from Finder's Open With menu. Files outside an added project are collected in the pathless Other Open Files workspace.
- Preview local images with the Native SDK Image component.
- Choose Dark Mode, Light Mode, or System Default in Settings.

Expand Down
48 changes: 47 additions & 1 deletion app.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,53 @@
"icons": ["assets/docyrus-open-ide-icon.png"],
"platforms": ["macos"],
"permissions": ["view", "command", "clipboard", "filesystem"],
"capabilities": ["native_views", "gpu_surfaces", "webview", "js_bridge", "clipboard", "reveal_path"],
"capabilities": ["native_views", "gpu_surfaces", "webview", "js_bridge", "clipboard", "reveal_path", "file_associations"],
"file_associations": [
{
"name": "Code and Text Document",
"role": "editor",
"extensions": [
"txt", "md", "markdown", "mdx", "json", "jsonc", "yaml", "yml",
"toml", "xml", "csv", "tsv", "ini", "cfg", "conf", "log",
"c", "h", "cpp", "hpp", "m", "mm", "swift", "zig",
"rs", "go", "java", "kt", "py", "rb", "js", "ts"
],
"mime_types": ["text/plain"]
},
{
"name": "Web and Script Source",
"role": "editor",
"extensions": [
"mjs", "cjs", "jsx", "mts", "cts", "tsx", "html", "htm",
"css", "scss", "sass", "less", "vue", "svelte", "astro", "php",
"sh", "bash", "zsh", "fish", "ps1", "bat", "cmd", "sql",
"graphql", "gql", "proto", "lua", "pl", "pm", "r", "dart"
],
"mime_types": ["text/plain"]
},
{
"name": "Configuration and Documentation",
"role": "editor",
"extensions": [
"json5", "properties", "env", "editorconfig", "gitignore", "gitattributes", "npmrc", "nvmrc",
"rst", "adoc", "asciidoc", "tex", "bib", "org", "wiki", "textile",
"gradle", "kts", "cmake", "mk", "podspec", "lock", "diff", "patch",
"dockerignore", "eslintignore", "prettierignore", "stylelintignore", "tf", "tfvars", "hcl", "cue"
],
"mime_types": ["text/plain"]
},
{
"name": "Additional Source Code",
"role": "editor",
"extensions": [
"cs", "fs", "fsx", "vb", "scala", "sc", "groovy", "gvy",
"clj", "cljs", "cljc", "edn", "ex", "exs", "erl", "hrl",
"hs", "lhs", "elm", "ml", "mli", "pas", "asm", "s",
"v", "vhd", "vhdl", "sol", "tcl", "vim", "wasm", "wat"
],
"mime_types": ["text/plain"]
}
],
"bridge": {
"commands": [
{ "name": "workspace.listTree", "permissions": ["filesystem"], "origins": ["zero://app"] },
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"description": "A lightweight Native SDK editor with Monaco, Markdown preview, and terminal panes.",
"scripts": {
"patch:native-sdk": "node scripts/patch-native-sdk-pointer.mjs",
"patch:native-sdk": "node scripts/patch-native-sdk-pointer.mjs && node scripts/patch-native-sdk-open-files.mjs",
"postinstall": "npm run patch:native-sdk",
"bundle:tree": "esbuild frontend/tree.js --bundle --format=iife --platform=browser --target=safari16 --outfile=frontend/dist/tree.js",
"precheck": "npm run patch:native-sdk && npm run bundle:tree",
Expand Down
30 changes: 30 additions & 0 deletions scripts/patch-native-sdk-open-files.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { readFileSync, writeFileSync } from "node:fs";
import { fileURLToPath } from "node:url";

const target = fileURLToPath(
new URL("../node_modules/@native-sdk/cli/src/platform/macos/appkit_host.m", import.meta.url),
);
const source = readFileSync(target, "utf8");
const marker = "// Docyrus forwards Finder/Open With document requests through the existing file event seam.";

if (!source.includes(marker)) {
const insertionPoint = "@implementation NativeSdkAppDelegate\n\n";
const implementation = `${insertionPoint}${marker}
- (void)application:(NSApplication *)sender openFiles:(NSArray<NSString *> *)filenames {
NSMutableArray<NSURL *> *urls = [NSMutableArray arrayWithCapacity:filenames.count];
for (NSString *filename in filenames) {
if (filename.length > 0) [urls addObject:[NSURL fileURLWithPath:filename]];
}
const BOOL accepted = [self.host emitDroppedFileURLs:urls
windowId:1
viewLabel:@"__docyrus_open_files__"
point:NSMakePoint(-1, -1)];
[sender replyToOpenOrPrint:accepted ? NSApplicationDelegateReplySuccess : NSApplicationDelegateReplyFailure];
}

`;
if (!source.includes(insertionPoint)) {
throw new Error("The Native SDK AppKit delegate changed; update the Docyrus open-document patch.");
}
writeFileSync(target, source.replace(insertionPoint, implementation));
}
8 changes: 6 additions & 2 deletions src/app.native
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,12 @@
</row>
<separator />

<if test="{has_projects}">
<split grow="1" value="{project_sidebar_fraction}" on-resize="project_sidebar_resized" gap="1">
<column min-width="160" max-width="360" background="surface_subtle" label="Project Folders">
<scroll grow="1">
<column padding="6" gap="4">
<for each="openProjects" key="path" as="project">
<for each="openProjects" key="id" as="project">
<panel height="56" role="button" selected="{project.selected}" on-press="select_project:{project.id}" on-drag="drag_project:{project.id}" on-hover-enter="hover_project:{project.id}" on-hover-leave="leave_project:{project.id}" label="{project.path}">
<row padding="6" gap="4" cross="start">
<column grow="1" gap="3" cross="start">
Expand Down Expand Up @@ -269,6 +270,7 @@
<else><use template="workspace" /></else>
</row>
</split>
</if>

<if test="{rename_project_open}">
<dialog label="Rename project" on-dismiss="cancel_rename_project">
Expand Down Expand Up @@ -312,7 +314,9 @@
</scroll>
</if>
<else><text foreground="text_muted">No recent projects yet.</text></else>
<row main="end"><button variant="ghost" on-press="close_add_project">Cancel</button></row>
<if test="{has_projects}">
<row main="end"><button variant="ghost" on-press="close_add_project">Cancel</button></row>
</if>
</column>
</dialog>
</if>
Expand Down
Loading
Loading