From 3f590b86c63aa61db56153173aa45b8b3d07d594 Mon Sep 17 00:00:00 2001 From: Martin Kozlovsky Date: Thu, 14 Apr 2022 00:44:18 +0200 Subject: [PATCH] New module: XMonad.Actions.RepeatAction Closes: https://github.com/xmonad/xmonad-contrib/issues/489 --- CHANGES.md | 5 ++ XMonad/Actions/RepeatAction.hs | 84 ++++++++++++++++++++++++++++++++++ xmonad-contrib.cabal | 1 + 3 files changed, 90 insertions(+) create mode 100644 XMonad/Actions/RepeatAction.hs diff --git a/CHANGES.md b/CHANGES.md index d34f49ca..b3ae97d5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -69,6 +69,11 @@ Flashes the name of the current workspace when switching to it. Like `XMonad.Layout.ShowWName`, but as a logHook. + * `XMonad.Actions.RepeatAction` + + A module for adding a keybinding to repeat the last action, similar + to Vim's `.` or Emacs's `dot-mode`. + ### Bug Fixes and Minor Changes * `XMonad.Prompt.OrgMode` diff --git a/XMonad/Actions/RepeatAction.hs b/XMonad/Actions/RepeatAction.hs new file mode 100644 index 00000000..c372e82d --- /dev/null +++ b/XMonad/Actions/RepeatAction.hs @@ -0,0 +1,84 @@ +{-# LANGUAGE LambdaCase #-} +----------------------------------------------------------------------------- +-- | +-- Module : XMonad.Actions.RepeatAction +-- Description : Repeat the last performed action. +-- Copyright : (c) 2022 Martin Kozlovsky +-- License : BSD3-style (see LICENSE) +-- +-- Maintainer : +-- Stability : unstable +-- Portability : not portable +-- +-- Ability to repeat the last action. +-- +----------------------------------------------------------------------------- + +module XMonad.Actions.RepeatAction ( + -- * Usage + -- $usage + rememberAction, + rememberActions, + repeatLast, +) where + +import XMonad + +import qualified XMonad.Util.ExtensibleState as XS + +-- $usage +-- +-- You can use this module with the following in your @xmonad.hs@: +-- +-- > import XMonad.Actions.RepeatAction +-- +-- Then join a dedicated key to run the last action with the rest of your +-- key bindings using the 'rememberActions': +-- +-- > rememberActions (modm, xK_period) [((modm, xK_c), kill), …] +-- +-- It can be also used in the same way for "XMonad.Util.EZConfig": +-- +-- > rememberActions "M-." [("M-c", kill), …] +-- +-- For example, if you use 'XMonad.Util.EZConfig.additionalKeysP', +-- +-- > main = xmonad $ … $ def +-- > { +-- > … +-- > } +-- > `additionalKeysP` myKeys +-- +-- you would adjust the call to 'XMonad.Util.EZConfig.additionalKeysP' +-- like so: +-- +-- > `additionalKeysP` (rememberActions "M-." myKeys) +-- +-- For more detailed instructions on editing your key bindings, see +-- . + +newtype LastAction = LastAction { runLastAction :: X () } + +instance ExtensionClass LastAction where + initialValue = LastAction $ pure () + +-- | Transforms an action into an action that can be remembered and repeated. +rememberAction :: X () -> X () +rememberAction x = userCode x >>= \case + Nothing -> pure () + Just () -> XS.put (LastAction x) -- Only remember action if nothing went wrong. + +-- | Maps 'rememberAction' over a list of key bindings. +rememberActions' :: [(a, X ())] -> [(a, X ())] +rememberActions' = map (fmap rememberAction) + +infixl 4 `rememberActions` +-- | Maps 'rememberAction' over a list of key bindings and adds a dedicated +-- key to repeat the last action. +rememberActions :: a -> [(a, X ())] -> [(a, X ())] +rememberActions key keyList = (key, repeatLast) : rememberActions' keyList + +-- | Runs the last remembered action. +-- / Be careful not to include this action in the remembered actions! / +repeatLast :: X () +repeatLast = XS.get >>= runLastAction diff --git a/xmonad-contrib.cabal b/xmonad-contrib.cabal index 4931a4cb..2832df95 100644 --- a/xmonad-contrib.cabal +++ b/xmonad-contrib.cabal @@ -126,6 +126,7 @@ library XMonad.Actions.Prefix XMonad.Actions.Promote XMonad.Actions.RandomBackground + XMonad.Actions.RepeatAction XMonad.Actions.RotSlaves XMonad.Actions.RotateSome XMonad.Actions.Search