Emacs Eask
GitHub Discord Toggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto mode Back to homepage
Edit page

Development API

This document provides a reference to the public Eask API, which you may use in your projects and extensions to Eask.


🚩 Entry Point

πŸ” Snippet: _prepare.el

Load lisp/_prepare.el to start using other Eask API.

(let ((dir (file-name-directory (nth 1 (member "-scriptload" command-line-args)))))
  (load (expand-file-name "_prepare.el"
                          (locate-dominating-file dir "_prepare.el"))
        nil t))

Each Elisp scripts should have this snippet at the very top of the file.

πŸ” Macro: eask-start (&rest body)

Command entry point. Each command file should contain this macro somewhere in the file.

(eask-start
  ;; TODO: design your command here!
  )

🚩 Core

πŸ” Variable: eask-lisp-root

Points to lisp directory from the project root.

(message "%s" eask-lisp-root)  ; path/to/eask/cli/lisp/

πŸ” Function: eask-command ()

Return the current command in string.

Suppose the command is:

$ eask init

then,

(message "%s" (eask-command))  ; init

πŸ” Function: eask-special-p ()

Return t if the command that can be run without Eask-file existence.

This allow some commands can still be executed without defining the user directory. This can be handy when you want to do normal operations without touching the user directory.

πŸ” Function: eask-checker-p ()

Return t if running Eask as the checker.

Without this flag, the process will be terminated once the error is occured. This flag allows you to run through operations without report error.

πŸ” Function: eask-script (script)

Return full script filename.

(eask-script "extern/pacakge")  ; {project-root}/lisp/extern/package.el

πŸ” Function: eask-load (script)

Load another eask script.

(eask-load "extern/ansi")  ; load {project-root}/lisp/extern/ansi.el file

πŸ” Function: eask-call (script)

Call another eask script.

(eask-call "clean/elc")  ; call command `eask clean-elc`
πŸ’‘ This is rarely used!

πŸ” Macro: eask-defvc< (version &rest body)

Define scope if Emacs version is below specific version.

VERSION is an integer and will be compared with emacs-major-version.

(eask-defvc< 28
  ;; This is missing before Emacs 28; define it
  (defvar package-native-compile nil))
πŸ’‘ This is used for Emacs compatibility!

πŸ” Macro: eask–silent (&rest body)

Mute all messages from standard output inside the scope.

(eask--unsilent (message "You can't hear me! :("))

πŸ” Macro: eask–unsilent (&rest body)

Unmute all messages from standard output inside the scope.

(eask--unsilent (message "You can hear me! :)"))

πŸ” Function: eask-dependencies ()

Return a list of dependencies.

Elements should either be (NAME . VERSION) or (NAME . RECIPE-FORMAT).

πŸ” Function: eask-pkg-init (&optional force)

Initialize packages for use.

(eask-start
  (eask-pkg-init)
  ;; Now you can use packages installed in `package-user-dir'
  )
πŸ’‘ This is usually called after eask-start!

πŸ” Macro: eask-with-archives (archives &rest body)

Scope that temporary makes archives available.

ARCHIVES can either be a string or a list of strings.

(eask-with-archives "melpa"
  (eask-package-install 'package-build))  ; install packages that are only defined in MELPA
πŸ’‘ This is handy when you need certain packages from certain archives.

πŸ” Function: eask-package-desc (name &optional current)

Build package descriptor for a package.

CURRENT means installed packages; otherwise it will return any available packages from selected package archives.

πŸ” Function: eask-argv (index)

Return a command-line argument by index.

πŸ” Function: eask-args ()

Return a list that is extracted from command-line arguments.

$ eask info --verbose 4 foo bar

It will ignore --verbose and 4, and only returns foo, and bar.

πŸ” Variable: eask-file

Path to currently loaded Eask-file.

πŸ” Variable: eask-file-root

Directory to currently loaded Eask-file.

πŸ” Function: eask–match-file (name)

Check to see if NAME is our target Eask-file, then return it.

The following output is with Emacs 28.1:

(eask--match-file "Eask")         ; t
(eask--match-file "Eask.28")      ; t
(eask--match-file "Eask.28.1")    ; t
(eask--match-file "Eask.29")      ; nil

(eask--match-file "Easkfile")     ; t
(eask--match-file "Easkfile.28")  ; t
(eask--match-file "Easkfile.29")  ; nil

πŸ” Function: eask–all-files (&optional dir)

Return a list of Eask files from DIR.

Consider following directory tree:

. root
β”œβ”€β”€ Eask
β”œβ”€β”€ Eask.28
└── Eask.29

The following output is with Emacs 28.1:

(eask--all-files "/root/")  ; '(Eask Eask.28)

πŸ” Function: eask–find-files (start-path)

Find the Eask-file from START-PATH.

Consider following directory tree:

.project
β”œβ”€ src
β”‚ └── config.el
β”œβ”€β”€ Eask
β”œβ”€β”€ Eask.28
└── Eask.29

The following output is with Emacs 28.1:

(eask--find-files "/project/src/config.el")  ; '(/project/Eask /project/Eask.28)

πŸ” Function: eask-file-try-load (start-path)

Try load the Eask-file in START-PATH.

(eask--find-files "/project/src/")  ; t

πŸ” Function: eask-network-insecure-p ()

Return t if the current Emacs session allows insecure network connections.

🚩 Flags

πŸ” Function: eask-global-p ()

Return t if the global option is enabled.

(when (eask-global-p)
  user-emacs-directory)   ; ~/.eask/

πŸ” Function: eask-config-p ()

Return t if the config option is enabled.

(when (eask-config-p)
  user-emacs-directory)   ; ~/.emacs.d
πŸ’‘ If both options --config and --global are on, the global space is chosen over the config space.

πŸ” Function: eask-local-p ()

This uses the current workspace, and this is the default.

(when (eask-local-p)
  user-emacs-directory)   ; ./.eask/{emacs-version}/
πŸ’‘ This function returns t only when (eask-global-p) and (eask-config-p) are false!

πŸ” Function: eask-all-p ()

Return t if the all option is enabled.

(when (eask-all-p)
  ;; Run all tests
  ...)

πŸ” Function: eask-quick-p ()

Return t if the quick option is enabled.

(unless (eask-quick-p)
  (load user-init-file)
  ...)

πŸ” Function: eask-force-p ()

Return t if the force option is enabled.

(package-delete .. (eask-force-p))

πŸ” Function: eask-dev-p ()

Return t if the development option is enabled.

(when (eask-dev-p)
  (package-install 'ert-runner))  ; install development dependency

πŸ” Function: eask-debug-p ()

Return t if the debug option is enabled.

(when (eask-debug-p)
  (error "Executing in debug mode..."))

πŸ” Function: eask-strict-p ()

Return t if the strict option is enabled.

(setq byte-compile-error-on-warn (eask-strict-p))

πŸ” Function: eask-timestamps-p ()

Return t/nil if the timestamps option is enabled/disabled.

These flags can’t co-exist in the same command.

(when (eask-timestamps-p)
  (message "Print log with timestamps!"))

πŸ” Function: eask-log-level-p ()

Return t/nil if the log-level option is enabled/disabled.

These flags can’t co-exist in the same command.

(when (eask-log-level-p)
  (message "Print log with level prefix!"))

πŸ” Function: eask-log-file-p ()

Return t/nil if the log-file option is enabled/disabled.

These flags can’t co-exist in the same command.

(when (eask-log-file-p)
  (message "Let's create a log file!"))

πŸ” Function: eask-no-color-p ()

Return t if the color option is enabled.

(unless (eask-no-color-p)
  (message "This string has no ansi code!"))

πŸ” Function: eask-allow-error-p ()

Return t if the allow-error option is enabled.

(unless (eask-allow-error-p)
  (error "Stop here."))

πŸ” Function: eask-insecure-p ()

Return t if the insecure option is enabled.

(when (eask-insecure-p)
  ;; Do some dangerous tasks?
  )

πŸ” Function: eask-proxy ()

πŸ” Function: eask-http-proxy ()

πŸ” Function: eask-https-proxy ()

πŸ” Function: eask-no-proxy ()

Return a string represents hostname + port number.

$ eask [command] --proxy "localhost:1000"
$ eask [command] --http-proxy "localhost:2000"
$ eask [command] --https-proxy "localhost:3000"
$ eask [command] --no-proxy "localhost:4000"

πŸ” Function: eask-destination ()

Return a string represents the destination (output path).

(write-file (or (eask-destination) "./dist"))  ; write file to destination

πŸ” Function: eask-depth ()

Return an integer represents the depth of the current print level.

(setq print-level (eask-depth))

πŸ” Function: eask-verbose ()

Return an integer represents the verbosity level.

(when (= (eask-verbose) 4)
  (setq byte-compile-verbose t))

🚩 Eask-file

These functions are the actual implementation of Eask-file DSL; and have the word eask- as the function prefix.

See DSL section for more information.

πŸ” Variable: eask-package

It holds package’s NAME, VERSION, and DESCRIPTION in a plist.

(plist-get eask-package :name)  ; return package name

Three functions that are extended from this variable:

  • (eask-package-name)
  • (eask-package-version)
  • (eask-package-description)

πŸ” Variable: eask-package-file

Points to package main file.

πŸ” Variable: eask-package-desc

Package descriptor from the package main file.

(package-desc-p eask-package-desc)  ; return t
⚠ This can be nil if the package-descriptor cannot be constructed correctly!

πŸ” Variable: eask-files

Holds a list of files pattern in wildcard specification.

πŸ” Variable: eask-scripts

Holds a list of available scripts that can be executed by user using the eask run-script command.

πŸ” Variable: eask-depends-on-emacs

Holds information about Emacs minimum version.

(depends-on "emacs" "26.1")

Function will return Emacs version in string.

  • (eask-depends-emacs-version) - return "26.1"

πŸ” Variable: eask-depends-on

Holds a list of dependencies.

πŸ” Variable: eask-depends-on-dev

Holds a list of dependencies that are development used.

πŸ” Function: eask-f-package (name version description)

Alias of package.

πŸ” Function: eask-f-website-url (url)

Alias of website-url.

πŸ” Function: eask-f-keywords (&rest keywords)

Alias of keywords.

πŸ” Function: eask-f-author (name &optional email)

Alias of author.

πŸ” Function: eask-f-license (name)

Alias of license.

πŸ” Function: eask-f-package-file (file)

Alias of package-file.

πŸ” Function: eask-f-files (pkg &rest args)

Alias of files.

πŸ” Function: eask-f-script (name command &rest args)

Alias of script.

πŸ” Function: eask-f-source (name &optional location)

Alias of source.

πŸ” Function: eask-f-source-priority (name &optional priority)

Alias of source-priority.

πŸ” Function: eask-f-depends-on (pkg &rest args)

Alias of depends-on.

πŸ” Function: eask-f-development (&rest dependencies)

Alias of development.

πŸ” Function: eask-f-exec-paths (&rest dirs)

Alias of exec-paths.

πŸ” Function: eask-f-load-paths (&rest dirs)

Alias of load-paths.

🚩 Logging

Logger utility with timestamps and log level.

The log level value is defined in function eask--verb2lvl.

Level Description Value
debug Designates fine-grained informational events that are most useful to debug an application. 4
log Designates normal messages. 3
info Designates informational messages that highlight the progress of the application at coarse-grained level. 2
warn Designates potentially harmful situations. 1
error Designates error events that might still allow the application to continue running. 0

The default level is log.

πŸ” Variable: eask-verbosity

The verbosity level is represented as an integer.

(setq eask-verbosity 4)  ; you could set from 0 to 4

πŸ” Variable: eask-timestamps

Log messages with timestamps.

(setq eask-timestamps t)

Output:

2022-04-14 13:44:46 This is a message with timestamps

πŸ” Variable: eask-log-level

Log messages with level. (default: nil)

(setq eask-log-level t)

Output:

[DEBUG] This is a DEBUG message with log level

πŸ” Variable: eask-log-file

Weather to generate log files. (default: nil)

(setq eask-log-level t)

Use command cat to see the log,

$ cat /.log/messages.log

πŸ” Variable: eask-level-color

Define each log level color.

(setq eask-level-color
      '((debug . ansi-blue)
        (log   . ansi-white)
        (info  . ansi-cyan)
        (warn  . ansi-yellow)
        (error . ansi-red)))

πŸ” Macro: eask-with-verbosity (symbol &rest body)

Define verbosity scope.

(eask-with-verbosity 'debug
  ;; TODO: execution here..
  )

Everything in the scope of this macro will be muted unless the verbosity reaches. It will only be printed when you have specified --verbose 4 global option.

πŸ” Macro: eask-with-verbosity-override (symbol &rest body)

Define override verbosity scope.

(eask-with-verbosity 'debug
  (eask-with-verbosity-override 'log
    ;; TODO: execution here..
    )
  (eask-with-verbosity-override 'info
    ;; TODO: execution here..
    ))

Like macro eask-with-verbosity; but force display messages if it wasn’t able to display.

πŸ” Function: eask-debug (msg &rest args)

(eask-debug "This is DEBUG message")
2022-04-14 17:31:54 [DEBUG] This is DEBUG message

πŸ” Function: eask-log (msg &rest args)

(eask-log "This is LOG message")
2022-04-14 17:31:54 [LOG] This is LOG message

πŸ” Function: eask-info (msg &rest args)

(eask-info "This is INFO message")
2022-04-14 17:31:54 [INFO] This is INFO message

πŸ” Function: eask-warn (msg &rest args)

(eask-warn "This is WARNING message")
2022-04-14 17:31:54 [WARNING] This is WARNING message

πŸ” Function: eask-error (msg &rest args)

(eask-error "This is ERROR message")
2022-04-14 17:31:54 [ERROR] This is ERROR message

πŸ” Function: eask-msg (msg &rest args)

Like message function but will replace unicodes with color.

(eask-msg "Print this message with newline!")

πŸ” Function: eask-write (msg &rest args)

Like eask-msg function but without newline at the end.

(eask-write "Print this message without newline...")

πŸ” Function: eask-report (&rest args)

Report error/warning depends on strict flag.

(eask-report "This can be warning or error")

See option –strict.

🚩 Error Handling

πŸ” Variable: eask–ignore-error-p

Non-nil to prevent Emacs from being killed.

(let ((eask--ignore-error-p t))
  (error "Emacs can't die! :P"))

πŸ” Variable: eask-inhibit-error-message

Non-nil to stop error/warning message.

(let ((eask-inhibit-error-message t))
  (error "This won't display at all!"))

πŸ” Macro: eask-ignore-errors (&rest body)

Prevent Emacs from being killed.

(eask-ignore-errors
  (error "Emacs can't die! :P"))

πŸ” Macro: eask–silent-error (&rest body)

Inhibit display error/warning messages.

(eask--silent-error
  (error "This won't display at all!"))

πŸ” Macro: eask-ignore-errors-silent (&rest body)

Prevent Emacs from being killed and inhibit display error/warning messages.

(eask-ignore-errors-silent
  (error "Nothing happens!"))

πŸ” Function: eask–exit ()

Send exit code.

This will kill Emacs process.

🚩 File

πŸ” Function: eask-guess-package-name ()

Return the possible package name.

πŸ” Function: eask-package-files ()

Return a list of package files.

πŸ” Function: eask-package-el-files ()

Return a list of package files with .el extension.

πŸ” Function: eask-package-elc-files ()

Return a list of package files with .elc extension.

πŸ” Function: eask-package-multi-p ()

Return nil if single file package.

πŸ” Function: eask-package-single-p ()

Return t if single file package.

πŸ” Function: eask-unpacked-size ()

Return size of the current package.

⚠️ This returns a string not bytes.

🚩 Progress

πŸ” Macro: eask-with-progress (msg-start body msg-end)

Create execution with the responsive message output.

(eask-with-progress 
  "Downloading files... "
  (eask-with-verbosity 'debug  ; Often used with `eask-with-verbosity'
    ;; Execute some operations..
    )
  "done βœ“")

Expect output:

Downloading files... done βœ“

πŸ” Function: eask-print-log-buffer (&optional buffer-or-name)

Print buffer and highlight the errors and warnings.

(eask-print-log-buffer "*Package-Lint*")
πŸ’‘ This is handy for linters that create a buffer to display errors and warnings.

🚩 Help

πŸ” Function: eask-help (command)

Print help manual located under lisp/help/ directory.

(eask-help "core/search")
πŸ’‘ This is used when a command fails, and would like to give users some tips!