@rhseung/ps-cli 1.13.1 → 1.14.2

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.
package/README.md CHANGED
@@ -17,6 +17,18 @@ npm install -g @rhseung/ps-cli
17
17
  bun install -g @rhseung/ps-cli
18
18
  ```
19
19
 
20
+ ### zsh 자동 완성
21
+
22
+ zsh 사용자는 다음 명령어로 자동 완성을 설치할 수 있습니다:
23
+
24
+ ```bash
25
+ ps completion --install
26
+ ```
27
+
28
+ 이 명령은 `.zshrc`에 필요한 설정을 자동으로 추가합니다. 적용하려면 새 터미널을 열거나 `exec zsh`를 실행하세요.
29
+
30
+ 수동 설치가 필요하면 `ps completion`으로 안내를 확인할 수 있습니다.
31
+
20
32
  ## 빠른 시작
21
33
 
22
34
  ```bash
@@ -415,6 +427,30 @@ ps config clear # .ps-cli 폴더 및 모든 설정 삭제
415
427
  - 설정은 현재 프로젝트의 .ps-cli 디렉토리 내에 저장됩니다
416
428
  - 대화형 모드로 키와 값을 선택할 수 있습니다
417
429
 
430
+ ---
431
+
432
+ ### `completion` - zsh 자동 완성 설치
433
+
434
+ zsh 자동 완성 설치 방법을 표시하거나 `.zshrc`에 자동으로 추가합니다.
435
+
436
+ **사용법:**
437
+
438
+ ```bash
439
+ ps completion [옵션]
440
+ ```
441
+
442
+ **옵션:**
443
+
444
+ - `--help`, `-h`: 도움말 표시
445
+ - `--install`: `.zshrc`에 자동 완성 설정을 자동으로 추가
446
+
447
+ **예제:**
448
+
449
+ ```bash
450
+ ps completion --install # 자동 설치 (권장)
451
+ ps completion # 수동 설치 안내 표시
452
+ ```
453
+
418
454
  ## 설정
419
455
 
420
456
  프로젝트 루트의 `.ps-cli/config.yaml` 파일에 저장됩니다.
