From bdf51cdc47df8e0053718b217ada5a329ea51fe9 Mon Sep 17 00:00:00 2001 From: Raphael Roberts Date: Fri, 14 May 2021 01:11:55 -0500 Subject: [PATCH] Added masm-mode and jinja2 mode --- custom.el | 4 +- elpa/jinja2-mode-0.2/jinja2-mode-autoloads.el | 29 + elpa/jinja2-mode-0.2/jinja2-mode-pkg.el | 2 + elpa/jinja2-mode-0.2/jinja2-mode.el | 330 ++++++++ .../masm-mode-autoloads.el | 31 + elpa/masm-mode-20200308.1450/masm-mode-pkg.el | 2 + elpa/masm-mode-20200308.1450/masm-mode.el | 737 ++++++++++++++++++ 7 files changed, 1134 insertions(+), 1 deletion(-) create mode 100644 elpa/jinja2-mode-0.2/jinja2-mode-autoloads.el create mode 100644 elpa/jinja2-mode-0.2/jinja2-mode-pkg.el create mode 100644 elpa/jinja2-mode-0.2/jinja2-mode.el create mode 100644 elpa/masm-mode-20200308.1450/masm-mode-autoloads.el create mode 100644 elpa/masm-mode-20200308.1450/masm-mode-pkg.el create mode 100644 elpa/masm-mode-20200308.1450/masm-mode.el diff --git a/custom.el b/custom.el index 754a395..116096d 100644 --- a/custom.el +++ b/custom.el @@ -122,7 +122,9 @@ ("shell" . sh) ("bash" . sh))) '(package-selected-packages - '(nginx-mode + '(jinja2-mode + masm-mode + nginx-mode disable-mouse meghanada pip-requirements diff --git a/elpa/jinja2-mode-0.2/jinja2-mode-autoloads.el b/elpa/jinja2-mode-0.2/jinja2-mode-autoloads.el new file mode 100644 index 0000000..149c782 --- /dev/null +++ b/elpa/jinja2-mode-0.2/jinja2-mode-autoloads.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 diff --git a/elpa/jinja2-mode-0.2/jinja2-mode-pkg.el b/elpa/jinja2-mode-0.2/jinja2-mode-pkg.el new file mode 100644 index 0000000..0c89b5c --- /dev/null +++ b/elpa/jinja2-mode-0.2/jinja2-mode-pkg.el @@ -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")) diff --git a/elpa/jinja2-mode-0.2/jinja2-mode.el b/elpa/jinja2-mode-0.2/jinja2-mode.el new file mode 100644 index 0000000..51798c9 --- /dev/null +++ b/elpa/jinja2-mode-0.2/jinja2-mode.el @@ -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 . + +;;; 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]* +;; 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