forked from lukhas/buffer-move
-
Notifications
You must be signed in to change notification settings - Fork 0
/
buffer-move.el
181 lines (161 loc) · 6.41 KB
/
buffer-move.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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
;;; buffer-move.el --- easily swap buffers
;; Copyright (C) 2004-2014 Lucas Bonnet <[email protected]>
;; Copyright (C) 2014 Mathis Hofer <[email protected]>
;; Copyright (C) 2014-2015 Geyslan G. Bem <[email protected]>
;; Authors: Lucas Bonnet <[email protected]>
;; Mathis Hofer <[email protected]>
;; Geyslan G. Bem <[email protected]>
;; URL: https://github.com/lukhas/buffer-move/
;; Version: 0.6.4
;; Package-Requires: ((emacs "24.3"))
;; Keywords: convenience
;; This file is NOT part of GNU Emacs.
;; 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 <http://www.gnu.org/licenses/>.
;;; Commentary:
;;
;; This file is for lazy people wanting to swap buffers without
;; typing C-x b on each window. This is useful when you have :
;;
;; +--------------+-------------+
;; | | |
;; | #emacs | #gnus |
;; | | |
;; +--------------+-------------+
;; | |
;; | .emacs |
;; | |
;; +----------------------------+
;;
;; and you want to have :
;;
;; +--------------+-------------+
;; | | |
;; | #gnus | .emacs |
;; | | |
;; +--------------+-------------+
;; | |
;; | #emacs |
;; | |
;; +----------------------------+
;;
;; With buffer-move, just go in #gnus, do buf-move-left, go to #emacs
;; (which now should be on top right) and do buf-move-down.
;;
;; To use it, simply put a (require 'buffer-move) in your ~/.emacs and
;; define some keybindings. For example, i use :
;;
;; (global-set-key (kbd "<C-S-up>") 'buf-move-up)
;; (global-set-key (kbd "<C-S-down>") 'buf-move-down)
;; (global-set-key (kbd "<C-S-left>") 'buf-move-left)
;; (global-set-key (kbd "<C-S-right>") 'buf-move-right)
;;
;; Alternatively, you may let the current window switch back to the previous
;; buffer, instead of swapping the buffers of both windows. Set the
;; following customization variable to 'move to activate this behavior:
;;
;; (setq buffer-move-behavior 'move)
;;; Code:
(require 'windmove)
(require 'cl-lib)
(defconst buffer-move-version "0.6.4"
"Version of buffer-move.el")
(defgroup buffer-move nil
"Swap buffers without typing C-x b on each window"
:group 'tools)
(defcustom buffer-move-behavior 'swap
"If set to 'swap (default), the buffers will be exchanged
(i.e. swapped), if set to 'move, the current window is switch back to the
previously displayed buffer (i.e. the buffer is moved)."
:group 'buffer-move
:type 'symbol)
(defcustom buffer-move-stay-after-swap nil
"If set to non-nil, point will stay in the current window
so it will not be moved when swapping buffers. This setting
only has effect if `buffer-move-behavior' is set to 'swap."
:group 'buffer-move
:type 'boolean)
(defun buf-move-to (direction)
"Helper function to move the current buffer to the window in the given
direction (with must be 'up, 'down', 'left or 'right). An error is
thrown, if no window exists in this direction."
(cl-flet ((window-settings (window)
(list (window-buffer window)
(window-start window)
(window-hscroll window)
(window-point window)))
(set-window-settings (window settings)
(cl-destructuring-bind (buffer start hscroll point)
settings
(set-window-buffer window buffer)
(set-window-start window start)
(set-window-hscroll window hscroll)
(set-window-point window point))))
(let* ((this-window (selected-window))
(this-window-settings (window-settings this-window))
(other-window (windmove-find-other-window direction))
(other-window-settings (window-settings other-window)))
(cond ((null other-window)
(error "No window in this direction"))
((window-dedicated-p other-window)
(error "The window in this direction is dedicated"))
((window-minibuffer-p other-window)
(error "The window in this direction is the Minibuffer")))
(set-window-settings other-window this-window-settings)
(if (eq buffer-move-behavior 'move)
(switch-to-prev-buffer this-window)
(set-window-settings this-window other-window-settings))
(select-window other-window))))
;;;###autoload
(defun buf-move-up ()
"Swap the current buffer and the buffer above the split.
If there is no split, ie now window above the current one, an
error is signaled."
(interactive)
(buf-move-to 'up))
;;;###autoload
(defun buf-move-down ()
"Swap the current buffer and the buffer under the split.
If there is no split, ie now window under the current one, an
error is signaled."
(interactive)
(buf-move-to 'down))
;;;###autoload
(defun buf-move-left ()
"Swap the current buffer and the buffer on the left of the split.
If there is no split, ie now window on the left of the current
one, an error is signaled."
(interactive)
(buf-move-to 'left))
;;;###autoload
(defun buf-move-right ()
"Swap the current buffer and the buffer on the right of the split.
If there is no split, ie now window on the right of the current
one, an error is signaled."
(interactive)
(buf-move-to 'right))
;;;###autoload
(defun buf-move ()
"Begin moving the current buffer to different windows.
Use the arrow keys to move in the desired direction. Pressing
any other key exits this function."
(interactive)
(let ((map (make-sparse-keymap)))
(dolist (x '(("<up>" . buf-move-up)
("<left>" . buf-move-left)
("<down>" . buf-move-down)
("<right>" . buf-move-right)))
(define-key map (read-kbd-macro (car x)) (cdr x)))
(set-transient-map map t)))
(provide 'buffer-move)
;;; buffer-move.el ends here