forked from agzam/spacehammer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspacehammer.el
165 lines (141 loc) · 6.18 KB
/
spacehammer.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
;;; spacehammer.el --- auxiliary Emacs helpers to be used with Spacehammer.
;;
;; Copyright (c) 2018-2019 Ag Ibragimov
;;
;; Author: Ag Ibragimov <[email protected]>
;; URL: https://github.com/spacehammer
;;
;;; License: GPLv3
(defun spacehammer/alert (message)
"shows Hammerspoon's hs.alert popup with a MESSAGE"
(when (and message (eq system-type 'darwin))
(call-process
(executable-find "hs")
nil 0 nil "-c" (concat "hs.alert.show(\"" message "\", 1)"))))
(defun spacehammer/fix-frame ()
"Fix Emacs frame. It may be necessary when screen size changes.
Sometimes zoom-frm functions would leave visible margins around the frame."
(let* ((geom (frame-monitor-attribute 'geometry))
(height (- (first (last geom)) 2))
(width (nth 2 geom))
(fs-p (frame-parameter nil 'fullscreen))
(frame (selected-frame))
(x (first geom))
(y (second geom)))
(when (member fs-p '(fullboth maximized))
(set-frame-position frame x y)
(set-frame-height frame height nil t)
(set-frame-width frame width nil t))
(when (frame-parameter nil 'full-width)
(set-frame-width frame width nil t)
(set-frame-parameter nil 'full-width nil))
(when (frame-parameter nil 'full-height)
(set-frame-height frame height nil t)
(set-frame-parameter nil 'full-height nil))))
(defun spacehammer/move-frame-one-display (direction)
"Moves current Emacs frame to another display at given DIRECTION
DIRECTION - can be North, South, West, East"
(let* ((hs (executable-find "hs"))
(cmd (concat "hs.window.focusedWindow():moveOneScreen" direction "()")))
(call-process hs nil 0 nil "-c" cmd)
(spacehammer/fix-frame)))
(defun spacehammer/switch-to-app (pid)
"Using third party tools tries to switch to the app with the given PID"
(when (and pid (eq system-type 'darwin))
(call-process (executable-find "hs") nil 0 nil "-c"
(concat "require(\"emacs\").switchToApp (\"" pid "\")"))))
(defvar spacehammer/edit-with-emacs-mode-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd "C-c C-c") 'spacehammer/finish-edit-with-emacs)
(define-key map (kbd "C-c C-k") 'spacehammer/cancel-edit-with-emacs)
map))
(define-minor-mode spacehammer/edit-with-emacs-mode
"Minor mode enabled on buffers opened by spacehammer/edit-by-emacs"
:init-value nil
:lighter " editwithemacs"
:keymap spacehammer/edit-with-emacs-mode-map)
(defun spacehammer/edit-with-emacs (&optional pid title screen)
"Edit anything with Emacs
PID is a pid of the app (the caller is responsible to set that right)
TITLE is a title of the window (the caller is responsible to set that right)"
(setq systemwide-edit-previous-app-pid pid)
(select-frame-by-name "edit")
(set-frame-position nil 400 400)
(set-frame-size nil 800 600 t)
(let ((buffer (get-buffer-create (concat "*edit-with-emacs " title " *"))))
(set-buffer-major-mode buffer)
(unless (bound-and-true-p global-edit-with-emacs-mode)
(global-edit-with-emacs-mode 1))
(with-current-buffer buffer
(spacemacs/copy-clipboard-to-whole-buffer)
(spacemacs/evil-search-clear-highlight)
(delete-other-windows)
(spacemacs/toggle-visual-line-navigation-on)
(markdown-mode)
(spacehammer/edit-with-emacs-mode 1)
(evil-insert 1))
(switch-to-buffer buffer))
(when (and pid (eq system-type 'darwin))
(call-process
(executable-find "hs") nil 0 nil "-c"
(concat "require(\"emacs\").editWithEmacsCallback(\""
pid "\",\"" title "\",\"" screen "\")"))))
(defun spacehammer/turn-on-edit-with-emacs-mode ()
"Turn on `spacehammer/edit-with-emacs-mode' if the buffer derives from that mode"
(when (string-match-p "*edit-with-emacs" (buffer-name (current-buffer)))
(spacehammer/edit-with-emacs-mode t)))
(define-global-minor-mode global-edit-with-emacs-mode
spacehammer/edit-with-emacs-mode spacehammer/turn-on-edit-with-emacs-mode)
(defvar systemwide-edit-previous-app-pid nil
"Last app that invokes `spacehammer/edit-with-emacs'.")
(defun spacehammer/finish-edit-with-emacs ()
(interactive)
(spacemacs/copy-whole-buffer-to-clipboard)
(kill-buffer)
(delete-frame)
(call-process (executable-find "hs") nil 0 nil "-c"
(concat "require(\"emacs\").switchToAppAndPasteFromClipboard (\"" systemwide-edit-previous-app-pid "\")"))
(setq systemwide-edit-previous-app-pid nil))
(defun spacehammer/cancel-edit-with-emacs ()
(interactive)
(kill-buffer)
(delete-frame)
(spacehammer/switch-to-app systemwide-edit-previous-app-pid)
(setq systemwide-edit-previous-app-pid nil))
;;;; System-wide org capture
(defvar systemwide-capture-previous-app-pid nil
"Last app that invokes `spacehammer/activate-capture-frame'.")
(defun spacehammer/activate-capture-frame (&optional pid title keys)
"Run ‘org-capture’ in capture frame.
PID is a pid of the app (the caller is responsible to set that right)
TITLE is a title of the window (the caller is responsible to set that right)
KEYS is a string associated with a template (will be passed to `org-capture')"
(setq systemwide-capture-previous-app-pid pid)
(select-frame-by-name "capture")
(set-frame-position nil 400 400)
(set-frame-size nil 1000 400 t)
(switch-to-buffer (get-buffer-create "*scratch*"))
(org-capture nil keys))
(defadvice org-switch-to-buffer-other-window
(after supress-window-splitting activate)
"Delete the extra window if we're in a capture frame."
(if (equal "capture" (frame-parameter nil 'name))
(delete-other-windows)))
(defadvice org-capture-finalize
(after delete-capture-frame activate)
"Advise capture-finalize to close the frame."
(when (and (equal "capture" (frame-parameter nil 'name))
(not (eq this-command 'org-capture-refile)))
(spacehammer/switch-to-app systemwide-capture-previous-app-pid)
(delete-frame)))
(defadvice org-capture-refile
(after delete-capture-frame activate)
"Advise ‘org-refile’ to close the frame."
(delete-frame))
(defadvice user-error
(before before-user-error activate)
"Advice"
(when (eq (buffer-name) "*Org Select*")
(spacehammer/switch-to-app systemwide-capture-previous-app-pid)))
(provide 'spacehammer)
;;; spacehammer.el ends here