-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcurrent-window-only.el
163 lines (128 loc) · 5.76 KB
/
current-window-only.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
;;; current-window-only.el --- Open things only in the current window -*- lexical-binding: t; -*-
;; Copyright (C) 2023 Jakub Kadlčík
;; Author: Jakub Kadlčík <[email protected]>
;; URL: https://github.com/FrostyX/current-window-only
;; Version: 1.0
;; Package-Requires: ((emacs "25.1"))
;; Keywords: frames
;;; License:
;; This program 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 of the License, or
;; (at your option) any later version.
;; This program 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.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; Open things only in the current window. No other windows, no splits.
;;; Code:
;;;; Customization
(defgroup current-window-only nil
"Open things only in the current window. No other windows, no splits."
:prefix "current-window-only-"
:group 'frames)
;;;; Modes
;;;###autoload
(define-minor-mode current-window-only-mode
"Open things only in the current window. No other windows, no splits."
:global t
(if current-window-only-mode
(current-window-only--on)
(current-window-only--off)))
;;;; Variables
;; Some modes and packages need to be explicitly said how to behave.
;; This is the list of variables that this package is going to modify.
(defvar Man-notify-method)
(defvar org-src-window-setup)
(defvar org-agenda-window-setup)
;; We want to rember the variable values that user had before activating the
;; `current-window-only-mode' in case he decides to disable it. In that case
;; we want to set the variables to their previous values instead of the
;; default ones.
(defvar current-window-only--old-config '())
;;;; Functions
;;;;; Private
(defun current-window-only--on ()
"Enable the `current-window-only-mode'."
;; Remember the user configuration in case we need to restore it
(dolist (var '(display-buffer-alist
Man-notify-method
org-src-window-setup
org-agenda-window-setup))
(when (boundp var)
(setf (alist-get var current-window-only--old-config)
(symbol-value var))))
;; The `display-buffer-alist' is still a magic to me but in the ideal world
;; this should be the only necessary setting.
(setq display-buffer-alist
'((".*" (display-buffer-reuse-window
display-buffer-same-window)
(reusable-frames . t))))
;; Some packages require a custom configuration just for them
(setq Man-notify-method 'pushy)
(setq org-src-window-setup 'current-window)
(setq org-agenda-window-setup 'current-window)
;; The `org-agenda', `org-capture', and probably all commands with the
;; similar input field that expects one character and blocks all other input,
;; don't respect the `display-buffer-alist' variable and appear in some other
;; window. Overriding `switch-to-buffer-other-window' helps.
(advice-add
'switch-to-buffer-other-window
:override #'current-window-only--switch-to-buffer-other-window)
;; Commands like `org-agenda' and `org-capture' temporarily maximize some
;; window, change layout, and/or close all other windows when they are
;; finished. This prevents them from doing so.
(advice-add
'delete-other-windows
:override #'current-window-only--delete-other-windows)
;; Commands like `vc-git-grep', `ripgrep-regexp', and other buffers based on
;; the Compilation Mode always keep their main buffer visible and jump to
;; the results in another window. See how `compilation-goto-locus' calls
;; `pop-to-buffer' with an explicit `'other-window' parameter.
;; Also, `find-file' and commands like `projectile-find-file' and
;; `dired-open-file' that are based on top of it, jump into an existing
;; window if a buffer is already opened there.
(advice-add
'pop-to-buffer
:override #'current-window-only--pop-to-buffer))
(defun current-window-only--off ()
"Disable the `current-window-only-mode'."
(dolist (item current-window-only--old-config)
(set (car item) (cdr item)))
(advice-remove
'switch-to-buffer-other-window
#'current-window-only--switch-to-buffer-other-window)
(advice-remove
'delete-other-windows
#'current-window-only--delete-other-windows)
(advice-remove
'pop-to-buffer
#'current-window-only--pop-to-buffer))
(defun current-window-only--switch-to-buffer-other-window
(buffer-or-name &optional norecord)
"Override for the `switch-to-buffer-other-window' function.
It uses the BUFFER-OR-NAME and NORECORD parameters and passes them to a
`switch-to-buffer'."
(switch-to-buffer buffer-or-name norecord t))
(defun current-window-only--delete-other-windows
(&optional window interactive)
"Override for the `delete-other-windows' function.
Do nothing and simply ignore the WINDOW and INTERACTIVE arguments."
(ignore window)
(ignore interactive))
(defun current-window-only--pop-to-buffer
(buffer-or-name &optional action norecord)
"Override for the `pop-to-buffer' function.
The mainly/only purpose of `pop-to-buffer' is to add some window management
features on top of simple buffer switching. For example allowing to open the
buffer in other window or frame, splitting windows etc. We want none of that
so we can use BUFFER-OR-NAME and NORECORD parameters, pass them to a simple
`switch-to-buffer' function, and ignore the ACTION parameter completely."
(ignore action)
(switch-to-buffer buffer-or-name norecord))
;;;; Footer
(provide 'current-window-only)
;;; current-window-only.el ends here