Skip to content

Skewer the monotony of hooking into major modes

Notifications You must be signed in to change notification settings

Walheimat/harpoon

Repository files navigation

harpoon

Coverage Status

harpoon skewers the monotony of hooking into (mainly language) major modes by providing a simple use-package-like macro.

It grew out of my configuration and therefore is currently still heavily geared towards packages I use (like corfu and lsp-mode). But I aim to slowly decouple its functionality from any particular package.

Installation

If you use straight or quelpa, you know what to do.

If you’re on Emacs >29, I recommend using package-vc-install.

Alternatively, provided you have Cask, you can install the package with make package-install.

Usage

Let’s take a look at a form using all currently available features.

(harpoon some-mode
  :bind t
  :completion (:provider corfu :prefix 1 :delay 0.1)
  :functions (some-fun other-fun)
  :ligatures ("::" ">>")
  :lsp (:function lsp-deferred :dir-ignore-list lsp-file-watch-ignored-list :ignore-dirs (".bucket"))
  :messages ("Something in the way" "She moves")
  :prog-like t
  :tabs t
  :checker flycheck-mode
  :whitespace delete

  (some-other-fun)
  (setq some-other-var t))

Setting :bind t will bind the value of harpoon-bind-key to a symbol named some-mode-<harpoon-bind-name-suffix> . In my configuration I set harpoon-bind-name-suffix to “-major”; this is a transient map for the current major-mode. You can also pass a symbol that will be bound.

The setting for :completion is a plist configuring the harpoon-completion-provider (only corfu is currently supported) to enable automatic completion with a prefix length of 1 and a delay of 0.1. This does not set values that aren’t explicitly set. You don’t need to set provider if the default (harpoon-completion-provider) should be used.

The list of symbols passed to :functions are called on the condition that they are bound when some-mode is enabled.

The list of strings passed to :ligatures will be set for some-mode using package ligature provided it can be required. Have a look at harpoon-common-ligatures for a list of ligatures always set up.

The plist passed to :lsp will add directory “.bucket” to a ignore list and call lsp-deferred when some-mode is enabled. Note that you don’t need to set :function if you set harpoon-lsp-function, but you could set eglot-ensure here instead to have some other mode use that. The ignore list will default to harpoon-lsp-dir-ignore-list.

Entries in the list of strings passed to :messages will be displayed randomly when some-mode is enabled.

If :prog-like is t, hook prog-like-hook is run. This is useful when some-mode is not derived from prog-mode but kind of like one (think yaml-mode) and you want to set up the same minor-modes for it that you do for real prog modes.

The symbol passed to :tabs can be either t, always or never. The latter two will set indent-tabs-mode to t or nil. Symbol t will setting indent-tabs-mode to t dependent on the value of harpoon-prefer-tabs which is a custom variable that should be set using a .dir-locals.el file.

The symbol passed to :checker should be the name of a syntax checker. You normally should instead just set harpoon-checker-function but if you have modes that should use another checker, set it here. You can also pass symbol disabled to instead don’t enable any checker even if harpoon-checker-function is set.

Any form after the keyword arguments will also be evaluated when some-mode is enabled.

The macro will set up function some-mode-harpoon that will be added to some-mode-hook. Note that if there is an alternative treesit mode that can be used the hook is created for it instead. So if you have the grammar for JavaScript, for example, and set up harpoon for js-mode, the hook will be created for js-ts-mode. Since the pattern for mode => language, and mode => treesitter variant isn’t uniform, this currently only works for a small number of modes/languages.

If you pass :flat t completion and syntax checking is not set up. This can be useful if you have some configuration for a mode and others for those derived from it.

Setting :whitespace delete means a before-save-hook will be installed to call delete-trailing-whitespace. This can also be enabled generally by setting harpoon-whitespace to delete. If you do that but want to exclude some modes, you can pass :whitespace keep for them.

You can set harpoon-log to t in your init file if you want to see what expanding your harpoon form(s) did. You can switch to the logs using harpoon-pop-to-logs.

Please also have a look, again, at my configuration for usage examples.

About

Skewer the monotony of hooking into major modes

Resources

Stars

Watchers

Forks

Packages

No packages published