@@ -0,0 +1,147 @@
1
+ #compdef ps
2
+ # ps-cli zsh completion script
3
+
4
+ local -a subcmds
5
+ subcmds=(
6
+ 'init:프로젝트 초기화'
7
+ 'fetch:문제 가져오기'
8
+ 'test:로컬 테스트'
9
+ 'run:코드 실행'
10
+ 'submit:제출'
11
+ 'archive:아카이빙'
12
+ 'solving:풀이 중인 문제 목록'
13
+ 'open:문제 페이지 또는 에디터 열기'
14
+ 'search:문제 검색'
15
+ 'stats:통계 조회'
16
+ 'config:설정 관리'
17
+ 'completion:zsh 자동 완성 설치 방법'
18
+ 'help:도움말 표시'
19
+ )
20
+
21
+ local -a languages
22
+ languages=(python javascript typescript cpp)
23
+
24
+ local -a config_subcmds
25
+ config_subcmds=(get set list clear)
26
+
27
+ local -a config_keys
28
+ config_keys=(
29
+ 'general.default-language:기본 언어'
30
+ 'general.solved-ac-handle:Solved.ac 핸들'
31
+ 'editor.command:에디터 명령어'
32
+ 'editor.auto-open:자동 에디터 열기'
33
+ 'paths.solving:Solving 디렉토리'
34
+ 'paths.archive:아카이브 디렉토리'
35
+ 'paths.archive-strategy:아카이빙 전략'
36
+ 'archive.auto-commit:자동 Git 커밋'
37
+ 'archive.commit-message:커밋 메시지 템플릿'
38
+ 'markdown.include-tag:태그 포함 여부'
39
+ )
40
+
41
+ local -a archive_strategies
42
+ archive_strategies=(flat 'by-range' 'by-tier' 'by-tag')
43
+
44
+ _ps() {
45
+ local context state line
46
+ typeset -A opt_args
47
+
48
+ _arguments -C \
49
+ '(-h --help)'{-h,--help}'[도움말 표시]' \
50
+ '1: :->cmd' \
51
+ '*::arg:->args'
52
+
53
+ case $state in
54
+ cmd)
55
+ _describe '명령어' subcmds
56
+ ;;
57
+ args)
58
+ case ${words[2]} in
59
+ init)
60
+ _arguments \
61
+ '(-h --help)'{-h,--help}'[도움말 표시]'
62
+ ;;
63
+ fetch)
64
+ _arguments \
65
+ '(-h --help)'{-h,--help}'[도움말 표시]' \
66
+ '(-l --language)'{-l,--language}'[언어 선택]:언어:($languages)' \
67
+ ':문제번호:'
68
+ ;;
69
+ test)
70
+ _arguments \
71
+ '(-h --help)'{-h,--help}'[도움말 표시]' \
72
+ '(-l --language)'{-l,--language}'[언어 선택]:언어:($languages)' \
73
+ '(-w --watch)'{-w,--watch}'[watch 모드]' \
74
+ '(-f --file)'{-f,--file}'[solution 파일 지정]:파일:_files' \
75
+ '(--index)'--index'[인덱스로 지정]:인덱스:' \
76
+ ':문제번호:'
77
+ ;;
78
+ run)
79
+ _arguments \
80
+ '(-h --help)'{-h,--help}'[도움말 표시]' \
81
+ '(-l --language)'{-l,--language}'[언어 선택]:언어:($languages)' \
82
+ '(-i --input)'{-i,--input}'[입력 파일]:파일:_files' \
83
+ '(-f --file)'{-f,--file}'[solution 파일 지정]:파일:_files' \
84
+ '(--index)'--index'[인덱스로 지정]:인덱스:' \
85
+ ':문제번호:'
86
+ ;;
87
+ submit)
88
+ _arguments \
89
+ '(-h --help)'{-h,--help}'[도움말 표시]' \
90
+ '(-l --language)'{-l,--language}'[언어 선택]:언어:($languages)' \
91
+ '(-f --file)'{-f,--file}'[solution 파일 지정]:파일:_files' \
92
+ '(-i --index)'{-i,--index}'[인덱스로 지정]:인덱스:' \
93
+ ':문제번호:'
94
+ ;;
95
+ archive)
96
+ _arguments \
97
+ '(-h --help)'{-h,--help}'[도움말 표시]' \
98
+ ':문제번호:'
99
+ ;;
100
+ solving)
101
+ _arguments \
102
+ '(-h --help)'{-h,--help}'[도움말 표시]'
103
+ ;;
104
+ open)
105
+ _arguments \
106
+ '(-h --help)'{-h,--help}'[도움말 표시]' \
107
+ '(-w --workbook)'{-w,--workbook}'[문제집 ID]:ID:' \
108
+ '(-e --editor)'{-e,--editor}'[에디터로 열기]' \
109
+ ':문제번호:'
110
+ ;;
111
+ search)
112
+ _arguments \
113
+ '(-h --help)'{-h,--help}'[도움말 표시]' \
114
+ '(--workbook)'--workbook'[문제집 ID]:ID:' \
115
+ ':검색 쿼리:'
116
+ ;;
117
+ stats)
118
+ _arguments \
119
+ '(-h --help)'{-h,--help}'[도움말 표시]' \
120
+ '(--handle)'--handle'[Solved.ac 핸들]:핸들:' \
121
+ ':핸들:'
122
+ ;;
123
+ config)
124
+ _arguments \
125
+ '(-h --help)'{-h,--help}'[도움말 표시]' \
126
+ '1:config 명령어:($config_subcmds)' \
127
+ '2:설정 키:($config_keys)' \
128
+ '3:값:'
129
+ ;;
130
+ completion)
131
+ _arguments \
132
+ '(-h --help)'{-h,--help}'[도움말 표시]' \
133
+ '(--install)'--install'[.zshrc에 자동 완성 설정 추가]'
134
+ ;;
135
+ help)
136
+ _describe '명령어' subcmds
137
+ ;;
138
+ *)
139
+ _arguments \
140
+ '(-h --help)'{-h,--help}'[도움말 표시]'
141
+ ;;
142
+ esac
143
+ ;;
144
+ esac
145
+ }
146
+
147
+ _ps "$@"
@@ -27,7 +27,7 @@ async function openEditor(path) {
27
27
  await execaCommand(`${editor} ${path}`, {
28
28
  shell: true,
29
29
  detached: true,
30
- stdio: "ignore"
30
+ stdio: "inherit"
31
31
  });
32
32
  }
33
33
 
