commit | author | age
|
76bbd0
|
1 |
;;; golden-ratio.el --- Automatic resizing of Emacs windows to the golden ratio |
C |
2 |
|
|
3 |
;; Copyright (C) 2012 Roman Gonzalez |
|
4 |
|
|
5 |
;; Author: Roman Gonzalez <romanandreg@gmail.com> |
|
6 |
;; Mantainer: Roman Gonzalez <romanandreg@gmail.com> |
|
7 |
;; Created: 13 Oct 2012 |
|
8 |
;; Keywords: Window Resizing |
|
9 |
;; Package-Version: 20150819.1120 |
|
10 |
;; Version: 0.0.4 |
|
11 |
|
|
12 |
;; Code inspired by ideas from Tatsuhiro Ujihisa |
|
13 |
|
|
14 |
;; This file is not part of GNU Emacs. |
|
15 |
|
|
16 |
;; This file is free software (MIT License) |
|
17 |
|
|
18 |
;;; Code: |
|
19 |
(eval-when-compile (require 'cl)) |
|
20 |
|
|
21 |
(defconst golden-ratio--value 1.618 |
|
22 |
"The golden ratio value itself.") |
|
23 |
|
|
24 |
(defgroup golden-ratio nil |
|
25 |
"Resize windows to golden ratio." |
|
26 |
:group 'windows) |
|
27 |
|
|
28 |
;; Major modes that are exempt from being resized. An example of this |
|
29 |
;; for users of Org-mode might be: |
|
30 |
;; ("calendar-mode") or (calendar-mode) |
|
31 |
(defcustom golden-ratio-exclude-modes nil |
|
32 |
"A list of symbols or strings naming major modes. |
|
33 |
Switching to a buffer whose major mode is a member of this list |
|
34 |
will not cause the window to be resized to the golden ratio." |
|
35 |
:type '(repeat (choice symbol string)) |
|
36 |
:group 'golden-ratio) |
|
37 |
|
|
38 |
;; Buffer names that are exempt from being resized. An example of this |
|
39 |
;; for users of Org-mode might be (note the leading spaces): |
|
40 |
;; (" *Org tags*" " *Org todo*") |
|
41 |
(defcustom golden-ratio-exclude-buffer-names nil |
|
42 |
"An array of strings containing buffer names. |
|
43 |
Switching to a buffer whose name is a member of this list |
|
44 |
will not cause the window to be resized to the golden ratio." |
|
45 |
:type '(repeat string) |
|
46 |
:group 'golden-ratio) |
|
47 |
|
|
48 |
(defcustom golden-ratio-inhibit-functions nil |
|
49 |
"List of functions to call with no arguments. |
|
50 |
Switching to a buffer, if any of these functions returns non-nil |
|
51 |
will not cause the window to be resized to the golden ratio." |
|
52 |
:group 'golden-ratio |
|
53 |
:type '(repeat symbol)) |
|
54 |
|
|
55 |
(defcustom golden-ratio-extra-commands |
|
56 |
'(windmove-left windmove-right windmove-down windmove-up) |
|
57 |
"List of extra commands used to jump to other window." |
|
58 |
:group 'golden-ratio |
|
59 |
:type '(repeat symbol)) |
|
60 |
|
|
61 |
(defcustom golden-ratio-recenter nil |
|
62 |
"Recenter window vertically and scroll right when non--nil." |
|
63 |
:group 'golden-ratio |
|
64 |
:type 'boolean) |
|
65 |
|
|
66 |
(defcustom golden-ratio-adjust-factor 1.0 |
|
67 |
"Adjust the width sizing by some factor. 1 is no adjustment. |
|
68 |
For very wide screens/frames, ie. 3400px, .4 may work well." |
|
69 |
:group 'golden-ratio |
|
70 |
:type 'integer) |
|
71 |
|
|
72 |
(defcustom golden-ratio-wide-adjust-factor 0.8 |
|
73 |
"Width adjustment factor for widescreens. Used when |
|
74 |
toggling between widescreen and regular modes." |
|
75 |
:group 'golden-ratio |
|
76 |
:type 'float) |
|
77 |
|
|
78 |
(defcustom golden-ratio-auto-scale nil |
|
79 |
"Automatic width adjustment factoring. Scales the width |
|
80 |
of the screens to be smaller as the frame gets bigger." |
|
81 |
:group 'golden-ratio |
|
82 |
:type 'boolean) |
|
83 |
|
|
84 |
(defcustom golden-ratio-exclude-buffer-regexp nil |
|
85 |
"A list of regexp's used to match buffer names. |
|
86 |
Switching to a buffer whose name matches one of these regexps |
|
87 |
will prevent the window to be resized to the golden ratio." |
|
88 |
:type '(repeat string) |
|
89 |
:group 'golden-ratio) |
|
90 |
|
|
91 |
;;; Compatibility |
|
92 |
;; |
|
93 |
(unless (fboundp 'window-resizable-p) |
|
94 |
(defalias 'window-resizable-p 'window--resizable-p)) |
|
95 |
|
|
96 |
(defun golden-ratio-toggle-widescreen () |
|
97 |
(interactive) |
|
98 |
(if (= golden-ratio-adjust-factor 1) |
|
99 |
(setq golden-ratio-adjust-factor golden-ratio-wide-adjust-factor) |
|
100 |
(setq golden-ratio-adjust-factor 1)) |
|
101 |
(golden-ratio)) |
|
102 |
|
|
103 |
(defun golden-ratio-adjust (a) |
|
104 |
"set the adjustment of window widths." |
|
105 |
(interactive |
|
106 |
(list |
|
107 |
(read-number "Screeen width adjustment factor: " golden-ratio-adjust-factor))) |
|
108 |
(setq golden-ratio-adjust-factor a) |
|
109 |
(golden-ratio)) |
|
110 |
|
|
111 |
(defun golden-ratio--scale-factor () |
|
112 |
(if golden-ratio-auto-scale |
|
113 |
(- 1.0 (* (/ (- (frame-width) 100.0) 1000.0) 1.8)) |
|
114 |
golden-ratio-adjust-factor)) |
|
115 |
|
|
116 |
(defun golden-ratio--dimensions () |
|
117 |
(list (floor (/ (frame-height) golden-ratio--value)) |
|
118 |
(floor (* (/ (frame-width) golden-ratio--value) |
|
119 |
(golden-ratio--scale-factor))))) |
|
120 |
|
|
121 |
(defun golden-ratio--resize-window (dimensions &optional window) |
|
122 |
(with-selected-window (or window (selected-window)) |
|
123 |
(let ((nrow (floor (- (first dimensions) (window-height)))) |
|
124 |
(ncol (floor (- (second dimensions) (window-width))))) |
|
125 |
(when (window-resizable-p (selected-window) nrow) |
|
126 |
(enlarge-window nrow)) |
|
127 |
(when (window-resizable-p (selected-window) ncol t) |
|
128 |
(enlarge-window ncol t))))) |
|
129 |
|
|
130 |
(defun golden-ratio-exclude-major-mode-p () |
|
131 |
"Returns non-nil if `major-mode' should not use golden-ratio." |
|
132 |
(or (memq major-mode golden-ratio-exclude-modes) |
|
133 |
(member (symbol-name major-mode) |
|
134 |
golden-ratio-exclude-modes))) |
|
135 |
|
|
136 |
;;;###autoload |
|
137 |
(defun golden-ratio (&optional arg) |
|
138 |
"Resizes current window to the golden-ratio's size specs." |
|
139 |
(interactive "p") |
|
140 |
(unless (or (and (not golden-ratio-mode) (null arg)) |
|
141 |
(window-minibuffer-p) |
|
142 |
(one-window-p) |
|
143 |
(golden-ratio-exclude-major-mode-p) |
|
144 |
(member (buffer-name) |
|
145 |
golden-ratio-exclude-buffer-names) |
|
146 |
(and golden-ratio-exclude-buffer-regexp |
|
147 |
(loop for r in golden-ratio-exclude-buffer-regexp |
|
148 |
thereis (string-match r (buffer-name)))) |
|
149 |
(and golden-ratio-inhibit-functions |
|
150 |
(loop for fun in golden-ratio-inhibit-functions |
|
151 |
thereis (funcall fun)))) |
|
152 |
(let ((dims (golden-ratio--dimensions)) |
|
153 |
(golden-ratio-mode nil)) |
|
154 |
;; Always disable `golden-ratio-mode' to avoid |
|
155 |
;; infinite loop in `balance-windows'. |
|
156 |
(balance-windows) |
|
157 |
(golden-ratio--resize-window dims) |
|
158 |
(when golden-ratio-recenter |
|
159 |
(scroll-right) (recenter))))) |
|
160 |
|
|
161 |
;; Should return nil |
|
162 |
(defadvice other-window |
|
163 |
(after golden-ratio-resize-window) |
|
164 |
(golden-ratio) nil) |
|
165 |
|
|
166 |
;; Should return the buffer |
|
167 |
(defadvice pop-to-buffer |
|
168 |
(around golden-ratio-resize-window) |
|
169 |
(prog1 ad-do-it (golden-ratio))) |
|
170 |
|
|
171 |
(defun golden-ratio--post-command-hook () |
|
172 |
(when (or (memq this-command golden-ratio-extra-commands) |
|
173 |
(and (consp this-command) ; A lambda form. |
|
174 |
(loop for com in golden-ratio-extra-commands |
|
175 |
thereis (or (memq com this-command) |
|
176 |
(memq (car-safe com) this-command))))) |
|
177 |
;; This is needed in emacs-25 to avoid this error from `recenter': |
|
178 |
;; `recenter'ing a window that does not display current-buffer. |
|
179 |
;; This doesn't happen in emacs-24.4 and previous versions. |
|
180 |
(run-with-idle-timer 0.01 nil (lambda () (golden-ratio))))) |
|
181 |
|
|
182 |
(defun golden-ratio--mouse-leave-buffer-hook () |
|
183 |
(run-at-time 0.1 nil (lambda () |
|
184 |
(golden-ratio)))) |
|
185 |
|
|
186 |
;;;###autoload |
|
187 |
(define-minor-mode golden-ratio-mode |
|
188 |
"Enable automatic window resizing with golden ratio." |
|
189 |
:lighter " Golden" |
|
190 |
:global t |
|
191 |
(if golden-ratio-mode |
|
192 |
(progn |
|
193 |
(add-hook 'window-configuration-change-hook 'golden-ratio) |
|
194 |
(add-hook 'post-command-hook 'golden-ratio--post-command-hook) |
|
195 |
(add-hook 'mouse-leave-buffer-hook 'golden-ratio--mouse-leave-buffer-hook) |
|
196 |
(ad-activate 'other-window) |
|
197 |
(ad-activate 'pop-to-buffer)) |
|
198 |
(remove-hook 'window-configuration-change-hook 'golden-ratio) |
|
199 |
(remove-hook 'post-command-hook 'golden-ratio--post-command-hook) |
|
200 |
(remove-hook 'mouse-leave-buffer-hook 'golden-ratio--mouse-leave-buffer-hook) |
|
201 |
(ad-deactivate 'other-window) |
|
202 |
(ad-deactivate 'pop-to-buffer))) |
|
203 |
|
|
204 |
|
|
205 |
(provide 'golden-ratio) |
|
206 |
|
|
207 |
;;; golden-ratio.el ends here |