evol-mode.el 9.25 KB
Newer Older
1
2
3
4
5
6
;; Major mode for Evol Scripts in Emacs
;; Author: Joseph Botosh <rumly111@gmail.com>
;; Licence: GNU General Public Licence v3.0 (http://www.gnu.org/licenses/gpl-3.0.en.html)

(require 'cl)

Joseph Botosh's avatar
Joseph Botosh committed
7
8
9
10
11
12
(defgroup evol nil
  "Settings for evol-mode."
  :prefix "evol-"
  :group 'emacs)

(defcustom evol-all-dir ""
Joseph Botosh's avatar
Joseph Botosh committed
13
  "Directory containing server-code and server-data subdirectories."
Joseph Botosh's avatar
Joseph Botosh committed
14
15
16
  :group 'evol
  :type 'string)

Joseph Botosh's avatar
Joseph Botosh committed
17
18
(defvar evol-mode-constants nil "List of all Evol constants.")
(defvar evol-mode-functions nil "List of Evol functions.")
19
20
21
22
  
(defun evol-mode-parse-const-db (dbfile)
  (interactive "fPath to const.txt: ")
  (with-temp-buffer
Joseph Botosh's avatar
Joseph Botosh committed
23
    (message "Loading Evol constants from %s" dbfile)
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
    (insert-file-contents dbfile)
    (let ((constants))
      (while (not (eobp))
	(let ((line (buffer-substring-no-properties
		     (line-beginning-position)
		     (line-end-position)))
	      (constant))
	  (when (string-match "\\(^[A-Za-z][A-Za-z0-9_]*\\)[\t ]+\\([0-9]+\\)"
			      line)
	    (setq constant (substring line (match-beginning 1)
				      (match-end 1))
		  constants (cons constant constants))))
	(forward-line 1))
      constants)))

(defun evol-mode-parse-map-index-db (dbfile)
  (interactive "fPath to map_index.txt: ")
  (with-temp-buffer
    (insert-file-contents dbfile)
    (let ((maps))
      (while (not (eobp))
	(let ((line (buffer-substring-no-properties
		     (line-beginning-position)
		     (line-end-position)))
	      (map_))
	  (when (string-match
		 "\\(^[A-Za-z0-9][A-Za-z0-9_-]*[A-Za-z0-9]\\) \\([0-9]+\\)"
		 line)
	    (setq map_ (substring line (match-beginning 1)
				      (match-end 1))
		  maps (cons map_ maps))))
	(forward-line 1))
      maps)))

(defun evol-mode-parse-skill-db (dbfile)
  (interactive "fPath to skill_db.txt: ")
  (with-temp-buffer
    (insert-file-contents dbfile)
    (let ((skills))
      (while (not (eobp))
	(let ((line (buffer-substring-no-properties
		     (line-beginning-position)
		     (line-end-position)))
	      (skill))
	  (when (string-match
		 "^[1-9][0-9]*,\\([^,]+,\\)\\{14\\}[\t ]+\\([A-Za-z][A-Za-z0-9_]*[A-Za-z0-9]\\),"
		 line)
	    (setq skill (substring line (match-beginning 2)
				      (match-end 2))
		  skills (cons skill skills))))
	(forward-line 1))
      skills)))

(defun evol-mode-parse-mob-db (dbfile)
Joseph Botosh's avatar
Joseph Botosh committed
78
  (interactive "fPath to mob_db.conf: ")
79
  (with-temp-buffer
Joseph Botosh's avatar
Joseph Botosh committed
80
    (message "Loading mob_db from %s" dbfile)
81
82
83
84
85
86
87
88
    (insert-file-contents dbfile)
    (let ((mobs))
      (while (not (eobp))
	(let ((line (buffer-substring-no-properties
		     (line-beginning-position)
		     (line-end-position)))
	      (mob))
	  (when (string-match
Joseph Botosh's avatar
Joseph Botosh committed
89
		 "^[\t ]+SpriteName:[\t ]+\"\\([A-Za-z]+\\)\""
90
91
92
93
94
95
96
97
98
99
		 line)
	    (setq mob (substring line (match-beginning 1)
				      (match-end 1))
		  mobs (cons mob mobs))))
	(forward-line 1))
      mobs)))
      
(defun evol-mode-parse-item-db (dbfile)
  (interactive "fPath to item_db.txt: ")
  (with-temp-buffer
Joseph Botosh's avatar
Joseph Botosh committed
100
    (message "Loading item_db from %s" dbfile)
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
    (insert-file-contents dbfile)
    (let ((items))
      (while (not (eobp))
	(let ((line (buffer-substring-no-properties
		     (line-beginning-position)
		     (line-end-position)))
	      (item))
	  (when (string-match
		 "^[\t ]+AegisName:[\t ]+\"\\([A-Za-z]+\\)\""
		 line)
	    (setq item (substring line (match-beginning 1)
				      (match-end 1))
		  items (cons item items))))
	(forward-line 1))
      items)))

(defun evol-mode-parse-atcommand-c (cfile)
  (interactive "fPath to src/map/atcommand.c: ")
  (with-temp-buffer
Joseph Botosh's avatar
Joseph Botosh committed
120
    (message "Loading functions from from %s" cfile)
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
    (insert-file-contents cfile)
    (let ((commands))
      (while (not (eobp))
	(let ((line (buffer-substring-no-properties
		     (line-beginning-position)
		     (line-end-position)))
	      (cmd))
	  (when (string-match
		 "^[\t ]+ACMD_DEF(\\([a-z][a-z0-9]+\\))"
		 line)
	    (setq cmd (substring line (match-beginning 1)
				      (match-end 1))
		  commands (cons cmd commands)))
	  (when (string-match
		 "^[\t ]+ACMD_DEF2(\"\\([a-z][a-z0-9]+\\)\""
		 line)
	    (setq cmd (substring line (match-beginning 1)
				      (match-end 1))
		  commands (cons cmd commands))))
	(forward-line 1))
      commands)))

(defun evol-mode-parse-init-c (cfile)
  (interactive "fPath to evol/src/emap/init.c: ")
  (with-temp-buffer
Joseph Botosh's avatar
Joseph Botosh committed
146
    (message "Loading functions from from %s" cfile)
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
    (insert-file-contents cfile)
    (let ((commands))
      (while (not (eobp))
	(let ((line (buffer-substring-no-properties
		     (line-beginning-position)
		     (line-end-position)))
	      (cmd))
	  (when (string-match
		 "^[\t ]+addScriptCommand(\"\\([a-z][a-z0-9]+\\)\""
		 line)
	    (setq cmd (substring line (match-beginning 1)
				      (match-end 1))
		  commands (cons cmd commands))))
	(forward-line 1))
      commands)))

(defun evol-mode-parse-script-c (cfile)
Joseph Botosh's avatar
Joseph Botosh committed
164
  (interactive "fPath to src/map/script.c: ")
165
  (with-temp-buffer
Joseph Botosh's avatar
Joseph Botosh committed
166
    (message "Loading functions from from %s" cfile)
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
    (insert-file-contents cfile)
    (let ((commands))
      (while (not (eobp))
	(let ((line (buffer-substring-no-properties
		     (line-beginning-position)
		     (line-end-position)))
	      (cmd))
	  (when (string-match
		 "^BUILDIN(\\([a-z][a-z0-9]+\\))"
		 line)
	    (setq cmd (substring line (match-beginning 1)
				      (match-end 1))
		  commands (cons cmd commands))))
	(forward-line 1))
      commands)))

Joseph Botosh's avatar
Joseph Botosh committed
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
(defun evol-mode-search-custom-functions (func-dir)
  (interactive "fPath to serverdata/npc/functions directory: ")
  (let (func-list)
    (dolist (file-name (directory-files func-dir t "^[a-z0-9]+.txt$") func-list)
      (with-temp-buffer
	(message "Loading functions from from %s" file-name)
	(insert-file-contents file-name)
	(while (not (eobp))
	  (let ((line (buffer-substring-no-properties
		       (line-beginning-position)
		       (line-end-position)))
		(func))
	    (when (string-match
		   "^function\tscript\t\\([a-z][a-z0-9_]+\\)\t{"
		   line)
	      (setq func (substring line (match-beginning 1)
				    (match-end 1)))
	      (push func func-list)))
	  (forward-line 1))))))
Joseph Botosh's avatar
Joseph Botosh committed
202
203
204
205
206
207
208
209
210
211
212
213

(defun evol-mode-setup-syntax-table ()
  (let ((st (standard-syntax-table)))
    (modify-syntax-entry ?_ "w" st)
    (modify-syntax-entry ?# "w" st)
    (modify-syntax-entry ?$ "w" st)
    (modify-syntax-entry ?@ "w" st)
    (modify-syntax-entry ?. "w" st)
    (modify-syntax-entry ?/ ". 124b" st)
    (modify-syntax-entry ?* ". 23" st)
    (modify-syntax-entry ?\n "> b" st)
    (set-syntax-table st)))
214
215

(defun evol-mode-setup-font-lock ()
Joseph Botosh's avatar
Joseph Botosh committed
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234

  (defun make-regex-list (consts &optional max-length)
    (let ((result)
	  (len (length consts))
	  (start 0) (end)
	  (diff (or max-length 1000)))
      (while (< start len)
	(setq end (min (+ start diff) len))
	(push (subseq consts start end) result)
	(setq start (+ start diff)))
      result))

  (let ((evol-mode-functions-regex))
    (unless evol-mode-constants
      (setq evol-mode-constants
	  (append
	   (evol-mode-parse-const-db
	    (concat evol-all-dir "/server-data/db/const.txt"))
	   (evol-mode-parse-mob-db
Joseph Botosh's avatar
Joseph Botosh committed
235
	    (concat evol-all-dir "/server-data/db/re/mob_db.conf"))
Joseph Botosh's avatar
Joseph Botosh committed
236
237
238
239
240
	   (evol-mode-parse-skill-db
	    (concat evol-all-dir "/server-data/db/re/skill_db.txt"))
	   ;; (evol-mode-parse-map-index-db
	   ;; 	(concat evol-all-dir "/server-data/db/map_index.txt"))
	   (evol-mode-parse-item-db
Joseph Botosh's avatar
Joseph Botosh committed
241
	    (concat evol-all-dir "/server-data/db/re/item_db.conf")))))
Joseph Botosh's avatar
Joseph Botosh committed
242
243
244
245

    (unless evol-mode-functions
      (setq evol-mode-functions
	  (append
Joseph Botosh's avatar
Joseph Botosh committed
246
247
	   (evol-mode-search-custom-functions
	    (concat evol-all-dir "/server-data/npc/functions"))
Joseph Botosh's avatar
Joseph Botosh committed
248
249
250
251
252
253
254
255
	   (evol-mode-parse-script-c
	    (concat evol-all-dir "/server-code/src/map/script.c"))       
	   (evol-mode-parse-atcommand-c
	    (concat evol-all-dir "/server-code/src/map/atcommand.c"))
	   (evol-mode-parse-init-c
	    (concat evol-all-dir "/server-code/src/evol/src/emap/init.c")))))

    (let ((regex (regexp-opt evol-mode-functions 'words)))
256
      (font-lock-add-keywords 'evol-mode
Joseph Botosh's avatar
Joseph Botosh committed
257
258
259
260
261
262
			      `((,regex . font-lock-function-name-face))))

    (dolist (lst (make-regex-list (sort evol-mode-constants 'string-lessp)))
      (let ((rx (regexp-opt lst 'words)))
	(font-lock-add-keywords 'evol-mode
				`((,rx . font-lock-constant-face)))))))
263
264
265
266
267
268
269
270
271
272
273


(define-generic-mode evol-mode
  '("//" ("/*" . "*/"))
  '("break" "continue" "if" "else" "switch" "do" "for" "while"
    "function" "procedure" "script" "case")
  `(("\\(\"[^\"]+\"\\)"  1 font-lock-string-face)
    ("\\<\\(FIXME\\|TODO\\|BUG\\|NOTE\\):" 1 font-lock-warning-face)
    ("function[\t ]+\\([a-zA-Z][a-zA-Z0-9_]*\\)[\t\n ]{" 1 font-lock-function-name-face)
    ("\\<[0-9]+\\>" . font-lock-constant-face)
    ("[,;]" . font-lock-builtin-face)
Joseph Botosh's avatar
Joseph Botosh committed
274
    ;; ("^On\\(Init\\|Timer[0-9]+\\|Touch\\|\\(Minute\\|Hour\\)[0-9]\\{2\\}\\|Day[0-9]\\|\\(Day\\|Clock\\|Sun\\|Mon\\|Tue\\|Wed\\|Thu\\|Fri\\|Sat\\)[0-9]\\{4\\}\\|\\(Buy\\|Sell\\)Item\\|TimerQuit\\|InstanceInit\\|TouchNPC\\|\\(Count\\|Pay\\)Funds\\|PC\\(Die\\|Kill\\|Login\\|Logout\\|LoadMap\\|BaseLvUp\\|JobLvUp\\)Event\\):" . font-lock-constant-face)
275
    ("^[A-Za-z][A-Za-z0-9_]+:" . font-lock-constant-face)
Joseph Botosh's avatar
Joseph Botosh committed
276
    ("\\<\\(@\\|$\\|$@\\|.\\|.@\\|'\\|#\\|##\\)\\([a-zA-Z][a-zA-Z0-9_]*\\)$\\{0,1\\}\\>" . font-lock-variable-name-face)
277
278
279
    )
  nil
  ;; nil
Joseph Botosh's avatar
Joseph Botosh committed
280
281
282
  '(evol-mode-setup-font-lock
    evol-mode-setup-syntax-table
    (lambda () (setq indent-tabs-mode nil)))
283
284
  "Major mode for syntax highlighting of Evol Scripts")

Joseph Botosh's avatar
Joseph Botosh committed
285
(add-to-list 'magic-mode-alist '("^// Evol \\(scripts\\|functions\\)." . evol-mode))
286
287

(provide 'evol-mode)