noshift.js 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ {
2
+ "tabWidth": 2
3
+ }
package/README-ja.md ADDED
@@ -0,0 +1,251 @@
1
+ # noshift.js
2
+
3
+ > Shift キーを押さずに JavaScript を書ける Joke 言語
4
+
5
+ [![npm](https://img.shields.io/npm/v/noshift.js)](https://www.npmjs.com/package/noshift.js)
6
+ [![license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
+ [![en](https://img.shields.io/badge/lang-English_version-blue)](README.md)
8
+
9
+ ---
10
+
11
+ ## インストール
12
+
13
+ ```bash
14
+ npm install -g noshift.js@latest
15
+ ```
16
+
17
+ ---
18
+
19
+ ## はじめに
20
+
21
+ ```bash
22
+ # インタラクティブなプロジェクトスキャフォールド
23
+ nsc create
24
+
25
+ # または、現在のディレクトリに nsjsconfig.json だけを作成
26
+ nsc --init
27
+ ```
28
+
29
+ ---
30
+
31
+ ## CLI リファレンス
32
+
33
+ `nsc` は TypeScript の `tsc` に似た使い心地を目指しています。
34
+
35
+ | コマンド | 説明 |
36
+ |---|---|
37
+ | `nsc` | `nsjsconfig.json` を使って `.nsjs` → `.js` にコンパイル |
38
+ | `nsc -w` / `nsc --watch` | 変更を監視して自動的に再コンパイル |
39
+ | `nsc --init` | 現在のディレクトリに `nsjsconfig.json` を作成 |
40
+ | `nsc --clean` | 出力ディレクトリ (`outDir`) を削除 |
41
+ | `nsc run <file>` | `.nsjs` ファイルを直接実行 |
42
+ | `nsc create [name]` | インタラクティブに新しいプロジェクトを作成 |
43
+ | `nsc -V` | バージョンを表示 |
44
+ | `nsc -h` | ヘルプを表示 |
45
+
46
+ ---
47
+
48
+ ## nsjsconfig.json
49
+
50
+ プロジェクトルートに `nsjsconfig.json` を置くとコンパイル設定を行えます。
51
+ `nsc --init` または `nsc create` で自動生成されます。
52
+
53
+ ```json
54
+ {
55
+ "compilerOptions": {
56
+ "rootDir": "src",
57
+ "outDir": "build"
58
+ }
59
+ }
60
+ ```
61
+
62
+ | オプション | デフォルト | 説明 |
63
+ |---|---|---|
64
+ | `compilerOptions.rootDir` | `"src"` | ソースディレクトリ |
65
+ | `compilerOptions.outDir` | `"build"` | 出力ディレクトリ |
66
+
67
+ ---
68
+
69
+ ## 記号マップ
70
+
71
+ > この変換表は NoShift.js 開発者のキーボード(JIS 配列)が基準です。
72
+
73
+ ![開発者のキーボード](https://raw.githubusercontent.com/otoneko1102/NoShift.js/refs/heads/main/my-keyboard.jpg)
74
+
75
+ | NoShift | JS | | NoShift | JS |
76
+ |:-------:|:--:|---|:-------:|:--:|
77
+ | `^1` | `!` | | `^^` | `~` |
78
+ | `^2` | `"` | | `^\` | `\|` |
79
+ | `^4` | `$` | | `^@` | `` ` `` |
80
+ | `^5` | `%` | | `^[` | `{` |
81
+ | `^6` | `&` | | `^]` | `}` |
82
+ | `^7` | `'` | | `^;` | `+` |
83
+ | `^8` | `(` | | `^:` | `*` |
84
+ | `^9` | `)` | | `^,` | `<` |
85
+ | `^-` | `=` | | `^.` | `>` |
86
+ | | | | `^/` | `?` |
87
+
88
+ テンプレート式: `^4^[` → `${`
89
+
90
+ ---
91
+
92
+ ## 構文サンプル
93
+
94
+ ### Hello World
95
+
96
+ ```nsjs
97
+ console.log^8^2Hello, World!^2^9;
98
+ ```
99
+
100
+ ```js
101
+ console.log("Hello, World!");
102
+ ```
103
+
104
+ ### 変数とアロー関数
105
+
106
+ ```nsjs
107
+ const add ^- ^8a, b^9 ^-^. a ^; b;
108
+
109
+ const result ^- add^85, 3^9;
110
+ console.log^8result^9; // 8
111
+ ```
112
+
113
+ ```js
114
+ const add = (a, b) => a + b;
115
+
116
+ const result = add(5, 3);
117
+ console.log(result); // 8
118
+ ```
119
+
120
+ ### 文字列
121
+
122
+ ```nsjs
123
+ // ダブルクォート文字列
124
+ const s1 ^- ^2Hello^2;
125
+
126
+ // シングルクォート文字列
127
+ const s2 ^- ^7World^7;
128
+
129
+ // テンプレートリテラル
130
+ const s3 ^- ^@^4^[s1^] ^4^[s2^]^@;
131
+
132
+ // エスケープ: ^2...^2 内の \^2 はリテラルの ^2 に展開される
133
+ const s4 ^- ^2quote: \^2^2;
134
+ ```
135
+
136
+ ```js
137
+ const s1 = "Hello";
138
+ const s2 = 'World';
139
+ const s3 = `Hello World`;
140
+ const s4 = "quote: ^2";
141
+ ```
142
+
143
+ ### オブジェクトと配列
144
+
145
+ ```nsjs
146
+ const obj ^- ^[
147
+ name: ^2NoShift^2,
148
+ version: 1,
149
+ isJoke: true
150
+ ^];
151
+
152
+ const arr ^- [1, 2, 3];
153
+ ```
154
+
155
+ ```js
156
+ const obj = {
157
+ name: "NoShift",
158
+ version: 1,
159
+ isJoke: true
160
+ };
161
+
162
+ const arr = [1, 2, 3];
163
+ ```
164
+
165
+ ### クラス
166
+
167
+ ```nsjs
168
+ class Animal ^[
169
+ constructor^8name^9 ^[
170
+ this.name ^- name;
171
+ ^]
172
+
173
+ speak^8^9 ^[
174
+ console.log^8^@^4^[this.name^] speaks.^@^9;
175
+ ^]
176
+ ^]
177
+
178
+ const dog ^- new Animal^8^2Dog^2^9;
179
+ dog.speak^8^9;
180
+ ```
181
+
182
+ ```js
183
+ class Animal {
184
+ constructor(name) {
185
+ this.name = name;
186
+ }
187
+
188
+ speak() {
189
+ console.log(`${this.name} speaks.`);
190
+ }
191
+ }
192
+
193
+ const dog = new Animal("Dog");
194
+ dog.speak();
195
+ ```
196
+
197
+ ### 条件分岐とループ
198
+
199
+ ```nsjs
200
+ const x ^- 10;
201
+
202
+ if ^8x ^. 5^9 ^[
203
+ console.log^8^2big^2^9;
204
+ ^] else ^[
205
+ console.log^8^2small^2^9;
206
+ ^]
207
+
208
+ for ^8let i ^- 0; i ^, 3; i^;^;^9 ^[
209
+ console.log^8i^9;
210
+ ^]
211
+ ```
212
+
213
+ ```js
214
+ const x = 10;
215
+
216
+ if (x > 5) {
217
+ console.log("big");
218
+ } else {
219
+ console.log("small");
220
+ }
221
+
222
+ for (let i = 0; i < 3; i++) {
223
+ console.log(i);
224
+ }
225
+ ```
226
+
227
+ ---
228
+
229
+ ## ファイル名の規則
230
+
231
+ `_` で始まるファイルはコンパイル対象から除外されます(パーシャル・ユーティリティ用途に便利)。
232
+
233
+ ```
234
+ src/
235
+ index.nsjs ← コンパイルされる
236
+ _helpers.nsjs ← スキップされる
237
+ ```
238
+
239
+ ---
240
+
241
+ ## リンク
242
+
243
+ - [VS Code 拡張機能](https://marketplace.visualstudio.com/items?itemName=otoneko1102.noshift-vscode)
244
+ - [ウェブサイト](https://noshift.js.org)
245
+ - [リポジトリ](https://github.com/otoneko1102/NoShift.js)
246
+
247
+ ---
248
+
249
+ ## ライセンス
250
+
251
+ MIT © otoneko.
package/README.md CHANGED
@@ -1,79 +1,251 @@
1
- # NoShift.js
2
-
3
- ## Setup
4
- ```bash
5
- npm install -g noshift.js@latest
6
- npx nsjs create
7
- ```
8
-
9
- ## English
10
-
11
- ### Language
12
- NoShift.js
13
-
14
- ### Extension
15
- `.nsjs`
16
-
17
- ### Summary
18
- Typing symbols with Shift is tiring. NoShift.js is a JavaScript-like language that allows you to write JavaScript **without using the Shift key**.
19
- It compiles to plain JavaScript.
20
-
21
- The mapping is based on the keyboard layout of the creator’s laptop.
22
-
23
- ## 日本語
24
- ### 言語名
25
- NoShift.js
26
-
27
- ### 張子
28
- .nsjs
29
-
30
- ### 概略
31
- 記号を入力するときに Shift を押すのが面倒なので、Shift を押さずに JavaScript が書ける言語を作りました。
32
- NoShift.js は JavaScript に変換されます。
33
-
34
- この記号変換の基準は、作者のノートパソコンのキーボード配列です。
35
-
36
- ```
37
- ! --> ^1
38
- " --> ^2
39
- $ --> ^4
40
- % --> ^5
41
- & --> ^6
42
- ' --> ^7
43
- ( --> ^8
44
- ) --> ^9
45
- = --> ^-
46
- ~ --> ^^
47
- | --> ^\
48
- ` --> ^@
49
- { --> ^[
50
- } --> ^]
51
- + --> ^;
52
- * --> ^:
53
- < --> ^,
54
- > --> ^.
55
- ? --> ^/
56
- ```
57
-
58
- ### Escaping in strings
59
- Examples:
60
- ```nsjs
61
- ^2^5^2 --> "^5"
62
- ^7^5^7 --> '^5'
63
- ^@^5^@ --> `^5`
64
- ```
65
- Template literals (${} syntax)
66
-
67
- ```nsjs
68
- ^@^5^4^[^2Hello World!^2^]^@ --> `^5${"Hello World!"}`
69
- ```
70
- Hello World!
71
- Example:
72
-
73
- ```nsjs
74
- console.log^8^2Hello World!^2^9;
75
- Result:
76
- ```
77
- ```js
78
- console.log("Hello World!");
79
- ```
1
+ # noshift.js
2
+
3
+ > A joke language that lets you write JavaScript without pressing the Shift key.
4
+
5
+ [![npm](https://img.shields.io/npm/v/noshift.js)](https://www.npmjs.com/package/noshift.js)
6
+ [![license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
+ [![ja](https://img.shields.io/badge/lang-日本語_バージョン-red)](README-ja.md)
8
+
9
+ ---
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install -g noshift.js@latest
15
+ ```
16
+
17
+ ---
18
+
19
+ ## Getting Started
20
+
21
+ ```bash
22
+ # Interactive full project scaffold
23
+ nsc create
24
+
25
+ # Or initialize only a nsjsconfig.json in the current directory
26
+ nsc --init
27
+ ```
28
+
29
+ ---
30
+
31
+ ## CLI Reference
32
+
33
+ `nsc` is designed to feel like TypeScript's `tsc`.
34
+
35
+ | Command | Description |
36
+ |---|---|
37
+ | `nsc` | Compile `.nsjs` → `.js` using `nsjsconfig.json` |
38
+ | `nsc -w` / `nsc --watch` | Watch for changes and recompile automatically |
39
+ | `nsc --init` | Create `nsjsconfig.json` in the current directory |
40
+ | `nsc --clean` | Delete the output directory (`outDir`) |
41
+ | `nsc run <file>` | Run a `.nsjs` file directly |
42
+ | `nsc create [name]` | Scaffold a new project interactively |
43
+ | `nsc -V` | Show version |
44
+ | `nsc -h` | Show help |
45
+
46
+ ---
47
+
48
+ ## nsjsconfig.json
49
+
50
+ Place a `nsjsconfig.json` at the project root to configure compilation.
51
+ Generated automatically by `nsc --init` or `nsc create`.
52
+
53
+ ```json
54
+ {
55
+ "compilerOptions": {
56
+ "rootDir": "src",
57
+ "outDir": "build"
58
+ }
59
+ }
60
+ ```
61
+
62
+ | Option | Default | Description |
63
+ |---|---|---|
64
+ | `compilerOptions.rootDir` | `"src"` | Source directory |
65
+ | `compilerOptions.outDir` | `"build"` | Output directory |
66
+
67
+ ---
68
+
69
+ ## Symbol Map
70
+
71
+ > This symbol mapping is based on the NoShift.js developer's keyboard (JIS layout).
72
+
73
+ ![Developer's Keyboard](https://raw.githubusercontent.com/otoneko1102/NoShift.js/refs/heads/main/my-keyboard.jpg)
74
+
75
+ | NoShift | JS | | NoShift | JS |
76
+ |:-------:|:--:|---|:-------:|:--:|
77
+ | `^1` | `!` | | `^^` | `~` |
78
+ | `^2` | `"` | | `^\` | `\|` |
79
+ | `^4` | `$` | | `^@` | `` ` `` |
80
+ | `^5` | `%` | | `^[` | `{` |
81
+ | `^6` | `&` | | `^]` | `}` |
82
+ | `^7` | `'` | | `^;` | `+` |
83
+ | `^8` | `(` | | `^:` | `*` |
84
+ | `^9` | `)` | | `^,` | `<` |
85
+ | `^-` | `=` | | `^.` | `>` |
86
+ | | | | `^/` | `?` |
87
+
88
+ Template expression: `^4^[` → `${`
89
+
90
+ ---
91
+
92
+ ## Syntax Examples
93
+
94
+ ### Hello World
95
+
96
+ ```nsjs
97
+ console.log^8^2Hello, World!^2^9;
98
+ ```
99
+
100
+ ```js
101
+ console.log("Hello, World!");
102
+ ```
103
+
104
+ ### Variables & Arrow Functions
105
+
106
+ ```nsjs
107
+ const add ^- ^8a, b^9 ^-^. a ^; b;
108
+
109
+ const result ^- add^85, 3^9;
110
+ console.log^8result^9; // 8
111
+ ```
112
+
113
+ ```js
114
+ const add = (a, b) => a + b;
115
+
116
+ const result = add(5, 3);
117
+ console.log(result); // 8
118
+ ```
119
+
120
+ ### Strings
121
+
122
+ ```nsjs
123
+ // Double-quote string
124
+ const s1 ^- ^2Hello^2;
125
+
126
+ // Single-quote string
127
+ const s2 ^- ^7World^7;
128
+
129
+ // Template literal
130
+ const s3 ^- ^@^4^[s1^] ^4^[s2^]^@;
131
+
132
+ // Escape: \^2 inside ^2...^2 yields a literal ^2 in the output
133
+ const s4 ^- ^2quote: \^2^2;
134
+ ```
135
+
136
+ ```js
137
+ const s1 = "Hello";
138
+ const s2 = 'World';
139
+ const s3 = `Hello World`;
140
+ const s4 = "quote: ^2";
141
+ ```
142
+
143
+ ### Objects & Arrays
144
+
145
+ ```nsjs
146
+ const obj ^- ^[
147
+ name: ^2NoShift^2,
148
+ version: 1,
149
+ isJoke: true
150
+ ^];
151
+
152
+ const arr ^- [1, 2, 3];
153
+ ```
154
+
155
+ ```js
156
+ const obj = {
157
+ name: "NoShift",
158
+ version: 1,
159
+ isJoke: true
160
+ };
161
+
162
+ const arr = [1, 2, 3];
163
+ ```
164
+
165
+ ### Classes
166
+
167
+ ```nsjs
168
+ class Animal ^[
169
+ constructor^8name^9 ^[
170
+ this.name ^- name;
171
+ ^]
172
+
173
+ speak^8^9 ^[
174
+ console.log^8^@^4^[this.name^] speaks.^@^9;
175
+ ^]
176
+ ^]
177
+
178
+ const dog ^- new Animal^8^2Dog^2^9;
179
+ dog.speak^8^9;
180
+ ```
181
+
182
+ ```js
183
+ class Animal {
184
+ constructor(name) {
185
+ this.name = name;
186
+ }
187
+
188
+ speak() {
189
+ console.log(`${this.name} speaks.`);
190
+ }
191
+ }
192
+
193
+ const dog = new Animal("Dog");
194
+ dog.speak();
195
+ ```
196
+
197
+ ### Conditionals & Loops
198
+
199
+ ```nsjs
200
+ const x ^- 10;
201
+
202
+ if ^8x ^. 5^9 ^[
203
+ console.log^8^2big^2^9;
204
+ ^] else ^[
205
+ console.log^8^2small^2^9;
206
+ ^]
207
+
208
+ for ^8let i ^- 0; i ^, 3; i^;^;^9 ^[
209
+ console.log^8i^9;
210
+ ^]
211
+ ```
212
+
213
+ ```js
214
+ const x = 10;
215
+
216
+ if (x > 5) {
217
+ console.log("big");
218
+ } else {
219
+ console.log("small");
220
+ }
221
+
222
+ for (let i = 0; i < 3; i++) {
223
+ console.log(i);
224
+ }
225
+ ```
226
+
227
+ ---
228
+
229
+ ## File Naming
230
+
231
+ Files starting with `_` are excluded from compilation (useful for partials/utilities).
232
+
233
+ ```
234
+ src/
235
+ index.nsjs ← compiled
236
+ _helpers.nsjs ← skipped
237
+ ```
238
+
239
+ ---
240
+
241
+ ## Links
242
+
243
+ - [VS Code Extension](https://marketplace.visualstudio.com/items?itemName=otoneko1102.noshift-vscode)
244
+ - [Website](https://noshift.js.org)
245
+ - [Repository](https://github.com/otoneko1102/NoShift.js)
246
+
247
+ ---
248
+
249
+ ## License
250
+
251
+ MIT © otoneko.
package/bin/cli.js CHANGED
@@ -1,11 +1,57 @@
1
- #!/usr/bin/env node
2
-
3
- import create from "../commands/create.js";
4
-
5
- const command = process.argv[2];
6
-
7
- if (command === "create") {
8
- create();
9
- } else {
10
- console.log("Unknown command.");
11
- }
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from "commander";
4
+ import { readFileSync } from "fs";
5
+ import { fileURLToPath } from "url";
6
+ import path from "path";
7
+
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+ const pkg = JSON.parse(
10
+ readFileSync(path.join(__dirname, "../package.json"), "utf-8"),
11
+ );
12
+
13
+ const program = new Command();
14
+
15
+ // nsc [options] ← デフォルト動作: compile
16
+ program
17
+ .name("nsc")
18
+ .description("NoShift.js compiler")
19
+ .version(pkg.version)
20
+ .option("-w, --watch", "Watch for file changes and recompile")
21
+ .option("--init", "Create a nsjsconfig.json in the current directory")
22
+ .option("--clean", "Delete the output directory (outDir)")
23
+ .action(async (options) => {
24
+ if (options.init) {
25
+ const { default: init } = await import("../commands/init.js");
26
+ await init();
27
+ } else if (options.clean) {
28
+ const { default: clean } = await import("../commands/clean.js");
29
+ await clean();
30
+ } else if (options.watch) {
31
+ const { default: dev } = await import("../commands/dev.js");
32
+ await dev();
33
+ } else {
34
+ const { default: compile } = await import("../commands/compile.js");
35
+ await compile();
36
+ }
37
+ });
38
+
39
+ // nsc run <file>
40
+ program
41
+ .command("run <file>")
42
+ .description("Run a .nsjs file directly")
43
+ .action(async (file) => {
44
+ const { default: run } = await import("../commands/run.js");
45
+ await run(file);
46
+ });
47
+
48
+ // nsc create [name] ← 対話式プロジェクト作成
49
+ program
50
+ .command("create [name]")
51
+ .description("Scaffold a new NoShift.js project interactively")
52
+ .action(async (name) => {
53
+ const { default: create } = await import("../commands/create.js");
54
+ await create(name);
55
+ });
56
+
57
+ program.parse();
@@ -0,0 +1,29 @@
1
+ import { rm, access } from "fs/promises";
2
+ import path from "path";
3
+ import { loadConfig } from "../src/config.js";
4
+
5
+ export default async function clean() {
6
+ const cwd = process.cwd();
7
+
8
+ let config;
9
+ try {
10
+ config = await loadConfig(cwd);
11
+ } catch (e) {
12
+ console.error(`error NS0: ${e.message}`);
13
+ process.exit(1);
14
+ }
15
+
16
+ const outDir = path.resolve(cwd, config.compilerOptions.outDir);
17
+
18
+ try {
19
+ await access(outDir);
20
+ } catch {
21
+ console.log(
22
+ `Nothing to clean ('${config.compilerOptions.outDir}' does not exist).`,
23
+ );
24
+ return;
25
+ }
26
+
27
+ await rm(outDir, { recursive: true, force: true });
28
+ console.log(`Deleted '${config.compilerOptions.outDir}'.`);
29
+ }