Major overhaul

This commit is contained in:
Henrik Lissner 2014-12-10 15:54:36 -05:00
parent 4ab3ae1125
commit 6bda25da1f
76 changed files with 7431 additions and 571 deletions

View file

@ -1,65 +0,0 @@
;;; evil-ex-registers.el --- Command to paste from register in ex mode
;; Author: INA Lintaro <tarao.gnn at gmail.com>
;; URL: http://github.com/tarao/evil-plugins
;; Version: 0.1
;; Keywords: evil, plugin
;; 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 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/>.
;;; Code:
(require 'evil)
(eval-when-compile (require 'cl))
(defalias 'evil-orig-get-register (symbol-function 'evil-get-register))
(defun evil-get-spec-register (register &optional noerror)
"Return contents of REGISTER.
Signal an error if empty, unless NOERROR is non-nil.
Support some registers listed below in addition to
`evil-get-register'.
 the file name under the cursor
 the expanded file name under the cursor
 the word under the cursor
 the WORD under the cursor"
(cond
((or (= register ?\C-f) ; ^F the filename under the cursor
(= register ?\C-p)) ; ^P the expanded filename under the cursor
(let ((file (thing-at-point 'filename)))
(or (and file (= register ?\C-p) (expand-file-name file)) file)))
((or (= register ?\C-w) ; ^W the word under the cursor
(= register ?\C-a)) ; ^A the WORD under the cursor
(let* ((word (if (= register ?\C-a) #'evil-move-WORD #'evil-move-word))
(range (evil-inner-object-range nil nil nil nil word)))
(filter-buffer-substring (nth 0 range) (nth 1 range))))
(t (evil-orig-get-register register noerror))))
(defun evil-ex-paste-from-register (&optional register)
"Paste from REGISTER in command line."
(interactive)
(cl-flet ((evil-get-register (register &optional noerror)
(with-current-buffer evil-ex-current-buffer
(evil-get-spec-register register noerror))))
(if (called-interactively-p 'any)
(call-interactively #'evil-paste-from-register)
(evil-paste-from-register register))))
(provide 'evil-ex-registers)
;;; evil-ex-registers.el ends here

View file

@ -1,126 +0,0 @@
;;; evil-little-word.el --- Emulate camelcasemotion.vim
;; Author: INA Lintaro <tarao.gnn at gmail.com>
;; URL: http://github.com/tarao/evil-plugins
;; Version: 0.1
;; Keywords: evil, plugin
;; 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 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/>.
;;; Code:
(require 'evil)
(defun maybe-define-category (cat doc &optional table)
(unless (category-docstring cat table) (define-category cat doc table)))
(let (uc lc defs (table (standard-category-table)))
(map-char-table
#'(lambda (key value)
(when (natnump value)
(let (from to)
(if (consp key)
(setq from (car key) to (cdr key))
(setq from (setq to key)))
(while (<= from to)
(cond ((/= from (downcase from))
(add-to-list 'uc from))
((/= from (upcase from))
(add-to-list 'lc from)))
(setq from (1+ from))))))
(standard-case-table))
(setq defs `(("Uppercase" ?U ,uc)
("Lowercase" ?u ,lc)
("Underscore" ?_ (?_))))
(dolist (elt defs)
(maybe-define-category (cadr elt) (car elt) table)
(dolist (ch (car (cddr elt)))
(modify-category-entry ch (cadr elt) table))))
(defgroup evil-little-word nil
"CamelCase and snake_case word movement support."
:prefix "evil-little-word-"
:group 'evil)
(defcustom evil-little-word-separating-categories
(append evil-cjk-word-separating-categories '((?u . ?U) (?_ . ?u) (?_ . ?U)))
"List of pair (cons) of categories to determine word boundary
for little word movement. See the documentation of
`word-separating-categories'. Use `describe-categories' to see
the list of categories."
:type '((character . character))
:group 'evil-little-word)
(defcustom evil-little-word-combining-categories
(append evil-cjk-word-combining-categories '())
"List of pair (cons) of categories to determine word boundary
for little word movement. See the documentation of
`word-combining-categories'. Use `describe-categories' to see the
list of categories."
:type '((character . character))
:group 'evil-little-word)
(defmacro evil-with-little-word (&rest body)
(declare (indent defun) (debug t))
`(let ((evil-cjk-word-separating-categories
evil-little-word-separating-categories)
(evil-cjk-word-combining-categories
evil-little-word-combining-categories))
,@body))
(defun forward-evil-little-word (&optional count)
"Forward by little words."
(evil-with-little-word (forward-evil-word count)))
(evil-define-motion evil-forward-little-word-begin (count)
"Move the cursor to the beginning of the COUNT-th next little word."
:type exclusive
(evil-with-little-word (evil-forward-word-begin count)))
(evil-define-motion evil-forward-little-word-end (count)
"Move the cursor to the end of the COUNT-th next little word."
:type inclusive
(evil-with-little-word (evil-forward-word-end count)))
(evil-define-motion evil-backward-little-word-begin (count)
"Move the cursor to the beginning of the COUNT-th previous little word."
:type exclusive
(evil-with-little-word (evil-backward-word-begin count)))
(evil-define-motion evil-backward-little-word-end (count)
"Move the cursor to the end of the COUNT-th previous little word."
:type inclusive
(evil-with-little-word (evil-backward-word-end count)))
(evil-define-text-object evil-a-little-word (count &optional beg end type)
"Select a little word."
(evil-select-an-object 'evil-little-word beg end type count))
(evil-define-text-object evil-inner-little-word (count &optional beg end type)
"Select inner little word."
(evil-select-inner-object 'evil-little-word beg end type count))
(define-key evil-motion-state-map (kbd "glw") 'evil-forward-little-word-begin)
(define-key evil-motion-state-map (kbd "glb") 'evil-backward-little-word-begin)
(define-key evil-motion-state-map (kbd "glW") 'evil-forward-little-word-end)
(define-key evil-motion-state-map (kbd "glB") 'evil-backward-little-word-end)
(define-key evil-outer-text-objects-map (kbd "lw") 'evil-a-little-word)
(define-key evil-inner-text-objects-map (kbd "lw") 'evil-inner-little-word)
(provide 'evil-little-word)
;;; evil-little-word.el ends here

File diff suppressed because it is too large Load diff

View file

@ -1,117 +0,0 @@
;;; hl-todo.el --- highlight TODO keywords
;; Copyright (C) 2013-2014 Jonas Bernoulli
;; Author: Jonas Bernoulli <jonas@bernoul.li>
;; Created: 20130310
;; Homepage: http://github.com/tarsius/hl-todo
;; Keywords: convenience
;; This file is not part of GNU Emacs.
;; 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:
;; Hightlight TODO keywords. There are many minor modes like it
;; but this one is mine. It also happens to be simpler than the
;; alternatives.
;; For now at least -- I might extend it. Or I might abandon it
;; in favor of one of the following -- so you might be better of
;; going straight for one of these:
;; - [[http://emacswiki.org/fic-ext-mode.el][fic-ext-mode]]
;; - [[https://github.com/lewang/fic-mode][fic-mode]]
;; - [[http://emacswiki.org/FixmeMode][fixme-mode]]
;; - [[https://github.com/rolandwalker/fixmee][fixmee]]
;; - see http://emacswiki.org/FixmeMode for more alternatives
;; If you like this you might also like [[https://github.com/tarsius/orglink][orglink]].
;;; Code:
(defgroup hl-todo nil
"Highlight TODO keywords in comments."
:group 'font-lock-extra-types)
(defface hl-todo
'((t (:bold t :foreground "#cc9393")))
"Face used to highlight TODO keywords."
:group 'hl-todo)
(defcustom hl-todo-activate-in-modes '(emacs-lisp-mode)
"Major modes in which `hl-todo-mode' should be activated.
This is used by `global-hl-todo-mode'."
:group 'hl-todo
:type '(repeat function))
(defvar hl-todo-keywords nil)
(defcustom hl-todo-keyword-faces
'(("HOLD" . "#d0bf8f")
("TODO" . "#cc9393")
("NEXT" . "#dca3a3")
("THEM" . "#dc8cc3")
("PROG" . "#7cb8bb")
("OKAY" . "#7cb8bb")
("DONT" . "#5f7f5f")
("FAIL" . "#8c5353")
("DONE" . "#afd8af")
("FIXME" . "#cc9393")
("XXX" . "#cc9393")
("XXXX" . "#cc9393")
("???" . "#cc9393"))
"Faces used to highlight specific TODO keywords."
:group 'hl-todo
:type '(repeat (cons (string :tag "Keyword")
(choice :tag "Face "
(string :tag "Color")
(sexp :tag "Face"))))
:set (lambda (symbol value)
(set-default symbol value)
(setq hl-todo-keywords
`((,(concat "\\_<\\("
(mapconcat 'car value "\\|")
"\\)\\_>")
(1 (hl-todo-get-face) t))))))
(defun hl-todo-get-face ()
(let ((f (cdr (assoc (match-string 1) hl-todo-keyword-faces))))
(if (stringp f) (list :inherit 'hl-todo :foreground f) f)))
;;;###autoload
(define-minor-mode hl-todo-mode
"Highlight TODO tags in comments."
:lighter ""
:group 'hl-todo
(if hl-todo-mode
(font-lock-add-keywords nil hl-todo-keywords 'append)
(font-lock-remove-keywords nil hl-todo-keywords))
(when (called-interactively-p 'any)
(font-lock-fontify-buffer)))
;;;###autoload
(define-globalized-minor-mode global-hl-todo-mode
hl-todo-mode turn-on-hl-todo-mode-if-desired)
(defun turn-on-hl-todo-mode-if-desired ()
(when (apply 'derived-mode-p hl-todo-activate-in-modes)
(hl-todo-mode 1)))
(provide 'hl-todo)
;; Local Variables:
;; indent-tabs-mode: nil
;; End:
;;; hl-todo.el ends here

View file

@ -1,93 +0,0 @@
;; From <http://www.emacswiki.org/emacs/RotateText>
(provide 'rotate-text)
(defvar rotate-text-rotations
'(("true" "false")
("True" "False")
("yes" "no")
("t" "nil")
("left" "right" "top" "bottom")
("left" "right" "top" "bottom")
("width" "height")))
;;;###autoload
(defun rotate-region (beg end)
"Rotate all matches in `rotate-text-rotations' between point and mark."
(interactive "r")
(let ((regexp (rotate-convert-rotations-to-regexp
rotate-text-rotations))
(end-mark (copy-marker end)))
(save-excursion
(goto-char beg)
(while (re-search-forward regexp (marker-position end-mark) t)
(let* ((found (match-string 0))
(replace (rotate-next found)))
(replace-match replace))))))
(defun rotate-string (string &optional rotations)
"Rotate all matches in STRING using associations in ROTATIONS.
If ROTATIONS are not given it defaults to `rotate-text-rotations'."
(let ((regexp (rotate-convert-rotations-to-regexp
(or rotations rotate-text-rotations)))
(start 0))
(while (string-match regexp string start)
(let* ((found (match-string 0 string))
(replace (rotate-next
found
(or rotations rotate-text-rotations))))
(setq start (+ (match-end 0)
(- (length replace) (length found))))
(setq string (replace-match replace nil t string))))
string))
(defun rotate-next (string &optional rotations)
"Return the next element after STRING in ROTATIONS."
(let ((rots (rotate-get-rotations-for
string
(or rotations rotate-text-rotations))))
(if (> (length rots) 1)
(error (format "Ambiguous rotation for %s" string))
(if (< (length rots) 1)
;; If we get this far, this should not occur:
(error (format "Unknown rotation for %s" string))
(let ((occurs-in-rots (member string (car rots))))
(if (null occurs-in-rots)
;; If we get this far, this should *never* occur:
(error (format "Unknown rotation for %s" string))
(if (null (cdr occurs-in-rots))
(caar rots)
(cadr occurs-in-rots))))))))
(defun rotate-get-rotations-for (string &optional rotations)
"Return the string rotations for STRING in ROTATIONS."
(remq nil (mapcar (lambda (rot) (if (member string rot) rot))
(or rotations rotate-text-rotations))))
(defun rotate-convert-rotations-to-regexp (rotations)
(regexp-opt (rotate-flatten-list rotations)))
(defun rotate-flatten-list (list-of-lists)
"Flatten LIST-OF-LISTS to a single list.
Example:
(rotate-flatten-list '((a b c) (1 ((2 3)))))
=> (a b c 1 2 3)"
(if (null list-of-lists)
list-of-lists
(if (listp list-of-lists)
(append (rotate-flatten-list (car list-of-lists))
(rotate-flatten-list (cdr list-of-lists)))
(list list-of-lists))))
;;;###autoload
(defun rotate-word-at-point ()
"Rotate word at point based on sets in `rotate-text-rotations'."
(interactive)
(let ((bounds (bounds-of-thing-at-point 'word))
(opoint (point)))
(when (consp bounds)
(let ((beg (car bounds))
(end (copy-marker (cdr bounds))))
(rotate-region beg end)
(goto-char (if (> opoint end) end opoint))))))

View file

@ -1,195 +0,0 @@
;;; ruby-mode-indent-fix.el ---
;; this file is not part of Emacs
;; Copyright (C) 2012 Le Wang
;; Author: Le Wang
;; Maintainer: Le Wang
;; Description:
;; Author: Le Wang
;; Maintainer: Le Wang
;; Created: Sun Feb 26 23:27:17 2012 (+0800)
;; Version: 0.1
;; Last-Updated: Mon Mar 26 11:23:48 2012 (+0800)
;; By: Le Wang
;; Update #: 29
;; URL:
;; Keywords:
;; Compatibility:
;;; Installation:
;; (eval-after-load "ruby-mod" '(require 'ruby-mode-indent-fix))
;;
;;
;;; Commentary:
;; Fix some indentation issues with ruby-mode with advices.
;;
;; Based on work by Dmitry Gutov(dgutov)
;; - http://stackoverflow.com/a/7622971/903943 and
;; - https://gist.github.com/1274520
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 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.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Code:
(eval-when-compile (require 'cl))
(defvar ruby--paren-closings-regex
"[])}\"']"
"regex matching closing paren or string delimiter.")
;; We make this advice around to avoid unnecessary buffer modifications.
(defadvice ruby-indent-line (around fix-closing-paren activate)
"indent closing paren to line up properly.
i.e.
foo_function( {:a => 'foo',
:b => 'bar'
}
)
Note that the closing paren is vertically aligned with the opening paren.
note: `ruby-deep-indent-paren' has to be enabled for this to work."
(let ((column (current-column))
indent)
(when ruby-deep-indent-paren
(save-excursion
(back-to-indentation)
(let ((state (syntax-ppss)))
(when (and (or (memq (sp-get-pair (char-after)) ruby-deep-indent-paren)
(and (eq (char-after) ?\})
(eq 'brace (ruby--point-in-braced-proc))))
(not (zerop (car state))))
(goto-char (cadr state))
(setq indent (current-column))))))
(if indent
(indent-line-to indent)
ad-do-it)))
(defun ruby--indent-before-all-sexps ()
"
1. search backwards for a closing delimiter ON THIS LINE, then
find the matching opening
2. if found, recurse, else the point is at a place we don't need
to worry about sexps.
"
(if (re-search-backward ruby--paren-closings-regex (point-at-bol) t)
(let ((ppss (syntax-ppss))
beg)
(goto-char (match-beginning 0))
(cond ((setq beg (nth 1 ppss)) ; brace
(goto-char beg))
((nth 3 ppss) ; string
(goto-char (nth 8 ppss))))
(ruby--indent-before-all-sexps))))
(defun ruby--point-in-braced-proc ()
"returns 'proc if point is in braces where starting bracs is EOL or followed by arg-list
i.e.
arr.each { |foo|
// do stuff
}
or
1.times {
// do stuff
}
returns 'brace if point in brace
return nil otherwise
"
(save-excursion
(let ((ppss (syntax-ppss))
beg)
(cond ((nth 3 ppss) ; string
nil)
((setq beg (nth 1 ppss)) ; brace
(goto-char beg)
(if (looking-at-p "{[\t ]*\\(?:$\\||\\)")
'proc
(when (looking-at-p "{")
'brace)))))))
(defadvice ruby-indent-line (around line-up-args activate)
"indent new line after comma at EOL properly:
i.e.
foo_function a_param,
b_param,
c_param
Note that all params line up after the function.
"
(let (indent ppss)
(save-excursion
(back-to-indentation)
(skip-chars-backward " \t\n")
(setq ppss (syntax-ppss))
;; check for inside comment, string, or inside braces
(when (and (eq ?, (char-before))
(not (memq (syntax-ppss-context ppss) '(comment string)))
(zerop (car ppss)))
(ruby--indent-before-all-sexps)
(back-to-indentation)
(if (save-excursion
(skip-chars-backward " \t\n")
(eq (char-before) ?,))
(setq indent (current-column))
(skip-syntax-forward "w_.")
(skip-chars-forward " ")
;; if the first symbol on the line is followed, by a comma, then this
;; line must be a continuation
(setq indent (current-column)))))
(if indent
(indent-line-to indent)
ad-do-it)))
;; (defadvice ruby-indent-line (around indent-no-brace-args activate)
;; "indent new line after comma at EOL properly:
;; i.e.
;; foo_function a_param,
;; b_param,
;; c_param
;; Note that all params line up after the function."
;; (let ((res (ruby--point-in-braced-proc)))
;; (cond ((eq 'brace res)
;; (let ((ruby-deep-indent-paren '(?\[ ?\( ?\{ t)))
;; ad-do-it))
;; (t
;; ad-do-it))))
(provide 'ruby-mode-indent-fix)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; ruby-mode-indent-fix.el ends here

View file

@ -1,425 +0,0 @@
;;; shaderlab-mode-el -- Major mode for editing Shaderlab files
;; Author: Simon Carter <bbbscarter@gmail.com>
;; Created: 1 August 2011
;; Keywords: Shaderlab languages
;; Copyright (C) 2011 Simon Carter <bbbscarter@gmail.com>
;; 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 2 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, write to the Free
;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
;; MA 02111-1307 USA
;;; Commentary:
;; Borrows heavily from cg-mode.el for syntax highlighting.
;; In addition, provides custom indentation, and works with other
;; shaderlab structures, such as material blocks, subshaders, etc.
;;; Code:
(defconst shaderlab-font-lock-keywords-1 nil
"Subdued level highlighting for shaderlab mode.")
(defconst shaderlab-font-lock-keywords-2 nil
"Medium level highlighting for Shaderlab mode.
See also `shaderlab-font-lock-extra-types'.")
(defconst shaderlab-font-lock-keywords-3 nil
"Gaudy level highlighting for Shaderlab mode.
See also `shaderlab-font-lock-extra-types'.")
;; taken largely from the c mode from font-lock.el
(let* ((shaderlab-keywords
(eval-when-compile
(regexp-opt '("break" "continue" "do" "else" "for" "if" "return"
"while"
"asm" "asm_fragment"
"technique" "pass" "compile"
"in" "out" "inout"
"typedef" "static" "const" "uniform" "packed"
"Shader" "Properties" "SubShader" "Pass"
"Material"
"Tags" "LOD" "Cull"
"CGPROGRAM" "ENDCG"
"Fallback"))))
(shaderlab-type-specs
(eval-when-compile
(regexp-opt '("struct" "interface"))))
(shaderlab-type-specs-depth
(regexp-opt-depth shaderlab-type-specs))
(shaderlab-type-names
`(mapconcat 'identity
(cons
,(eval-when-compile
(regexp-opt
'("void" "string"
"fragout" "fragout_float"
"sampler" "sampler1D" "sampler2D" "sampler3D"
"samplerCube" "samplerRECT"
"SurfaceOutput")))
'("\\(bool\\|double\\|c?float\\|fixed\\|half\\|c?int\\)\\([1234]\\(x[1234]\\)?\\)?"))
"\\|"))
(shaderlab-type-names-depth
`(regexp-opt-depth ,shaderlab-type-names))
(shaderlab-reserved-names
(eval-when-compile
(regexp-opt
;; reserved but not supported (Cg is UGLY!)
'("short" "dword" "long" "signed"
"auto" "catch" "char" "class" "column major"
"const_cast" "decl" "default" "delete"
"discard" "dynamic_cast" "emit" "enum" "explicit"
"extern" "friend" "get" "goto" "inline"
"long" "mutable" "namespace" "new" "operator"
"pixelfragment" "pixelshader" "private"
"protected" "public" "register" "reinterpret_cast"
"row_major" "sampler_state" "shared" "sizeof"
"static_cast" "template" "this" "throw"
"try" "typeid" "typename" "union" "using"
"virtual" "volatile" "__identifier"
"switch" "case" "default"))))
(shaderlab-reserved-names-depth
`(regexp-opt-depth ,shaderlab-reserved-names))
(shaderlab-bindings
(eval-when-compile
(regexp-opt
'("COLOR" "COLOR0" "COLOR1" "COLOR2" "COLOR3"
"POSITION" "BLENDWEIGHT" "NORMAL" "DIFFUSE"
"SPECULAR" "FOGCOORD" "PSIZE" "ATTR6" "TANGENT"
"TEXCOORD0" "TEXCOORD1" "TEXCOORD2" "TEXCOORD3"
"TEXCOORD4" "TEXCOORD5" "TEXCOORD6" "TEXCOORD7"
"HPOS" "PSIZ" "FOG" "FOGC" "COL0" "COL1" "BCOL0"))))
(shaderlab-bindings-depth
(regexp-opt-depth shaderlab-bindings))
(shaderlab-math-calls
(eval-when-compile
(regexp-opt
'(;; Mathmatical Functions
"abs" "acos" "all" "any" "asin" "atan" "atan2" "ceil" "clamp"
"cos" "cosh" "cross" "degrees" "determinant" "dot" "exp" "exp2"
"floor" "fmod" "frac" "frexp" "isfinite" "isinf" "isnan" "ldexp"
"lerp" "lit" "log" "log2" "log10" "max" "min" "modf" "mul" "noise"
"pow" "radians" "round" "rsqrt" "saturate" "sign" "sin" "sincos"
"sinh" "smoothstep" "step" "sqrt" "tan" "tanh" "transpose"
;; Geometric Functions
"distance" "faceforward" "length" "normalize" "reflect" "refract"
;; Texture Map Functions
"tex1D" "tex1Dproj" "tex2D" "tex2Dproj" "texRECT" "texRECTproj"
"tex3D" "tex3Dproj" "texCUBE texCUBEproj"
;; Derivitive Functions
"ddx" "ddy"
;; Debugging Function
"debug"
))))
(shaderlab-math-calls-depth
(regexp-opt-depth shaderlab-math-calls))
(shaderlab-preprocessor-directives
(eval-when-compile
(regexp-opt
'("define" "else" "endif" "if" "ifdef" "elif"
"ifndef" "include" "line" "pragma" "undef"))))
(shaderlab-preprocessor-directives-depth
(regexp-opt-depth shaderlab-preprocessor-directives)))
(setq shaderlab-font-lock-keywords-1
(list
;;
;; These are all anchored at the beginning of line for speed.
;;
;; Fontify function name definitions (GNU style; without type on line).
'("^\\(\\sw+\\)[ \t]*(" 1 font-lock-function-name-face)
;;
;'("\".*\"" . font-lock-string-face)
;; Fontify error directives.
'("^#[ \t]*error[ \t]+\\(.+\\)" 1 font-lock-warning-face prepend)
;;
;; Fontify filenames in #include <...> preprocessor directives as strings.
'("^#[ \t]*\\(import\\|include\\)[ \t]*\\(<[^>\"\n]*>?\\)"
2 font-lock-string-face)
;;
;; Fontify function macro names.
'("^#[ \t]*define[ \t]+\\(\\sw+\\)(" 1 font-lock-function-name-face)
;;
;; Fontify symbol names in #if ... defined preprocessor directives.
'("^#[ \t]*\\(elif\\|if\\)\\>"
("\\<\\(defined\\)\\>[ \t]*(?\\(\\sw+\\)?" nil nil
(1 font-lock-builtin-face) (2 font-lock-variable-name-face nil t)))
;;
;; Fontify otherwise as symbol names, and the preprocessor directive names.
(list
(concat "^#[ \t]*\\(" shaderlab-preprocessor-directives
"\\)\\>[ \t!]*\\(\\sw+\\)?")
'(1 font-lock-builtin-face)
(list (+ 2 shaderlab-preprocessor-directives-depth)
'font-lock-variable-name-face nil t))))
(setq shaderlab-font-lock-keywords-2
(append shaderlab-font-lock-keywords-1
(list
;;
;; Simple regexps for speed.
;;
;; Fontify all type names.
`(eval .
(cons (concat "\\<\\(" ,shaderlab-type-names "\\)\\>") 'font-lock-type-face))
;;
;; Fontify all bindings.
`(eval .
(cons (concat "\\<\\(" ,shaderlab-bindings "\\)\\>") 'font-lock-constant-face))
;;
;; Fontify all math calls.
`(eval .
(cons (concat "\\<\\(" ,shaderlab-math-calls "\\)\\>") 'font-lock-builtin-face))
;;
;; Fontify reserved but unimplemented keywords
`(eval .
(cons (concat "\\<\\(" ,shaderlab-reserved-names "\\)\\>") 'font-lock-warning-face))
;;
;; Fontify all builtin keywords (except case, default and goto; see below).
(concat "\\<\\(" shaderlab-keywords "\\|" shaderlab-type-specs "\\)\\>")
;;
;; Fontify case/goto keywords and targets, and case default/goto tags.
'("\\<\\(case\\|goto\\)\\>"
(1 font-lock-keyword-face)
("\\(-[0-9]+\\|\\sw+\\)"
;; Return limit of search.
(save-excursion (skip-chars-forward "^:\n") (point))
nil
(1 font-lock-constant-face nil t)))
;; Anders Lindgren <andersl@andersl.com> points out that it is quicker to
;; use MATCH-ANCHORED to effectively anchor the regexp on the left.
;; This must come after the one for keywords and targets.
'(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:[ \t]*$"
(beginning-of-line) (end-of-line)
(1 font-lock-constant-face)))
)))
(setq shaderlab-font-lock-keywords-3
(append shaderlab-font-lock-keywords-2
;;
;; More complicated regexps for more complete highlighting for types.
;; We still have to fontify type specifiers individually, as C is so hairy.
(list
;;
;; Fontify builtin true and false constants
'("\\(true\\|false\\)" 1 font-lock-constant-face)
;;
;; Fontify all storage types, plus their items.
`(eval .
(list (concat "\\<\\(" ,shaderlab-type-names "\\)\\>"
"\\([ \t*&]+\\sw+\\>\\)*")
;; Fontify each declaration item.
(list 'font-lock-match-c-style-declaration-item-and-skip-to-next
;; Start with point after all type specifiers.
(list 'goto-char (list 'or
(list 'match-beginning
(+ ,shaderlab-type-names-depth 2))
'(match-end 1)))
;; Finish with point after first type specifier.
'(goto-char (match-end 1))
;; Fontify as a variable or function name.
'(1 (if (match-beginning 2)
font-lock-function-name-face
font-lock-variable-name-face)))))
;;
;; Fontify all storage specs and types, plus their items.
`(eval .
(list (concat "\\<\\(" ,shaderlab-type-specs "\\)\\>"
"[ \t]*\\(\\sw+\\)?")
(list 1 'font-lock-keyword-face)
(list ,(+ shaderlab-type-specs-depth 2) 'font-lock-type-face nil t)
(list 'font-lock-match-c-style-declaration-item-and-skip-to-next
nil
;; Finish with point after the variable name if
;; there is one.
`(if (match-end 2)
(goto-char (match-end 2)))
;; Fontify as a variable or function name.
'(1 (if (match-beginning 2)
font-lock-function-name-face
font-lock-variable-name-face) nil t))))
;;
;; Fontify structures, or typedef names, plus their items.
'("\\(}\\)[ \t*]*\\sw"
(font-lock-match-c-style-declaration-item-and-skip-to-next
(goto-char (match-end 1)) nil
(1 font-lock-type-face)))
;;
;; Fontify anything at beginning of line as a declaration or definition.
'("^\\(\\sw+\\)\\>\\([ \t*]+\\sw+\\>\\)*"
(1 font-lock-type-face)
(font-lock-match-c-style-declaration-item-and-skip-to-next
(goto-char (or (match-beginning 2) (match-end 1))) nil
(1 (if (match-beginning 2)
font-lock-function-name-face
font-lock-variable-name-face))))
)))
)
(defvar shaderlab-font-lock-keywords shaderlab-font-lock-keywords-3
"Default expressions to highlight in C mode.
See also `shaderlab-font-lock-extra-types'.")
(defvar shaderlab-mode-hook nil)
(defvar shaderlab-mode-map
(let ((shaderlab-mode-map (make-keymap)))
(define-key shaderlab-mode-map "\C-j" 'newline-and-indent)
shaderlab-mode-map)
"Keymap for SHADERLAB major mode")
(define-derived-mode shaderlab-mode text-mode "Shaderlab"
"Major mode for editing shaderlab shaders.
\\{shaderlab-mode-map}"
(set-syntax-table shaderlab-mode-syntax-table2)
(set (make-local-variable 'font-lock-defaults) '(shaderlab-font-lock-keywords))
;; Register our indentation function
(set (make-local-variable 'indent-line-function) 'shaderlab-indent-line)
)
(add-to-list 'auto-mode-alist '("\\.shader" . shaderlab-mode))
(defun shaderlab-indent-line ()
"Indent current line as SHADERLAB code."
(interactive)
(beginning-of-line)
(let ((regexp-closing-brace "^[^ \\W\n]*};?\\w*")
(regexp-opening-brace "^.*{\\w*$")
(regexp-empty-line "^[\t ]*\n"))
(let ((not-indented t) cur-indent)
(cond ((bobp)
;(message "bobp")
(setq cur-indent 0))
((looking-at regexp-closing-brace) ; If the line we are looking at is the end of a block, then decrease the indentation
;(message "Closing brace")
(save-excursion
;Look backwards for a non-whitespace block or an opening brace
(let ((looking-for-line t))
(while looking-for-line
(forward-line -1)
(cond ((looking-at regexp-opening-brace)
(setq cur-indent (current-indentation))
(setq looking-for-line nil))
((not (looking-at regexp-empty-line))
(setq cur-indent (- (current-indentation) tab-width))
(setq looking-for-line nil))))))
(when (< cur-indent 0) ; We can't indent past the left margin
(setq cur-indent 0)))
((looking-at "^\\W*#")
(message "preprocessor")
(setq cur-indent 0))
(t (save-excursion
(while not-indented ; Iterate backwards until we find an indentation hint
(forward-line -1)
(cond ((looking-at regexp-closing-brace) ; This hint indicates that we need to indent at the level of the END_ token
;(message "Found closing brace at %s" (what-line))
(setq cur-indent (current-indentation))
(setq not-indented nil))
((looking-at regexp-opening-brace) ; This hint indicates that we need to indent an extra level
;(message "Found opening brace at %s" (what-line))
(setq cur-indent (+ (current-indentation) tab-width)) ; Do the actual indenting
(setq not-indented nil))
((bobp)
(setq not-indented nil)))))))
(if cur-indent
(progn
;(message "Indenting to %d" cur-indent)
(indent-line-to cur-indent))
;(message "not indenting!")
(indent-line-to 0))))) ; If we didn't see an indentation hint, then allow no indentation
(defvar shaderlab-mode-syntax-table
(let ((table (make-syntax-table)))
;; Populate the syntax TABLE
(modify-syntax-entry ?_ "_" table)
;(modify-syntax-entry ?_ "w" table)
(modify-syntax-entry ?\\ "\\" table)
(modify-syntax-entry ?+ "." table)
(modify-syntax-entry ?- "." table)
(modify-syntax-entry ?= "." table)
(modify-syntax-entry ?% "." table)
(modify-syntax-entry ?< "." table)
(modify-syntax-entry ?> "." table)
(modify-syntax-entry ?& "." table)
(modify-syntax-entry ?| "." table)
(modify-syntax-entry ?\' "\"" table)
;; Set up block and line oriented comments. The new C standard
;; mandates both comment styles even in C, so since all languages
;; now require dual comments, we make this the default.
;;(cond
;; Emacs 22 and higher do nothing
;; ((>= emacs-major-version 22))
;; XEmacs 19 & 20
;; ((memq '8-bit c-emacs-features)
;; (modify-syntax-entry ?/ ". 1456" table)
;; (modify-syntax-entry ?* ". 23" table))
;; Emacs 19 & 20
;; ((memq '1-bit c-emacs-features)
;; (modify-syntax-entry ?/ ". 124b" table)
;; (modify-syntax-entry ?* ". 23" table))
;; incompatible
;; (t (error "Shaderlab Mode is incompatible with this version of Emacs"))
;; )
(modify-syntax-entry ?\n "> b" table)
;; Give CR the same syntax as newline, for selective-display
(modify-syntax-entry ?\^m "> b" table)
table)
"Syntax table for shaderlab-mode")
(provide 'shaderlab-mode)
(defun shaderlab-populate-syntax-table (table)
"Populate the given syntax table as necessary for a C-like language.
This includes setting ' and \" as string delimiters, and setting up
the comment syntax to handle both line style \"//\" and block style
\"/*\" \"*/\" comments."
(modify-syntax-entry ?_ "w" table)
;(modify-syntax-entry ?_ "_" table)
(modify-syntax-entry ?\\ "\\" table)
(modify-syntax-entry ?+ "." table)
(modify-syntax-entry ?- "." table)
(modify-syntax-entry ?= "." table)
(modify-syntax-entry ?% "." table)
(modify-syntax-entry ?< "." table)
(modify-syntax-entry ?> "." table)
(modify-syntax-entry ?& "." table)
(modify-syntax-entry ?| "." table)
(modify-syntax-entry ?\' "\"" table)
(modify-syntax-entry ?\240 "." table)
;; Set up block and line oriented comments. The new C
;; standard mandates both comment styles even in C, so since
;; all languages now require dual comments, we make this the
;; default.
(modify-syntax-entry ?/ ". 124b" table)
(modify-syntax-entry ?* ". 23" table)
(modify-syntax-entry ?\n "> b" table)
;; Give CR the same syntax as newline, for selective-display
(modify-syntax-entry ?\^m "> b" table)
table)
(defvar shaderlab-mode-syntax-table2
(let ((shaderlab-mode-syntax-table2 (shaderlab-populate-syntax-table (make-syntax-table))))
shaderlab-mode-syntax-table2)
"Syntax table for shaderlab-mode")
;;; shaderlab-mode.el ends here