Skip to content

mohkale/projection

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Projection

MELPA

Project type support for Emacs builtin project.el.

This Emacs package provides a Projectile like project management library atop Emacs built-in project.el. The end goal is to provide a stable and reliable out-of-the-box project management experience for as many project types as possible while supporting very targeted support for some project types like CMake.

The Why?

Projectile is fantastic! The out of the box experience is amazing, but it’s also quite overbearing. Currently projectile has almost 6000 lines of source code all contained in a single file. This includes cross-platform facilities for detecting the current project root, definitions for numerous project types, and a myriad of helper functions (such as a pluggable TAGS table back-end, or wrappers across other Emacs commands or packages with the sole amendment being they run in the project root). Suffice it to say I think projectile is spread a little too thin and trying to do way too much. This is a consequence of it evolving naturally from a time when Emacs had poor built-in project support. Going forward I expect more packages to start using the new built-in Emacs project.el and Projectile becoming yet-another pluggable backend for it. In that vein this project is simply trying to migrate over the minimum feature set I find valuable from Projectile for my personal use. Where possible I do also try to improve on features. For example Projectile doesn’t support binding an interactive function as a compilation command (like rustic-compile) but Projection does.

Note: If any part of this description is no longer up-to-date please open a PR to discuss updating it :-).

Installation

Manually

  1. Clone the repo.
  2. Add the src and/or the src/projection-multi path to your Emacs load-path.
  3. Load it when needed.

MELPA

Projection and any extension packages are on MELPA. You can add this to your package-archives variable and then install through M-x package-install.

