diff --git a/.forgejo/install-emacs/action.yml b/.forgejo/install-emacs/action.yml new file mode 100644 index 0000000..f27e80d --- /dev/null +++ b/.forgejo/install-emacs/action.yml @@ -0,0 +1,13 @@ +name: 'Set up Emacs' +description: 'Install a specific Emacs version for use in your workflow.' +author: 'Steve Purcell' +inputs: + version: + description: 'The version of Emacs to install, e.g. "24.3", or "snapshot" for a recent development version.' +runs: + using: 'composite' + steps: + - run: ${{ github.action_path }}/install.sh + shell: bash + env: + INPUT_VERSION: ${{ inputs.version }} diff --git a/.forgejo/install-emacs/flake.lock b/.forgejo/install-emacs/flake.lock new file mode 100644 index 0000000..c25e6bb --- /dev/null +++ b/.forgejo/install-emacs/flake.lock @@ -0,0 +1,42 @@ +{ + "nodes": { + "flake-utils": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1669165918, + "narHash": "sha256-hIVruk2+0wmw/Kfzy11rG3q7ev3VTi/IKVODeHcVjFo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3b400a525d92e4085e46141ff48cbf89fd89739e", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixpkgs-unstable", + "type": "indirect" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} \ No newline at end of file diff --git a/.forgejo/install-emacs/flake.nix b/.forgejo/install-emacs/flake.nix new file mode 100644 index 0000000..9610be0 --- /dev/null +++ b/.forgejo/install-emacs/flake.nix @@ -0,0 +1,21 @@ +{ + description = "Setup Emacs Action"; + + inputs = + { + nixpkgs.url = "nixpkgs/nixpkgs-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { inherit system; }; + in + { + devShell = pkgs.mkShell { + buildInputs = with pkgs; [ pkgs.shellcheck ]; + }; + } + ); +} \ No newline at end of file diff --git a/.forgejo/install-emacs/install-nix.sh b/.forgejo/install-emacs/install-nix.sh new file mode 100755 index 0000000..75c0177 --- /dev/null +++ b/.forgejo/install-emacs/install-nix.sh @@ -0,0 +1,127 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Sudo is required by this installer +apt-get update -qq +apt-get install -y sudo + +if nix_path="$(type -p nix)" ; then + echo "Aborting: Nix is already installed at ${nix_path}" + exit +fi + +if [[ ($OSTYPE =~ linux) && ($INPUT_ENABLE_KVM == 'true') ]]; then + enable_kvm() { + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-install-nix-action-kvm.rules + sudo udevadm control --reload-rules && sudo udevadm trigger --name-match=kvm + } + + echo '::group::Enabling KVM support' + enable_kvm && echo 'Enabled KVM' || echo 'KVM is not available' + echo '::endgroup::' +fi + +# GitHub command to put the following log messages into a group which is collapsed by default +echo "::group::Installing Nix" + +# Create a temporary workdir +workdir=$(mktemp -d) +trap 'rm -rf "$workdir"' EXIT + +# Configure Nix +add_config() { + echo "$1" >> "$workdir/nix.conf" +} +add_config "show-trace = true" +# Set jobs to number of cores +add_config "max-jobs = auto" +if [[ $OSTYPE =~ darwin ]]; then + add_config "ssl-cert-file = /etc/ssl/cert.pem" +fi +# Allow binary caches for user +add_config "trusted-users = root ${USER:-}" +# Add a GitHub access token. +# Token-less access is subject to lower rate limits. +if [[ -n "${INPUT_GITHUB_ACCESS_TOKEN:-}" ]]; then + echo "::debug::Using the provided github_access_token for github.com" + add_config "access-tokens = github.com=$INPUT_GITHUB_ACCESS_TOKEN" +# Use the default GitHub token if available. +# Skip this step if running an Enterprise instance. The default token there does not work for github.com. +elif [[ -n "${GITHUB_TOKEN:-}" && $GITHUB_SERVER_URL == "https://github.com" ]]; then + echo "::debug::Using the default GITHUB_TOKEN for github.com" + add_config "access-tokens = github.com=$GITHUB_TOKEN" +else + echo "::debug::Continuing without a GitHub access token" +fi +# Append extra nix configuration if provided +if [[ -n "${INPUT_EXTRA_NIX_CONFIG:-}" ]]; then + add_config "$INPUT_EXTRA_NIX_CONFIG" +fi +if [[ ! $INPUT_EXTRA_NIX_CONFIG =~ "experimental-features" ]]; then + add_config "experimental-features = nix-command flakes" +fi +# Always allow substituting from the cache, even if the derivation has `allowSubstitutes = false`. +# This is a CI optimisation to avoid having to download the inputs for already-cached derivations to rebuild trivial text files. +if [[ ! $INPUT_EXTRA_NIX_CONFIG =~ "always-allow-substitutes" ]]; then + add_config "always-allow-substitutes = true" +fi + +# Nix installer flags +installer_options=( + --no-channel-add + --darwin-use-unencrypted-nix-store-volume + --nix-extra-conf-file "$workdir/nix.conf" +) + +# only use the nix-daemon settings if on darwin (which get ignored) or systemd is supported +if [[ (! $INPUT_INSTALL_OPTIONS =~ "--no-daemon") && ($OSTYPE =~ darwin || -e /run/systemd/system) ]]; then + installer_options+=( + --daemon + --daemon-user-count "$(python3 -c 'import multiprocessing as mp; print(mp.cpu_count() * 2)')" + ) +else + # "fix" the following error when running nix* + # error: the group 'nixbld' specified in 'build-users-group' does not exist + add_config "build-users-group =" + sudo mkdir -p /etc/nix + sudo chmod 0755 /etc/nix + sudo cp "$workdir/nix.conf" /etc/nix/nix.conf +fi + +if [[ -n "${INPUT_INSTALL_OPTIONS:-}" ]]; then + IFS=' ' read -r -a extra_installer_options <<< "$INPUT_INSTALL_OPTIONS" + installer_options=("${extra_installer_options[@]}" "${installer_options[@]}") +fi + +echo "installer options: ${installer_options[*]}" + +# There is --retry-on-errors, but only newer curl versions support that +curl_retries=5 +while ! curl -sS -o "$workdir/install" -v --fail -L "${INPUT_INSTALL_URL:-https://releases.nixos.org/nix/nix-2.22.1/install}" +do + sleep 1 + ((curl_retries--)) + if [[ $curl_retries -le 0 ]]; then + echo "curl retries failed" >&2 + exit 1 + fi +done + +sh "$workdir/install" "${installer_options[@]}" + +# Set paths +echo "/nix/var/nix/profiles/default/bin" >> "$GITHUB_PATH" +# new path for nix 2.14 +echo "$HOME/.nix-profile/bin" >> "$GITHUB_PATH" + +if [[ -n "${INPUT_NIX_PATH:-}" ]]; then + echo "NIX_PATH=${INPUT_NIX_PATH}" >> "$GITHUB_ENV" +fi + +# Set temporary directory (if not already set) to fix https://github.com/cachix/install-nix-action/issues/197 +if [[ -z "${TMPDIR:-}" ]]; then + echo "TMPDIR=${RUNNER_TEMP}" >> "$GITHUB_ENV" +fi + +# Close the log message group which was opened above +echo "::endgroup::" diff --git a/.forgejo/install-emacs/install.sh b/.forgejo/install-emacs/install.sh new file mode 100755 index 0000000..42bd940 --- /dev/null +++ b/.forgejo/install-emacs/install.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +# Users should use install-nix-action if they want to customise how Nix is installed. + +set -euo pipefail + +if ! type -p nix &>/dev/null ; then + env INPUT_EXTRA_NIX_CONFIG= \ + INPUT_INSTALL_OPTIONS= \ + INPUT_INSTALL_URL= \ + INPUT_NIX_PATH="nixpkgs=channel:nixos-unstable" \ + INPUT_ENABLE_KVM=true \ + "$(dirname "$0")"/install-nix.sh + # Make the installed Nix immediately available here + source "$GITHUB_ENV" + while IFS= read -r dir; do PATH="$dir:$PATH"; done < "$GITHUB_PATH" +fi + +echo "::group::Configuring build cache and installing Emacs" +nix profile install --accept-flake-config "github:purcell/nix-emacs-ci#emacs-${INPUT_VERSION/./-}" +echo "::endgroup::" diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml new file mode 100644 index 0000000..7ced8e7 --- /dev/null +++ b/.forgejo/workflows/ci.yml @@ -0,0 +1,41 @@ +on: [push] +jobs: + test: + name: Test on ${{matrix.emacs-version}} + runs-on: docker + strategy: + matrix: + node: ["20"] + emacs-version: ["snapshot", "28.2", "29.4"] + + steps: + - name: Checkout + uses: https://code.forgejo.org/actions/checkout@v4 + + - name: Setup NodeJS + uses: https://code.forgejo.org/actions/setup-node@v4 + with: + node-version: ${{matrix.node}} + + - name: Install ripgrep + run: apt-get update -qq && apt-get install ripgrep -y + + - name: Setup emacs + uses: ./.forgejo/install-emacs + with: + version: ${{ matrix.emacs-version }} + + - name: Install eask + run: npm install -g @emacs-eask/cli + + - name: Install deps + run: eask install-deps --dev + + - name: Run tests + run: eask test buttercup + + - name: Build package to dist + run: eask package + + - name: Uninstall eask + run: npm uninstall -g @emacs-eask/cli diff --git a/.gitignore b/.gitignore index 1304fa2..edf700e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.elc -/.cask/ +/.eask/ +/dist/ diff --git a/Cask b/Cask deleted file mode 100644 index ce1fddc..0000000 --- a/Cask +++ /dev/null @@ -1,10 +0,0 @@ -(source gnu) -(source melpa) - -(package-file "counsel-projectile.el") - -(files "*.el") - -(development - (depends-on "counsel") - (depends-on "projectile")) diff --git a/Eask b/Eask new file mode 100644 index 0000000..53d1357 --- /dev/null +++ b/Eask @@ -0,0 +1,18 @@ +(package "counsel-projectile" + "0.4.0" + "Ivy integration for Projectile") + +(website-url "https://git.icejam.ee/maciej/counsel-projectile") +(keywords "project" "convenience") + +(package-file "counsel-projectile.el") + +(source "gnu") +(source "melpa") + +(depends-on "emacs" "26.1") +(depends-on "projectile") +(depends-on "counsel") + +(development + (depends-on "buttercup")) diff --git a/Makefile b/Makefile index d473676..eb4e300 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,13 @@ emacs ?= emacs -CASK = ~/.cask/bin/cask -BEMACS = $(emacs) -batch -l targets/elpa.el +EASK ?= eask all: compile -cask: - $(CASK) +eask: + $(EASK) compile: - $(BEMACS) -l targets/compile.el + $(EASK) compile .PHONY: all compile clean cask diff --git a/counsel-projectile.el b/counsel-projectile.el index 81b6b01..a13d618 100644 --- a/counsel-projectile.el +++ b/counsel-projectile.el @@ -3,10 +3,10 @@ ;; Copyright (C) 2016-2021 Eric Danan ;; Author: Eric Danan -;; URL: https://github.com/ericdanan/counsel-projectile +;; URL: https://git.icejam.ee/maciej/counsel-projectile ;; Keywords: project, convenience -;; Version: 0.3.2 -;; Package-Requires: ((counsel "0.13.4") (projectile "2.5.0")) +;; Version: 0.4.0 +;; Package-Requires: ((counsel "0.13.4") (projectile "2.5.0") (emacs "26.1")) ;; This file is NOT part of GNU Emacs. @@ -58,7 +58,7 @@ with default value ACTION, to be used as `:action' parameter for COMMAND's `ivy-read' call. -This variable holds either a single action function, or an action +;; This variable holds either a single action function, or an action list whose first element is the index of the default action in the list and the remaining elements are the actions (a key, a function, and a name for each action)." @@ -348,7 +348,7 @@ on `counsel-find-file-ignore-regexp'." ;; We apply `counsel--find-file-matcher' to `cands' so we can ;; honor `ivy-use-ignore', but we don't need to filter ;; again. - (counsel--find-file-matcher nil cands)))) + (counsel--find-file-matcher nil cands)))) (defun counsel-projectile-find-file-action (file) "Find FILE and run `projectile-find-file-hook'." @@ -450,7 +450,7 @@ The sorting function can be modified by adding an entry for ("p" counsel-projectile-find-dir-action-switch-project "switch project")) 'counsel-projectile) - + (defun counsel-projectile--project-directories () "Return a list of current project's directories." (if projectile-find-dir-includes-top-level @@ -923,7 +923,7 @@ is called with a `\\[universal-argument]' prefix argument." (projectile--globally-ignored-file-suffixes-glob) (projectile-ignored-files-rel) (projectile-ignored-directories-rel)) - " ")) + " ")) (counsel-rg-base-command (let ((counsel-ag-command counsel-rg-base-command)) (counsel--format-ag-command ignored "%s")))) @@ -1110,7 +1110,7 @@ The format is the same as in `org-capture-templates-contexts'." "Switch project action for `counsel-projectile-org-capture'." (setq org-capture-templates counsel-projectile--org-capture-templates-backup) (counsel-projectile-switch-project 'counsel-projectile-switch-project-action-org-capture)) - + ;;;###autoload (defun counsel-projectile-org-capture (&optional from-buffer) "Capture into the current project. @@ -1576,7 +1576,7 @@ files." (if (member name counsel-projectile--buffers) (ivy--kill-buffer-action name) (counsel-projectile-find-file-action-delete name))) - + (defun counsel-projectile-action-find-file-manually (name) "Call `counsel-find-file' from default directory of buffer directory of file named NAME." diff --git a/targets/compile.el b/targets/compile.el deleted file mode 100644 index 06ed493..0000000 --- a/targets/compile.el +++ /dev/null @@ -1,3 +0,0 @@ -(setq files '("counsel-projectile.el")) -(setq byte-compile--use-old-handlers nil) -(mapc #'byte-compile-file files) diff --git a/targets/elpa.el b/targets/elpa.el deleted file mode 100644 index 3e15e4e..0000000 --- a/targets/elpa.el +++ /dev/null @@ -1,6 +0,0 @@ -(setq package-user-dir - (expand-file-name (format ".cask/%s/elpa" emacs-version))) -(package-initialize) -(message "ELPA dir: %S" package-user-dir) -(add-to-list 'load-path default-directory) - diff --git a/tests/test-counsel-projectile.el b/tests/test-counsel-projectile.el new file mode 100644 index 0000000..f6a2e82 --- /dev/null +++ b/tests/test-counsel-projectile.el @@ -0,0 +1,73 @@ +;;; test-counsel-projectile.el --- Buttercup tests for counsel-projectile -*- lexical-binding: t; -*- +;;; Commentary: +;;; Code: +(require 'counsel-projectile) +(require 'buttercup) + +;; Example test! +(describe "counsel-projectile-switch-project" + (before-each + (spy-on 'ivy-read) + (spy-on 'projectile-project-root :and-return-value "/usr/fake-project") + (setq + projectile-known-projects '("/usr/fake-project" "~/some-project") + counsel-projectile-switch-project-action 'counsel-projectile-switch-project-action)) + + (it "calls ivy-read" + (counsel-projectile-switch-project) + (expect 'projectile-project-root :to-have-been-called) + (expect + 'ivy-read + :to-have-been-called-with + "[fake-project] Switch to project: " + '("/usr/fake-project" "~/some-project") + :preselect "/usr/fake-project" + :action 'counsel-projectile-switch-project-action + :require-match t + :sort nil + :caller 'counsel-projectile-switch-project))) + +(describe "counsel-projectile-rg" + (before-each + (spy-on 'ivy-read) + (spy-on 'projectile-project-root :and-return-value "/usr/fake-project")) + + (it "calls ivy-read" + (counsel-projectile-rg) + (expect + 'ivy-read + :to-have-been-called-with + "[fake-project] rg: " + 'counsel-ag-function + :initial-input nil + :dynamic-collection t + :keymap '(keymap + (24 keymap (4 . counsel-cd)) + (67108903 . swiper-avy) + (27 keymap (113 . counsel-git-grep-query-replace)) + (12 . ivy-call-and-recenter)) + :history 'counsel-git-grep-history + :action 'counsel-git-grep-action + :require-match t + :caller 'counsel-rg))) + +(describe "counsel-projectile-find-file" + (before-each + (spy-on 'ivy-read) + (spy-on 'projectile-project-root :and-return-value user-emacs-directory)) + + (it "calls ivy-read" + (counsel-projectile-find-file) + (expect + 'ivy-read + :to-have-been-called-with (format "[%s] Find file: " emacs-version) + nil + :matcher 'counsel-projectile--find-file-matcher + :require-match t + :sort nil + :action counsel-projectile-find-file-action + :caller 'counsel-projectile-find-file))) +;; Local Variables: +;; no-byte-compile: t +;; End: +;;; test-counsel-projectile.el ends here