7 changed files with 1134 additions and 1 deletions
-
4custom.el
-
29elpa/jinja2-mode-0.2/jinja2-mode-autoloads.el
-
2elpa/jinja2-mode-0.2/jinja2-mode-pkg.el
-
330elpa/jinja2-mode-0.2/jinja2-mode.el
-
31elpa/masm-mode-20200308.1450/masm-mode-autoloads.el
-
2elpa/masm-mode-20200308.1450/masm-mode-pkg.el
-
737elpa/masm-mode-20200308.1450/masm-mode.el
@ -0,0 +1,29 @@ |
|||||
|
;;; jinja2-mode-autoloads.el --- automatically extracted autoloads |
||||
|
;; |
||||
|
;;; Code: |
||||
|
|
||||
|
(add-to-list 'load-path (directory-file-name |
||||
|
(or (file-name-directory #$) (car load-path)))) |
||||
|
|
||||
|
|
||||
|
;;;### (autoloads nil "jinja2-mode" "jinja2-mode.el" (0 0 0 0)) |
||||
|
;;; Generated autoloads from jinja2-mode.el |
||||
|
|
||||
|
(autoload 'jinja2-mode "jinja2-mode" "\ |
||||
|
Major mode for editing jinja2 files |
||||
|
|
||||
|
\(fn)" t nil) |
||||
|
|
||||
|
(add-to-list 'auto-mode-alist '("\\.jinja2\\'" . jinja2-mode)) |
||||
|
|
||||
|
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "jinja2-mode" '("jinja2-" "sgml-indent-line-num"))) |
||||
|
|
||||
|
;;;*** |
||||
|
|
||||
|
;; Local Variables: |
||||
|
;; version-control: never |
||||
|
;; no-byte-compile: t |
||||
|
;; no-update-autoloads: t |
||||
|
;; coding: utf-8 |
||||
|
;; End: |
||||
|
;;; jinja2-mode-autoloads.el ends here |
||||
@ -0,0 +1,2 @@ |
|||||
|
;;; Generated package description from jinja2-mode.el -*- no-byte-compile: t -*- |
||||
|
(define-package "jinja2-mode" "0.2" "A major mode for jinja2" 'nil :commit "cfaa7bbe7bb290cc500440124ce89686f3e26f86" :authors '(("Florian Mounier aka paradoxxxzero")) :maintainer '("Florian Mounier aka paradoxxxzero")) |
||||
@ -0,0 +1,330 @@ |
|||||
|
;;; jinja2-mode.el --- A major mode for jinja2 |
||||
|
|
||||
|
;; Copyright (C) 2011 Florian Mounier aka paradoxxxzero |
||||
|
|
||||
|
;; Author: Florian Mounier aka paradoxxxzero |
||||
|
;; Version: 0.2 |
||||
|
;; Package-Version: 0.2 |
||||
|
;; Package-Commit: cfaa7bbe7bb290cc500440124ce89686f3e26f86 |
||||
|
|
||||
|
;; 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 is an emacs major mode for jinja2 with: |
||||
|
;; syntax highlighting |
||||
|
;; sgml/html integration |
||||
|
;; indentation (working with sgml) |
||||
|
;; more to come |
||||
|
|
||||
|
;; This file comes from http://github.com/paradoxxxzero/jinja2-mode |
||||
|
|
||||
|
;;; Code: |
||||
|
|
||||
|
(require 'sgml-mode) |
||||
|
|
||||
|
(defgroup jinja2 nil |
||||
|
"Major mode for editing jinja2 code." |
||||
|
:prefix "jinja2-" |
||||
|
:group 'languages) |
||||
|
|
||||
|
(defcustom jinja2-user-keywords nil |
||||
|
"Custom keyword names" |
||||
|
:type '(repeat string) |
||||
|
:group 'jinja2) |
||||
|
|
||||
|
(defcustom jinja2-user-functions nil |
||||
|
"Custom function names" |
||||
|
:type '(repeat string) |
||||
|
:group 'jinja2) |
||||
|
|
||||
|
;; (defcustom jinja2-debug nil |
||||
|
;; "Log indentation logic" |
||||
|
;; :type 'boolean |
||||
|
;; :group 'jinja2) |
||||
|
|
||||
|
(defun jinja2-closing-keywords () |
||||
|
(append |
||||
|
jinja2-user-keywords |
||||
|
'("if" "for" "block" "filter" "with" |
||||
|
"raw" "macro" "autoescape" "trans" "call"))) |
||||
|
|
||||
|
(defun jinja2-indenting-keywords () |
||||
|
(append |
||||
|
(jinja2-closing-keywords) |
||||
|
'("else" "elif"))) |
||||
|
|
||||
|
(defun jinja2-builtin-keywords () |
||||
|
'("as" "autoescape" "debug" "extends" |
||||
|
"firstof" "in" "include" "load" |
||||
|
"now" "regroup" "ssi" "templatetag" |
||||
|
"url" "widthratio" "elif" "true" |
||||
|
"false" "none" "False" "True" "None" |
||||
|
"loop" "super" "caller" "varargs" |
||||
|
"kwargs" "break" "continue" "is" |
||||
|
"not" "or" "and" |
||||
|
"do" "pluralize" "set" "from" "import" |
||||
|
"context" "with" "without" "ignore" |
||||
|
"missing" "scoped")) |
||||
|
|
||||
|
(defun jinja2-functions-keywords () |
||||
|
(append |
||||
|
jinja2-user-functions |
||||
|
'("abs" "attr" "batch" "capitalize" |
||||
|
"center" "default" "dictsort" |
||||
|
"escape" "filesizeformat" "first" |
||||
|
"float" "forceescape" "format" |
||||
|
"groupby" "indent" "int" "join" |
||||
|
"last" "length" "list" "lower" |
||||
|
"pprint" "random" "replace" |
||||
|
"reverse" "round" "safe" "slice" |
||||
|
"sort" "string" "striptags" "sum" |
||||
|
"title" "trim" "truncate" "upper" |
||||
|
"urlize" "wordcount" "wordwrap" "xmlattr"))) |
||||
|
|
||||
|
(defun jinja2-find-open-tag () |
||||
|
(if (search-backward-regexp |
||||
|
(rx-to-string |
||||
|
`(and "{%" |
||||
|
(? "-") |
||||
|
(* whitespace) |
||||
|
(? (group |
||||
|
"end")) |
||||
|
(group |
||||
|
,(append '(or) |
||||
|
(jinja2-closing-keywords) |
||||
|
)) |
||||
|
(group |
||||
|
(*? anything)) |
||||
|
(* whitespace) |
||||
|
(? "-") |
||||
|
"%}")) nil t) |
||||
|
(if (match-string 1) ;; End tag, going on |
||||
|
(let ((matches (jinja2-find-open-tag))) |
||||
|
(if (string= (car matches) (match-string 2)) |
||||
|
(jinja2-find-open-tag) |
||||
|
(list (match-string 2) (match-string 3)))) |
||||
|
(list (match-string 2) (match-string 3))) |
||||
|
nil)) |
||||
|
|
||||
|
(defun jinja2-close-tag () |
||||
|
"Close the previously opened template tag." |
||||
|
(interactive) |
||||
|
(let ((open-tag (save-excursion (jinja2-find-open-tag)))) |
||||
|
(if open-tag |
||||
|
(insert |
||||
|
(if (string= (car open-tag) "block") |
||||
|
(format "{%% end%s%s %%}" |
||||
|
(car open-tag)(nth 1 open-tag)) |
||||
|
(format "{%% end%s %%}" |
||||
|
(match-string 2)))) |
||||
|
(error "Nothing to close"))) |
||||
|
(save-excursion (jinja2-indent-line))) |
||||
|
|
||||
|
(defun jinja2-insert-tag () |
||||
|
"Insert an empty tag" |
||||
|
(interactive) |
||||
|
(insert "{% ") |
||||
|
(save-excursion |
||||
|
(insert " %}") |
||||
|
(jinja2-indent-line))) |
||||
|
|
||||
|
(defun jinja2-insert-var () |
||||
|
"Insert an empty tag" |
||||
|
(interactive) |
||||
|
(insert "{{ ") |
||||
|
(save-excursion |
||||
|
(insert " }}") |
||||
|
(jinja2-indent-line))) |
||||
|
|
||||
|
(defun jinja2-insert-comment () |
||||
|
"Insert an empty tag" |
||||
|
(interactive) |
||||
|
(insert "{# ") |
||||
|
(save-excursion |
||||
|
(insert " #}") |
||||
|
(jinja2-indent-line))) |
||||
|
|
||||
|
(defconst jinja2-font-lock-comments |
||||
|
`( |
||||
|
(,(rx "{#" |
||||
|
(* whitespace) |
||||
|
(group |
||||
|
(*? anything) |
||||
|
) |
||||
|
(* whitespace) |
||||
|
"#}") |
||||
|
. (1 font-lock-comment-face t)))) |
||||
|
|
||||
|
(defconst jinja2-font-lock-keywords-1 |
||||
|
(append |
||||
|
jinja2-font-lock-comments |
||||
|
sgml-font-lock-keywords-1)) |
||||
|
|
||||
|
(defconst jinja2-font-lock-keywords-2 |
||||
|
(append |
||||
|
jinja2-font-lock-keywords-1 |
||||
|
sgml-font-lock-keywords-2)) |
||||
|
|
||||
|
(defconst jinja2-font-lock-keywords-3 |
||||
|
(append |
||||
|
jinja2-font-lock-keywords-1 |
||||
|
jinja2-font-lock-keywords-2 |
||||
|
`( |
||||
|
(,(rx "{{" |
||||
|
(* whitespace) |
||||
|
(group |
||||
|
(*? anything) |
||||
|
) |
||||
|
(* |
||||
|
"|" (* whitespace) (*? anything)) |
||||
|
(* whitespace) |
||||
|
"}}") (1 font-lock-variable-name-face t)) |
||||
|
(,(rx (group "|" (* whitespace)) |
||||
|
(group (+ word)) |
||||
|
) |
||||
|
(1 font-lock-keyword-face t) |
||||
|
(2 font-lock-warning-face t)) |
||||
|
(,(rx-to-string `(and (group "|" (* whitespace)) |
||||
|
(group |
||||
|
,(append '(or) |
||||
|
(jinja2-functions-keywords) |
||||
|
)))) |
||||
|
(1 font-lock-keyword-face t) |
||||
|
(2 font-lock-function-name-face t) |
||||
|
) |
||||
|
(,(rx-to-string `(and word-start |
||||
|
(? "end") |
||||
|
,(append '(or) |
||||
|
(jinja2-indenting-keywords) |
||||
|
) |
||||
|
word-end)) (0 font-lock-keyword-face)) |
||||
|
(,(rx-to-string `(and word-start |
||||
|
,(append '(or) |
||||
|
(jinja2-builtin-keywords) |
||||
|
) |
||||
|
word-end)) (0 font-lock-builtin-face)) |
||||
|
|
||||
|
(,(rx (or "{%" "%}" "{%-" "-%}")) (0 font-lock-function-name-face t)) |
||||
|
(,(rx (or "{{" "}}")) (0 font-lock-type-face t)) |
||||
|
(,(rx "{#" |
||||
|
(* whitespace) |
||||
|
(group |
||||
|
(*? anything) |
||||
|
) |
||||
|
(* whitespace) |
||||
|
"#}") |
||||
|
(1 font-lock-comment-face t)) |
||||
|
(,(rx (or "{#" "#}")) (0 font-lock-comment-delimiter-face t)) |
||||
|
))) |
||||
|
|
||||
|
(defvar jinja2-font-lock-keywords |
||||
|
jinja2-font-lock-keywords-1) |
||||
|
|
||||
|
(defun sgml-indent-line-num () |
||||
|
"Indent the current line as SGML." |
||||
|
(let* ((savep (point)) |
||||
|
(indent-col |
||||
|
(save-excursion |
||||
|
(back-to-indentation) |
||||
|
(if (>= (point) savep) (setq savep nil)) |
||||
|
(sgml-calculate-indent)))) |
||||
|
(if (null indent-col) |
||||
|
0 |
||||
|
(if savep |
||||
|
(save-excursion indent-col) |
||||
|
indent-col)))) |
||||
|
|
||||
|
(defun jinja2-calculate-indent-backward (default) |
||||
|
"Return indent column based on previous lines" |
||||
|
(let ((indent-width sgml-basic-offset) (default (sgml-indent-line-num))) |
||||
|
(forward-line -1) |
||||
|
(if (looking-at "^[ \t]*{%-? *end") ; Don't indent after end |
||||
|
(current-indentation) |
||||
|
(if (looking-at (concat "^[ \t]*{%-? *.*?{%-? *end" (regexp-opt (jinja2-indenting-keywords)))) |
||||
|
(current-indentation) |
||||
|
(if (looking-at (concat "^[ \t]*{%-? *" (regexp-opt (jinja2-indenting-keywords)))) ; Check start tag |
||||
|
(+ (current-indentation) indent-width) |
||||
|
(if (looking-at "^[ \t]*<") ; Assume sgml block trust sgml |
||||
|
default |
||||
|
(if (bobp) |
||||
|
0 |
||||
|
(jinja2-calculate-indent-backward default)))))))) |
||||
|
|
||||
|
|
||||
|
(defun jinja2-calculate-indent () |
||||
|
"Return indent column" |
||||
|
(if (bobp) ; Check begining of buffer |
||||
|
0 |
||||
|
(let ((indent-width sgml-basic-offset) (default (sgml-indent-line-num))) |
||||
|
(if (looking-at "^[ \t]*{%-? *e\\(nd\\|lse\\|lif\\)") ; Check close tag |
||||
|
(save-excursion |
||||
|
(forward-line -1) |
||||
|
(if |
||||
|
(and |
||||
|
(looking-at (concat "^[ \t]*{%-? *" (regexp-opt (jinja2-indenting-keywords)))) |
||||
|
(not (looking-at (concat "^[ \t]*{%-? *.*?{% *end" (regexp-opt (jinja2-indenting-keywords)))))) |
||||
|
(current-indentation) |
||||
|
(- (current-indentation) indent-width))) |
||||
|
(if (looking-at "^[ \t]*</") ; Assume sgml end block trust sgml |
||||
|
default |
||||
|
(save-excursion |
||||
|
(jinja2-calculate-indent-backward default))))))) |
||||
|
|
||||
|
(defun jinja2-indent-line () |
||||
|
"Indent current line as Jinja code" |
||||
|
(interactive) |
||||
|
(let ((old_indent (current-indentation)) (old_point (point))) |
||||
|
(move-beginning-of-line nil) |
||||
|
(let ((indent (max 0 (jinja2-calculate-indent)))) |
||||
|
(indent-line-to indent) |
||||
|
(if (< old_indent (- old_point (line-beginning-position))) |
||||
|
(goto-char (+ (- indent old_indent) old_point))) |
||||
|
indent))) |
||||
|
|
||||
|
|
||||
|
;;;###autoload |
||||
|
(define-derived-mode jinja2-mode html-mode "Jinja2" |
||||
|
"Major mode for editing jinja2 files" |
||||
|
:group 'jinja2 |
||||
|
;; Disabling this because of this emacs bug: |
||||
|
;; http://lists.gnu.org/archive/html/bug-gnu-emacs/2002-09/msg00041.html |
||||
|
;; (modify-syntax-entry ?\' "\"" sgml-mode-syntax-table) |
||||
|
(set (make-local-variable 'comment-start) "{#") |
||||
|
(set (make-local-variable 'comment-start-skip) "{#") |
||||
|
(set (make-local-variable 'comment-end) "#}") |
||||
|
(set (make-local-variable 'comment-end-skip) "#}") |
||||
|
;; it mainly from sgml-mode font lock setting |
||||
|
(set (make-local-variable 'font-lock-defaults) |
||||
|
'(( |
||||
|
jinja2-font-lock-keywords |
||||
|
jinja2-font-lock-keywords-1 |
||||
|
jinja2-font-lock-keywords-2 |
||||
|
jinja2-font-lock-keywords-3) |
||||
|
nil t nil nil |
||||
|
(font-lock-syntactic-keywords |
||||
|
. sgml-font-lock-syntactic-keywords))) |
||||
|
(set (make-local-variable 'indent-line-function) 'jinja2-indent-line)) |
||||
|
|
||||
|
(define-key jinja2-mode-map (kbd "C-c c") 'jinja2-close-tag) |
||||
|
(define-key jinja2-mode-map (kbd "C-c t") 'jinja2-insert-tag) |
||||
|
(define-key jinja2-mode-map (kbd "C-c v") 'jinja2-insert-var) |
||||
|
(define-key jinja2-mode-map (kbd "C-c #") 'jinja2-insert-comment) |
||||
|
|
||||
|
;;;###autoload |
||||
|
(add-to-list 'auto-mode-alist '("\\.jinja2\\'" . jinja2-mode)) |
||||
|
|
||||
|
(provide 'jinja2-mode) |
||||
|
|
||||
|
;;; jinja2-mode.el ends here |
||||
@ -0,0 +1,31 @@ |
|||||
|
;;; masm-mode-autoloads.el --- automatically extracted autoloads |
||||
|
;; |
||||
|
;;; Code: |
||||
|
|
||||
|
(add-to-list 'load-path (directory-file-name |
||||
|
(or (file-name-directory #$) (car load-path)))) |
||||
|
|
||||
|
|
||||
|
;;;### (autoloads nil "masm-mode" "masm-mode.el" (0 0 0 0)) |
||||
|
;;; Generated autoloads from masm-mode.el |
||||
|
|
||||
|
(autoload 'masm-mode "masm-mode" "\ |
||||
|
Major mode for editing MASM assembly programs. |
||||
|
|
||||
|
\(fn)" t nil) |
||||
|
|
||||
|
(add-to-list 'auto-mode-alist '("\\.asm\\'" . masm-mode)) |
||||
|
|
||||
|
(add-to-list 'auto-mode-alist '("\\.inc\\'" . masm-mode)) |
||||
|
|
||||
|
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "masm-mode" '("masm-"))) |
||||
|
|
||||
|
;;;*** |
||||
|
|
||||
|
;; Local Variables: |
||||
|
;; version-control: never |
||||
|
;; no-byte-compile: t |
||||
|
;; no-update-autoloads: t |
||||
|
;; coding: utf-8 |
||||
|
;; End: |
||||
|
;;; masm-mode-autoloads.el ends here |
||||
@ -0,0 +1,2 @@ |
|||||
|
;;; Generated package description from masm-mode.el -*- no-byte-compile: t -*- |
||||
|
(define-package "masm-mode" "20200308.1450" "MASM x86 and x64 assembly major mode" '((emacs "25.1")) :commit "626b9255c2bb967a53d1d50be0b98a1bcae3250c" :authors '(("YiGeeker" . "zyfchinese@yeah.net")) :maintainer '("YiGeeker" . "zyfchinese@yeah.net") :keywords '("languages") :url "https://github.com/YiGeeker/masm-mode") |
||||
@ -0,0 +1,737 @@ |
|||||
|
;;; masm-mode.el --- MASM x86 and x64 assembly major mode -*- lexical-binding: t; -*- |
||||
|
|
||||
|
;; This is free and unencumbered software released into the public domain. |
||||
|
|
||||
|
;; Author: YiGeeker <zyfchinese@yeah.net> |
||||
|
;; Version: 1.0.0 |
||||
|
;; Package-Version: 20200308.1450 |
||||
|
;; Package-Commit: 626b9255c2bb967a53d1d50be0b98a1bcae3250c |
||||
|
;; Package-Requires: ((emacs "25.1")) |
||||
|
;; Keywords: languages |
||||
|
;; URL: https://github.com/YiGeeker/masm-mode |
||||
|
|
||||
|
;; 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 GNU General Public License. |
||||
|
|
||||
|
;;; Commentary: |
||||
|
|
||||
|
;; A major mode for editing MASM x86 and x64 assembly code. It |
||||
|
;; includes syntax highlighting, automatic comment indentation and |
||||
|
;; various build commands. |
||||
|
;; Notice: masm-mode will clobber Emacs's built-in asm-mode. |
||||
|
|
||||
|
;;; Code: |
||||
|
|
||||
|
(defgroup masm nil |
||||
|
"Options for `masm-mode'." |
||||
|
:link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) |
||||
|
:group 'languages) |
||||
|
|
||||
|
(defcustom masm-program-win64 t |
||||
|
"Syntax for `masm-mode', t for Win64 and nil for Win32." |
||||
|
:type '(choice (const :tag "Win64" t) |
||||
|
(const :tag "Win32" nil)) |
||||
|
:group 'masm-mode) |
||||
|
|
||||
|
(defcustom masm-win32-compile-args '("/c" "/coff") |
||||
|
"Default arguments for the ml.exe in `masm-mode'." |
||||
|
:type '(repeat string) |
||||
|
:group 'masm-mode) |
||||
|
|
||||
|
(defcustom masm-win32-link-args '("/subsystem:windows") |
||||
|
"Default arguments for the Win32 link.exe in `masm-mode'." |
||||
|
:type '(repeat string) |
||||
|
:group 'masm-mode) |
||||
|
|
||||
|
(defcustom masm-win32-executable-path "" |
||||
|
"Path for ml.exe." |
||||
|
:type 'directory |
||||
|
:group 'masm-mode) |
||||
|
|
||||
|
(defcustom masm-win32-include-path () |
||||
|
"Path for Win32 inc files in `masm-mode'." |
||||
|
:type '(repeat directory) |
||||
|
:group 'masm-mode) |
||||
|
|
||||
|
(defcustom masm-win32-library-path () |
||||
|
"Path for Win32 lib files in `masm-mode'." |
||||
|
:type '(repeat directory) |
||||
|
:group 'masm-mode) |
||||
|
|
||||
|
(defcustom masm-win64-compile-args '("/c") |
||||
|
"Default arguments for the ml64.exe in `masm-mode'." |
||||
|
:type '(repeat string) |
||||
|
:group 'masm-mode) |
||||
|
|
||||
|
(defcustom masm-win64-link-args '("/subsystem:windows" "/machine:x64" "/entry:main") |
||||
|
"Default arguments for the Win64 link.exe in `masm-mode'." |
||||
|
:type '(repeat string) |
||||
|
:group 'masm-mode) |
||||
|
|
||||
|
(defcustom masm-win64-executable-path "" |
||||
|
"Path for ml64.exe." |
||||
|
:type 'directory |
||||
|
:group 'masm-mode) |
||||
|
|
||||
|
(defcustom masm-win64-include-path () |
||||
|
"Path for Win64 inc files in `masm-mode'." |
||||
|
:type '(repeat directory) |
||||
|
:group 'masm-mode) |
||||
|
|
||||
|
(defcustom masm-win64-library-path () |
||||
|
"Path for Win64 lib files in `masm-mode'." |
||||
|
:type '(repeat directory) |
||||
|
:group 'masm-mode) |
||||
|
|
||||
|
(defcustom masm-build-executable "nmake" |
||||
|
"Default executable for building the assembly project in `masm-mode'." |
||||
|
:type 'string |
||||
|
:group 'masm-mode) |
||||
|
|
||||
|
(defcustom masm-build-args () |
||||
|
"Default arguments for the build command in `masm-mode'." |
||||
|
:type '(repeat string) |
||||
|
:group 'masm-mode) |
||||
|
|
||||
|
(defvar-local masm--program-win64 |
||||
|
masm-program-win64 |
||||
|
"Decided by customizable value.") |
||||
|
|
||||
|
(defvar-local masm--compile-command-used nil |
||||
|
"Save changed compile command.") |
||||
|
|
||||
|
(defvar-local masm--link-command-used nil |
||||
|
"Save changed link command.") |
||||
|
|
||||
|
(defvar-local masm--build-command-used nil |
||||
|
"Save changed build command.") |
||||
|
|
||||
|
(defgroup masm-mode-faces () |
||||
|
"Faces used by `masm-mode'." |
||||
|
:group 'masm-mode) |
||||
|
|
||||
|
(defvar masm-mode-abbrev-table nil |
||||
|
"Abbrev table used while in `masm-mode'.") |
||||
|
(define-abbrev-table 'masm-mode-abbrev-table ()) |
||||
|
|
||||
|
(defface masm-registers |
||||
|
'((t :inherit (font-lock-variable-name-face))) |
||||
|
"Face for registers." |
||||
|
:group 'masm-mode-faces) |
||||
|
|
||||
|
(defface masm-prefix |
||||
|
'((t :inherit (font-lock-builtin-face))) |
||||
|
"Face for prefix." |
||||
|
:group 'masm-mode-faces) |
||||
|
|
||||
|
(defface masm-types |
||||
|
'((t :inherit (font-lock-type-face))) |
||||
|
"Face for types." |
||||
|
:group 'masm-mode-faces) |
||||
|
|
||||
|
(defface masm-instructions |
||||
|
'((t :inherit (font-lock-builtin-face))) |
||||
|
"Face for instructions." |
||||
|
:group 'masm-mode-faces) |
||||
|
|
||||
|
(defface masm-directives |
||||
|
'((t :inherit (font-lock-keyword-face))) |
||||
|
"Face for directives." |
||||
|
:group 'masm-mode-faces) |
||||
|
|
||||
|
(defface masm-labels |
||||
|
'((t :inherit (font-lock-function-name-face))) |
||||
|
"Face for labels." |
||||
|
:group 'masm-mode-faces) |
||||
|
|
||||
|
(defface masm-subprogram |
||||
|
'((t :inherit (font-lock-function-name-face))) |
||||
|
"Face for subprogram." |
||||
|
:group 'masm-mode-faces) |
||||
|
|
||||
|
(defface masm-macro |
||||
|
'((t :inherit (font-lock-function-name-face))) |
||||
|
"Face for macro." |
||||
|
:group 'masm-mode-faces) |
||||
|
|
||||
|
(defface masm-section-name |
||||
|
'((t :inherit (font-lock-type-face))) |
||||
|
"Face for section name." |
||||
|
:group 'masm-mode-faces) |
||||
|
|
||||
|
(defface masm-constant |
||||
|
'((t :inherit (font-lock-constant-face))) |
||||
|
"Face for constant." |
||||
|
:group 'masm-mode-faces) |
||||
|
|
||||
|
(defface masm-struct |
||||
|
'((t :inherit (font-lock-type-face))) |
||||
|
"Face for struct." |
||||
|
:group 'masm-mode-faces) |
||||
|
|
||||
|
(defface masm-union |
||||
|
'((t :inherit (font-lock-type-face))) |
||||
|
"Face for union." |
||||
|
:group 'masm-mode-faces) |
||||
|
|
||||
|
(eval-and-compile |
||||
|
(defconst masm-registers-common |
||||
|
'("ah" "al" "ax" "bh" "bl" "bp" "bx" "ch" "cl" "cr0" "cr2" "cr3" |
||||
|
"cs" "cx" "dh" "di" "dl" "dr0" "dr1" "dr2" "dr3" "dr6" "dr7" |
||||
|
"ds" "dx" "eax" "ebp" "ebx" "ecx" "edi" "edx" "eip" "es" "esi" |
||||
|
"esp" "fpr0" "fpr1" "fpr2" "fpr3" "fpr4" "fpr5" "fpr6" "fpr7" |
||||
|
"fs" "gs" "ip" "mmx0" "mmx1" "mmx2" "mmx3" "mmx4" "mmx5" "mmx6" |
||||
|
"mmx7" "si" "sp" "ss" "st" "tr3" "tr4" "tr5" "tr6" "tr7" ) |
||||
|
"MASM registers for `masm-mode'.")) |
||||
|
|
||||
|
|
||||
|
(eval-and-compile |
||||
|
(defconst masm-registers-win64-only |
||||
|
'( "r10" "r10b" "r10d" "r10w" "r11" "r11b" "r11d" "r11w" "r12" |
||||
|
"r12b" "r12d" "r12w" "r13" "r13b" "r13d" "r13w" "r14" "r14b" |
||||
|
"r14d" "r14w" "r15" "r15b" "r15d" "r15w" "r8" "r8b" "r8d" "r8w" |
||||
|
"r9" "r9b" "r9d" "r9w" "rax" "rbp" "rbx" "rcx" "rdi" "rdx" "rip" |
||||
|
"rsi" "rsp" "xmm0" "xmm1" "xmm10" "xmm11" "xmm12" "xmm13" |
||||
|
"xmm14" "xmm15" "xmm2" "xmm3" "xmm4" "xmm5" "xmm6" "xmm7" "xmm8" |
||||
|
"xmm9") |
||||
|
"MASM win64 registers for `masm-mode'.")) |
||||
|
|
||||
|
(eval-and-compile |
||||
|
(defconst masm-instructions-common |
||||
|
'("aaa" "aad" "aam" "aas" "adc" "adcx" "add" "addpd" "addps" |
||||
|
"addsd" "addss" "addsubpd" "addsubps" "adox" "aesdec" |
||||
|
"aesdeclast" "aesenc" "aesenclast" "aesimc" "aeskeygenassist" |
||||
|
"and" "andn" "andnpd" "andnps" "andpd" "andps" "arpl" "bound" |
||||
|
"bsf" "bsr" "bswap" "bt" "btc" "btr" "bts" "call" "clc" "cld" |
||||
|
"cli" "clts" "cmp" "cmps" "cmpsb" "cmpsw" "cmpxchg" "cwd" "daa" |
||||
|
"das" "dec" "div" "enter" "esc" "f2xm1" "fabs" "fadd" "faddp" |
||||
|
"fbld" "fbstp" "fchs" "fclex" "fcom" "fcomp" "fcompp" "fcos" |
||||
|
"fdecstp" "fdisi" "fdiv" "fdivp" "fdivr" "fdivrp" "feni" "ffree" |
||||
|
"fiadd" "ficom" "ficomp" "fidiv" "fidivr" "fild" "fimul" |
||||
|
"fincstp" "finit" "fist" "fistp" "fisub" "fisubr" "fld" "fld1" |
||||
|
"fldcw" "fldenv" "fldenvd" "fldenvw" "fldl2e" "fldl2t" "fldlg2" |
||||
|
"fldln2" "fldpi" "fldz" "fmul" "fmulp" "fnclex" "fndisi" "fneni" |
||||
|
"fninit" "fnop" "fnsave" "fnsaved" "fnsavew" "fnstcw" "fnstenv" |
||||
|
"fnstenvd" "fnstenvw" "fnstsw" "fpatan" "fprem" "fprem1" "fptan" |
||||
|
"frndint" "frstor" "frstord" "frstorw" "fsave" "fsaved" "fsavew" |
||||
|
"fscale" "fsetpm" "fsin" "fincos" "fsqrt" "fst" "fstcw" "fstenv" |
||||
|
"fstenvd" "fstenvw" "fstp" "fstsw" "fsub" "fsubp" "fsubr" |
||||
|
"fsubrp" "ftst" "fucom" "fucomp" "fucompp" "fwait" "fxam" "fxch" |
||||
|
"fxtract" "fyl2x" "fyl2xp1" "hlt" "idiv" "imul" "in" "inc" "ins" |
||||
|
"insb" "insd" "insw" "int" "into" "invd" "invlpg" "iret" "iretd" |
||||
|
"iretdf" "iretf" "ja" "jae" "jb" "jbe" "jc" "jcxz" "je" "jecxz" |
||||
|
"jg" "jge" "jl" "jle" "jmp" "jna" "jnae" "jnb" "jnbe" "jnc" |
||||
|
"jne" "jng" "jnge" "jnl" "jnle" "jno" "jnp" "jns" "jnz" "jo" |
||||
|
"jp" "jpe" "jpo" "js" "jz" "lahf" "lar" "lds" "lea" "leave" |
||||
|
"les" "lfs" "lgdt" "lgs" "lidt" "lldt" "lmsw" "lods" "lodsb" |
||||
|
"lodsd" "lodsw" "loop" "loopd" "loope" "looped" "loopew" |
||||
|
"loopne" "loopned" "loopnz" "loopnzd" "loopnzw" "loopw" "loopz" |
||||
|
"loopzd" "loopzw" "lsl" "lss" "ltr" "mov" "movapd" "movaps" |
||||
|
"movbe" "movd" "movddup" "movdq2q" "movdqa" "movdqu" "movhlps" |
||||
|
"movhpd" "movhps" "movlhps" "movlpd" "movlps" "movmskpd" |
||||
|
"movmskps" "movntdq" "movntdqa" "movnti" "movntpd" "movntps" |
||||
|
"movntq" "movntsd" "movntss" "movq" "movq2dq" "movs" "movsb" |
||||
|
"movsd" "movsx" "movsw" "movzx" "mul" "nop" "not" "or" "out" |
||||
|
"outs" "outsb" "outsd" "outsw" "pabsb" "pabsd" "pabsw" |
||||
|
"packssdw" "packsswb" "packusdw" "packuswb" "paddb" "paddd" |
||||
|
"paddq" "paddsb" "paddsiw" "paddsw" "paddusb" "paddusw" "paddw" |
||||
|
"palignr" "pand" "pandn" "pause" "paveb" "pavgb" "pavgusb" |
||||
|
"pavgw" "pblendvb" "pblendw" "pclmulhqhqdq" "pclmulhqlqdq" |
||||
|
"pclmullqhqdq" "pclmullqlqdq" "pclmulqdq" "pcmpeqb" "pcmpeqd" |
||||
|
"pcmpeqq" "pcmpeqw" "pcmpestri" "pcmpestrm" "pcmpgtb" "pcmpgtd" |
||||
|
"pcmpgtq" "pcmpgtw" "pcmpistri" "pcmpistrm" "pdep" "pdistib" |
||||
|
"pext" "pextrb" "pextrd" "pextrq" "pextrw" "pf2id" "pf2iw" |
||||
|
"pfacc" "pfadd" "pfcmpeq" "pfcmpge" "pfcmpgt" "pfmax" "pfmin" |
||||
|
"pfmul" "pfnacc" "pfpnacc" "pfrcp" "pfrcpit1" "pfrcpit2" |
||||
|
"pfrcpv" "pfrsqit1" "pfrsqrt" "pfrsqrtv" "pfsub" "pfsubr" |
||||
|
"phaddd" "phaddsw" "phaddw" "phminposuw" "phsubd" "phsubsw" |
||||
|
"phsubw" "pi2fd" "pi2fw" "pinsrb" "pinsrd" "pinsrq" "pinsrw" |
||||
|
"pmachriw" "pmaddubsw" "pmaddwd" "pmagw" "pmaxsb" "pmaxsd" |
||||
|
"pmaxsw" "pmaxub" "pmaxud" "pmaxuw" "pminsb" "pminsd" "pminsw" |
||||
|
"pminub" "pminud" "pminuw" "pmovmskb" "pmovsxbd" "pmovsxbq" |
||||
|
"pmovsxbw" "pmovsxdq" "pmovsxwd" "pmovsxwq" "pmovzxbd" |
||||
|
"pmovzxbq" "pmovzxbw" "pmovzxdq" "pmovzxwd" "pmovzxwq" "pmuldq" |
||||
|
"pmulhriw" "pmulhrsw" "pmulhrwa" "pmulhrwc" "pmulhuw" "pmulhw" |
||||
|
"pmulld" "pmullw" "pmuludq" "pmvgezb" "pmvlzb" "pmvnzb" "pmvzb" |
||||
|
"pop" "popa" "popf" "popfd" "push" "pusha" "pushd" "pushf" |
||||
|
"pushfd" "pushw" "rcl" "rcr" "ret" "retf" "retn" "rol" "ror" |
||||
|
"sahf" "sal" "sar" "sbb" "scas" "scasb" "scasd" "scasw" "seta" |
||||
|
"setae" "setb" "setbe" "setc" "sete" "setg" "setge" "setl" |
||||
|
"setle" "setna" "setnae" "setnb" "setnbe" "setnc" "setne" |
||||
|
"setng" "setnge" "setnl" "setnle" "setno" "setnp" "setns" |
||||
|
"setnz" "seto" "setp" "setpe" "setpo" "sets" "setz" "shld" "shl" |
||||
|
"shld" "shr" "shrd" "sidt" "sldt" "smsw" "stc" "std" "sti" "str" |
||||
|
"stos" "stosb" "stosd" "stosw" "sub" "test" "verr" "verw" |
||||
|
"wbinvd" "xadd" "xchg" "xlat" "xlatb" "xor") |
||||
|
"MASM instructions for `masm-mode'.")) |
||||
|
|
||||
|
(eval-and-compile |
||||
|
(defconst masm-instructions-win32-only |
||||
|
'("pushad" "popad") |
||||
|
"MASM Win32 instructions for `masm-mode'.")) |
||||
|
|
||||
|
(eval-and-compile |
||||
|
(defconst masm-section-name |
||||
|
'(".code" ".const" ".data" ".data?" ".stack") |
||||
|
"MASM section names for `masm-mode'.")) |
||||
|
|
||||
|
(eval-and-compile |
||||
|
(defconst masm-types |
||||
|
'("byte" "dword" "fword" "qword" "Real4" "Real8" "Real10" "sbyte" |
||||
|
"sdword" "sword" "tbyte" "word") |
||||
|
"MASM types for `masm-mode'.")) |
||||
|
|
||||
|
(eval-and-compile |
||||
|
(defconst masm-prefix |
||||
|
'("lock" "rep" "repe" "repne" "repnz" "repz") |
||||
|
"MASM prefixes for `masm-mode'.")) |
||||
|
|
||||
|
(eval-and-compile |
||||
|
(defconst masm-directives-win32-only |
||||
|
'(".186" ".286" ".286c" ".286p" ".287" ".386" ".386c" ".386p" |
||||
|
".387" ".486" ".486p" ".8086" ".8087" ".alpha" ".break" |
||||
|
".continue" ".cref" ".dosseg" ".else" ".elseif" ".endif" ".endw" |
||||
|
".err" ".err1" ".err2" ".errb" ".errdef" ".errdif" ".errdifi" |
||||
|
".erre" ".erridn" ".erridni" ".errnb" ".errndef" ".errnz" |
||||
|
".exit" ".fardata" ".fardata?" ".if" ".lall" ".lfcond" ".list" |
||||
|
".listall" ".listif" ".listmacro" ".listmacroall" ".mmx" |
||||
|
".model" ".msfloat" ".no87" ".nocref" ".nolist" ".nolistif" |
||||
|
".nolistmacro" ".radix"".repeat" ".sall" ".seq" ".sfcond" |
||||
|
".startup" ".tfcond" ".type" ".until" ".untilcxz" ".while" |
||||
|
".xall" ".xcref" ".xlist" "%out" "carry?" "invoke" "overflow?" |
||||
|
"parity?" "sign?" "zero?") |
||||
|
"MASM win32 directives for `masm-mode'.")) |
||||
|
|
||||
|
(eval-and-compile |
||||
|
(defconst masm-directives-common |
||||
|
'("alias" "align" "assume" "catstr" "comm" "comment" "db" "dd" |
||||
|
"df" "dosseg" "dq" "dt" "dup" "dw" "echo" "else" "elseif" |
||||
|
"elseif1" "elseif2" "elseifb" "elseifdef" "elseifdif" |
||||
|
"elseifdifi" "elseife" "elseifidn" "elseifidni" "elseifnb" |
||||
|
"elseifndef" "end" "endif" "endm" "endp" "ends" "eq" "equ" |
||||
|
"even" "exitm" "extern" "externdef" "extrn" "for" "forc""ge" |
||||
|
"goto" "group" "gt" "high" "highword" "if" "if1" "if2" "ifb" |
||||
|
"ifdef" "ifdif" "ifdifi" "ife" "ifidn" "ifidni" "ifnb" "ifndef" |
||||
|
"include" "includelib" "instr" "irp" "irpc" "label" "le" |
||||
|
"length" "lengthof" "local" "low" "lowword" "lroffset" "lt" |
||||
|
"macro" "mask" "mod" "name" "ne" "offset" "opattr" "option" |
||||
|
"org" "page" "popcontext" "proc" "proto" "ptr" "public" "purge" |
||||
|
"pushcontext" "record" "repeat" "rept" "seg" "segment" "short" |
||||
|
"size" "sizeof" "sizestr" "struc" "struct" "substr" "subtitle" |
||||
|
"subttl" "textequ" "this" "title" "type" "typedef" "union" "uses" |
||||
|
"while") |
||||
|
"MASM directives for `masm-mode'.")) |
||||
|
|
||||
|
(defconst masm-label-regexp |
||||
|
"\\(\\_<[a-zA-Z_@][a-zA-Z0-9_@?]*\\_>\\):\\s-*" |
||||
|
"Regexp for `masm-mode' for matching labels.") |
||||
|
|
||||
|
(defconst masm-subprogram-regexp |
||||
|
"\\(\\_<[a-zA-Z_@]+\\_>\\)[ \t]+\\(proc\\|endp\\)\\s-*" |
||||
|
"Regexp for `masm-mode' for matching subprogram.") |
||||
|
|
||||
|
(defconst masm-constant-regexp |
||||
|
"\\<[-+]?\\([0-9]+[Dd]?\\|[01]+[Bb]\\|[0-7]+[Qq]\\|[0-9A-Fa-f]+[Hh]\\)\\([-+]\\([0-9]+[Dd]?\\|[01]+[Bb]\\|[0-7]+[Qq]\\|[0-9A-Fa-f]+[Hh]\\)\\)*\\>" |
||||
|
"Regexp for `masm-mode' for matching numeric constants.") |
||||
|
|
||||
|
(defconst masm-struct-regexp |
||||
|
"\\(\\_<[a-zA-Z_@]+\\_>\\)[ \t]+\\(struct\\|ends\\)\\s-*" |
||||
|
"Regexp for `masm-mode' for matching struct.") |
||||
|
|
||||
|
(defconst masm-union-regexp |
||||
|
"\\(\\_<[a-zA-Z_@]+\\_>\\)[ \t]+\\(union\\|ends\\)\\s-*" |
||||
|
"Regexp for `masm-mode' for matching struct.") |
||||
|
|
||||
|
(defconst masm-macro-regexp |
||||
|
"\\(\\_<[a-zA-Z_@]+\\_>\\)[ \t]+macro\\s-*" |
||||
|
"Regexp for `masm-mode' for matching macro.") |
||||
|
|
||||
|
(defmacro masm--opt (keywords) |
||||
|
"Prepare KEYWORDS for `looking-at'." |
||||
|
`(eval-when-compile |
||||
|
(regexp-opt ,keywords 'words))) |
||||
|
|
||||
|
(defconst masm-imenu-generic-expression |
||||
|
`((nil ,(concat "^\\s-*" masm-label-regexp) 1) |
||||
|
(nil ,(concat "\\(\\_<[a-zA-Z_@]+\\_>\\)[ \t]+" |
||||
|
(masm--opt '("proc" "macro"))) |
||||
|
1)) |
||||
|
"Expressions for `imenu-generic-expression'.") |
||||
|
|
||||
|
(defconst masm-win32-font-lock-keywords |
||||
|
`((,(masm--opt masm-section-name) . 'masm-section-name) |
||||
|
(,(masm--opt masm-registers-common) . 'masm-registers) |
||||
|
(,(masm--opt masm-types) . 'masm-types) |
||||
|
(,(masm--opt masm-instructions-common) . 'masm-instructions) |
||||
|
(,(masm--opt masm-instructions-win32-only) . 'masm-instructions) |
||||
|
(,(masm--opt masm-prefix) . 'masm-prefix) |
||||
|
(,masm-label-regexp (1 'masm-labels)) |
||||
|
(,masm-subprogram-regexp (1 'masm-subprogram)) |
||||
|
(,masm-constant-regexp . 'masm-constant) |
||||
|
(,masm-struct-regexp (1 'masm-struct)) |
||||
|
(,masm-union-regexp (1 'masm-union)) |
||||
|
(,masm-macro-regexp (1 'masm-macro)) |
||||
|
(,(masm--opt masm-directives-common) . 'masm-directives) |
||||
|
(,(masm--opt masm-directives-win32-only) . 'masm-directives)) |
||||
|
"Win32 keywords for `masm-mode'.") |
||||
|
|
||||
|
(defconst masm-win64-font-lock-keywords |
||||
|
`((,(masm--opt masm-section-name) . 'masm-section-name) |
||||
|
(,(masm--opt masm-registers-common) . 'masm-registers) |
||||
|
(,(masm--opt masm-registers-win64-only) . 'masm-registers) |
||||
|
(,(masm--opt masm-types) . 'masm-types) |
||||
|
(,(masm--opt masm-instructions-common) . 'masm-instructions) |
||||
|
(,(masm--opt masm-prefix) . 'masm-prefix) |
||||
|
(,masm-label-regexp (1 'masm-labels)) |
||||
|
(,masm-subprogram-regexp (1 'masm-subprogram)) |
||||
|
(,masm-constant-regexp . 'masm-constant) |
||||
|
(,masm-struct-regexp (1 'masm-struct)) |
||||
|
(,masm-union-regexp (1 'masm-union)) |
||||
|
(,masm-macro-regexp (1 'masm-macro)) |
||||
|
(,(masm--opt masm-directives-common) . 'masm-directives)) |
||||
|
"Win64 keywords for `masm-mode'.") |
||||
|
|
||||
|
(defconst masm-mode-syntax-table |
||||
|
(with-syntax-table (copy-syntax-table) |
||||
|
(modify-syntax-entry ?_ "w") |
||||
|
(modify-syntax-entry ?@ "w") |
||||
|
(modify-syntax-entry ?\? "w") |
||||
|
(modify-syntax-entry ?\. "w") |
||||
|
(modify-syntax-entry ?\; "<") |
||||
|
(modify-syntax-entry ?\n ">") |
||||
|
(modify-syntax-entry ?\" "\"") |
||||
|
(modify-syntax-entry ?\' "\"") |
||||
|
(syntax-table)) |
||||
|
"Syntax table for `masm-mode'.") |
||||
|
|
||||
|
(defvar masm-mode-map |
||||
|
(let ((map (make-sparse-keymap))) |
||||
|
;; Note that the comment character isn't set up until masm-mode is called. |
||||
|
(define-key map ":" #'masm-colon) |
||||
|
(define-key map "\C-c;" #'comment-region) |
||||
|
(define-key map ";" #'masm-comment) |
||||
|
(define-key map "\C-j" #'masm-newline-and-indent) |
||||
|
(define-key map "\C-m" #'masm-newline-and-indent) |
||||
|
(define-key map "\C-c\C-c" #'masm-build) |
||||
|
(define-key map "\C-c\C-b" #'masm-compile) |
||||
|
(define-key map "\C-c\C-l" #'masm-link) |
||||
|
(define-key map "\C-c\C-s" #'masm-change-program-type) |
||||
|
(define-key map [menu-bar masm-mode] (cons "Masm" (make-sparse-keymap))) |
||||
|
|
||||
|
(define-key map [menu-bar masm-mode newline-and-indent] |
||||
|
'(menu-item "Insert Newline and Indent" masm-newline-and-indent |
||||
|
:help "Insert a newline, then indent according to major mode")) |
||||
|
(define-key map [menu-bar masm-mode masm-colon] |
||||
|
'(menu-item "Insert Colon" masm-colon |
||||
|
:help "Insert a colon; if it follows a label, delete the label's indentation")) |
||||
|
(define-key map [menu-bar masm-mode masm-change-program-type] |
||||
|
'(menu-item "Switch program type" masm-change-program-type |
||||
|
:help "Switch between Win32 and Win64")) |
||||
|
(define-key map [menu-bar masm-mode masm-link] |
||||
|
'(menu-item "Link the obj file" masm-link |
||||
|
:help "Use link to link the obj file")) |
||||
|
(define-key map [menu-bar masm-mode masm-compile] |
||||
|
'(menu-item "Compile the file" masm-compile |
||||
|
:help "Use ml64 to compile the file")) |
||||
|
(define-key map [menu-bar masm-mode masm-build] |
||||
|
'(menu-item "Build the project" masm-build |
||||
|
:help "Use nmake to build the project")) |
||||
|
(define-key map [menu-bar masm-mode comment-region] |
||||
|
'(menu-item "Comment Region" comment-region |
||||
|
:help "Comment or uncomment each line in the region")) |
||||
|
map) |
||||
|
"Keymap for masm mode.") |
||||
|
|
||||
|
(defun masm-colon () |
||||
|
"Insert a colon and convert the current line into a label." |
||||
|
(interactive) |
||||
|
(call-interactively #'self-insert-command) |
||||
|
(save-excursion |
||||
|
(back-to-indentation) |
||||
|
(delete-horizontal-space))) |
||||
|
|
||||
|
(defun masm-newline-and-indent () |
||||
|
"Auto-indent the new line." |
||||
|
(interactive) |
||||
|
(let ((indent |
||||
|
(save-excursion |
||||
|
(back-to-indentation) |
||||
|
(current-column))) |
||||
|
(col (current-column))) |
||||
|
(newline-and-indent) |
||||
|
(if (eql indent col) |
||||
|
(indent-line-to indent)))) |
||||
|
|
||||
|
(defun masm--current-line () |
||||
|
"Return the current line as a string." |
||||
|
(save-excursion |
||||
|
(let ((start (line-beginning-position)) |
||||
|
(end (line-end-position))) |
||||
|
(buffer-substring-no-properties start end)))) |
||||
|
|
||||
|
(defun masm--empty-line-p () |
||||
|
"Return non-nil if current line has non-whitespace." |
||||
|
(not (string-match-p "\\S-" (masm--current-line)))) |
||||
|
|
||||
|
(defun masm--line-has-comment-p () |
||||
|
"Return non-nil if current line contain a comment." |
||||
|
(save-excursion |
||||
|
(end-of-line) |
||||
|
(nth 4 (syntax-ppss)))) |
||||
|
|
||||
|
(defun masm--line-has-non-comment-p () |
||||
|
"Return non-nil of the current line has code." |
||||
|
(let* ((line (masm--current-line)) |
||||
|
(match (string-match-p "\\S-" line))) |
||||
|
(when match |
||||
|
(not (eql ?\; (aref line match)))))) |
||||
|
|
||||
|
(defun masm--inside-indentation-p () |
||||
|
"Return non-nil if point is within the indentation." |
||||
|
(save-excursion |
||||
|
(let ((point (point)) |
||||
|
(start (line-beginning-position)) |
||||
|
(end (save-excursion (back-to-indentation) (point)))) |
||||
|
(and (<= start point) (<= point end))))) |
||||
|
|
||||
|
(defun masm-insert-comment () |
||||
|
"Insert a comment if the current line doesn’t contain one." |
||||
|
(let ((comment-insert-comment-function nil)) |
||||
|
(if (or (masm--empty-line-p) (nth 3 (syntax-ppss))) |
||||
|
(progn |
||||
|
(indent-line-to 0) |
||||
|
(insert ";")) |
||||
|
(comment-indent)))) |
||||
|
|
||||
|
(defun masm-comment (&optional arg) |
||||
|
"Begin or edit a comment with context-sensitive placement. |
||||
|
|
||||
|
The right-hand comment gutter is far away from the code, so this |
||||
|
command uses the mark ring to help move back and forth between |
||||
|
code and the comment gutter. |
||||
|
|
||||
|
* If no comment gutter exists yet, mark the current position and |
||||
|
jump to it. |
||||
|
* If already within the gutter, pop the top mark and return to |
||||
|
the code. |
||||
|
* If on a line with no code, just insert a comment character. |
||||
|
* If within the indentation, just insert a comment character. |
||||
|
This is intended prevent interference when the intention is to |
||||
|
comment out the line. |
||||
|
|
||||
|
With a prefix ARG, kill the comment on the current line with |
||||
|
`comment-kill'." |
||||
|
(interactive "p") |
||||
|
(if (not (eql arg 1)) |
||||
|
(comment-kill nil) |
||||
|
(cond |
||||
|
;; Empty line, or inside a string? Insert. |
||||
|
((or (masm--empty-line-p) (nth 3 (syntax-ppss))) |
||||
|
(indent-line-to 0) |
||||
|
(insert ";")) |
||||
|
;; Inside the indentation? Comment out the line. |
||||
|
((masm--inside-indentation-p) |
||||
|
(insert ";")) |
||||
|
;; Currently in a right-side comment? Return. |
||||
|
((and (masm--line-has-comment-p) |
||||
|
(masm--line-has-non-comment-p) |
||||
|
(nth 4 (syntax-ppss))) |
||||
|
(setf (point) (mark)) |
||||
|
(pop-mark)) |
||||
|
;; Line has code? Mark and jump to right-side comment. |
||||
|
((masm--line-has-non-comment-p) |
||||
|
(push-mark) |
||||
|
(comment-indent)) |
||||
|
;; Otherwise insert. |
||||
|
((insert ";"))))) |
||||
|
|
||||
|
(defun masm-compile (_savep command) |
||||
|
"Compile COMMAND in `masm-mode'." |
||||
|
(interactive |
||||
|
(list (if (buffer-modified-p) |
||||
|
(let ((savep (y-or-n-p (format "Buffer %s modified; Save it before compile? " (current-buffer))))) |
||||
|
(if savep |
||||
|
(save-buffer)))) |
||||
|
(if masm--compile-command-used |
||||
|
(read-shell-command "Compile command: " masm--compile-command-used) |
||||
|
(let ((command (if masm--program-win64 |
||||
|
(concat |
||||
|
"ml64 " |
||||
|
(mapconcat (lambda (str) str) masm-win64-compile-args " ") |
||||
|
" " |
||||
|
(file-name-nondirectory buffer-file-name)) |
||||
|
(concat |
||||
|
"ml " |
||||
|
(mapconcat (lambda (str) str) masm-win32-compile-args " ") |
||||
|
" " |
||||
|
(file-name-nondirectory buffer-file-name))))) |
||||
|
(read-shell-command "Compile command: " command))))) |
||||
|
(setq masm--compile-command-used command) |
||||
|
(if masm--program-win64 |
||||
|
(let ((process-environment |
||||
|
(append |
||||
|
(list |
||||
|
(concat "PATH=" masm-win64-executable-path ";" |
||||
|
(getenv "path")) |
||||
|
(concat "INCLUDE=" (mapconcat #'file-name-as-directory masm-win64-include-path ";") |
||||
|
(getenv "include")) |
||||
|
(concat "LIB=" (mapconcat #'file-name-as-directory masm-win64-library-path ";") |
||||
|
(getenv "lib"))) |
||||
|
process-environment))) |
||||
|
(compilation-start |
||||
|
command nil (lambda (_maj-mode) |
||||
|
"*masm x64 compile*"))) |
||||
|
(let ((process-environment |
||||
|
(append |
||||
|
(list |
||||
|
(concat "PATH=" masm-win32-executable-path ";" |
||||
|
(getenv "path")) |
||||
|
(concat "INCLUDE=" (mapconcat #'file-name-as-directory masm-win32-include-path ";") |
||||
|
(getenv "include")) |
||||
|
(concat "LIB=" (mapconcat #'file-name-as-directory masm-win32-library-path ";") |
||||
|
(getenv "lib"))) |
||||
|
process-environment))) |
||||
|
(compilation-start |
||||
|
command nil (lambda (_maj-mode) |
||||
|
"*masm x86 compile*"))))) |
||||
|
|
||||
|
|
||||
|
(defun masm-link (command) |
||||
|
"Compile COMMAND in `masm-mode'." |
||||
|
(interactive |
||||
|
(list (if masm--link-command-used |
||||
|
(read-shell-command "Link command: " masm--link-command-used) |
||||
|
(let ((command (concat |
||||
|
"link " |
||||
|
(mapconcat (lambda (str) str) (if masm--program-win64 masm-win64-link-args masm-win32-link-args) " ") |
||||
|
" " |
||||
|
(file-name-base buffer-file-name) |
||||
|
".obj"))) |
||||
|
(read-shell-command "Link command: " command))))) |
||||
|
(setq masm--link-command-used command) |
||||
|
(if masm--program-win64 |
||||
|
(let ((process-environment |
||||
|
(append |
||||
|
(list |
||||
|
(concat "PATH=" masm-win64-executable-path ";" |
||||
|
(getenv "path")) |
||||
|
(concat "INCLUDE=" (mapconcat #'file-name-as-directory masm-win64-include-path ";") |
||||
|
(getenv "include")) |
||||
|
(concat "LIB=" (mapconcat #'file-name-as-directory masm-win64-library-path ";") |
||||
|
(getenv "lib"))) |
||||
|
process-environment))) |
||||
|
(compilation-start |
||||
|
command nil (lambda (_maj-mode) |
||||
|
"*masm x64 link*"))) |
||||
|
(let ((process-environment |
||||
|
(append |
||||
|
(list |
||||
|
(concat "PATH=" masm-win32-executable-path ";" |
||||
|
(getenv "path")) |
||||
|
(concat "INCLUDE=" (mapconcat #'file-name-as-directory masm-win32-include-path ";") |
||||
|
(getenv "include")) |
||||
|
(concat "LIB=" (mapconcat #'file-name-as-directory masm-win32-library-path ";") |
||||
|
(getenv "lib"))) |
||||
|
process-environment))) |
||||
|
(compilation-start |
||||
|
command nil (lambda (_maj-mode) |
||||
|
"*masm x86 link*"))))) |
||||
|
|
||||
|
(defun masm-build (_savep command) |
||||
|
"Build COMMAND in `masm-mode'." |
||||
|
(interactive |
||||
|
(list (if (buffer-modified-p) |
||||
|
(let ((savep (y-or-n-p (format "Buffer %s modified; Save it before build? " (current-buffer))))) |
||||
|
(if savep |
||||
|
(save-buffer)))) |
||||
|
(if masm--build-command-used |
||||
|
(read-shell-command "Build command: " masm--build-command-used) |
||||
|
(let ((command (concat |
||||
|
masm-build-executable " " |
||||
|
(mapconcat (lambda (str) str) masm-build-args " ")))) |
||||
|
(read-shell-command "Build command: " command))))) |
||||
|
(setq masm--build-command-used command) |
||||
|
(if masm--program-win64 |
||||
|
(let ((process-environment |
||||
|
(append |
||||
|
(list |
||||
|
(concat "PATH=" masm-win64-executable-path ";" |
||||
|
(getenv "path")) |
||||
|
(concat "INCLUDE=" (mapconcat #'file-name-as-directory masm-win64-include-path ";") |
||||
|
(getenv "include")) |
||||
|
(concat "LIB=" (mapconcat #'file-name-as-directory masm-win64-library-path ";") |
||||
|
(getenv "lib"))) |
||||
|
process-environment))) |
||||
|
(compilation-start |
||||
|
command nil (lambda (_maj-mode) |
||||
|
"*masm x64 build*"))) |
||||
|
(let ((process-environment |
||||
|
(append |
||||
|
(list |
||||
|
(concat "PATH=" masm-win32-executable-path ";" |
||||
|
(getenv "path")) |
||||
|
(concat "INCLUDE=" (mapconcat #'file-name-as-directory masm-win32-include-path ";") |
||||
|
(getenv "include")) |
||||
|
(concat "LIB=" (mapconcat #'file-name-as-directory masm-win32-library-path ";") |
||||
|
(getenv "lib"))) |
||||
|
process-environment))) |
||||
|
(compilation-start |
||||
|
command nil (lambda (_maj-mode) |
||||
|
"*masm x86 build*"))))) |
||||
|
|
||||
|
(defun masm-win32 () |
||||
|
"Change to Win32 highlighting." |
||||
|
(interactive) |
||||
|
(setq-local masm--program-win64 nil) |
||||
|
(setq-local font-lock-keywords masm-win32-font-lock-keywords) |
||||
|
(font-lock-flush)) |
||||
|
|
||||
|
(defun masm-win64 () |
||||
|
"Change to Win64 highlighting." |
||||
|
(interactive) |
||||
|
(setq-local masm--program-win64 t) |
||||
|
(setq-local font-lock-keywords masm-win64-font-lock-keywords) |
||||
|
(font-lock-flush)) |
||||
|
|
||||
|
(defun masm-change-program-type () |
||||
|
"Switch program highlighting." |
||||
|
(interactive) |
||||
|
(if masm--program-win64 |
||||
|
(call-interactively #'masm-win32) |
||||
|
(call-interactively #'masm-win64))) |
||||
|
|
||||
|
(defun masm-mode-before () |
||||
|
"Delay this to a hook instead of running it immediately, due the order in which file local variables are processed." |
||||
|
(unless (eql masm--program-win64 masm-program-win64) |
||||
|
(setq masm--program-win64 masm-program-win64) |
||||
|
(if masm-program-win64 |
||||
|
(setq-local font-lock-keywords masm-win64-font-lock-keywords) |
||||
|
(setq-local font-lock-keywords masm-win32-font-lock-keywords)))) |
||||
|
|
||||
|
;;;###autoload |
||||
|
(define-derived-mode masm-mode prog-mode "MASM" |
||||
|
"Major mode for editing MASM assembly programs." |
||||
|
:group 'masm-mode |
||||
|
(setq local-abbrev-table masm-mode-abbrev-table) |
||||
|
(if masm--program-win64 |
||||
|
(setq-local font-lock-defaults '(masm-win64-font-lock-keywords nil :case-fold)) |
||||
|
(setq-local font-lock-defaults '(masm-win32-font-lock-keywords nil :case-fold))) |
||||
|
(setq-local comment-start ";") |
||||
|
(setq-local comment-insert-comment-function #'masm-insert-comment) |
||||
|
(setq-local imenu-generic-expression masm-imenu-generic-expression) |
||||
|
|
||||
|
(add-hook 'after-change-major-mode-hook #'masm-mode-before t t)) |
||||
|
|
||||
|
;;;###autoload |
||||
|
(add-to-list 'auto-mode-alist '("\\.asm\\'" . masm-mode)) |
||||
|
;;;###autoload |
||||
|
(add-to-list 'auto-mode-alist '("\\.inc\\'" . masm-mode)) |
||||
|
|
||||
|
(provide 'masm-mode) |
||||
|
|
||||
|
;; Local Variables: |
||||
|
;; indent-tabs-mode: nil |
||||
|
;; End: |
||||
|
|
||||
|
;;; masm-mode.el ends here |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue