-
Notifications
You must be signed in to change notification settings - Fork 35
/
ergoemacs-lib.el
279 lines (248 loc) · 10.3 KB
/
ergoemacs-lib.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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
;;; ergoemacs-lib.el --- Ergoemacs libraries -*- lexical-binding: t -*-
;; Copyright © 2013-2021 Free Software Foundation, Inc.
;; Author: Matthew L. Fidler, Xah Lee
;; Maintainer:
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 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, 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/>.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Code:
;; (require 'guide-key nil t)
(require 'cl-lib)
(require 'find-func)
(eval-when-compile
(require 'ergoemacs-macros))
(defvar mode-icons-show-mode-name)
(defvar mode-icons-read-only-space)
(defvar mode-icons-cached-mode-name)
(defvar mode-icons-eol-text)
(defvar ergoemacs-excluded-major-modes)
(defvar ergoemacs-keyboard-layout)
(defvar ergoemacs-keymap)
(defvar ergoemacs-mode)
(defvar ergoemacs-mode-names)
(defvar ergoemacs-require)
(defvar ergoemacs-theme-hash)
(defvar ergoemacs-dir)
(declare-function ergoemacs-next-emacs-buffer "ergoemacs-functions")
(declare-function ergoemacs-next-user-buffer "ergoemacs-functions")
(declare-function ergoemacs-previous-emacs-buffer "ergoemacs-functions")
(declare-function ergoemacs-previous-user-buffer "ergoemacs-functions")
(declare-function mode-icons-get-mode-icon "mode-icons")
(declare-function ergoemacs-autoloadp "ergoemacs-macros")
(declare-function ergoemacs-mode-reset "ergoemacs-mode")
(declare-function ergoemacs-theme-option-on "ergoemacs-theme-engine")
(declare-function ergoemacs-key-description--menu "ergoemacs-key-description")
(declare-function ergoemacs-emacs-exe "ergoemacs-functions")
(declare-function ergoemacs-translate--ahk-ini "ergoemacs-translate")
(declare-function ergoemacs-command-loop--spinner-display "ergoemacs-command-loop")
(defun ergoemacs-setcdr (var val &optional default)
"Use `setcdr' on VAL to VAL.
If VAL is a symbol, use `ergoemacs-sv' to determine the value.
If VAR is nil, return nil and do nothing.
If DEFAULT is non-nil set the default value, instead of the symbol value."
(if (symbolp var)
(setcdr (ergoemacs-sv var default) val)
(if (not var) nil
(setcdr var val))))
(defvar ergoemacs-xah-emacs-lisp-tutorial-url
"http://ergoemacs.org/emacs/elisp.html")
(defvar ergoemacs-mode-web-page-url
"http://ergoemacs.github.io/")
(defun ergoemacs-menu--get-major-mode-name (mode)
"Gets the MODE language name.
Tries to get the value from `ergoemacs-mode-names'. If not guess the language name."
(let ((ret (assoc mode ergoemacs-mode-names)))
(if (not ret)
(setq ret (replace-regexp-in-string
"-" " "
(replace-regexp-in-string
"-mode" ""
(symbol-name mode))))
(setq ret (car (cdr ret))))
(setq ret (concat (upcase (substring ret 0 1))
(substring ret 1)))
ret))
(defcustom ergoemacs-major-mode-menu-map-extra-modes
'(fundamental-mode lisp-interaction-mode)
"List of extra modes that should bring up the major-mode menu."
:type '(repeat (function :tag "Major Mode"))
:group 'ergoemacs-mode)
(defvar ergoemacs-menu--get-major-modes nil
"List of major-modes known to `ergoemacs-mode'.")
(defcustom ergoemacs-excluded-major-modes
'(conf-colon-mode
conf-xdefaults-mode conf-space-mode conf-javaprop-mode
conf-ppd-mode mail-mode
ebrowse-tree-mode diff-mode fundamental-mode emacs-lisp-byte-code-mode
R-transcript-mode S-transcript-mode XLS-mode tar-mode
git-commit-mode git-rebase-mode image-mode
archive-mode ses-mode)
"List of major modes excluded from ergoemacs' Languages menu."
:type '(repeat (symbol :tag "Excluded Major Mode"))
:group 'ergoemacs-mode)
(defcustom ergoemacs-mode-names
'((conf-mode "Settings")
(ses-mode "Emacs Spreadsheet")
(m2-mode "Modula-2")
(snmpv2-mode "SNMPv2 MIBs")
(snmp-mode "SKMP MIBs"))
"Menu name for ergoemacs' Languages menu."
:type '(repeat
(list
(symbol :tag "Major Mode Name")
(text :tag "Alternative Description:")))
:group 'ergoemacs-mode)
(defun ergoemacs-menu--get-major-modes ()
"Gets a list of language modes known to `ergoemacs-mode'.
This gets all major modes known from the variables:
- `interpreter-mode-alist';
- `magic-mode-alist'
- `magic-fallback-mode-alist'
- `auto-mode-alist'
- `ergoemacs-major-mode-menu-map-extra-modes'
All other modes are assumed to be minor modes or unimportant.
"
;; Get known major modes
(let ((ret '())
all dups cur-lst current-letter
added-modes
(modes '()))
(dolist (elt ergoemacs-major-mode-menu-map-extra-modes)
(unless (memq elt modes)
(when (and (functionp elt)
(ignore-errors (string-match "-mode$" (symbol-name elt))))
(unless (or (memq elt ergoemacs-excluded-major-modes)
(member (downcase (symbol-name elt)) added-modes))
(let* ((name (ergoemacs-menu--get-major-mode-name elt))
(first (upcase (substring name 0 1))))
(if (member first all)
(unless (member first dups)
(push first dups))
(push first all))
(push (list elt 'menu-item
name
elt)
ret))
(push (downcase (symbol-name elt)) added-modes)
(push elt modes)))))
(dolist (elt (append
interpreter-mode-alist
magic-mode-alist
magic-fallback-mode-alist
auto-mode-alist))
(unless (memq (cdr elt) modes)
(when (and (functionp (cdr elt))
(ignore-errors (string-match "-mode$" (symbol-name (cdr elt)))))
(unless (or (memq (cdr elt) ergoemacs-excluded-major-modes)
(member (downcase (symbol-name (cdr elt))) added-modes))
(let* ((name (ergoemacs-menu--get-major-mode-name (cdr elt)))
(first (upcase (substring name 0 1))))
(if (member first all)
(unless (member first dups)
(push first dups))
(push first all))
(push (list (cdr elt) 'menu-item
name
(cdr elt))
ret))
(push (downcase (symbol-name (cdr elt))) added-modes)
(push (cdr elt) modes)))))
(setq modes (sort ret (lambda(x1 x2) (string< (downcase (nth 2 x2))
(downcase (nth 2 x1)))))
ergoemacs-menu--get-major-modes (mapcar (lambda(x) (intern x)) added-modes))
(setq ret '())
(dolist (elt modes)
(let ((this-letter (upcase (substring (nth 2 elt) 0 1))))
(cond
((not (member this-letter dups))
;; not duplicated -- add prior list and push current element.
(when cur-lst
(push `(,(intern current-letter) menu-item ,current-letter
(keymap ,@cur-lst)) ret))
(push elt ret)
(setq current-letter this-letter)
(setq cur-lst nil))
((not (equal this-letter current-letter))
;; duplicated, but not last letter.
(when cur-lst
(push `(,(intern current-letter) menu-item ,current-letter
(keymap ,@cur-lst)) ret))
(setq cur-lst nil)
(setq current-letter this-letter)
(push elt cur-lst))
(t
;; duplicated and last letter
(push elt cur-lst)))))
(when cur-lst
(push `(,(intern current-letter) menu-item ,current-letter
(keymap ,@cur-lst)) ret))
;; Now create nested menu.
`(keymap ,@ret
(separator1 menu-item "--")
(package menu-item "Manage Packages" list-packages))))
;;;###autoload
(defun ergoemacs-gen-ahk (&optional all)
"Generates autohotkey for all layouts and themes"
(interactive)
(if (called-interactively-p 'any)
(progn
(shell-command (format "%s -Q --batch -l %s/ergoemacs-mode --eval \"(ergoemacs-gen-ahk %s)\" &"
(ergoemacs-emacs-exe)
ergoemacs-dir (if current-prefix-arg "t" "nil"))))
(let ((xtra "ahk")
(extra-dir)
file-temp)
(setq extra-dir (expand-file-name "ergoemacs-extras" user-emacs-directory))
(if (not (file-exists-p extra-dir))
(make-directory extra-dir t))
(setq extra-dir (expand-file-name xtra extra-dir))
(if (not (file-exists-p extra-dir))
(make-directory extra-dir t))
(setq file-temp (expand-file-name "ergoemacs.ini" extra-dir))
(with-temp-file file-temp
(set-buffer-file-coding-system 'utf-8)
(insert (ergoemacs-translate--ahk-ini all)))
(setq file-temp (expand-file-name "ergoemacs.ahk" extra-dir))
(with-temp-file file-temp
(set-buffer-file-coding-system 'utf-8)
(insert-file-contents (expand-file-name "ahk-us.ahk" ergoemacs-dir)))
(message "Generated ergoemacs.ahk")
(when (executable-find "ahk2exe")
(shell-command (format "ahk2exe /in %s" file-temp))
(message "Generated ergoemacs.exe")))))
(defvar ergoemacs-warn nil
"List of warnings that `ergoemacs-mode' already gave.")
(defun ergoemacs-warn (&rest args)
"Warn user only once.
When not contaiend in the variable `ergoemacs-mode', apply ARGS
to the `warn' function."
(unless (member args ergoemacs-warn)
(display-warning 'ergoemacs (apply #'format args) :warning)
(push args ergoemacs-warn)))
(defvar ergoemacs-field-len nil)
(defvar ergoemacs-cc-len nil)
(defvar ergoemacs-at-len nil)
(defvar ergoemacs-et-len nil)
(defvar ergoemacs-mn-len nil)
(defvar ergoemacs-mx-len nil)
(provide 'ergoemacs-lib)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; ergoemacs-lib.el ends here
;; Local Variables:
;; coding: utf-8-emacs
;; End: