initial commit
Some checks failed
CI / test (snapshot, ubuntu-latest) (push) Failing after 1s
CI / test (26.3, macos-latest) (push) Has been cancelled
CI / test (26.3, windows-latest) (push) Has been cancelled
CI / test (27.2, macos-latest) (push) Has been cancelled
CI / test (27.2, windows-latest) (push) Has been cancelled
CI / test (28.1, macos-latest) (push) Has been cancelled
CI / test (28.1, ubuntu-latest) (push) Has started running
CI / test (28.1, windows-latest) (push) Has been cancelled
CI / test (snapshot, macos-latest) (push) Has been cancelled
CI / test (snapshot, windows-latest) (push) Has been cancelled
CI / test (26.3, ubuntu-latest) (push) Has been cancelled
CI / test (27.2, ubuntu-latest) (push) Has been cancelled

This commit is contained in:
2025-11-19 11:46:15 +01:00
commit e9680c4116
7 changed files with 401 additions and 0 deletions

40
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: CI
on:
push:
branches:
- master
- main
pull_request:
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
emacs-version:
- 26.3
- 27.2
- 28.1
- snapshot
steps:
- uses: actions/checkout@v2
- uses: jcs090218/setup-emacs@master
with:
version: ${{ matrix.emacs-version }}
- uses: actions/setup-node@v2
with:
node-version: '16'
- uses: emacs-eask/setup-eask@master
with:
version: 'snapshot'
- name: Run tests
run:
make ci

14
.gitignore vendored Normal file
View File

@@ -0,0 +1,14 @@
# ignore these directories
/.git
/recipes
# ignore generated files
*.elc
# eask packages
.eask/
dist/
# packaging
*-autoloads.el
*-pkg.el

14
Eask Normal file
View File

@@ -0,0 +1,14 @@
;; -*- mode: Cask -*-
(package "npm-transient"
"0.1.0"
"A transient menu for NPM projects")
(website-url "https://labs.phundrak.com/phundrak/npm-transient.el")
(keywords "npm" "transient" "convenience" "project" "javascript" "typescript" "node" "yarn" "pnpm")
(package-file "npm-transient.el")
(source "gnu")
(depends-on "emacs" "25.1")
(depends-on "transient" "0.3.7")

88
Makefile Normal file
View File

@@ -0,0 +1,88 @@
##
# Eask generated template Makefile
#
# File located in https://github.com/emacs-eask/template-elisp/blob/master/Makefile
##
EMACS ?= emacs
EASK ?= eask
.PHONY: clean package install compile test checkdoc lint
# CI entry point
#
# You can add or remove any commands here
#
# (Option 1): Basic for beginner, only tests for package's installation
ci: clean package install compile
# (Option 2): Advanced for a high-quality package
#ci: clean package install compile checkdoc lint test
# Build an package artefact, default to `dist` folder
#
# This is used to test if your package can be built correctly before the
# package installation.
package:
@echo "Packaging..."
$(EASK) package
# Install package
#
# If your package is a single file package, you generally wouldn't need to
install:
@echo "Installing..."
$(EASK) install
# Byte-compile package
#
# Compile all your package .el files to .elc
compile:
@echo "Compiling..."
$(EASK) compile
# Run regression tests
#
# The default test is `ert`; but Eask also support other regression test!
# See https://emacs-eask.github.io/Getting-Started/Commands-and-options/#-linter
test:
@echo "Testing..."
$(EASK) install-deps --dev
$(EASK) test ert ./test/*.el
# Run checkdoc
#
# See https://www.emacswiki.org/emacs/CheckDoc
checkdoc:
@echo "Checking documentation..."
$(EASK) lint checkdoc --strict
# Lint package metadata
#
# See https://github.com/purcell/package-lint
lint:
@echo "Linting..."
$(EASK) lint package
# Generate autoloads file
#
# NOTE: This is generally unnecessary
autoloads:
@echo "Generating autoloads..."
$(EASK) autoloads
# Generate -pkg file
#
# NOTE: This is generally unnecessary
pkg-file:
@echo "Generating -pkg file..."
$(EASK) pkg-file
# Clean up
#
# This will clean all the entire workspace including the following folders
# and files
#
# - .eask folder (sandbox)
# - all .elc files
clean:
$(EASK) clean-all

2
README.md Normal file
View File

@@ -0,0 +1,2 @@
# npm-transient
> A transient menu for NPM projects

7
README.org Normal file
View File

@@ -0,0 +1,7 @@
#+title: npm-transient
#+author: Lucien Cartier-Tilet
#+email: lucien@phundrak.com
#+begin_quote
A transient menu for NPM projects
#+end_quote

236
npm-transient.el Normal file
View File

@@ -0,0 +1,236 @@
;;; npm-transient.el --- A transient menu for NPM projects -*- lexical-binding: t; -*-
;; Copyright (C) 2022 Lucien Cartier-Tilet
;; Author: Lucien Cartier-Tilet <lucien@phundrak.com>
;; Maintainer: Lucien Cartier-Tilet <lucien@phundrak.com>
;; URL: https://labs.phundrak.com/phundrak/npm-transient.el
;; Version: 0.1.0
;; Package-Requires: ((emacs "25.1") (transient "0.3.7"))
;; Keywords: npm transient convenience project javascript typescript node yarn pnpm
;; This file is not part of GNU Emacs.
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;;
;; A transient menu for NPM projects
;;
;;; Code:
(require 'transient)
;;; Internal functions
(defun npm-transient--dummy ()
"Dummy function for development purposes only.
Display ARGS."
(interactive)
(message "=== Dummy function."))
;;; Group and Custom Variables
(defgroup npm-transient nil
"Customization group for `npm-transient'."
:group 'applications
:group 'convenience
:group 'tools
:prefix "npm-transient-"
:link '(url-link :tag "Gitea" "https://labs.phundrak.com/phundrak/npm-transient.el"))
(defconst npm-transient--package-managers '(npm yarn pnpm)
"Package managers supported by `npm-transient'.")
(defclass npm-transient-package-manager ()
((name :initarg :name
:initform nil
:type symbol
:custom symbol
:documentation "Name of the package manager.")
(install :initarg :install-cmd
:initform "install"
:type string
:custom string
:documentation "command for installing dependencies")
(add :initarg :add-cmd
:initform ""
:type string
:custom string
:documentation "command for adding a regular dependency")
(dev-option :initarg :dev-option
:initform "--save-dev"
:type string
:custom string
:documentation "flag for dev commands, such as npm i --save-dev")
(optional-option :initarg :optional-option
:initform "--save-optional"
:type string
:custom string
:documentation "flag for optional commands, such as npm i --save-optional")
(peer-option :initarg :peer-option
:initform "--save-peer"
:type string
:custom string
:documentation "flag for peer commands, such as npm i --save-peer")
(prod-option :initarg :prod-option
:initform "--save-prod"
:type string
:custom string
:documentation "flag for prod commands, such as npm i --save-prod")
(uninstall :initarg :uninstall-cmd
:initform ""
:type string
:custom string
:documentation "command for removing a dependency")
(list :initarg :list-cmd
:initform "list"
:type string
:custom string
:documentation "command for listing dependencies")
(init :initarg :init-cmd
:initform "init"
:type string
:custom string
:documentation "command for initializing a project")
(run :initarg :run-cmd
:initform ""
:type string
:custom string
:documentation "command for running scripts")))
(defconst npm-transient-npm
(npm-transient-package-manager :name 'npm
:add-cmd "install"
:uninstall-cmd "uninstall"
:run-cmd "run")
"Properties for the npm package manager.")
(defconst npm-transient-yarn
(npm-transient-package-manager :name 'yarn
:add-cmd "add"
:dev-option "--dev"
:optional-option "--optional"
:peer-option "--peer"
:prod-option "--prod"
:uninstall-cmd "remove"
:list-cmd "list"
:init-cmd "init"
:run-cmd "")
"Properties for the yarn package manager.")
(defconst npm-transient-pnpm
(npm-transient-package-manager :name 'pnpm
:install-cmd "install"
:add-cmd "add"
:add-dev-cmd "add -D"
:uninstall-cmd "remove"
:list-cmd "list"
:init-cmd "init"
:run-cmd ""))
;;; Transients
(eval-when-compile
(defmacro npm-transient--def-action (name description transient &rest body)
"Create a function called from TRANSIENT.
DESCRIPTION is the docstring of the function named
npm-transient--action-NAME, and it gets BODY as its body.
This macro is inspired by Tecosaurs screenshot.el"
`(defun ,(intern (concat "npm-transient--action-" name)) (&optional _args)
,(concat description "
This function is meant to be called by a transient.")
(interactive
(list (transient-args ,transient)))
,@body))
(npm-transient--def-action
"delete-node-modules"
"Delete the current projects \\='node_modules\\=' directory.
This function will search the root of the project and delete its
\\='node_modules\\=' directory, unless it is located in the
users home directory."
'npm-transient-main
nil)
(npm-transient--def-action
"delete-package-manager-files"
"Delete the current projects \\='node_modules\\=' and lock file.
This function will search for the root of the project and delete
its \\='node_modules\\=' directory as well as the current package
managers lock file, unless the project root is located in the
users home directory."
'npm-transient-main
nil)
(defmacro npm-transient--def-infix (key name description type version default &rest reader)
"Define infix and its corresponding variable at once.
The variable is named bitwarden-NAME is of type TYPE, has a
DESCRIPTION and a specified VERSION.
The KEY and READER are for the infix declaration.
This macro is inspired by Tecosaurs screenshot.el"
(let ((var-name (concat "npm-transient--" name)))
`(progn
(defcustom ,(intern var-name) ,default
,description
:type ,type
:group 'npm-transient
:version ,version)
(transient-define-infix ,(intern (concat "npm-transient--set-" name)) ()
"Set npm-transient options."
:class 'transient-lisp-variable
:variable ',(intern var-name)
:key ,key
:description ,description
:argument ,(concat "--" name)
:reader (lambda (&rest _) ,@reader)))))
(npm-transient--def-infix
"-p" "package-manager" "Package manager"
'symbol "0.1.0"
'npm
(completing-read "Package manager: "
npm-transient--package-managers
nil t)))
(transient-define-prefix npm-transient-main ()
["Options"
(npm-transient--set-package-manager)]
["Dependencies"
("i" "Install dependencies" npm-transient--dummy)
("a" "Add dependency" npm-transient--dummy)
("d" "Add dev dependency" npm-transient--dummy)
("u" "Uninstall dependency" npm-transient--dummy)
("l" "List dependencies" npm-transient--dummy)]
["Action"
("n" "Initialize" npm-transient--dummy)
("r" "Run script" npm-transient--dummy)
("v" "Visit project file" npm-transient--dummy)]
["Clear"
("c" "Clean node_modules" npm-transient--action-delete-node-modules)
("C" "Clear package manager files" npm-transient--action-delete-package-manager-files)
("q" "Quit" (lambda () (interactive) nil))])
;;;###autoload
(defun npm-transient ()
"Call the main transient for npm-transient."
(interactive)
(call-interactively #'npm-transient-main))
(provide 'npm-transient)
;;; npm-transient.el ends here