-
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 1855006
Showing
4 changed files
with
347 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/*.elc | ||
/*-autoloads.el | ||
/.config.mk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
-include .config.mk | ||
|
||
PKG = minions | ||
|
||
ELS = $(PKG).el | ||
ELCS = $(ELS:.el=.elc) | ||
|
||
DEPS = | ||
|
||
EMACS ?= emacs | ||
EMACS_ARGS ?= | ||
|
||
LOAD_PATH ?= $(addprefix -L ../,$(DEPS)) | ||
LOAD_PATH += -L . | ||
|
||
all: lisp | ||
|
||
help: | ||
$(info make all - generate byte-code and autoloads) | ||
$(info make lisp - generate byte-code and autoloads) | ||
$(info make clean - remove generated files) | ||
@printf "\n" | ||
|
||
lisp: $(ELCS) loaddefs | ||
|
||
loaddefs: $(PKG)-autoloads.el | ||
|
||
%.elc: %.el | ||
@printf "Compiling $<\n" | ||
@$(EMACS) -Q --batch $(EMACS_ARGS) $(LOAD_PATH) -f batch-byte-compile $< | ||
|
||
CLEAN = $(ELCS) $(PKG)-autoloads.el | ||
|
||
clean: | ||
@printf "Cleaning...\n" | ||
@rm -rf $(CLEAN) | ||
|
||
define LOADDEFS_TMPL | ||
;;; $(PKG)-autoloads.el --- automatically extracted autoloads | ||
;; | ||
;;; Code: | ||
(add-to-list 'load-path (directory-file-name \ | ||
(or (file-name-directory #$$) (car load-path)))) | ||
|
||
;; Local Variables: | ||
;; version-control: never | ||
;; no-byte-compile: t | ||
;; no-update-autoloads: t | ||
;; End: | ||
;;; $(PKG)-autoloads.el ends here | ||
endef | ||
export LOADDEFS_TMPL | ||
#' | ||
|
||
$(PKG)-autoloads.el: $(ELS) | ||
@printf "Generating $@\n" | ||
@printf "%s" "$$LOADDEFS_TMPL" > $@ | ||
@$(EMACS) -Q --batch --eval "(progn\ | ||
(setq make-backup-files nil)\ | ||
(setq vc-handled-backends nil)\ | ||
(setq default-directory (file-truename default-directory))\ | ||
(setq generated-autoload-file (expand-file-name \"$@\"))\ | ||
(setq find-file-visit-truename t)\ | ||
(update-directory-autoloads default-directory))" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
A minor-mode menu for the mode line | ||
=================================== | ||
|
||
This package implements a menu that lists enabled minor-modes, as | ||
well as commonly but not currently enabled minor-modes. It can be | ||
used to toggle local and global minor-modes, to access mode-specific | ||
menus, and to get help about modes. | ||
|
||
This menu is intended as a replacement for the incomplete yet wide | ||
list of enabled minor-modes that is displayed in the mode line by | ||
default. To use the menu like this, enable Minions mode. | ||
|
||
Alternatively the menu can be bound globally, for example: | ||
`(global-set-key [S-down-mouse-3] 'minions-minor-modes-menu)`. | ||
|
||
![screenshot](https://emacsair.me/assets/readme/minions.png) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,264 @@ | ||
;;; minions.el --- A minor-mode menu for the mode line -*- lexical-binding: t -*- | ||
|
||
;; Copyright (C) 2018 Jonas Bernoulli | ||
|
||
;; Author: Jonas Bernoulli <[email protected]> | ||
;; Homepage: https://github.com/tarsius/minions | ||
|
||
;; Package-Requires: ((emacs "25.3")) | ||
|
||
;; This file is not part of GNU Emacs. | ||
|
||
;; This file is free software; you can redistribute it and/or modify | ||
;; it under the terms of the GNU General Public License as published by | ||
;; the Free Software Foundation; either version 3, or (at your option) | ||
;; any later version. | ||
|
||
;; This file is distributed in the hope that it will be useful, | ||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
;; GNU General Public License for more details. | ||
|
||
;; For a full copy of the GNU General Public License | ||
;; see <http://www.gnu.org/licenses/>. | ||
|
||
;;; Commentary: | ||
|
||
;; This package implements a menu that lists enabled minor-modes, as | ||
;; well as commonly but not currently enabled minor-modes. It can be | ||
;; used to toggle local and global minor-modes, to access mode-specific | ||
;; menus, and to get help about modes. | ||
|
||
;; This menu is intended as a replacement for the incomplete yet wide | ||
;; list of enabled minor-modes that is displayed in the mode line by | ||
;; default. To use the menu like this, enable Minions mode. | ||
|
||
;; Alternatively the menu can be bound globally, for example: | ||
;; (global-set-key [S-down-mouse-3] 'minions-minor-modes-menu) | ||
|
||
;;; Code: | ||
|
||
(require 'cl-lib) | ||
(require 'subr-x) | ||
|
||
;;; Options | ||
|
||
(defgroup minions nil | ||
"A minor-mode menu for the mode line." | ||
:group 'mode-line) | ||
|
||
(defcustom minions-blacklist nil | ||
"List of minor-modes that are never shown in the mode menu. | ||
These modes are not even displayed when they are enabled." | ||
:group 'minions | ||
:type '(repeat (symbol :tag "Mode"))) | ||
|
||
(defcustom minions-whitelist | ||
;; Based on elements of `mode-line-mode-menu'. | ||
'((abbrev-mode . nil) | ||
(auto-fill-mode . nil) | ||
(auto-revert-mode . nil) | ||
(auto-revert-tail-mode . nil) | ||
(flyspell-mode . nil) | ||
(font-lock-mode . nil) | ||
(glasses-mode . nil) | ||
(hide-ifdef-mode . nil) | ||
(highlight-changes-mode . nil) | ||
(outline-minor-mode . nil) | ||
(overwrite-mode . nil) | ||
(ruler-mode . nil)) | ||
"List of minor-modes that are always shown in the mode menu. | ||
These modes are displayed even when they are not enabled, | ||
provided they are at least autoloaded. Elements have the | ||
form (MODE . SCOPE), where SCOPE should be t if MODE is a | ||
global minor-mode, nil otherwise." | ||
:group 'minions | ||
:type '(repeat (cons (symbol :tag "Mode") | ||
(boolean :tag "Scope" | ||
:on "global (non-nil)" | ||
:off "local (nil)")))) | ||
|
||
(defcustom minions-direct nil | ||
"List of minor-modes that are shown directly in the mode line." | ||
:group 'minions | ||
:type '(repeat (symbol :tag "Mode"))) | ||
|
||
;;; Mode | ||
|
||
;;;###autoload | ||
(define-minor-mode minions-mode | ||
"Display a minor-mode menu in the mode line. | ||
This replaces the likely incomplete and possibly cut off list of | ||
minor-modes that is usually displayed directly in the mode line." | ||
:group 'minions | ||
:global t | ||
(if minions-mode | ||
(unless (memq 'minions-mode-line-modes mode-line-format) | ||
(unless (memq 'mode-line-modes mode-line-format) | ||
(setq minions-mode nil) | ||
(error "Cannot turn on Minions mode")) | ||
(setcar (memq 'mode-line-modes mode-line-format) | ||
'minions-mode-line-modes)) | ||
(setcar (memq 'minions-mode-line-modes mode-line-format) | ||
'mode-line-modes))) | ||
|
||
;;; Menu | ||
|
||
(defvar minions-mode-line-minor-modes-map | ||
(let ((map (make-sparse-keymap))) | ||
(define-key map [mode-line down-mouse-1] 'minions-minor-modes-menu) | ||
map)) | ||
|
||
(defvar minions-mode-line-modes | ||
(let ((recursive-edit-help-echo "Recursive edit, type C-M-c to get out")) | ||
(list (propertize "%[" 'help-echo recursive-edit-help-echo) | ||
"(" | ||
`(:propertize ("" mode-name) | ||
help-echo "Major mode | ||
mouse-1: Display major mode menu | ||
mouse-2: Show help for major mode | ||
mouse-3: Toggle minor modes" | ||
mouse-face mode-line-highlight | ||
local-map ,mode-line-major-mode-keymap) | ||
'("" mode-line-process) | ||
(propertize "%n" 'help-echo "mouse-2: Remove narrowing from buffer" | ||
'mouse-face 'mode-line-highlight | ||
'local-map (make-mode-line-mouse-map | ||
'mouse-2 #'mode-line-widen)) | ||
`(:propertize ("" (:eval (--filter (memq (car it) minions-direct) | ||
minor-mode-alist))) | ||
mouse-face mode-line-highlight | ||
help-echo "Minor mode\n\ | ||
mouse-1: Display minor mode menu\n\ | ||
mouse-2: Show help for minor mode\n\ | ||
mouse-3: Toggle minor modes" | ||
local-map ,mode-line-minor-mode-keymap) | ||
" " | ||
`(:propertize ";-" | ||
mouse-face mode-line-highlight | ||
help-echo "Minions | ||
mouse-1: Display minor modes menu" | ||
local-map ,minions-mode-line-minor-modes-map) | ||
")" | ||
(propertize "%]" 'help-echo recursive-edit-help-echo) | ||
" ")) | ||
"Alternative mode line construct for displaying major and minor modes. | ||
Similar to `mode-line-modes' but instead of showing (a subset | ||
of) the enable minor modes directly in the mode line, list all | ||
minor modes in a space conserving menu.") | ||
|
||
(put 'minions-mode-line-modes 'risky-local-variable t) | ||
(make-variable-buffer-local 'minions-mode-line-modes) | ||
|
||
(defun minions-minor-modes-menu () | ||
"Pop up a menu with minor mode menus and toggles. | ||
The menu has an entry for every enabled minor mode, except those | ||
that are listed in `minions-blacklist'. It also has entries for | ||
modes that are not enabled but listed in `minions-whitelist'. | ||
If a mode defines a menu, then its entry shows that as a submenu. | ||
Otherwise the entry can only be used to toggle the mode." | ||
(interactive) | ||
(pcase-let ((map (make-sparse-keymap)) | ||
(`(,local ,global) (minions--modes))) | ||
(define-key map [minions--help-menu] | ||
(list 'menu-item "Describe..." (minions--help-menu))) | ||
(define-key map [describe-mode] | ||
(list 'menu-item "Describe modes" 'describe-mode)) | ||
(define-key map [--help] (list 'menu-item "Help")) | ||
(define-key map [--line1] (list 'menu-item "--double-line")) | ||
(dolist (mode global) | ||
(if-let (menu (and (symbol-value mode) | ||
(minions--mode-menu mode))) | ||
(define-key map (vector mode) menu) | ||
(minions--define-toggle map mode))) | ||
(define-key map [--global] (list 'menu-item "Global Modes")) | ||
(define-key map [--line2] (list 'menu-item "--double-line")) | ||
(dolist (mode local) | ||
(if-let (menu (and (symbol-value mode) | ||
(minions--mode-menu mode))) | ||
(define-key map (vector mode) menu) | ||
(minions--define-toggle map mode))) | ||
(define-key map [--local] (list 'menu-item "Local Modes")) | ||
(popup-menu map))) | ||
|
||
(defun minions--modes () | ||
(let (local global) | ||
(dolist (mode (cl-set-difference | ||
(cl-union (cl-mapcan (pcase-lambda (`(,mode ,_)) | ||
(and (boundp mode) | ||
(symbol-value mode) | ||
(list mode))) | ||
minor-mode-alist) | ||
(cl-mapcan (pcase-lambda (`(,mode ,_)) | ||
(and (boundp mode) | ||
(list mode))) | ||
minions-whitelist)) | ||
minions-blacklist)) | ||
(if (or (local-variable-if-set-p mode) | ||
(let ((elt (assq mode minions-whitelist))) | ||
(and elt (not (cdr elt))))) | ||
(push mode local) | ||
(push mode global))) | ||
(list (sort local #'string>) | ||
(sort global #'string>)))) | ||
|
||
(defun minions--mode-menu (mode) | ||
(let* ((map (or (cdr (assq mode minor-mode-map-alist)) | ||
(cdr (assq mode minor-mode-overriding-map-alist)))) | ||
(menu (and (keymapp map) | ||
(lookup-key map [menu-bar]))) | ||
(menu (and menu | ||
(mouse-menu-non-singleton menu)))) | ||
(and menu | ||
(let ((wrap (make-sparse-keymap))) | ||
(set-keymap-parent wrap menu) | ||
(define-key wrap [minions] (list 'menu-item "--double-line")) | ||
(minions--define-toggle wrap mode) | ||
(list 'menu-item (symbol-name mode) wrap))))) | ||
|
||
(defun minions--define-toggle (map mode) | ||
(define-key map (vector mode) | ||
(list 'menu-item | ||
(symbol-name mode) | ||
(or (get mode :minor-mode-function) mode) | ||
:help (minions--documentation mode) | ||
:button (cons :toggle mode)))) | ||
|
||
(defun minions--help-menu () | ||
(pcase-let ((map (make-sparse-keymap)) | ||
(`(,local ,global) (minions--modes))) | ||
(dolist (mode global) | ||
(minions--define-help map mode)) | ||
(define-key map [--global] (list 'menu-item "Global Modes")) | ||
(define-key map [--line2] (list 'menu-item "--double-line")) | ||
(dolist (mode local) | ||
(minions--define-help map mode)) | ||
(define-key map [--local] (list 'menu-item "Local Modes")) | ||
map)) | ||
|
||
(defun minions--define-help (map mode) | ||
(define-key map (vector mode) | ||
(list 'menu-item | ||
(symbol-name mode) | ||
(lambda () | ||
(interactive) | ||
(describe-minor-mode-from-symbol | ||
(or (get mode :minor-mode-function) mode))) | ||
:help (minions--documentation mode)))) | ||
|
||
(defun minions--documentation (function) | ||
(let ((doc (documentation function t))) | ||
(and doc | ||
(string-match "\\`.+" doc) | ||
(match-string 0 doc)))) | ||
|
||
;;; Banana! | ||
(provide 'minions) | ||
;; Local Variables: | ||
;; indent-tabs-mode: nil | ||
;; End: | ||
;;; minions.el ends here |