@@ -321,7 +321,7 @@ function useFetchProblem({
321
321
  await execaCommand(`${editor} ${problemDir}`, {
322
322
  shell: true,
323
323
  detached: true,
324
- stdio: "ignore"
324
+ stdio: "inherit"
325
325
  });
326
326
  setMessage(
327
327
  `\uBB38\uC81C \uD30C\uC77C\uC774 \uC0DD\uC131\uB418\uC5C8\uC2B5\uB2C8\uB2E4: ${problemDir}
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  useFetchProblem
4
- } from "./chunk-ZAIU4LPX.js";
4
+ } from "./chunk-QZJUVKM7.js";
5
5
  import {
6
6
  Command,
7
7
  CommandBuilder,
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ CommandBuilder,
4
+ defineFlags,
5
+ logger
6
+ } from "../chunk-E5PL24PI.js";
7
+
8
+ // src/commands/completion.tsx
9
+ import { existsSync, readFileSync, appendFileSync } from "fs";
10
+ import { dirname, join } from "path";
11
+ import { fileURLToPath } from "url";
12
+ var __dirname = dirname(fileURLToPath(import.meta.url));
13
+ var COMPLETION_MARKER = "# ps-cli zsh completion";
14
+ var COMPLETION_END_MARKER = "# end ps-cli zsh completion";
15
+ function getZshrcPath() {
16
+ const home = process.env.HOME || process.env.USERPROFILE;
17
+ if (!home) {
18
+ throw new Error("HOME \uD658\uACBD \uBCC0\uC218\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
19
+ }
20
+ return join(home, ".zshrc");
21
+ }
22
+ function getCompletionBlock(completionsDir) {
23
+ return `
24
+ ${COMPLETION_MARKER}
25
+ fpath=("${completionsDir}" $fpath)
26
+ autoload -U compinit && compinit
27
+ ${COMPLETION_END_MARKER}
28
+ `;
29
+ }
30
+ function isAlreadyInstalled(zshrcPath) {
31
+ if (!existsSync(zshrcPath)) return false;
32
+ const content = readFileSync(zshrcPath, "utf-8");
33
+ return content.includes(COMPLETION_MARKER);
34
+ }
35
+ var completion_default = CommandBuilder.define(
36
+ "completion",
37
+ "zsh \uC790\uB3D9 \uC644\uC131 \uC124\uCE58 \uBC29\uBC95\uC744 \uD45C\uC2DC\uD558\uAC70\uB098 \uC790\uB3D9\uC73C\uB85C \uC124\uCE58\uD569\uB2C8\uB2E4.",
38
+ async (_args, flags) => {
39
+ const packageRoot = join(__dirname, "..", "..");
40
+ const completionsDir = join(packageRoot, "completions");
41
+ const completionsPath = join(completionsDir, "_ps");
42
+ if (!existsSync(completionsPath)) {
43
+ logger.error("completions \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
44
+ console.log(` \uC608\uC0C1 \uACBD\uB85C: ${completionsPath}`);
45
+ process.exit(1);
46
+ return;
47
+ }
48
+ if (flags.install) {
49
+ const zshrcPath = getZshrcPath();
50
+ if (isAlreadyInstalled(zshrcPath)) {
51
+ logger.success("zsh \uC790\uB3D9 \uC644\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4.");
52
+ logger.dim(` \uC124\uC815 \uC704\uCE58: ${zshrcPath}
53
+ `);
54
+ return;
55
+ }
56
+ try {
57
+ appendFileSync(zshrcPath, getCompletionBlock(completionsDir));
58
+ logger.success("zsh \uC790\uB3D9 \uC644\uC131\uC774 \uC124\uCE58\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
59
+ console.log(`
60
+ ${logger.dim("\uC124\uC815\uC774 .zshrc\uC5D0 \uCD94\uAC00\uB418\uC5C8\uC2B5\uB2C8\uB2E4.")}
61
+ ${logger.dim("\uC801\uC6A9: \uC0C8 \uD130\uBBF8\uB110\uC744 \uC5F4\uAC70\uB098")} exec zsh ${logger.dim("\uC2E4\uD589")}
62
+
63
+ `);
64
+ } catch (err) {
65
+ logger.error("\uC124\uCE58\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.");
66
+ console.error(err);
67
+ process.exit(1);
68
+ return;
69
+ }
70
+ return;
71
+ }
72
+ logger.bold("\n zsh \uC790\uB3D9 \uC644\uC131 \uC124\uCE58\n");
73
+ console.log(`
74
+ \uC790\uB3D9 \uC124\uCE58 (\uAD8C\uC7A5):
75
+
76
+ ps completion --install
77
+
78
+ \uC218\uB3D9 \uC124\uCE58:
79
+
80
+ .zshrc\uC5D0 \uB2E4\uC74C\uC744 \uCD94\uAC00\uD558\uC138\uC694:
81
+
82
+ ${logger.dim("# ps-cli zsh completion")}
83
+ fpath=("${completionsDir}" $fpath)
84
+ autoload -U compinit && compinit
85
+
86
+ \uC801\uC6A9: \uBCC0\uACBD \uD6C4 \uC0C8 \uD130\uBBF8\uB110\uC744 \uC5F4\uAC70\uB098 \`exec zsh\` \uC2E4\uD589
87
+
88
+ `);
89
+ logger.dim(
90
+ ' \uC644\uB8CC \uD6C4 "ps " \uC785\uB825 \uD6C4 Tab\uC744 \uB20C\uB7EC \uC790\uB3D9 \uC644\uC131\uC744 \uD655\uC778\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n'
91
+ );
92
+ },
93
+ {
94
+ autoDetectProblemId: false,
95
+ flags: defineFlags({
96
+ install: {
97
+ type: "boolean",
98
+ description: ".zshrc\uC5D0 \uC790\uB3D9 \uC644\uC131 \uC124\uC815\uC744 \uC790\uB3D9\uC73C\uB85C \uCD94\uAC00\uD569\uB2C8\uB2E4"
99
+ }
100
+ })
101
+ }
102
+ );
103
+ export {
104
+ completion_default as default
105
+ };
@@ -3,8 +3,8 @@ import {
3
3
  FetchCommand,
4
4
  FetchView,
5
5
  fetch_default
6
- } from "../chunk-BFUQPT6F.js";
7
- import "../chunk-ZAIU4LPX.js";
6
+ } from "../chunk-ZV4IVTK4.js";
7
+ import "../chunk-QZJUVKM7.js";
8
8
  import "../chunk-6TZSHRNP.js";
9
9
  import "../chunk-E5PL24PI.js";
10
10
  export {
@@ -3,7 +3,7 @@ import {
3
3
  OpenCommand,
4
4
  OpenView,
5
5
  open_default
6
- } from "../chunk-YRPMKMV4.js";
6
+ } from "../chunk-IZHAFPNR.js";
7
7
  import "../chunk-3LR2NGRC.js";
8
8
  import "../chunk-QGMWUOJ3.js";
9
9
  import "../chunk-E5PL24PI.js";
@@ -17,8 +17,8 @@ import "../chunk-ZRNV3W7X.js";
17
17
  import "../chunk-NIWHZY4V.js";
18
18
  import {
19
19
  FetchView
20
- } from "../chunk-BFUQPT6F.js";
21
- import "../chunk-ZAIU4LPX.js";
20
+ } from "../chunk-ZV4IVTK4.js";
21
+ import "../chunk-QZJUVKM7.js";
22
22
  import {
23
23
  fetchWithRetry,
24
24
  getProblem,
@@ -27,7 +27,7 @@ import {
27
27
  import "../chunk-CL6IVA6K.js";
28
28
  import {
29
29
  OpenView
30
- } from "../chunk-YRPMKMV4.js";
30
+ } from "../chunk-IZHAFPNR.js";
31
31
  import "../chunk-3LR2NGRC.js";
32
32
  import "../chunk-QGMWUOJ3.js";
33
33
  import "../chunk-6MJPXSAN.js";
@@ -4,7 +4,7 @@ import {
4
4
  } from "../chunk-BHCANIOJ.js";
5
5
  import {
6
6
  OpenView
7
- } from "../chunk-YRPMKMV4.js";
7
+ } from "../chunk-IZHAFPNR.js";
8
8
  import "../chunk-3LR2NGRC.js";
9
9
  import "../chunk-QGMWUOJ3.js";
10
10
  import {
@@ -8,7 +8,7 @@ import "../chunk-WJGED2TC.js";
8
8
  import "../chunk-MZUR7SER.js";
9
9
  import "../chunk-ZRNV3W7X.js";
10
10
  import "../chunk-NIWHZY4V.js";
11
- import "../chunk-ZAIU4LPX.js";
11
+ import "../chunk-QZJUVKM7.js";
12
12
  import "../chunk-6TZSHRNP.js";
13
13
  import "../chunk-CL6IVA6K.js";
14
14
  import "../chunk-3LR2NGRC.js";
package/dist/index.js CHANGED
@@ -9531,7 +9531,7 @@ async function main() {
9531
9531
  rawArgs = commandCli.input;
9532
9532
  finalFlags = { ...cli.flags, ...commandCli.flags };
9533
9533
  }
9534
- if (command !== "init") {
9534
+ if (command !== "init" && command !== "completion") {
9535
9535
  const projectRoot = findProjectRoot();
9536
9536
  if (!projectRoot) {
9537
9537
  logger.error("\uD604\uC7AC \uB514\uB809\uD1A0\uB9AC\uAC00 ps-cli \uD504\uB85C\uC81D\uD2B8\uAC00 \uC544\uB2D9\uB2C8\uB2E4.");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhseung/ps-cli",
3
- "version": "1.13.1",
3
+ "version": "1.14.2",
4
4
  "description": "백준(BOJ) 문제 해결을 위한 통합 CLI 도구",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,6 +8,7 @@
8
8
  },
9
9
  "files": [
10
10
  "dist",
11
+ "completions",
11
12
  "templates",
12
13
  "LICENSE"
13
14
  ],