(push '("melpa" . "https://melpa.org/packages/") package-archives)
(package-refresh-contents)
(package-install 'projection)
(package-install 'projection-multi)

Quickstart

Must of projection is optional. By default projection does not do anything, not even bind any keys (although it does provide a map to make this more convenient). Here’s a base configuration that will enable ALL the feature of projection out of the box. See Features for a list of features.

(use-package projection
  :ensure t
  ;; Enable the `projection-hook' feature.
  :hook (after-init . global-projection-hook-mode)

  ;; Require projections immediately after project.el.
  :config
  (with-eval-after-load 'project
    (require 'projection))

  :config
  ;; Uncomment if you want to disable prompts for compile commands customized in .dir-locals.el
  ;; (put 'projection-commands-configure-project 'safe-local-variable #'stringp)
  ;; (put 'projection-commands-build-project 'safe-local-variable #'stringp)
  ;; (put 'projection-commands-test-project 'safe-local-variable #'stringp)
  ;; (put 'projection-commands-run-project 'safe-local-variable #'stringp)
  ;; (put 'projection-commands-package-project 'safe-local-variable #'stringp)
  ;; (put 'projection-commands-install-project 'safe-local-variable #'stringp)

  ;; Access pre-configured projection commands from a keybinding of your choice.
  ;; Run `M-x describe-keymap projection-map` for a list of available commands.
  :bind-keymap
  ("C-x P" . projection-map))

(use-package projection-multi
  :ensure t
  ;; Allow interactively selecting available compilation targets from the current
  ;; project type.
  :init
  (define-key global-map "RET" #'projection-multi-compile))

(use-package projection-multi-embark
  :ensure t
  :after embark
  :after projection-multi
  :demand t
  ;; Add the projection set-command bindings to `compile-multi-embark-command-map'.
  :config (projection-multi-embark-setup-command-map))

Features

Projection Commands

This feature works just like projectiles projectile-compile-project family of commands. Each project can optionally expose one of the following command types and you can use the associated projection-commands-TYPE-project command to invoke it interactively.

TypeDescription
ConfigureRun any pre-configure steps such as generating Makefiles.
BuildCompile the project.
TestRun any configured tests for the current project.
RunRun the project (for example: Starting a game).
PackageProduce a package from the built project.
InstallInstall the packaged project into an install directory.

At any point you can customize or override what command to run for these command-types by passing a prefix argument (C-u) to the command. The command you enter will be cached so subsequent attempts to run the same command-type will use the same command. You can reset to the project defaults with M-x projection-reset-project-cache.

Note: Projection supports both shell-commands, interactive functions and helper functions which can return either of these as valid targets for each of these commands. This means, for example, we can support using rustic-modes builtin compilation commands and fallback to basic shell-commands when those aren’t defined. See projection-types for how this is configured.

Projection Hook

Provides a more general purpose parallel to projectile-toggle-project-read-only. With this you can hook certain functions (Example: read-only-mode) into a project and retroactively apply it to both all the open buffers from that project and any new buffers that will be opened in it.

Projection ibuffer

Offers variants of projectile-ibuffer and the ibuffer-projectile project in the form of ibuffer-projection-current-project and ibuffer-projection-set-filter-groups. The former creates and displays a dedicated ibuffer window for only buffers in the current project. The latter pre-pends filters to group by a specific project for all currently open projects.

Projection Find

Adds facilities for jumping to related files within a project. The most common use case for this would be jumping between C++ header .h and implementation .cpp files. This is already possible with Emacs’s builtin ff-find-other-file command but projection builds on top of it by supporting jumping to related files in other directories or with alterations to the file-name beyond extensions. For example if you have header files in an include directory and implementation files in a src directory then projection-find-other-file can still jump between them without any extra configuration. If you’re working on a python project and define test files with a test_BASENAME.py format then projection-find-other-file can also jump between BASENAME.py and test_BASENAME.py. projection-find-other-file is intended to be a consistent and transitive command. You can invoke it repeatedly to cycle between related files and the order in which you cycle will be consistent independent of which file you’re currently in.

General associations between the current files extension and possible related file extensions is configured in projection-find-other-file-suffix. Supported suffixes and prefixes for test files is configured by the project-type in src/projection-types.el.

Projection recentf

A variant of M-x recentf for files exclusively in the current project.

Projection multi-compile

MELPA

Demo

compile-multi is a multi target interface to M-x compile. It allows you to configure and interactively select compilation targets based on arbitrary projects.

Projection has an optional extension package called projection-multi-compile to integrate compile-multi into the current project type. It can extract available compilation targets from Makefiles, CMake configuration, etc. and let you execute them easily. By default projection-multi-compile determines all project types matching the current project and then resolves compilation targets based on them. For example a project that would match CMake and tox would let you select both tox environments and CMake build targets.

Each target generation function in projection-multi also supports being run independently. To select a tox task you can run M-x projection-multi-compile-tox, and you won’t be presented with CMake or any other target types. This bypasses project type matching altogether and so may present targets not normally discovered by projection-multi-compile.

Currently automatic target generation functions are available for the following project types:

  • projection (This simply presents available commands for the matching project types)
  • CMake (& CTest)
  • Make
  • Poetry Poe
  • Tox

Projection multi-embark

MELPA

Add embark integration to multi-compile using the multi-compile-embark extension feature. This allows you to immediately set one of the candidates show in a compile-multi session as the projects build, configure, etc. command type. Use this to interactively and incrementally update build targets.

Projection dape

MELPA

Adds support for interactively selecting debuggable artifacts of a project and starting a debugger instance with dape.

Specialised Project Support

Currently projection has very extensive support for certain project types. This tries to bind Emacs a little stronger into the framework and bring more IDE like support for extending the project builds. This section documents some of the extra support available.

CMake

For CMake projects projection supports the following extensions:

  • projection-cmake-set-preset - Interactively sets a preset for a given build-type in the current project. By default if a project has any supported presets for a build-type projection will automatically prompt you for which to use and then cache it for subsequent invocations. See projection-cmake-preset to set an alternative preset behaviour for your use case.
  • projection-cmake-set-build-type - Alter the value of the CMAKE_BUILD_TYPE option passed through to CMake while configuring.
  • Target resolution through the CMake file API. This is disabled by default but can be enabled by customizing projection-cmake-target-backend (for example: (setq projection-cmake-target-backend 'code-model)) and then re-configuring the project.

Configuration

Permanently Configuring Project Types

Project types are eioio objects. Every project type currently supported by projection has a defvar to allow you to modify it. For example you can override the default compilation command run for a given project by overriding the build attribute:

;; Change the test command for dotnet projects.
(oset projection-project-type-dotnet test "dotnet lint")
;; Unset the build command for dotnet projects.
(oset projection-project-type-dotnet build nil)

To remove a project type from the configuration list altogether you can delete it from projection-project-types.

(delq projection-project-type-cmake projection-project-types)

About

Projectile like project management library built on Emacs project.el

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages