Skip to content

Commit 93f20db

Browse files
authored
feat(command): Add custom command (#195)
* feat(command): Add custom command * Changelog * Fix desc * add doc * fix options
1 parent b45700e commit 93f20db

File tree

11 files changed

+204
-24
lines changed

11 files changed

+204
-24
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
3333
* Enter docker directly when no arguments (#191)
3434
* Add command to generate recipe (#192)
3535
* Add option to init from `Eldev`-file (#193)
36+
* Add command `commnad` for custom commands (#195)
3637

3738
## 0.8.x
3839
> Released Mar 08, 2023

cmds/core/command.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* Copyright (C) 2023 Jen-Chieh Shen
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 3, or (at your option)
7+
* any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with GNU Emacs; see the file COPYING. If not, write to the
16+
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17+
* Boston, MA 02110-1301, USA.
18+
*/
19+
20+
"use strict";
21+
22+
exports.command = ['command [names..]', 'cmd [names..]'];
23+
exports.desc = 'Run custom command';
24+
exports.builder = yargs => yargs
25+
.positional(
26+
'[names..]', {
27+
description: 'list of function commands to execute',
28+
type: 'array',
29+
});
30+
31+
exports.handler = async (argv) => {
32+
await UTIL.e_call(argv, 'core/command'
33+
, argv.names);
34+
};

docs/content/en/Getting-Started/Advanced-Usage.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ title: 🔧 Advanced Usage
33
weight: 400
44
---
55

6+
{{< toc >}}
7+
68
`Eask` is just a regular Emacs Lisp file and should be read from Emacs itself!
79
You can do:
810

@@ -12,6 +14,8 @@ You can do:
1214
(setq byte-compile-error-on-warn t) ; Signal error if warning occurred
1315
```
1416

17+
# 🪝 Hooks
18+
1519
`eask` provides some hooks which enable you to execute code before and after
1620
each command. The hooks look like so:
1721

@@ -58,3 +62,13 @@ therefore,
5862
;; do stuff before checkdoc linting...
5963
))
6064
```
65+
66+
# 📇 Adding your own command
67+
68+
You can add your own command through our command interface:
69+
70+
```elisp
71+
(eask-defcommand my-test-command
72+
"A test command that prints out useless message."
73+
(message "This is a test command!"))
74+
```

docs/content/en/Getting-Started/Basic-Usage/_index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Usage: eask <command> [options..]
3434
Commands:
3535
archives List out all package archives [aliases: sources]
3636
clean <type> Delete various files produced during building
37+
command [names..] Run custom command [aliases: cmd]
3738
compile [names..] Byte compile all Emacs Lisp files in the package
3839
create <type> Create a new elisp project
3940
docker <version> [args..] Launch specified Emacs version in a Docker container

docs/content/en/Getting-Started/Commands-and-options.md

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -278,16 +278,6 @@ Concatenate all Emacs Lisp files into one file.
278278
$ eask [GLOBAL-OPTIONS] concate [FILES..]
279279
```
280280

281-
## 🔍 eask run
282-
283-
Run the script.
284-
285-
```sh
286-
$ eask [GLOBAL-OPTIONS] run [FILES..]
287-
```
288-
289-
Alias: `run-script`
290-
291281
# 🚩 Execution
292282

293283
Commands allow you execute on top of Eask core.
@@ -326,6 +316,26 @@ Evaluate `FORM` as a lisp form.
326316
$ eask [GLOBAL-OPTIONS] eval [FORM]
327317
```
328318

319+
## 🔍 eask run
320+
321+
Run the script.
322+
323+
```sh
324+
$ eask [GLOBAL-OPTIONS] run [NAMES..]
325+
```
326+
327+
Alias: `run-script`
328+
329+
## 🔍 eask command
330+
331+
Run the command.
332+
333+
```sh
334+
$ eask [GLOBAL-OPTIONS] command [NAMES..]
335+
```
336+
337+
Alias: `cmd`
338+
329339
## 🔍 eask docker
330340

331341
Launch specified Emacs version in a Docker container.

docs/content/zh-TW/Getting-Started/Advanced-Usage.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ title: 🔧 進階用法
33
weight: 400
44
---
55

6+
{{< toc >}}
7+
68
`Eask` 只是一個普通的 Emacs Lisp 文件,應該從 Emacs 本身讀取! 你可以做:
79

810
```elisp
@@ -11,6 +13,8 @@ weight: 400
1113
(setq byte-compile-error-on-warn t) ; 出現警告時信號錯誤
1214
```
1315

16+
# 🪝 Hooks
17+
1418
`eask` 提供了一些 hooks,使您能夠在每個命令之前和之後執行代碼。 hook 看起來像這樣:
1519

1620
- `eask-before-COMMAND-hook`
@@ -55,3 +59,13 @@ $ eask generate license # generate/license
5559
;; 在 checkdoc linting 之前做一些事情...
5660
))
5761
```
62+
63+
# 📇 加入你自己的指令
64+
65+
您可以透過我們的 command 介面添加自己的命令:
66+
67+
```elisp
68+
(eask-defcommand my-test-command
69+
"測試指令印出無用的訊息。"
70+
(message "這是一個測試指令!"))
71+
```

docs/content/zh-TW/Getting-Started/Basic-Usage/_index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Usage: eask <command> [options..]
3131
Commands:
3232
archives List out all package archives [aliases: sources]
3333
clean <type> Delete various files produced during building
34+
command [names..] Run custom command [aliases: cmd]
3435
compile [names..] Byte compile all Emacs Lisp files in the package
3536
create <type> Create a new elisp project
3637
docker <version> [args..] Launch specified Emacs version in a Docker container

docs/content/zh-TW/Getting-Started/Commands-and-options.md

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -274,16 +274,6 @@ $ eask [GLOBAL-OPTIONS] cat [PATTERNS..]
274274
$ eask [GLOBAL-OPTIONS] concate [FILES..]
275275
```
276276

277-
## 🔍 eask run
278-
279-
運行腳本。
280-
281-
```sh
282-
$ eask [GLOBAL-OPTIONS] run [FILES..]
283-
```
284-
285-
別名: `run-script`
286-
287277
# 🚩 執行
288278

289279
指令允許執行在 Eask 核心之上。
@@ -322,6 +312,26 @@ $ eask [GLOBAL-OPTIONS] emacs [ARGUMENTS ...]
322312
$ eask [GLOBAL-OPTIONS] eval [FORM]
323313
```
324314

315+
## 🔍 eask run
316+
317+
運行腳本。
318+
319+
```sh
320+
$ eask [GLOBAL-OPTIONS] run [NAMES..]
321+
```
322+
323+
別名: `run-script`
324+
325+
## 🔍 eask command
326+
327+
運行指令。
328+
329+
```sh
330+
$ eask [GLOBAL-OPTIONS] command [NAMES..]
331+
```
332+
333+
別名: `cmd`
334+
325335
## 🔍 eask docker
326336

327337
在 Docker 容器中啟動指定的 Emacs 版本

lisp/_prepare.el

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22
;;; Commentary: Prepare to setup Eask environment for sandboxing
33
;;; Code:
44

5+
;;
6+
;;; Requirement
7+
8+
(when (version< emacs-version "26.1")
9+
(error "Eask requires Emacs 26.1 and above!"))
10+
11+
;;
12+
;;; Includes
13+
514
(require 'ansi-color)
615
(require 'package)
716
(require 'project)
@@ -1844,9 +1853,17 @@ variable we use to test validation."
18441853
(eask-load "extern/package-build")
18451854

18461855
;;
1847-
;;; Requirement
1848-
1849-
(when (version< emacs-version "26.1")
1850-
(eask-error "Eask requires Emacs 26.1 and above!"))
1856+
;;; API
1857+
1858+
(defvar eask-commands nil
1859+
"List of defined commands.")
1860+
1861+
(defmacro eask-defcommand (name &rest body)
1862+
"Define an Eask command."
1863+
(declare (doc-string 2) (indent 1))
1864+
(or name (error "Cannot define '%s' as a command" name))
1865+
(push name eask-commands)
1866+
(setq eask-commands (delete-dups eask-commands))
1867+
`(defun ,name nil ,@body))
18511868

18521869
;;; _prepare.el ends here

lisp/core/command.el

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
;;; core/command.el --- Run custom command -*- lexical-binding: t; -*-
2+
3+
;;; Commentary:
4+
;;
5+
;; Command use to run custom command
6+
;;
7+
;; $ eask command [names..]
8+
;;
9+
;;
10+
;; Positionals:
11+
;;
12+
;; [names..] name of the function command
13+
;;
14+
15+
;;; Code:
16+
17+
(let ((dir (file-name-directory (nth 1 (member "-scriptload" command-line-args)))))
18+
(load (expand-file-name "_prepare.el"
19+
(locate-dominating-file dir "_prepare.el"))
20+
nil t))
21+
22+
(defun eask--command-desc (name)
23+
"Return command's description by its command's NAME."
24+
(car (split-string (documentation name) "\n")))
25+
26+
(defun eask--print-commands ()
27+
"Print all available commands."
28+
(eask-msg "available via `eask command`")
29+
(eask-msg "")
30+
(let* ((keys (reverse eask-commands))
31+
(offset (eask-seq-str-max keys))
32+
(fmt (concat " %-" (eask-2str offset) "s %s")))
33+
(dolist (key keys)
34+
(eask-msg fmt key (eask--command-desc key)))
35+
(eask-msg "")
36+
(eask-info "(Total of %s available script%s)" (length keys)
37+
(eask--sinr keys "" "s"))))
38+
39+
(defun eask--execute-command (name)
40+
"Execute the command by NAME."
41+
(eask-info "[RUN]: %s" name)
42+
(funcall (eask-intern name)))
43+
44+
(defun eask--unmatched-commands (commands)
45+
"Return a list of COMMANDS that cannot be found in `eask-commands'."
46+
(let (unmatched)
47+
(dolist (command commands)
48+
(unless (memq (eask-intern command) eask-commands)
49+
(push command unmatched)))
50+
unmatched))
51+
52+
(eask-start
53+
(cond ((null eask-commands)
54+
(eask-info "(No command specified)")
55+
(eask-help "core/command"))
56+
((eask-all-p)
57+
(dolist (name (reverse eask-commands))
58+
(eask--execute-command name)))
59+
((when-let ((commands (eask-args)))
60+
(if-let ((unmatched (eask--unmatched-commands commands)))
61+
(progn ; if there are unmatched commands, don't even try to execute
62+
(eask-info "(Missing command%s: `%s`)"
63+
(eask--sinr unmatched "" "s")
64+
(mapconcat #'identity unmatched ", "))
65+
(eask-msg "")
66+
(eask--print-commands))
67+
(dolist (command commands)
68+
(eask--execute-command command))
69+
t)))
70+
(t (eask--print-commands))))
71+
72+
;;; core/command.el ends here

0 commit comments

Comments
 (0)