The Selected Window Accent Mode is an Emacs package designed to visually distinguish the currently selected window by applying a unique accent color to its fringes, mode line, header line, and margins.
feat: add function to sync tab-bar faces with current theme
- Introduced `selected-window-accent-sync-tab-bar-to-theme`, which synchronizes the tab-bar faces (tab, tab-inactive) with the current theme.
- Sets the tab-bar face background and foreground to match the current `default` face settings.
- Added “Tab Sync to Theme” option under “Other” actions in the selected-window-accent hydra.
First full version.
Enhanced selected-window-accent functionality with blending options
This means that not only will the modeline, fringes and header be accent colored, but also the whole selected window background color, tinted to the alpha chosen.
- Introduced
selected-window-accent-use-blend-background
andselected-window-accent-use-blend-alpha
to allow blending of the accent color with the background of the selected window a selected alpha amount. - Introduced new toggle functions and added to transient:
selected-window-accent-toggle-blend-background
selected-window-accent-toggle-pywal
- Added function
selected-window-accent-blend-colors
to support blending of two colors. - Updated
selected-window-accent--set-foreground-color
andselected-window-accent
functions to incorporate new blending feature. - Improved existing functions for setting and toggling accent features, ensuring consistent style and formatting.
- Cleaned up indentation and formatting inconsistencies across the file for better readability.
Example use of new selected window blending functionality:
Note: that currently there are some limitations, and in fact the same ones that apply to general tiling
outline borders - see Limitations section.
(use-package selected-window-accent-mode
:config (selected-window-accent-mode 1)
:custom
(selected-window-accent-fringe-thickness 10)
(selected-window-accent-use-blend-background t)
(selected-window-accent-use-blend-alpha 0.2)
(selected-window-accent-tab-accent t)
(selected-window-accent-custom-color "cyan4")
(selected-window-accent-mode-style 'default))
(use-package selected-window-accent-mode
:config (selected-window-accent-mode 1)
:custom
(selected-window-accent-fringe-thickness 10)
(selected-window-accent-use-blend-background t)
(selected-window-accent-use-blend-alpha 0.1)
(selected-window-accent-tab-accent t)
(selected-window-accent-custom-color "orange")
(selected-window-accent-mode-style 'subtle))
Added explicit (require ‘transient)
Add Pywal color integration to selected-window-accent-mode to allow the accent color to be consistent with the wallpaper of the operating system.
Note: will only work on linux.
- Introduce `selected-window-accent-use-pywal` option to use a Pywal-generated color palette.
- Add `selected-window-accent–get-pywal-color` function to fetch colors from Pywal palette.
- Update logic in `selected-window-accent` function to use Pywal color if enabled.
- Require `json` package for handling Pywal palette.
Pywal is a tool on linux that generates color schemes from images, allowing users to apply these colors to their desktop and application themes for a cohesive and dynamic look.
Example use:
(setq selected-window-accent-use-pywal t)
When enabled, color1
is selected as the accent color, taken from the file : ~/.cache/wal/colors.json
which is a generic color file typically generated by pywal.
This means that the accent color can be more tied in with the current wallpaper once pywal is connected to the wallpaper change mechanism of your operating system.
Note that this feature will require an external pywal generation step, triggered on wallpaper change, examples given below.
See below for an example colors.json
file
Technically any tool that can write to a json file in a similar format will have a carry through affect on the accent color associated with this package. Here is an example :
{
"wallpaper": "/home/jdyer/.last_wallpaper.jpg",
"alpha": "100",
"special": {
"background": "#0d1a05",
"foreground": "#c8cfdb",
"cursor": "#c8cfdb"
},
"colors": {
"color0": "#0d1a05",
"color1": "#8FA944",
"color2": "#165E97",
"color3": "#5C7391",
"color4": "#748AA6",
"color5": "#7498C4",
"color6": "#8D9BB1",
"color7": "#c8cfdb",
"color8": "#8c9099",
"color9": "#8FA944",
"color10": "#165E97",
"color11": "#5C7391",
"color12": "#748AA6",
"color13": "#7498C4",
"color14": "#8D9BB1",
"color15": "#c8cfdb"
}
}
On linux, install python-pywal
using your package manager of choice.
At which point you can generate a colors.json
with the following commands:
wal -c
wal -i ~/.last_wallpaper.jpg -q -n
Changing a wallpaper and hooking pywal
up accordingly, which technically should work for both Wayland and X11.
#!/bin/bash
wallpaper_path="$(find ~/wallpaper-dir -type f | shuf -n 1)"
echo $wallpaper_path > ~/.last_wallpaper_path
cp -f $wallpaper_path ~/.last_wallpaper.jpg
if [[ $XDG_SESSION_TYPE == "x11" ]]; then
feh --bg-scale "$wallpaper_path"
fi
if [[ $XDG_SESSION_TYPE == "wayland" ]]; then
swww img "$wallpaper_path" --transition-step 20 --transition-fps=20
fi
# lets run pywal for color scheme generation
wal -c
wal -i ~/.last_wallpaper.jpg -q -n
feat: Add transient dependency and fix indentation
- Added ‘transient’ package requirement to `Package-Requires` in the header.
- Fixed indentation inconsistencies across the file for better code readability.
Details:
- Added `transient` package dependency:
- Updated the header to include `(transient “0.1.0”)` in `Package-Requires`.
- Added transient menu for interactive adjustments (see README usage)
- Upgraded emacs dependency to 28.1.
- Added `selected-window-accent-fg-color` for custom foreground accent color.
- Introduced various `defcustom` options for finer control over foreground accent:
- `selected-window-accent-foreground-adjust-factor`
- `selected-window-accent–use-complementary-color`
- `selected-window-accent–foreground-invert-state`
- `selected-window-accent–foreground-offset`
- Implemented functions for adjusting foreground brightness:
- `selected-window-accent-flip-foreground-color`
- `selected-window-accent-increment-foreground-color`
- `selected-window-accent-decrement-foreground-color`
- `selected-window-accent-toggle-complementary-color`
- `selected-window-accent-toggle-tab-accent`
- `selected-window-accent-toggle-smart-borders`
- Provided a function to output current settings for copy and paste to emacs init file: `selected-window-accent-output-selected-window-accent-settings`
- Miscellaneous improvements and refactoring.
To use left and bottom accent based on the themes highlight color:
(use-package selected-window-accent-mode
:config (selected-window-accent-mode 1)
:custom
(selected-window-accent-fringe-thickness 10)
(selected-window-accent-custom-color nil)
(selected-window-accent-mode-style 'subtle))
OR define your own color:
(use-package selected-window-accent-mode
:config (selected-window-accent-mode 1)
:custom
(selected-window-accent-fringe-thickness 10)
(selected-window-accent-custom-color "#427900")
(selected-window-accent-mode-style 'subtle))
(use-package selected-window-accent-mode
:config (selected-window-accent-mode 1))
Put the following into your emacs init file:
(use-package selected-window-accent-mode
:vc (:fetcher github :repo "captainflasmr/selected-window-accent-mode")
:config (selected-window-accent-mode 1))
Download the `.el` file and place it in your Emacs `load-path`.
Then either manually load it or add it to your configuration to be loaded at startup.
(require 'selected-window-accent-mode)
(selected-window-accent-mode 1)
Interactively Toggle the mode on and off M-x selected-window-accent-mode
A transient map is available (Emacs 28.1+):
(eval-after-load 'selected-window-accent-mode
'(progn
(define-key global-map (kbd "C-c w") 'selected-window-accent-transient)))
which will bring up the following transient menu:
The styles that are currently supported :
- default
- tiling
- subtle
To enable the accent mode automatically upon starting Emacs, add the following line to your `.emacs` or `init.el` file:
(use-package selected-window-accent-mode
:config (selected-window-accent-mode 1)
:custom
(selected-window-accent-fringe-thickness 20)
(selected-window-accent-custom-color "goldenrod")
(selected-window-accent-mode-style 'default))
This will accent the modeline only for the selected window with the goldenrod
color.
(use-package selected-window-accent-mode
:config (selected-window-accent-mode 1)
:custom
(selected-window-accent-fringe-thickness 6)
(selected-window-accent-custom-color "#4179b2")
(selected-window-accent-mode-style 'tiling))
This will accent the full outline of the window with the color #4179b2 more akin to a tiling window manager.
Example is using the theme doom-one
(use-package selected-window-accent-mode
:config (selected-window-accent-mode 1)
:custom
(selected-window-accent-fringe-thickness 10)
(selected-window-accent-custom-color nil)
(selected-window-accent-mode-style 'tiling))
This will accent the full outline of the window with the highlight
color taken from the current theme.
Example is using the theme doom-one
(use-package selected-window-accent-mode
:config (selected-window-accent-mode 1)
:custom
(selected-window-accent-fringe-thickness 20)
(selected-window-accent-custom-color nil)
(selected-window-accent-mode-style 'subtle))
This will accent the modeline and just the left fringe and in this case be quite a pronounced thick accent.
Example is using the theme doom-one
The takes the default highlight color from the theme as before but applies darkening and desaturation.
(use-package selected-window-accent-mode
:config (selected-window-accent-mode 1)
:custom
(selected-window-accent-fringe-thickness 20)
(selected-window-accent-percentage-darken 10)
(selected-window-accent-percentage-desaturate 100)
(selected-window-accent-custom-color nil)
(selected-window-accent-mode-style 'subtle))
Example is using the theme doom-one
The takes the default highlight color from the theme as before but applies lightening and saturation along with the same color tab accent.
(use-package selected-window-accent-mode
:config (selected-window-accent-mode 1)
:custom
(selected-window-accent-fringe-thickness 20)
(selected-window-accent-percentage-darken -10)
(selected-window-accent-percentage-desaturate -100)
(selected-window-accent-tab-accent t)
(selected-window-accent-custom-color nil)
(selected-window-accent-mode-style 'subtle))
Custom variable | Description |
---|---|
selected-window-accent-foreground-adjust-factor | Adjustment factor for incrementing or decrementing foreground color brightness. |
selected-window-accent-mode-style | Current style for accenting the selected window. |
selected-window-accent-percentage-darken | The percentage the highlight accent is darkened. |
selected-window-accent-use-blend-background | When non-nil, use the accent color to blend with background of selected window. |
selected-window-accent-use-pywal | When non-nil, use a color from Pywal generated palette. |
selected-window-accent-smart-borders | When non-nil, the `selected-window-accent-smart-borders` is active. |
selected-window-accent-fg-color | Custom foreground accent color for the selected window. |
selected-window-accent-custom-color | Custom accent color for the selected window. |
selected-window-accent-percentage-desaturate | The percentage the highlight accent is saturated. |
selected-window-accent-mode | Non-nil if Selected-Window-Accent mode is enabled. |
selected-window-accent-use-blend-alpha | Adjustment alpha factor for background of selected window blending. |
selected-window-accent-tab-accent | When non-nil, the `selected-window-accent-tab-accent` is active. |
selected-window-accent-mode-hook | Hook run after entering or leaving `selected-window-accent-mode’. |
selected-window-accent-fringe-thickness | The thickness of the fringes in pixels. |
selected-window-accent–reset-window-accent | Reset the accent colors for all windows to their defaults. | |
selected-window-accent-sync-tab-bar-to-theme | Synchronize tab-bar faces with the current theme. | |
selected-window-accent-switch-selected-window-accent-style | Switch the selected window accent style to STYLE and apply it. | |
selected-window-accent-increment-foreground-color | Increment the foreground color brightness. With ARG, adjust by a larger factor. | |
selected-window-accent-decrement-foreground-color | Decrement the foreground color brightness. With ARG, adjust by a larger factor. | |
selected-window-accent-flip-foreground-color | Flip the current foreground color to its opposite value. | |
selected-window-accent-output-selected-window-accent-settings | Output current `selected-window-accent-mode’ settings to a new buffer. | |
C-c w | selected-window-accent-transient | Transient for selected window accent. |
selected-window-accent-toggle-tab-accent | Toggle between showing the tab accent. | |
C-q a | selected-window-accent-mode | Toggle selected window accenting. |
selected-window-accent-toggle-pywal | Toggle between pywal. | |
selected-window-accent-switch-accent-color | Switch the selected window accent color and apply it. | |
selected-window-accent-toggle-blend-background | Toggle between blend background. | |
selected-window-accent-toggle-smart-borders | Toggle between smart borders. | |
selected-window-accent-toggle-complementary-color | Toggle between complementary color for foreground based on background color. |
The selected-window-accent-mode
is a global minor mode that you can toggle to enable or disable the accenting of the selected window.
When enabled, it distinguishes the selected window with a special accent color.
Two hooks are used to automatically update the window accents when the window configuration or state changes:
- window-configuration-change-hook
- window-state-change-hook
These are added when the selected-window-accent-mode
is enabled and removed when disabled.
Just as a note, the overall design of this package is a little, lets just say clunky, something that has been somewhat shoehorned into the Emacs functional architecture, therefore there will be a few little quirks. In this section I look to explain my general design ideas regarding how I achieved some kind of window highlighting / accenting and the associated limitations.
This section is mainly for me, as the maintainer of this package, but may be informative to others. This section is to try and fully understand how I have designed this thing for when I come back and have another rethink on improvements.
Firstly it is important to define the scope of window based visual highlighting in Emacs, which hopefully will help to explain some of the limitations of this package.
It works well enough I think at the moment and I especially I tend to favour the ‘subtle accent mode which inherently has the fewest issues along with providing a satisfying visually distinguishing highlighting mechanism, more bang for the buck if you will.
position: left, right face-attribute: ‘fringe : all-windows size: (set-window-fringes left right) : per-window
position: top value: header-line-format : per-window face-attribute: ‘header-line : all-windows size: face-attribute :height : all-windows
position: bottom value: mode-line-format : selected-window face-attribute: ‘mode-line-active : selected-window size: face-attribute :height : all-windows
face-attribute: ‘tab-bar-tab
calculate accent colors update global face-attributes walk-windows for each window update window with accent or default appearance if window is not selected reset header-line to nil reset fringes to 0
As a header-line can only have a single global color it does mean that the header-line-format for each window needs to be made blank in order to preserve accent consistency, this means that modes which change the header-line, such as some modes of magit and org-sticky-header will possibly have to be sacrificed for this selected-window-accent-mode to function coherently.
There is a possibility that I could add in some extra logic depending on the mode that is set, but that might be for a future version, and at this moment I’m just not sure the effort is worth it.
The accent is now always alongside an Emacs default margin so as not to overlap with existing packages that utilize the window margin settings, this would make the accent facility look a little less visually appealing then applying a little margin for the selected window along with a compensating margin for non selected windows, but this will have to be sacrificed for not disrupting other Emacs package functionality.
All non selected windows have been fringe zeroed to preserve fringe accent consistency as the fringe color can only be set globally meaning that any Emacs packages that implement fringe functionality, which I have found to be uncommon, would show varying levels of window accents.
When a buffer is split into multiple windows in tiling mode the header line is shared, thus leading to an accented header line across all splits, this is an inherent limitation of Emacs and how it processes windows / buffers.
Phew!, that might be it, this can get quite complicated!
At the moment this package works well enough for my needs and I will think about overlays again at some point to see if I can somehow re-purpose them to fit my needs, currently it is the buffer / window scrolling that I think would always tend to look pretty clunky if implemented.
I of course shall keep an eye on Emacs development to see if at some time in the future a more flexible per window visual facility becomes available.
TODO | DOING | DONE |
---|---|---|
ISSUE #6 - Feature request: accent currently se… | ISSUE #4 - Doesn’t work well with other packages | ISSUE #1 - Do not apply highlighting when frame… |
Limiting magit-log when enabled | ISSUE #3 - Package breaks fringes | |
Add pywal toggle to transient | ||
blend accent color into selected window background | ||
Added pywal integration | ||
Restore modeline height when switching between … | ||
Define accent color saturation adjustment | ||
Define accent color darken adjustment | ||
Highlight selected tab with same accent color | ||
Add to MELPA | ||
Minor change to properly format color-theme-buf… | ||
Pacified package-lint with visual-fill-column 0.0 | ||
Added similar package comparisons as suggested | ||
Rename color-name-to-hex to selected-window-acc… | ||
Fixing issues to be able to submit to MELPA | ||
Images to img directory and referenced from README | ||
Expand emacs help / documentation | ||
Add GNU header | ||
Cope better with 0 thickness | ||
Add ChangeLog. | ||
isual-fill-column-mode not working again! | ||
Improve modeline contrast between fg and bg |
TODO | DOING |
---|---|
Incorporate mode-line-active and mode-line-inactive | |
Header-line not shown on window split | |
Adjust the not selected-window margin to avoid little window navigation. disruption | |
Excess selected-window disruption in header-line. (not sure I can do much about this) | |
Add some form of unit test |
If multiple Emacs frames exist, then the selected window in each will be accented. It would be nice if the currently selected/focused frame was accented more than non-focused frames.
olivetti & org-sticky-header broken with selected-window-accent-mode
I have decided to disable the setting of windows margins as part of this package as this is often used for padding in other packages. This means I can now let packages such as olivetti-mode and visual-fill-column do their own thing without any margin interference. Therefore this package will mainly achieve its functionality via fringe modification rather than fringe/margins.
The disadvantage of this is that on window transition there will be more of a text in buffer offset shift as the select-window-accent-mode fringe is applied to the select window without a default compensatory margin / fringe shift. This didn’t really work anyway and there was always a little shift depending on the width of the native emacs margin character vs fringe pixel size.
This means I don’t have to depend on package checks and maybe packages I am unaware of that depend on window buffer margin changes will work better in the future.
Maybe I can just define a non selected window compensatory margin in the future, for now I will leave as is and see how it goes!
However this currently doesn’t cover any mode that modifies a window header, like for example org-sticky-header.
- byte-compile / flycheck
- checkdoc
- package-lint
- other
This would make more sense especially in the ‘default mode. So in-built Emacs modeline functionality would come into play.
I have a funny feeling this could be very difficult, if not impossible!
Hence translating a fringe pixel width to a number of margin characters, not quite sure how I am going to do this yet.
See CHANGELOG.org
There exist a few Emacs packages that perform window highlighting but that don’t quite provide the feature set of selected-window-accent.
selected-window-accent focusses more on clearly but non-intrusively highlighting the currently selected/focussed window by highlighting aspects of the window border without having to modify the appearance of non-selected windows, hence more akin to a tiling window manager.
“This package provides a minor mode that indicates which buffer is currently active by dimming the faces in the other buffers.”
This is the closest in functionality to selected-window-accent, the difference being that dimmer dims non selected windows rather than accent the selected window.
dimmer can be used in conjunction and will complement selected-window-accent to further enhance the emphasizing of the selected window.
“This package provides a minor-mode to change the background color of the non active window.”
It uses overlays to highlight non active windows, so is similar to dimmer but is less subtle in its highlighting mechanism and hasn’t been updated in excess of 10 years.
“This package lets you set a color-theme on a per-buffer basis.”
Unlike dimmer and hiwin this package isn’t related to the concept of a selected window but more of defining different themes for different windows to distinguish them.
“This package is designed to visually distinguish “real” buffers (i.e. file-visiting code buffers where you do most of your work) from “unreal” buffers (like popups, sidebars, log buffers, terminals, etc) by giving the latter a slightly different – often darker – background”
Unlike dimmer and hiwin this package isn’t related to the concept of a selected window but more of distinguishing between collections of IDE like elements within Emacs.
Contributions to arscript-mode are welcome! Whether it’s bug reports, feature suggestions, or code contributions, feel free to reach out or submit pull requests on GitHub.