local packages not in git repos or package managers
This commit is contained in:
parent
c26662171d
commit
607bb9b3b1
451
local-lisp/glsl-mode.el
Normal file
451
local-lisp/glsl-mode.el
Normal file
|
@ -0,0 +1,451 @@
|
|||
;;; glsl-mode.el --- major mode for Open GLSL shader files
|
||||
|
||||
;; Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2011, 2014, 2019 Jim Hourihan
|
||||
;;
|
||||
;; Authors: Xavier.Decoret@imag.fr,
|
||||
;; Jim Hourihan <jimhourihan ~at~ gmail.com> (updated for 4.6, etc)
|
||||
;; Keywords: languages OpenGL GPU SPIR-V Vulkan
|
||||
;; Version: 2.4
|
||||
;; X-URL: https://github.com/jimhourihan/glsl-mode
|
||||
;;
|
||||
;; Original X-URL http://artis.inrialpes.fr/~Xavier.Decoret/resources/glsl-mode/
|
||||
|
||||
;; This file is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; This file 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.
|
||||
|
||||
;; For a full copy of the GNU General Public License
|
||||
;; see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Major mode for editing OpenGLSL grammar files, usually files ending with
|
||||
;; `.vert', `.frag', `.glsl', `.geom'. Is is based on c-mode plus some
|
||||
;; features and pre-specified fontifications.
|
||||
;;
|
||||
;; Modifications from the 1.0 version of glsl-mode (jimhourihan):
|
||||
;; * Removed original optimized regexps for font-lock-keywords and
|
||||
;; replaced with keyword lists for easier maintenance
|
||||
;; * Added customization group and faces
|
||||
;; * Preprocessor faces
|
||||
;; * Updated to GLSL 4.6
|
||||
;; * Separate deprecated symbols
|
||||
;; * Made _ part of a word
|
||||
;; * man page lookup at opengl.org
|
||||
|
||||
;; This package provides the following features:
|
||||
;; * Syntax coloring (via font-lock) for grammar symbols and
|
||||
;; builtin functions and variables for up to GLSL version 4.6
|
||||
;; * Indentation for the current line (TAB) and selected region (C-M-\).
|
||||
;; * Switching between file.vert and file.frag
|
||||
;; with S-lefttab (via ff-find-other-file)
|
||||
;; * interactive function glsl-find-man-page prompts for glsl built
|
||||
;; in function, formats opengl.org url and passes to browse-url
|
||||
|
||||
;;; Installation:
|
||||
|
||||
;; This file requires Emacs-20.3 or higher and package cc-mode.
|
||||
|
||||
;; If glsl-mode is not part of your distribution, put this file into your
|
||||
;; load-path and the following into your ~/.emacs:
|
||||
;; (autoload 'glsl-mode "glsl-mode" nil t)
|
||||
;; (add-to-list 'auto-mode-alist '("\\.glsl\\'" . glsl-mode))
|
||||
;; (add-to-list 'auto-mode-alist '("\\.vert\\'" . glsl-mode))
|
||||
;; (add-to-list 'auto-mode-alist '("\\.frag\\'" . glsl-mode))
|
||||
;; (add-to-list 'auto-mode-alist '("\\.geom\\'" . glsl-mode))
|
||||
|
||||
;; Reference:
|
||||
;; https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.pdf
|
||||
|
||||
;;; Code:
|
||||
|
||||
(provide 'glsl-mode)
|
||||
|
||||
(eval-when-compile ; required and optional libraries
|
||||
(require 'cc-mode)
|
||||
(require 'find-file))
|
||||
|
||||
(require 'align)
|
||||
|
||||
(defgroup glsl nil
|
||||
"OpenGL Shading Language Major Mode"
|
||||
:group 'languages)
|
||||
|
||||
(defconst glsl-language-version "4.6"
|
||||
"GLSL language version number.")
|
||||
|
||||
(defconst gl-version "4.6"
|
||||
"OpenGL major mode version number.")
|
||||
|
||||
(defvar glsl-mode-menu nil "Menu for GLSL mode")
|
||||
|
||||
(defvar glsl-mode-hook nil "GLSL mode hook")
|
||||
|
||||
(defvar glsl-type-face 'glsl-type-face)
|
||||
(defface glsl-type-face
|
||||
'((t (:inherit font-lock-type-face))) "glsl: type face"
|
||||
:group 'glsl)
|
||||
|
||||
(defvar glsl-builtin-face 'glsl-builtin-face)
|
||||
(defface glsl-builtin-face
|
||||
'((t (:inherit font-lock-builtin-face))) "glsl: builtin face"
|
||||
:group 'glsl)
|
||||
|
||||
(defvar glsl-deprecated-builtin-face 'glsl-deprecated-builtin-face)
|
||||
(defface glsl-deprecated-builtin-face
|
||||
'((t (:inherit font-lock-warning-face))) "glsl: deprecated builtin face"
|
||||
:group 'glsl)
|
||||
|
||||
(defvar glsl-qualifier-face 'glsl-qualifier-face)
|
||||
(defface glsl-qualifier-face
|
||||
'((t (:inherit font-lock-keyword-face))) "glsl: qualifier face"
|
||||
:group 'glsl)
|
||||
|
||||
(defvar glsl-keyword-face 'glsl-keyword-face)
|
||||
(defface glsl-keyword-face
|
||||
'((t (:inherit font-lock-keyword-face))) "glsl: keyword face"
|
||||
:group 'glsl)
|
||||
|
||||
(defvar glsl-deprecated-keyword-face 'glsl-deprecated-keyword-face)
|
||||
(defface glsl-deprecated-keyword-face
|
||||
'((t (:inherit font-lock-warning-face))) "glsl: deprecated keyword face"
|
||||
:group 'glsl)
|
||||
|
||||
(defvar glsl-variable-name-face 'glsl-variable-name-face)
|
||||
(defface glsl-variable-name-face
|
||||
'((t (:inherit font-lock-variable-name-face))) "glsl: variable face"
|
||||
:group 'glsl)
|
||||
|
||||
(defvar glsl-deprecated-variable-name-face 'glsl-deprecated-variable-name-face)
|
||||
(defface glsl-deprecated-variable-name-face
|
||||
'((t (:inherit font-lock-warning-face))) "glsl: deprecated variable face"
|
||||
:group 'glsl)
|
||||
|
||||
(defvar glsl-reserved-keyword-face 'glsl-reserved-keyword-face)
|
||||
(defface glsl-reserved-keyword-face
|
||||
'((t (:inherit glsl-keyword-face))) "glsl: reserved keyword face"
|
||||
:group 'glsl)
|
||||
|
||||
(defvar glsl-preprocessor-face 'glsl-preprocessor-face)
|
||||
(defface glsl-preprocessor-face
|
||||
'((t (:inherit font-lock-preprocessor-face))) "glsl: preprocessor face"
|
||||
:group 'glsl)
|
||||
|
||||
(defcustom glsl-additional-types nil
|
||||
"List of additional keywords to be considered types. These are
|
||||
added to the `glsl-type-list' and are fontified using the
|
||||
`glsl-type-face'. Examples of existing types include \"float\", \"vec4\",
|
||||
and \"int\"."
|
||||
:type '(repeat (string :tag "Type Name"))
|
||||
:group 'glsl)
|
||||
|
||||
(defcustom glsl-additional-qualifiers nil
|
||||
"List of additional keywords to be considered qualifiers. These
|
||||
are added to the `glsl-qualifier-list' and are fontified using
|
||||
the `glsl-qualifier-face'. Examples of existing qualifiers
|
||||
include \"const\", \"in\", and \"out\"."
|
||||
:type '(repeat (string :tag "Qualifier Name"))
|
||||
:group 'glsl)
|
||||
|
||||
(defcustom glsl-additional-keywords nil
|
||||
"List of additional GLSL keywords. These are added to the
|
||||
`glsl-keyword-list' and are fontified using the
|
||||
`glsl-keyword-face'. Example existing keywords include \"while\",
|
||||
\"if\", and \"return\"."
|
||||
:type '(repeat (string :tag "Keyword"))
|
||||
:group 'glsl)
|
||||
|
||||
(defcustom glsl-additional-built-ins nil
|
||||
"List of additional functions to be considered built-in. These
|
||||
are added to the `glsl-builtin-list' and are fontified using the
|
||||
`glsl-builtin-face'."
|
||||
:type '(repeat (string :tag "Keyword"))
|
||||
:group 'glsl)
|
||||
|
||||
(defvar glsl-mode-hook nil)
|
||||
|
||||
(defvar glsl-mode-map
|
||||
(let ((glsl-mode-map (make-sparse-keymap)))
|
||||
(define-key glsl-mode-map [S-iso-lefttab] 'ff-find-other-file)
|
||||
glsl-mode-map)
|
||||
"Keymap for GLSL major mode.")
|
||||
|
||||
(defcustom glsl-browse-url-function 'browse-url
|
||||
"Function used to display GLSL man pages. E.g. browse-url, eww, w3m, etc"
|
||||
:type 'function
|
||||
:group 'glsl)
|
||||
|
||||
(defcustom glsl-man-pages-base-url "http://www.opengl.org/sdk/docs/man/html/"
|
||||
"Location of GL man pages."
|
||||
:type 'string
|
||||
:group 'glsl)
|
||||
|
||||
;;;###autoload
|
||||
(progn
|
||||
(add-to-list 'auto-mode-alist '("\\.vert\\'" . glsl-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.frag\\'" . glsl-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.geom\\'" . glsl-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.glsl\\'" . glsl-mode)))
|
||||
|
||||
(eval-and-compile
|
||||
;; These vars are useful for completion so keep them around after
|
||||
;; compile as well. The goal here is to have the byte compiled code
|
||||
;; have optimized regexps so its not done at eval time.
|
||||
(defvar glsl-type-list
|
||||
'("float" "double" "int" "void" "bool" "true" "false" "mat2" "mat3"
|
||||
"mat4" "dmat2" "dmat3" "dmat4" "mat2x2" "mat2x3" "mat2x4" "dmat2x2"
|
||||
"dmat2x3" "dmat2x4" "mat3x2" "mat3x3" "mat3x4" "dmat3x2" "dmat3x3"
|
||||
"dmat3x4" "mat4x2" "mat4x3" "mat4x4" "dmat4x2" "dmat4x3" "dmat4x4" "vec2"
|
||||
"vec3" "vec4" "ivec2" "ivec3" "ivec4" "bvec2" "bvec3" "bvec4" "dvec2"
|
||||
"dvec3" "dvec4" "uint" "uvec2" "uvec3" "uvec4" "atomic_uint"
|
||||
"sampler1D" "sampler2D" "sampler3D" "samplerCube" "sampler1DShadow"
|
||||
"sampler2DShadow" "samplerCubeShadow" "sampler1DArray" "sampler2DArray"
|
||||
"sampler1DArrayShadow" "sampler2DArrayShadow" "isampler1D" "isampler2D"
|
||||
"isampler3D" "isamplerCube" "isampler1DArray" "isampler2DArray"
|
||||
"usampler1D" "usampler2D" "usampler3D" "usamplerCube" "usampler1DArray"
|
||||
"usampler2DArray" "sampler2DRect" "sampler2DRectShadow" "isampler2DRect"
|
||||
"usampler2DRect" "samplerBuffer" "isamplerBuffer" "usamplerBuffer"
|
||||
"sampler2DMS" "isampler2DMS" "usampler2DMS" "sampler2DMSArray"
|
||||
"isampler2DMSArray" "usampler2DMSArray" "samplerCubeArray"
|
||||
"samplerCubeArrayShadow" "isamplerCubeArray" "usamplerCubeArray"
|
||||
"image1D" "iimage1D" "uimage1D" "image2D" "iimage2D" "uimage2D" "image3D"
|
||||
"iimage3D" "uimage3D" "image2DRect" "iimage2DRect" "uimage2DRect"
|
||||
"imageCube" "iimageCube" "uimageCube" "imageBuffer" "iimageBuffer"
|
||||
"uimageBuffer" "image1DArray" "iimage1DArray" "uimage1DArray"
|
||||
"image2DArray" "iimage2DArray" "uimage2DArray" "imageCubeArray"
|
||||
"iimageCubeArray" "uimageCubeArray" "image2DMS" "iimage2DMS" "uimage2DMS"
|
||||
"image2DMSArray" "iimage2DMSArray" "uimage2DMSArray"))
|
||||
|
||||
(defvar glsl-qualifier-list
|
||||
'("attribute" "const" "uniform" "varying" "buffer" "shared" "coherent"
|
||||
"volatile" "restrict" "readonly" "writeonly" "layout" "centroid" "flat"
|
||||
"smooth" "noperspective" "patch" "sample" "in" "out" "inout"
|
||||
"invariant" "lowp" "mediump" "highp"))
|
||||
|
||||
(defvar glsl-keyword-list
|
||||
'("break" "continue" "do" "for" "while" "if" "else" "subroutine"
|
||||
"discard" "return" "precision" "struct" "switch" "default" "case"))
|
||||
|
||||
(defvar glsl-reserved-list
|
||||
'("input" "output" "asm" "class" "union" "enum" "typedef" "template" "this"
|
||||
"packed" "resource" "goto" "inline" "noinline"
|
||||
"common" "partition" "active" "long" "short" "half" "fixed" "unsigned" "superp"
|
||||
"public" "static" "extern" "external" "interface"
|
||||
"hvec2" "hvec3" "hvec4" "fvec2" "fvec3" "fvec4"
|
||||
"filter" "sizeof" "cast" "namespace" "using"
|
||||
"sampler3DRect"))
|
||||
|
||||
(defvar glsl-deprecated-qualifier-list
|
||||
'("varying" "attribute")) ; centroid is deprecated when used with varying
|
||||
|
||||
(defvar glsl-builtin-list
|
||||
'("abs" "acos" "acosh" "all" "any" "anyInvocation" "allInvocations"
|
||||
"allInvocationsEqual" "asin" "asinh" "atan" "atanh"
|
||||
"atomicAdd" "atomicMin" "atomicMax" "atomicAnd" "atomicOr"
|
||||
"atomicXor" "atomicExchange" "atomicCompSwap"
|
||||
"atomicCounter" "atomicCounterDecrement" "atomicCounterIncrement"
|
||||
"atomicCounterAdd" "atomicCounterSubtract" "atomicCounterMin"
|
||||
"atomicCounterMax" "atomicCounterAnd" "atomicCounterOr"
|
||||
"atomicCounterXor" "atomicCounterExchange" "atomicCounterCompSwap"
|
||||
"barrier" "bitCount" "bitfieldExtract" "bitfieldInsert" "bitfieldReverse"
|
||||
"ceil" "clamp" "cos" "cosh" "cross" "degrees" "determinant" "dFdx" "dFdy"
|
||||
"dFdyFine" "dFdxFine" "dFdyCoarse" "dFdxCoarse" "distance" "dot"
|
||||
"fwidthFine" "fwidthCoarse"
|
||||
"EmitStreamVertex" "EmitStreamPrimitive" "EmitVertex" "EndPrimitive"
|
||||
"EndStreamPrimitive" "equal" "exp" "exp2" "faceforward" "findLSB"
|
||||
"findMSB" "floatBitsToInt" "floatBitsToUint" "floor" "fma" "fract"
|
||||
"frexp" "fwidth" "greaterThan" "greaterThanEqual" "groupMemoryBarrier"
|
||||
"imageAtomicAdd" "imageAtomicAnd" "imageAtomicCompSwap" "imageAtomicExchange"
|
||||
"imageAtomicMax" "imageAtomicMin" "imageAtomicOr" "imageAtomicXor"
|
||||
"imageLoad" "imageSize" "imageStore" "imulExtended" "intBitsToFloat"
|
||||
"imageSamples" "interpolateAtCentroid" "interpolateAtOffset" "interpolateAtSample"
|
||||
"inverse" "inversesqrt" "isinf" "isnan" "ldexp" "length" "lessThan"
|
||||
"lessThanEqual" "log" "log2" "matrixCompMult" "max" "memoryBarrier"
|
||||
"memoryBarrierAtomicCounter" "memoryBarrierBuffer"
|
||||
"memoryBarrierShared" "memoryBarrierImage" "memoryBarrier"
|
||||
"min" "mix" "mod" "modf" "normalize" "not" "notEqual" "outerProduct"
|
||||
"packDouble2x32" "packHalf2x16" "packSnorm2x16" "packSnorm4x8"
|
||||
"packUnorm2x16" "packUnorm4x8" "pow" "radians" "reflect" "refract"
|
||||
"round" "roundEven" "sign" "sin" "sinh" "smoothstep" "sqrt" "step" "tan"
|
||||
"tanh" "texelFetch" "texelFetchOffset" "texture" "textureGather"
|
||||
"textureGatherOffset" "textureGatherOffsets" "textureGrad" "textureSamples"
|
||||
"textureGradOffset" "textureLod" "textureLodOffset" "textureOffset"
|
||||
"textureProj" "textureProjGrad" "textureProjGradOffset" "textureProjLod"
|
||||
"textureProjLodOffset" "textureProjOffset" "textureQueryLevels" "textureQueryLod"
|
||||
"textureSize" "transpose" "trunc" "uaddCarry" "uintBitsToFloat"
|
||||
"umulExtended" "unpackDouble2x32" "unpackHalf2x16" "unpackSnorm2x16"
|
||||
"unpackSnorm4x8" "unpackUnorm2x16" "unpackUnorm4x8" "usubBorrow"))
|
||||
|
||||
(defvar glsl-deprecated-builtin-list
|
||||
'("noise1" "noise2" "noise3" "noise4"
|
||||
"texture1D" "texture1DProj" "texture1DLod" "texture1DProjLod"
|
||||
"texture2D" "texture2DProj" "texture2DLod" "texture2DProjLod"
|
||||
"texture2DRect" "texture2DRectProj"
|
||||
"texture3D" "texture3DProj" "texture3DLod" "texture3DProjLod"
|
||||
"shadow1D" "shadow1DProj" "shadow1DLod" "shadow1DProjLod"
|
||||
"shadow2D" "shadow2DProj" "shadow2DLod" "shadow2DProjLod"
|
||||
"textureCube" "textureCubeLod"))
|
||||
|
||||
(defvar glsl-deprecated-variables-list
|
||||
'("gl_FragColor" "gl_FragData" "gl_MaxVarying" "gl_MaxVaryingFloats"
|
||||
"gl_MaxVaryingComponents"))
|
||||
|
||||
(defvar glsl-preprocessor-directive-list
|
||||
'("define" "undef" "if" "ifdef" "ifndef" "else" "elif" "endif"
|
||||
"error" "pragma" "extension" "version" "line"))
|
||||
|
||||
(defvar glsl-preprocessor-expr-list
|
||||
'("defined" "##"))
|
||||
|
||||
(defvar glsl-preprocessor-builtin-list
|
||||
'("__LINE__" "__FILE__" "__VERSION__"))
|
||||
|
||||
) ; eval-and-compile
|
||||
|
||||
(eval-and-compile
|
||||
(defun glsl-ppre (re)
|
||||
(format "\\<\\(%s\\)\\>" (regexp-opt re))))
|
||||
|
||||
(defvar glsl-font-lock-keywords-1
|
||||
(append
|
||||
(list
|
||||
(cons (eval-when-compile
|
||||
(format "^[ \t]*#[ \t]*\\<\\(%s\\)\\>"
|
||||
(regexp-opt glsl-preprocessor-directive-list)))
|
||||
glsl-preprocessor-face)
|
||||
(cons (eval-when-compile
|
||||
(glsl-ppre glsl-type-list))
|
||||
glsl-type-face)
|
||||
(cons (eval-when-compile
|
||||
(glsl-ppre glsl-deprecated-qualifier-list))
|
||||
glsl-deprecated-keyword-face)
|
||||
(cons (eval-when-compile
|
||||
(glsl-ppre glsl-reserved-list))
|
||||
glsl-reserved-keyword-face)
|
||||
(cons (eval-when-compile
|
||||
(glsl-ppre glsl-qualifier-list))
|
||||
glsl-qualifier-face)
|
||||
(cons (eval-when-compile
|
||||
(glsl-ppre glsl-keyword-list))
|
||||
glsl-keyword-face)
|
||||
(cons (eval-when-compile
|
||||
(glsl-ppre glsl-preprocessor-builtin-list))
|
||||
glsl-keyword-face)
|
||||
(cons (eval-when-compile
|
||||
(glsl-ppre glsl-deprecated-builtin-list))
|
||||
glsl-deprecated-builtin-face)
|
||||
(cons (eval-when-compile
|
||||
(glsl-ppre glsl-builtin-list))
|
||||
glsl-builtin-face)
|
||||
(cons (eval-when-compile
|
||||
(glsl-ppre glsl-deprecated-variables-list))
|
||||
glsl-deprecated-variable-name-face)
|
||||
(cons "gl_[A-Z][A-Za-z_]+" glsl-variable-name-face)
|
||||
)
|
||||
|
||||
(when glsl-additional-types
|
||||
(list
|
||||
(cons (glsl-ppre glsl-additional-types) glsl-type-face)))
|
||||
(when glsl-additional-keywords
|
||||
(list
|
||||
(cons (glsl-ppre glsl-additional-keywords) glsl-keyword-face)))
|
||||
(when glsl-additional-qualifiers
|
||||
(list
|
||||
(cons (glsl-ppre glsl-additional-qualifiers) glsl-qualifier-face)))
|
||||
(when glsl-additional-built-ins
|
||||
(list
|
||||
(cons (glsl-ppre glsl-additional-built-ins) glsl-builtin-face)))
|
||||
)
|
||||
"Highlighting expressions for GLSL mode.")
|
||||
|
||||
|
||||
(defvar glsl-font-lock-keywords glsl-font-lock-keywords-1
|
||||
"Default highlighting expressions for GLSL mode.")
|
||||
|
||||
(defvar glsl-mode-syntax-table
|
||||
(let ((glsl-mode-syntax-table (make-syntax-table)))
|
||||
(modify-syntax-entry ?/ ". 124b" glsl-mode-syntax-table)
|
||||
(modify-syntax-entry ?* ". 23" glsl-mode-syntax-table)
|
||||
(modify-syntax-entry ?\n "> b" glsl-mode-syntax-table)
|
||||
(modify-syntax-entry ?_ "w" glsl-mode-syntax-table)
|
||||
glsl-mode-syntax-table)
|
||||
"Syntax table for glsl-mode.")
|
||||
|
||||
(defvar glsl-other-file-alist
|
||||
'(("\\.frag$" (".vert"))
|
||||
("\\.vert$" (".frag"))
|
||||
)
|
||||
"Alist of extensions to find given the current file's extension.")
|
||||
|
||||
(defun glsl-man-completion-list ()
|
||||
"Return list of all GLSL keywords."
|
||||
(append glsl-builtin-list glsl-deprecated-builtin-list))
|
||||
|
||||
(defun glsl-find-man-page (thing)
|
||||
"Collects and displays manual entry for GLSL built-in function THING."
|
||||
(interactive
|
||||
(let ((word (current-word nil t)))
|
||||
(list
|
||||
(completing-read
|
||||
(concat "OpenGL.org GLSL man page: (" word "): ")
|
||||
(glsl-man-completion-list)
|
||||
nil nil nil nil word))))
|
||||
(save-excursion
|
||||
(apply glsl-browse-url-function
|
||||
(list (concat glsl-man-pages-base-url thing ".xhtml")))))
|
||||
|
||||
(easy-menu-define glsl-menu glsl-mode-map
|
||||
"GLSL Menu"
|
||||
`("GLSL"
|
||||
["Comment Out Region" comment-region
|
||||
(c-fn-region-is-active-p)]
|
||||
["Uncomment Region" (comment-region (region-beginning)
|
||||
(region-end) '(4))
|
||||
(c-fn-region-is-active-p)]
|
||||
["Indent Expression" c-indent-exp
|
||||
(memq (char-after) '(?\( ?\[ ?\{))]
|
||||
["Indent Line or Region" c-indent-line-or-region t]
|
||||
["Fill Comment Paragraph" c-fill-paragraph t]
|
||||
"----"
|
||||
["Backward Statement" c-beginning-of-statement t]
|
||||
["Forward Statement" c-end-of-statement t]
|
||||
"----"
|
||||
["Up Conditional" c-up-conditional t]
|
||||
["Backward Conditional" c-backward-conditional t]
|
||||
["Forward Conditional" c-forward-conditional t]
|
||||
"----"
|
||||
["Backslashify" c-backslash-region (c-fn-region-is-active-p)]
|
||||
"----"
|
||||
["Find GLSL Man Page" glsl-find-man-page t]
|
||||
))
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode glsl-mode prog-mode "GLSL"
|
||||
"Major mode for editing GLSL shader files."
|
||||
(c-initialize-cc-mode t)
|
||||
(setq abbrev-mode t)
|
||||
(c-init-language-vars-for 'c-mode)
|
||||
(c-common-init 'c-mode)
|
||||
(cc-imenu-init cc-imenu-c++-generic-expression)
|
||||
(set (make-local-variable 'font-lock-defaults) '(glsl-font-lock-keywords))
|
||||
(set (make-local-variable 'ff-other-file-alist) 'glsl-other-file-alist)
|
||||
(set (make-local-variable 'comment-start) "// ")
|
||||
(set (make-local-variable 'comment-end) "")
|
||||
(set (make-local-variable 'comment-padding) "")
|
||||
(easy-menu-add glsl-menu)
|
||||
(add-to-list 'align-c++-modes 'glsl-mode)
|
||||
(c-run-mode-hooks 'c-mode-common-hook)
|
||||
(run-mode-hooks 'glsl-mode-hook)
|
||||
:after-hook (progn (c-make-noise-macro-regexps)
|
||||
(c-make-macro-with-semi-re)
|
||||
(c-update-modeline))
|
||||
)
|
||||
|
||||
;;; glsl-mode.el ends here
|
581
local-lisp/hlsl-mode.el
Normal file
581
local-lisp/hlsl-mode.el
Normal file
|
@ -0,0 +1,581 @@
|
|||
;;; hlsl-mode.el --- Major mode for HLSL shader files -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2011, 2014, 2019 Jim Hourihan
|
||||
;; Copyright (C) 2022 Jcaw
|
||||
;;
|
||||
;; Authors: Xavier.Decoret@imag.fr,
|
||||
;; Jim Hourihan <jimhourihan ~at~ gmail.com>
|
||||
;; GitHub user "jcaw"
|
||||
;; Keywords: languages HLSL GPU shaders
|
||||
;; Version: 1.1.3
|
||||
;; URL: https://github.com/jcaw/hlsl-mode
|
||||
;; Package-Requires: ((emacs "24.4"))
|
||||
;;
|
||||
;; Original URL http://artis.inrialpes.fr/~Xavier.Decoret/resources/glsl-mode/
|
||||
|
||||
;; This file is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; This file 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.
|
||||
|
||||
;; For a full copy of the GNU General Public License
|
||||
;; see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Major mode for editing OpenHLSL grammar files, usually files ending with
|
||||
;; `.fx[hc]', `.hlsl', `.shader', `.compute'. It is based on c-mode plus some
|
||||
;; features and pre-specified fontifications.
|
||||
;;
|
||||
;; It is modified from `glsl-mode', maintained at the time of writing by Jim
|
||||
;; Hourihan: https://github.com/jimhourihan/glsl-mode
|
||||
|
||||
;; This package provides the following features:
|
||||
;; * Syntax coloring (via font-lock) for grammar symbols and
|
||||
;; builtin functions and variables for HLSL (up to the version specified
|
||||
;; by `hlsl-shader-model-version')
|
||||
;; * Indentation for the current line (TAB) and selected region (C-M-\).
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'cc-mode)
|
||||
|
||||
(eval-when-compile ; required and optional libraries
|
||||
(require 'find-file)
|
||||
(require 'subr-x))
|
||||
|
||||
(require 'align)
|
||||
|
||||
(defgroup hlsl nil
|
||||
"Microsoft HLSL Major Mode."
|
||||
:group 'languages)
|
||||
|
||||
(defconst hlsl-shader-model-version "6.0"
|
||||
"Shader model version number.")
|
||||
|
||||
(defconst hlsl-direct3d-version "12"
|
||||
"Direct3D language version number.")
|
||||
|
||||
(defvar hlsl-type-face 'hlsl-type-face)
|
||||
(defface hlsl-type-face
|
||||
'((t (:inherit font-lock-type-face))) "HLSL: type face."
|
||||
:group 'hlsl)
|
||||
|
||||
(defvar hlsl-builtin-face 'hlsl-builtin-face)
|
||||
(defface hlsl-builtin-face
|
||||
'((t (:inherit font-lock-builtin-face))) "HLSL: builtin face."
|
||||
:group 'hlsl)
|
||||
|
||||
(defvar hlsl-deprecated-builtin-face 'hlsl-deprecated-builtin-face)
|
||||
(defface hlsl-deprecated-builtin-face
|
||||
'((t (:inherit font-lock-warning-face))) "HLSL: deprecated builtin face."
|
||||
:group 'hlsl)
|
||||
|
||||
(defvar hlsl-qualifier-face 'hlsl-qualifier-face)
|
||||
(defface hlsl-qualifier-face
|
||||
'((t (:inherit font-lock-keyword-face))) "HLSL: qualifier face."
|
||||
:group 'hlsl)
|
||||
|
||||
(defvar hlsl-keyword-face 'hlsl-keyword-face)
|
||||
(defface hlsl-keyword-face
|
||||
'((t (:inherit font-lock-keyword-face))) "HLSL: keyword face."
|
||||
:group 'hlsl)
|
||||
|
||||
(defvar hlsl-deprecated-keyword-face 'hlsl-deprecated-keyword-face)
|
||||
(defface hlsl-deprecated-keyword-face
|
||||
'((t (:inherit font-lock-warning-face))) "HLSL: deprecated keyword face."
|
||||
:group 'hlsl)
|
||||
|
||||
(defvar hlsl-variable-name-face 'hlsl-variable-name-face)
|
||||
(defface hlsl-variable-name-face
|
||||
'((t (:inherit font-lock-variable-name-face))) "HLSL: variable face."
|
||||
:group 'hlsl)
|
||||
|
||||
(defvar hlsl-deprecated-variable-name-face 'hlsl-deprecated-variable-name-face)
|
||||
(defface hlsl-deprecated-variable-name-face
|
||||
'((t (:inherit font-lock-warning-face))) "HLSL: deprecated variable face."
|
||||
:group 'hlsl)
|
||||
|
||||
(defvar hlsl-reserved-keyword-face 'hlsl-reserved-keyword-face)
|
||||
(defface hlsl-reserved-keyword-face
|
||||
'((t (:inherit hlsl-keyword-face))) "HLSL: reserved keyword face."
|
||||
:group 'hlsl)
|
||||
|
||||
(defvar hlsl-preprocessor-face 'hlsl-preprocessor-face)
|
||||
(defface hlsl-preprocessor-face
|
||||
'((t (:inherit font-lock-preprocessor-face))) "HLSL: preprocessor face."
|
||||
:group 'hlsl)
|
||||
|
||||
(defcustom hlsl-additional-types nil
|
||||
"List of additional keywords to be considered types.
|
||||
|
||||
These are added to the `hlsl-type-list' and are fontified using
|
||||
the `hlsl-type-face'. Examples of existing types include
|
||||
\"float\", \"float4\", and \"RWStructuredBuffer\"."
|
||||
:type '(repeat (string :tag "Type Name"))
|
||||
:group 'hlsl)
|
||||
|
||||
(defcustom hlsl-additional-qualifiers nil
|
||||
"List of additional keywords to be considered qualifiers.
|
||||
|
||||
These are added to the `hlsl-qualifier-list' and are fontified
|
||||
using the `hlsl-qualifier-face'. Examples of existing qualifiers
|
||||
include \"const\", \"in\", and \"out\"."
|
||||
:type '(repeat (string :tag "Qualifier Name"))
|
||||
:group 'hlsl)
|
||||
|
||||
(defcustom hlsl-additional-keywords nil
|
||||
"List of additional HLSL keywords.
|
||||
|
||||
These are added to the `hlsl-keyword-list' and are fontified
|
||||
using the `hlsl-keyword-face'. Example existing keywords include
|
||||
\"while\", \"if\", and \"return\"."
|
||||
:type '(repeat (string :tag "Keyword"))
|
||||
:group 'hlsl)
|
||||
|
||||
(defcustom hlsl-additional-built-ins nil
|
||||
"List of additional functions to be considered built-in.
|
||||
|
||||
These are added to the `hlsl-builtin-list' and are fontified
|
||||
using the `hlsl-builtin-face'."
|
||||
:type '(repeat (string :tag "Keyword"))
|
||||
:group 'hlsl)
|
||||
|
||||
(defvar hlsl-mode-map
|
||||
(let ((hlsl-mode-map (make-sparse-keymap)))
|
||||
(define-key hlsl-mode-map [S-iso-lefttab] 'ff-find-other-file)
|
||||
hlsl-mode-map)
|
||||
"Keymap for HLSL major mode.")
|
||||
|
||||
;; (defcustom hlsl-browse-url-function 'browse-url
|
||||
;; "Function used to display HLSL man pages.
|
||||
|
||||
;; E.g. `browse-url', `eww', `w3m', etc."
|
||||
;; :type 'function
|
||||
;; :group 'hlsl)
|
||||
|
||||
;; (defcustom hlsl-man-pages-base-url "http://www.opengl.org/sdk/docs/man/html/"
|
||||
;; "Location of GL man pages."
|
||||
;; :type 'string
|
||||
;; :group 'hlsl)
|
||||
|
||||
;;;###autoload
|
||||
(progn
|
||||
(add-to-list 'auto-mode-alist '("\\.fx\\'" . hlsl-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.fxc\\'" . hlsl-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.fxh\\'" . hlsl-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.hlsl\\'" . hlsl-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.cg\\'" . hlsl-mode))
|
||||
;; Unity shader format
|
||||
(add-to-list 'auto-mode-alist '("\\.shader\\'" . hlsl-mode))
|
||||
;; Unity shader include suffix
|
||||
(add-to-list 'auto-mode-alist '("\\.cginc\\'" . hlsl-mode))
|
||||
;; Unity compute shaders are HLSL
|
||||
(add-to-list 'auto-mode-alist '("\\.compute\\'" . hlsl-mode))
|
||||
)
|
||||
|
||||
(eval-and-compile
|
||||
(defun hlsl--mixed-case (strings)
|
||||
"Get original `strings', plus lowercase and uppercase versions.
|
||||
|
||||
For example:
|
||||
|
||||
(hlsl--mixed-case '(\"TexCoord\" \"POSITION\"))
|
||||
-> '(\"TexCoord\" \"TEXCOORD\" \"Texcoord\"
|
||||
\"POSITION\" \"Position\")
|
||||
|
||||
Returns a flattened list of all the resultant strings (without
|
||||
duplicates)."
|
||||
(apply #'append (mapcar (lambda (s)
|
||||
(if (= 0 (length s))
|
||||
s
|
||||
(delete-dups
|
||||
(list s (upcase s)
|
||||
(concat (upcase (substring s 0 1))
|
||||
(downcase (substring s 1)))))))
|
||||
strings)))
|
||||
|
||||
;; These vars are useful for completion so keep them around after compile as
|
||||
;; well. The goal here is to have the byte compiled code have optimized
|
||||
;; regexps so its not done at eval time.
|
||||
(defvar hlsl-type-list
|
||||
`(
|
||||
;; TODO: Maybe make `void' a keyword?
|
||||
"matrix" "void"
|
||||
|
||||
;; Numeric scalars, plus all the vector and matrix expressions for each. E.g:
|
||||
;; float, float1, float1x2, uint2, bool3x4, etc.
|
||||
,@(mapcar (lambda (type)
|
||||
(concat type "\\([1234]?\\|\\([1234]x[1234]\\)?\\)"))
|
||||
'("bool" "int" "uint" "float"
|
||||
"min16float" "min10float" "min16int" "min12int" "min16uint"))
|
||||
;; These numeric scalars don't expand to vectors/matrices
|
||||
"half" "dword" "double"
|
||||
|
||||
;; Texture samplers
|
||||
"sampler" "sampler1D" "sampler2D" "sampler3D" "samplerCUBE" "sampler_state"
|
||||
"SamplerState" "SampleComparisonState"
|
||||
|
||||
;; Buffer-esque types
|
||||
"AppendStructuredBuffer" "Buffer" "ByteAddressBuffer" "ConsumeStructuredBuffer"
|
||||
"InputPatch" "OutputPatch" "RWBuffer" "RWByteAddressBuffer" "RWStructuredBuffer"
|
||||
"RWTexture1D" "RWTexture1DArray" "RWTexture2D" "RWTexture2DArray" "RWTexture3D"
|
||||
"StructuredBuffer" "Texture1D" "Texture1DArray" "Texture2D" "Texture2DArray"
|
||||
"Texture2DMS" "Texture2DMSArray" "Texture3D" "TextureCube" "TextureCubeArray"
|
||||
;; Rasterizer Order Views
|
||||
"RasterizerOrderedBuffer" "RasterizerOrderedByteAddressBuffer" "RasterizerOrderedStructuredBuffer"
|
||||
"RasterizerOrderedTexture1D" "RasterizerOrderedTexture1DArray" "RasterizerOrderedTexture2D"
|
||||
"RasterizerOrderedTexture2DArray" "RasterizerOrderedTexture3D"
|
||||
|
||||
;; Misc
|
||||
;;
|
||||
;; TODO: Double check Object2 usage
|
||||
"Object2"
|
||||
|
||||
;; Geometry shader stream outputs
|
||||
"PointStream" "LineStream" "TriangleStream"))
|
||||
|
||||
(defvar hlsl-qualifier-list
|
||||
'(
|
||||
;; Misc
|
||||
"snorm" "unorm" "in" "inline" "inout" "precise" "extern" "nointerpolation"
|
||||
"precise" "shared" "groupshared" "static" "uniform" "volatile" "const"
|
||||
"row_major" "column_major" "export" "linear" "centroid" "noperspective"
|
||||
"sample" "globallycoherent" "out"
|
||||
|
||||
;; Geom shader primitives
|
||||
"point" "line" "triangle" "lineadj" "triangledj"
|
||||
|
||||
"pixelfragment" "vertexfragment"))
|
||||
|
||||
(defvar hlsl-keyword-list
|
||||
`(
|
||||
;; Special types
|
||||
"true" "false" "NULL" "null"
|
||||
|
||||
;; Misc
|
||||
"compile_fragment" "class" "interface" "break" "continue" "do" "default"
|
||||
"discard" "for" "while" "if" "else" "return" "struct" "switch" "case"
|
||||
"register" "packoffset" "cbuffer" "tbuffer" "fxgroup" "pass"
|
||||
"technique[1-9]?[1-9]?"
|
||||
"SetVertexShader" "SetGeometryShader" "SetPixelSader"
|
||||
|
||||
;; Attributes
|
||||
"maxvertexcount" "domain" "earlydepthstencil" "instance" "maxtessfactor"
|
||||
"numthreads" "outputcontrolpoints" "outputtopology" "partitioning"
|
||||
"patchconstantfunc"
|
||||
;; domain types
|
||||
;; TODO: move these into a dedicated domain matcher?
|
||||
;; TODO: `point' and `line' at least are duplicated here and in qualifiers
|
||||
;; TODO: Take another look at these, they should probably be handled differently
|
||||
"tri" "quad" "isoline" "point" "line" "triangle_cw" "triangle_ccw"
|
||||
"integer" "fractional_even" "fractional_odd" "pow2"
|
||||
;; Branching attributes
|
||||
"unroll" "loop" "fastopt" "allow_uav_condition" "branch" "flatten"
|
||||
"forcecase" "call"
|
||||
|
||||
;; Shader profiles
|
||||
;;
|
||||
;; Shader Model 1
|
||||
"vs_1_1"
|
||||
;; Shader Model 2
|
||||
"ps_2_0" "ps_2_x" "vs_2_0" "vs_2_x" "ps_4_0_level_9_0" "ps_4_0_level_9_1"
|
||||
"ps_4_0_level_9_3" "vs_4_0_level_9_0" "vs_4_0_level_9_1" "vs_4_0_level_9_3"
|
||||
"lib_4_0_level_9_1" "lib_4_0_level_9_"
|
||||
;; Shader Model 3
|
||||
"ps_3_0" "vs_3_0"
|
||||
;; Shader Model 4
|
||||
"cs_4_0" "gs_4_0" "ps_4_0" "vs_4_0" "cs_4_1" "gs_4_1" "ps_4_1" "vs_4_1"
|
||||
"lib_4_0" "lib_4_"
|
||||
;; Shader Model 5
|
||||
"cs_5_0" "ds_5_0" "gs_5_0" "hs_5_0" "ps_5_0" "vs_5_0" "lib_5_"
|
||||
;; Shader Model 6
|
||||
"cs_6_0" "ds_6_0" "gs_6_0" "hs_6_0" "ps_6_0" "vs_6_0" "lib_6_"
|
||||
;; FX Profiles
|
||||
"fx_1_0" "fx_2_0" "fx_4_0" "fx_4_1" "fx_5_0"
|
||||
|
||||
;; Semantics
|
||||
;;
|
||||
;; All semantics are case-insensitive, so allow uppercase, lowercase and
|
||||
;; capitalised versions. Other/weird mixtures of case will not be
|
||||
;; highlighted for now, even though the HLSL spec allows them.
|
||||
,@(hlsl--mixed-case
|
||||
'("Binormal[0-9]?" "BlendIndices[0-9]?" "BlendWeight[0-9]?" "Color[0-9]?"
|
||||
"Normal[0-9]?" "Position[0-9]?" "PositionT" "PSize[0-9]?" "Tangent[0-9]?"
|
||||
"TexCoord[0-9]" "Fog" "TessFactor[0-9]?" "VFace" "VPos" "Depth[0-9]?"
|
||||
"SV_ClipDistance[0-9]?" "SV_CullDistance[0-9]?" "SV_Coverage" "SV_Depth"
|
||||
"SV_DepthGreaterEqual" "SV_DepthLessEqual" "SV_DispatchThreadID"
|
||||
"SV_DomainLocation" "SV_GroupID" "SV_GroupIndex" "SV_GroupThreadID"
|
||||
"SV_GSInstanceID" "SV_InnerCoverage" "SV_InsideTessFactor" "SV_InstanceID"
|
||||
"SV_IsFrontFace" "SV_OutputControlPointID" "SV_Position" "SV_PrimitiveID"
|
||||
"SV_RenderTargetArrayIndex" "SV_SampleIndex" "SV_StencilRef" "SV_Target[0-7]"
|
||||
"SV_TessFactor" "SV_VertexID" "SV_ViewportArrayIndex" "SV_ShadingRate"
|
||||
"SV_Target"
|
||||
;; Misc Semantics
|
||||
"BezierPos" "WorldPos" "TanUCorner" "TanVCorner" "TanWeights" "Bitangent[0-9]?"))
|
||||
|
||||
;; Unity keywords
|
||||
;;
|
||||
;; TODO: Separate derived mode for Unity ".shader" files? They're not strictly HLSL.
|
||||
"Shader" "Properties" "SubShader" "Tags" "Pass" "CGPROGRAM" "ENDCG"))
|
||||
|
||||
(defvar hlsl-reserved-list
|
||||
'(
|
||||
;; [2022/01/31] Just the reserved words found on:
|
||||
;; https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-appendix-reserved-words
|
||||
"auto" "case" "catch" "char" "class" "const_cast" "default" "delete" "dynamic_cast"
|
||||
"enum" "explicit" "friend" "goto" "long" "mutable" "new" "operator" "private"
|
||||
"protected" "public" "reinterpret_cast" "short" "signed" "sizeof" "static_cast"
|
||||
"template" "this" "throw" "try" "typename" "union" "unsigned" "using" "virtual"))
|
||||
|
||||
(defvar hlsl-deprecated-qualifier-list
|
||||
'())
|
||||
|
||||
(defvar hlsl-builtin-list
|
||||
|
||||
'(
|
||||
;; This is the list of the builtins taken directly from the Direct3D 12 docs (Shader Model 6.0)
|
||||
"abort" "abs" "acos" "all" "AllMemoryBarrier" "AllMemoryBarrierWithGroupSync"
|
||||
"any" "asdouble" "asfloat" "asin" "asint" "asint" "asuint" "asuint" "atan" "atan2"
|
||||
"ceil" "CheckAccessFullyMapped" "clamp" "clip" "cos" "cosh" "countbits" "cross"
|
||||
"D3DCOLORtoUBYTE4" "ddx" "ddx_coarse" "ddx_fine" "ddy" "ddy_coarse" "ddy_fine"
|
||||
"degrees" "determinant" "DeviceMemoryBarrier" "DeviceMemoryBarrierWithGroupSync"
|
||||
"distance" "dot" "dst" "errorf" "EvaluateAttributeAtCentroid" "EvaluateAttributeAtSample"
|
||||
"EvaluateAttributeSnapped" "exp" "exp2" "f16tof32" "f32tof16" "faceforward"
|
||||
"firstbithigh" "firstbitlow" "floor" "fma" "fmod" "frac" "frexp" "fwidth"
|
||||
"GetRenderTargetSampleCount" "GetRenderTargetSamplePosition" "GroupMemoryBarrier"
|
||||
"GroupMemoryBarrierWithGroupSync" "InterlockedAdd" "InterlockedAnd"
|
||||
"InterlockedCompareExchange" "InterlockedCompareStore" "InterlockedExchange"
|
||||
"InterlockedMax" "InterlockedMin" "InterlockedOr" "InterlockedXor" "isfinite"
|
||||
"isinf" "isnan" "ldexp" "length" "lerp" "lit" "log" "log10" "log2" "mad" "max"
|
||||
"min" "modf" "msad4" "mul" "noise" "normalize" "pow" "printf"
|
||||
"Process2DQuadTessFactorsAvg" "Process2DQuadTessFactorsMax" "Process2DQuadTessFactorsMin"
|
||||
"ProcessIsolineTessFactors" "ProcessQuadTessFactorsAvg" "ProcessQuadTessFactorsMax"
|
||||
"ProcessQuadTessFactorsMin" "ProcessTriTessFactorsAvg" "ProcessTriTessFactorsMax"
|
||||
"ProcessTriTessFactorsMin" "radians" "rcp" "reflect" "refract" "reversebits"
|
||||
"round" "rsqrt" "saturate" "sign" "sin" "sincos" "sinh" "smoothstep" "sqrt"
|
||||
"step" "tan" "tanh" "tex1D" "tex1Dbias" "tex1Dgrad" "tex1Dlod" "tex1Dproj"
|
||||
"tex2D" "tex2Dbias" "tex2Dgrad" "tex2Dlod" "tex2Dproj" "tex3D" "tex3Dbias"
|
||||
"tex3Dgrad" "tex3Dlod" "tex3Dproj" "texCUBE" "texCUBEbias" "texCUBEgrad" "texCUBElod"
|
||||
"texCUBEproj" "transpose" "trunc"
|
||||
|
||||
;; Geometry shader streams
|
||||
"Append" "RestartStrip"
|
||||
|
||||
;; Textures/Buffers
|
||||
"CalculateLevelOfDetail" "CalculateLevelOfDetailUnclamped" "Gather" "GetDimensions"
|
||||
"GetSamplePosition" "Sample" "SampleBias" "SampleCmp" "SampleGrad" "SampleLevel"
|
||||
"Operator\\[\\]" "Load[234]?" "Store[234]?"
|
||||
"GatherRed" "GatherGreen" "GatherBlue" "GatherAlpha" "GatherCmp" "GatherCmpRed"
|
||||
"GatherCmpGreen" "GatherCmpBlue" "GatherCmpAlpha"
|
||||
"Sample" "SampleBias" "SampleCmp" "SampleCmpLevelZero" "SampleGrad" "SampleLevel"
|
||||
|
||||
;; Wave Intrinsics
|
||||
"QuadReadAcrossDiagonal" "QuadReadLaneAt" "QuadReadAcrossX" "QuadReadAcrossY"
|
||||
"WaveActiveAllEqual" "WaveActiveBitAnd" "WaveActiveBitOr" "WaveActiveBitXor"
|
||||
"WaveActiveCountBits" "WaveActiveMax" "WaveActiveMin" "WaveActiveProduct"
|
||||
"WaveActiveSum" "WaveActiveAllTrue" "WaveActiveAnyTrue" "WaveActiveBallot"
|
||||
"WaveGetLaneCount" "WaveGetLaneIndex" "WaveIsFirstLane" "WavePrefixCountBits"
|
||||
"WavePrefixProduct" "WavePrefixSum" "WaveReadLaneFirst" "WaveReadLaneAt"
|
||||
|
||||
;; Unsorted
|
||||
"Consume" "DecrementCounter" "IncrementCounter"))
|
||||
|
||||
(defvar hlsl-deprecated-builtin-list
|
||||
'())
|
||||
|
||||
(defvar hlsl-deprecated-variables-list
|
||||
'())
|
||||
|
||||
(defvar hlsl-preprocessor-directive-list
|
||||
'(
|
||||
"define" "elif" "else" "endif" "error" "if" "ifdef" "ifndef" "include"
|
||||
"line" "pragma" "undef"))
|
||||
|
||||
(defvar hlsl-preprocessor-expr-list
|
||||
'(
|
||||
;; Taken directly from glsl-mode - not audited yet
|
||||
"defined" "##"))
|
||||
|
||||
(defvar hlsl-preprocessor-builtin-list
|
||||
'(
|
||||
;; Taken directly from glsl-mode - not audited yet
|
||||
"__LINE__" "__FILE__" "__VERSION__"))
|
||||
|
||||
;; TODO: Highlighting for annotations <int something=27;>
|
||||
|
||||
) ; eval-and-compile
|
||||
|
||||
(eval-and-compile
|
||||
(defun hlsl-ppre (re)
|
||||
;; FIXME: This doesn't sanitise the inputs, so a bad member could corrupt the whole expression
|
||||
(format "\\<\\(%s\\)\\>" (string-join re "\\|"))))
|
||||
|
||||
(defvar hlsl-font-lock-keywords-1
|
||||
(append
|
||||
(list
|
||||
(cons (eval-when-compile
|
||||
(format "^[ \t]*#[ \t]*\\<\\(%s\\)\\>"
|
||||
(regexp-opt hlsl-preprocessor-directive-list)))
|
||||
hlsl-preprocessor-face)
|
||||
(cons (eval-when-compile
|
||||
(hlsl-ppre hlsl-type-list))
|
||||
hlsl-type-face)
|
||||
(cons (eval-when-compile
|
||||
(hlsl-ppre hlsl-deprecated-qualifier-list))
|
||||
hlsl-deprecated-keyword-face)
|
||||
(cons (eval-when-compile
|
||||
(hlsl-ppre hlsl-reserved-list))
|
||||
hlsl-reserved-keyword-face)
|
||||
(cons (eval-when-compile
|
||||
(hlsl-ppre hlsl-qualifier-list))
|
||||
hlsl-qualifier-face)
|
||||
(cons (eval-when-compile
|
||||
(hlsl-ppre hlsl-keyword-list))
|
||||
hlsl-keyword-face)
|
||||
(cons (eval-when-compile
|
||||
(hlsl-ppre hlsl-preprocessor-builtin-list))
|
||||
hlsl-keyword-face)
|
||||
(cons (eval-when-compile
|
||||
(hlsl-ppre hlsl-deprecated-builtin-list))
|
||||
hlsl-deprecated-builtin-face)
|
||||
(cons (eval-when-compile
|
||||
(hlsl-ppre hlsl-builtin-list))
|
||||
hlsl-builtin-face)
|
||||
(cons (eval-when-compile
|
||||
(hlsl-ppre hlsl-deprecated-variables-list))
|
||||
hlsl-deprecated-variable-name-face)
|
||||
;; Swizzles are a special case. We want to highlight swizzles only when
|
||||
;; they're after a dot, but we don't want to highlight the dot itself.
|
||||
(list (eval-when-compile
|
||||
;; TODO: Maybe these types of swizzles?
|
||||
;; /\.\(_m[0-3]\{2}\)\{1,4\}/
|
||||
;; /\.\(_[1-4]\{2}\)\{1,4\}/
|
||||
"\\.\\_<\\([xyzw]\\{1,4\\}\\|[rgba]\\{1,4\\}\\)\\_>")
|
||||
'(1 hlsl-builtin-face))
|
||||
;; TODO: What to do about dedicated named variables?
|
||||
;; (cons "unity_[A-Z0-9a-z_]+" hlsl-variable-name-face)
|
||||
)
|
||||
|
||||
(when hlsl-additional-types
|
||||
(list
|
||||
(cons (hlsl-ppre hlsl-additional-types) hlsl-type-face)))
|
||||
(when hlsl-additional-keywords
|
||||
(list
|
||||
(cons (hlsl-ppre hlsl-additional-keywords) hlsl-keyword-face)))
|
||||
(when hlsl-additional-qualifiers
|
||||
(list
|
||||
(cons (hlsl-ppre hlsl-additional-qualifiers) hlsl-qualifier-face)))
|
||||
(when hlsl-additional-built-ins
|
||||
(list
|
||||
(cons (hlsl-ppre hlsl-additional-built-ins) hlsl-builtin-face)))
|
||||
)
|
||||
"Highlighting expressions for HLSL mode.")
|
||||
|
||||
|
||||
(defvar hlsl-font-lock-keywords hlsl-font-lock-keywords-1
|
||||
"Default highlighting expressions for HLSL mode.")
|
||||
|
||||
(defvar hlsl-mode-syntax-table
|
||||
(let ((hlsl-mode-syntax-table (make-syntax-table)))
|
||||
(modify-syntax-entry ?/ ". 124b" hlsl-mode-syntax-table)
|
||||
(modify-syntax-entry ?* ". 23" hlsl-mode-syntax-table)
|
||||
(modify-syntax-entry ?\n "> b" hlsl-mode-syntax-table)
|
||||
(modify-syntax-entry ?_ "w" hlsl-mode-syntax-table)
|
||||
hlsl-mode-syntax-table)
|
||||
"Syntax table for `hlsl-mode'.")
|
||||
|
||||
(defvar hlsl-other-file-alist
|
||||
;; TODO: Add common pairings, e.g. vert & corresponding frag files, perhaps
|
||||
;; also geom
|
||||
'()
|
||||
"Alist of extensions to find given the current file's extension.")
|
||||
|
||||
(defun hlsl-man-completion-list ()
|
||||
"Return list of all HLSL keywords."
|
||||
(append hlsl-builtin-list hlsl-deprecated-builtin-list))
|
||||
|
||||
;; TODO: Switch over to HLSL docs?
|
||||
;; (defun hlsl-find-man-page (thing)
|
||||
;; "Collects and displays manual entry for HLSL built-in function THING."
|
||||
;; (interactive
|
||||
;; (let ((word (current-word nil t)))
|
||||
;; (list
|
||||
;; (completing-read
|
||||
;; (concat "OpenGL.org HLSL man page: (" word "): ")
|
||||
;; (hlsl-man-completion-list)
|
||||
;; nil nil nil nil word))))
|
||||
;; (save-excursion
|
||||
;; (apply hlsl-browse-url-function
|
||||
;; (list (concat hlsl-man-pages-base-url thing ".xhtml")))))
|
||||
|
||||
;; TODO: Maybe remove easy menu?
|
||||
(easy-menu-define hlsl-menu hlsl-mode-map
|
||||
"HLSL Menu."
|
||||
`("HLSL"
|
||||
["Comment Out Region" comment-region
|
||||
(c-fn-region-is-active-p)]
|
||||
["Uncomment Region" (comment-region (region-beginning)
|
||||
(region-end) '(4))
|
||||
(c-fn-region-is-active-p)]
|
||||
["Indent Expression" c-indent-exp
|
||||
(memq (char-after) '(?\( ?\[ ?\{))]
|
||||
["Indent Line or Region" c-indent-line-or-region t]
|
||||
["Fill Comment Paragraph" c-fill-paragraph t]
|
||||
"----"
|
||||
["Backward Statement" c-beginning-of-statement t]
|
||||
["Forward Statement" c-end-of-statement t]
|
||||
"----"
|
||||
["Up Conditional" c-up-conditional t]
|
||||
["Backward Conditional" c-backward-conditional t]
|
||||
["Forward Conditional" c-forward-conditional t]
|
||||
"----"
|
||||
["Backslashify" c-backslash-region (c-fn-region-is-active-p)]
|
||||
"----"
|
||||
["Find HLSL Man Page" hlsl-find-man-page t]
|
||||
))
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode hlsl-mode prog-mode "HLSL"
|
||||
"Major mode for editing HLSL shader files."
|
||||
(c-initialize-cc-mode t)
|
||||
(setq abbrev-mode t)
|
||||
(c-init-language-vars-for 'c-mode)
|
||||
(c-common-init 'c-mode)
|
||||
(cc-imenu-init cc-imenu-c++-generic-expression)
|
||||
(set (make-local-variable 'font-lock-defaults) '(hlsl-font-lock-keywords))
|
||||
(set (make-local-variable 'ff-other-file-alist) 'hlsl-other-file-alist)
|
||||
(set (make-local-variable 'comment-start) "// ")
|
||||
(set (make-local-variable 'comment-end) "")
|
||||
(set (make-local-variable 'comment-padding) "")
|
||||
;; TODO: Indentation rules for annotated for loops, e.g:
|
||||
;; [unroll] for (...) {
|
||||
;; --->|
|
||||
;; }
|
||||
;; Currently it just indents flat as though no scope was declared
|
||||
(add-to-list 'align-c++-modes 'hlsl-mode)
|
||||
(c-run-mode-hooks 'c-mode-common-hook)
|
||||
(run-mode-hooks 'hlsl-mode-hook)
|
||||
;; TODO: Guard `c-make-noise-macro-regexps' based on Emacs version, then lower
|
||||
;; dependency.
|
||||
:after-hook (progn (when (fboundp 'c-make-noise-macro-regexps)
|
||||
;; Depends on Emacs 26.1, guarding this allows us to
|
||||
;; support down to Emacs 24.4
|
||||
(c-make-noise-macro-regexps))
|
||||
(c-make-macro-with-semi-re)
|
||||
(c-update-modeline)))
|
||||
|
||||
|
||||
;; TODO: Float number highlighting (i.e. 1.0f)
|
||||
;; TODO: Negative number highlighting
|
||||
;; TODO: Highlight numbers adjacent to operators e.g. 1-variable
|
||||
|
||||
|
||||
(provide 'hlsl-mode)
|
||||
;;; hlsl-mode.el ends here
|
197
local-lisp/move-text.el
Normal file
197
local-lisp/move-text.el
Normal file
|
@ -0,0 +1,197 @@
|
|||
;;; move-text.el --- Move current line or region with M-up or M-down. -*- lexical-binding: t; -*-
|
||||
|
||||
;; filename: move-text.el
|
||||
;; Description: Move current line or region with M-up or M-down.
|
||||
;; Author: Jason Milkins <jasonm23@gmail.com>
|
||||
;; Keywords: edit
|
||||
;; Url: https://github.com/emacsfodder/move-text
|
||||
;; Compatibility: GNU Emacs 25.1
|
||||
;; Version: 2.0.10
|
||||
;;
|
||||
;;; This file is NOT part of GNU Emacs
|
||||
|
||||
;;; License
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
||||
;; Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; MoveText 2.0.0 is a re-write of the old move-text and compatible with >= Emacs 25.1
|
||||
;;
|
||||
;; It allows you to move the current line using M-up / M-down if a
|
||||
;; region is marked, it will move the region instead.
|
||||
;;
|
||||
;; Using the prefix (C-u *number* or META *number*) you can predefine how
|
||||
;; many lines move-text will travel.
|
||||
;;
|
||||
|
||||
;;; Installation:
|
||||
;;
|
||||
;; Put move-text.el to your load-path.
|
||||
;; The load-path is usually ~/elisp/.
|
||||
;; It's set in your ~/.emacs like this:
|
||||
;; (add-to-list 'load-path (expand-file-name "~/elisp"))
|
||||
;;
|
||||
;; And the following to your ~/.emacs startup file.
|
||||
;;
|
||||
;; (require 'move-text)
|
||||
;; (move-text-default-bindings)
|
||||
|
||||
;;; Acknowledgements:
|
||||
;;
|
||||
;; Original v1.x was a Feature extracted from basic-edit-toolkit.el - by Andy Stewart (LazyCat)
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
(require 'cl-lib)
|
||||
|
||||
(defun move-text-get-region-and-prefix ()
|
||||
"Get the region and prefix for the `interactive' macro, without aborting.
|
||||
|
||||
Note: `region-beginning' and `region-end' are the reason why an
|
||||
`interactive' macro with \"r\" will blow up with the error:
|
||||
|
||||
\"The mark is not set now, so there is no region\"
|
||||
|
||||
We check with `use-region-p' to avoid calling
|
||||
them when there's no region or it is not appropriate
|
||||
to act on it.
|
||||
|
||||
We use `prefix-numeric-value' to return a number.
|
||||
"
|
||||
(list
|
||||
(when (use-region-p) (region-beginning)) ;; otherwise nil
|
||||
(when (use-region-p) (region-end))
|
||||
(prefix-numeric-value current-prefix-arg)))
|
||||
|
||||
;;;###autoload
|
||||
(defun move-text--total-lines ()
|
||||
"Convenience function to get the total lines in the buffer / or narrowed buffer."
|
||||
(line-number-at-pos (point-max)))
|
||||
|
||||
;;;###autoload
|
||||
(defun move-text--at-first-line-p ()
|
||||
"Predicate, is the point at the first line?"
|
||||
(= (line-number-at-pos) 1))
|
||||
|
||||
;;;###autoload
|
||||
(defun move-text--at-penultimate-line-p ()
|
||||
"Predicate, is the point at the penultimate line?"
|
||||
(= (line-number-at-pos) (1- (move-text--total-lines))))
|
||||
|
||||
;; save-mark-and-excursion in Emacs 25 works like save-excursion did before
|
||||
(eval-when-compile
|
||||
(when (< emacs-major-version 25)
|
||||
(defmacro save-mark-and-excursion (&rest body)
|
||||
`(save-excursion ,@body))))
|
||||
|
||||
;;;###autoload
|
||||
(defun move-text--last-line-is-just-newline ()
|
||||
"Predicate, is last line just a newline?"
|
||||
(save-mark-and-excursion
|
||||
(goto-char (point-max))
|
||||
(beginning-of-line)
|
||||
(= (point-max) (point))))
|
||||
|
||||
;;;###autoload
|
||||
(defun move-text--at-last-line-p ()
|
||||
"Predicate, is the point at the last line?"
|
||||
(= (line-number-at-pos) (move-text--total-lines)))
|
||||
|
||||
;;;###autoload
|
||||
(defun move-text-line-up ()
|
||||
"Move the current line up."
|
||||
(interactive)
|
||||
(if (move-text--at-last-line-p)
|
||||
(let ((target-point))
|
||||
(kill-whole-line)
|
||||
(forward-line -1)
|
||||
(beginning-of-line)
|
||||
(setq target-point (point))
|
||||
(yank)
|
||||
(unless (looking-at "\n")
|
||||
(newline))
|
||||
(goto-char target-point))
|
||||
(let ((col (current-column)))
|
||||
(progn (transpose-lines 1)
|
||||
(forward-line -2)
|
||||
(move-to-column col)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun move-text-line-down ()
|
||||
"Move the current line down."
|
||||
(interactive)
|
||||
(unless (or
|
||||
(move-text--at-last-line-p)
|
||||
(and
|
||||
(move-text--last-line-is-just-newline)
|
||||
(move-text--at-penultimate-line-p)))
|
||||
(let ((col (current-column)))
|
||||
(forward-line 1)
|
||||
(transpose-lines 1)
|
||||
(forward-line -1)
|
||||
(move-to-column col))))
|
||||
|
||||
;;;###autoload
|
||||
(defun move-text-region (start end n)
|
||||
"Move the current region (START END) up or down by N lines."
|
||||
(interactive (move-text-get-region-and-prefix))
|
||||
(let ((line-text (delete-and-extract-region start end)))
|
||||
(forward-line n)
|
||||
(let ((start (point)))
|
||||
(insert line-text)
|
||||
(setq deactivate-mark nil)
|
||||
(set-mark start))))
|
||||
|
||||
;;;###autoload
|
||||
(defun move-text-region-up (start end n)
|
||||
"Move the current region (START END) up by N lines."
|
||||
(interactive (move-text-get-region-and-prefix))
|
||||
(move-text-region start end (- n)))
|
||||
|
||||
;;;###autoload
|
||||
(defun move-text-region-down (start end n)
|
||||
"Move the current region (START END) down by N lines."
|
||||
(interactive (move-text-get-region-and-prefix))
|
||||
(move-text-region start end n))
|
||||
|
||||
;;;###autoload
|
||||
(defun move-text-up (start end n)
|
||||
"Move the line or region (START END) up by N lines."
|
||||
(interactive (move-text-get-region-and-prefix))
|
||||
(if (not (move-text--at-first-line-p))
|
||||
(if (region-active-p)
|
||||
(move-text-region-up start end n)
|
||||
(cl-loop repeat n do (move-text-line-up)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun move-text-down (start end n)
|
||||
"Move the line or region (START END) down by N lines."
|
||||
(interactive (move-text-get-region-and-prefix))
|
||||
(if (region-active-p)
|
||||
(move-text-region-down start end n)
|
||||
(cl-loop repeat n do (move-text-line-down))))
|
||||
|
||||
;;;###autoload
|
||||
(defun move-text-default-bindings ()
|
||||
"Bind `move-text-up' and `move-text-down' to M-up & M-down."
|
||||
(interactive)
|
||||
(global-set-key [M-down] 'move-text-down)
|
||||
(global-set-key [M-up] 'move-text-up))
|
||||
|
||||
(provide 'move-text)
|
||||
|
||||
;;; move-text.el ends here
|
Loading…
Reference in a new issue