javascript stuff
This commit is contained in:
parent
c4e74d2121
commit
351d0dbc69
8 changed files with 1277 additions and 19 deletions
|
|
@ -255,6 +255,9 @@
|
|||
(when (memq window-system '(mac ns))
|
||||
(exec-path-from-shell-initialize))
|
||||
|
||||
;; Company mode everywhere. What could go wrong?
|
||||
(global-company-mode)
|
||||
|
||||
;; =================================================================
|
||||
;; Text mode configuration.
|
||||
;; =================================================================
|
||||
|
|
@ -514,9 +517,6 @@
|
|||
(add-to-list 'auto-mode-alist '("\\.cool$" . csharp-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.cs$" . csharp-mode))
|
||||
|
||||
(eval-after-load
|
||||
'company
|
||||
'(add-to-list 'company-backends 'company-omnisharp))
|
||||
|
||||
;; =================================================================
|
||||
;; "XML" Support
|
||||
|
|
@ -579,13 +579,6 @@
|
|||
;; Flycheck
|
||||
;; =================================================================
|
||||
(require 'flycheck)
|
||||
;; disable jshint since we prefer eslint checking
|
||||
(setq-default flycheck-disabled-checkers
|
||||
(append flycheck-disabled-checkers
|
||||
'(javascript-jshint)))
|
||||
|
||||
;; use eslint with web-mode for jsx files
|
||||
(flycheck-add-mode 'javascript-eslint 'web-mode)
|
||||
|
||||
;; customize flycheck temp file prefix
|
||||
(setq-default flycheck-temp-prefix ".flycheck")
|
||||
|
|
@ -625,17 +618,34 @@
|
|||
;; =================================================================
|
||||
(autoload 'python-mode "python-mode" "Python editing mode." t)
|
||||
|
||||
(setq auto-mode-alist
|
||||
(cons '("\\.py$" . python-mode) auto-mode-alist))
|
||||
(setq interpreter-mode-alist
|
||||
(cons '("python" . python-mode) interpreter-mode-alist))
|
||||
(add-to-list 'auto-mode-alist '("\\.py$" . python-mode))
|
||||
(add-to-list 'interpreter-mode-alist '("python" . python-mode))
|
||||
|
||||
;; =================================================================
|
||||
;; JavaScript Support
|
||||
;; =================================================================
|
||||
(autoload 'js2-mode "js2-mode" nil t)
|
||||
(add-to-list 'auto-mode-alist '("\\.js$" . js2-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.jsx$" . web-mode))
|
||||
(require 'rjsx-mode)
|
||||
(require 'prettier-js)
|
||||
(require 'flycheck-flow)
|
||||
(require 'flow-minor-mode)
|
||||
|
||||
;; disable jshint since we prefer eslint checking
|
||||
(setq-default flycheck-disabled-checkers
|
||||
(append flycheck-disabled-checkers
|
||||
'(javascript-jshint)))
|
||||
(flycheck-add-next-checker 'javascript-eslint 'javascript-flow)
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.js$" . rjsx-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.jsx$" . rjsx-mode))
|
||||
|
||||
(defun my-js-mode-hook ()
|
||||
"My custom javascript mode hook."
|
||||
(add-node-modules-path)
|
||||
(flow-minor-enable-automatically)
|
||||
(prettier-js-mode))
|
||||
|
||||
(add-hook 'rjsx-mode-hook #'my-js-mode-hook)
|
||||
|
||||
|
||||
;; =================================================================
|
||||
;; Ruby Mode
|
||||
|
|
|
|||
|
|
@ -14,6 +14,11 @@
|
|||
'(comint-input-ignoredups t)
|
||||
'(comint-prompt-read-only t)
|
||||
'(comint-scroll-to-bottom-on-input t)
|
||||
'(company-backends
|
||||
(quote
|
||||
(company-bbdb company-nxml company-css company-eclim company-semantic company-clang company-xcode company-cmake company-capf company-files
|
||||
(company-dabbrev-code company-gtags company-etags company-keywords)
|
||||
company-oddmuse company-dabbrev company-flow)))
|
||||
'(css-indent-offset 2)
|
||||
'(debug-on-error nil)
|
||||
'(fast-lock-cache-directories (quote ("~/flc-cache")))
|
||||
|
|
@ -46,7 +51,7 @@
|
|||
((sequence "TODO" "|" "DONE" "ABANDONED" "DEFERRED"))))
|
||||
'(package-selected-packages
|
||||
(quote
|
||||
(company omnisharp geiser cider clojure-mode graphviz-dot-mode multi-term xterm-color thrift markdown-mode tuareg merlin ag use-package flycheck dockerfile-mode js2-mode web-mode zencoding-mode tss switch-window python-mode paredit magit lua-mode go-mode go-autocomplete exec-path-from-shell csharp-mode color-theme-solarized color-theme-monokai auto-complete auto-complete-nxml flymake flyspell json-mode popup ruby-mode)))
|
||||
(mocha add-node-modules-path rjsx-mode xref-js2 js2-refactor company omnisharp geiser cider clojure-mode graphviz-dot-mode multi-term xterm-color thrift markdown-mode tuareg merlin ag use-package flycheck dockerfile-mode js2-mode web-mode zencoding-mode tss switch-window python-mode paredit magit lua-mode go-mode go-autocomplete exec-path-from-shell csharp-mode color-theme-solarized color-theme-monokai auto-complete auto-complete-nxml flymake flyspell json-mode popup ruby-mode)))
|
||||
'(reb-re-syntax (quote string))
|
||||
'(rmail-mail-new-frame t)
|
||||
'(safe-local-variable-values
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
(
|
||||
(:id "sha1:24c7a1e6369fef1e50de1deb1a9e5bbc68f80c8b" :fingerprint "sha1:26:26:88:6a:58:94:85:2f:98:ce:97:a0:0d:93:75:63:0a:9e:44:b5" :host "orgmode.org:443" :conditions (:insecure :unknown-ca :invalid))
|
||||
(:id "sha1:60f141fb7e2767fbc9d5f309850c9db8bfaadb86" :fingerprint "sha1:f3:eb:c5:20:3c:f3:c8:79:46:3b:2d:d4:b7:c2:12:09:54:0e:d9:3b" :host "github-production-release-asset-2e65be.s3.amazonaws.com:443" :conditions (:insecure :unknown-ca :invalid))
|
||||
(:id "sha1:379522f41fcdf5d279b33c30780e7512c9348430" :fingerprint "sha1:d4:ee:9d:2a:67:12:b3:61:4c:27:2d:15:8b:04:fc:c8:ca:08:a0:b6" :host "github.com:443" :conditions (:insecure :unknown-ca :invalid))
|
||||
(:id "sha1:24c7a1e6369fef1e50de1deb1a9e5bbc68f80c8b" :fingerprint "sha1:fe:3b:22:d5:9b:33:20:74:3c:0d:7e:d2:7d:71:41:5d:84:e7:ca:82" :host "orgmode.org:443" :conditions (:insecure :unknown-ca :invalid))
|
||||
(:id "sha1:85457c729378cc93c732b6a3941c8e4f9c2e60f3" :fingerprint "sha1:ab:a6:d7:6a:b3:d3:63:fa:19:0d:65:41:60:23:6e:ef:d3:2a:46:dc" :host "marmalade-repo.org:443" :conditions (:unknown-ca :invalid))
|
||||
)
|
||||
|
|
|
|||
208
site-lisp/company-flow.el
Normal file
208
site-lisp/company-flow.el
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
;;; company-flow.el --- Flow backend for company-mode -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2016 by Aaron Jensen
|
||||
|
||||
;; Author: Aaron Jensen <aaronjensen@gmail.com>
|
||||
;; URL: https://github.com/aaronjensen/company-flow
|
||||
;; Version: 0.1.0
|
||||
;; Package-Requires: ((company "0.8.0") (dash "2.13.0"))
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This package adds support for flow to company. It requires
|
||||
;; flow to be in your path.
|
||||
|
||||
;; To use it, add to your company-backends:
|
||||
|
||||
;; (eval-after-load 'company
|
||||
;; '(add-to-list 'company-backends 'company-flow))
|
||||
|
||||
;;; License:
|
||||
|
||||
;; This file is not part of GNU Emacs.
|
||||
;; However, it is distributed under the same license.
|
||||
|
||||
;; GNU Emacs 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.
|
||||
|
||||
;; GNU Emacs 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 GNU Emacs; see the file COPYING. If not, write to the
|
||||
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
;; Boston, MA 02110-1301, USA.
|
||||
|
||||
;;; Code:
|
||||
(require 'company)
|
||||
(require 'dash)
|
||||
|
||||
(defgroup company-flow ()
|
||||
"Flow company backend."
|
||||
:group 'company
|
||||
:prefix "company-flow-")
|
||||
|
||||
(defcustom company-flow-executable "flow"
|
||||
"Flow executable to run."
|
||||
:group 'company-flow
|
||||
:type 'string)
|
||||
(make-variable-buffer-local 'company-flow-executable)
|
||||
|
||||
(defcustom company-flow-modes '(
|
||||
js-mode
|
||||
js-jsx-mode
|
||||
js2-mode
|
||||
js2-jsx-mode
|
||||
rjsx-mode
|
||||
web-mode
|
||||
)
|
||||
"List of major modes where company-flow will be providing completions."
|
||||
:type '(choice (const :tag "All" nil)
|
||||
(repeat (symbol :tag "Major mode")))
|
||||
:group 'company-flow)
|
||||
|
||||
(defun company-flow--handle-signal (process _event)
|
||||
(when (memq (process-status process) '(signal exit))
|
||||
(let ((callback (process-get process 'company-flow-callback))
|
||||
(prefix (process-get process 'company-flow-prefix)))
|
||||
(if (and (eq (process-status process) 'exit)
|
||||
(eq (process-exit-status process) 0))
|
||||
(funcall callback (->> process
|
||||
company-flow--get-output
|
||||
company-flow--parse-output
|
||||
;; Remove nils
|
||||
(--filter it)))
|
||||
(funcall callback nil)))))
|
||||
|
||||
(defun company-flow--make-candidate (line)
|
||||
"Creates a candidate with a meta property from LINE.
|
||||
|
||||
LINE is expected to look like:
|
||||
registrationSuccess () => {type: 'REGISTRATION_SUCCESS'}"
|
||||
(let ((first-space (string-match " " line)))
|
||||
(when first-space
|
||||
(let ((text (substring line 0 first-space))
|
||||
(meta (substring line (+ 1 first-space))))
|
||||
(propertize text 'meta meta)))))
|
||||
|
||||
(defun company-flow--parse-output (output)
|
||||
(when (not (equal output "Error: not enough type information to autocomplete\n"))
|
||||
(mapcar 'company-flow--make-candidate
|
||||
(split-string output "\n"))))
|
||||
|
||||
(defun company-flow--get-output (process)
|
||||
"Get the complete output of PROCESS."
|
||||
(with-demoted-errors "Error while retrieving process output: %S"
|
||||
(let ((pending-output (process-get process 'company-flow-pending-output)))
|
||||
(apply #'concat (nreverse pending-output)))))
|
||||
|
||||
(defun company-flow--receive-checker-output (process output)
|
||||
"Receive a syntax checking PROCESS OUTPUT."
|
||||
(push output (process-get process 'company-flow-pending-output)))
|
||||
|
||||
(defun company-flow--process-send-buffer (process)
|
||||
"Send all contents of current buffer to PROCESS.
|
||||
|
||||
Sends all contents of the current buffer to the standard input of
|
||||
PROCESS, and terminates standard input with EOF."
|
||||
(save-restriction
|
||||
(widen)
|
||||
(process-send-region process (point-min) (point-max)))
|
||||
;; flow requires EOF be on its own line
|
||||
(process-send-string process "\n")
|
||||
(process-send-eof process))
|
||||
|
||||
(defun company-flow--candidates-query (prefix callback)
|
||||
(let* ((line (line-number-at-pos (point)))
|
||||
(col (+ 1 (current-column)))
|
||||
(command (list (executable-find company-flow-executable)
|
||||
"autocomplete"
|
||||
"--quiet"
|
||||
buffer-file-name
|
||||
(number-to-string line)
|
||||
(number-to-string col)))
|
||||
(process-connection-type nil)
|
||||
(process (apply 'start-process "company-flow" nil command)))
|
||||
(set-process-sentinel process #'company-flow--handle-signal)
|
||||
(set-process-filter process #'company-flow--receive-checker-output)
|
||||
(process-put process 'company-flow-callback callback)
|
||||
(process-put process 'company-flow-prefix prefix)
|
||||
(company-flow--process-send-buffer process)))
|
||||
|
||||
(defun company-flow--prefix ()
|
||||
"Grab prefix for flow."
|
||||
(and (or (null company-flow-modes)
|
||||
(-contains? company-flow-modes major-mode))
|
||||
company-flow-executable
|
||||
(executable-find company-flow-executable)
|
||||
buffer-file-name
|
||||
(file-exists-p buffer-file-name)
|
||||
(not (company-in-string-or-comment))
|
||||
(locate-dominating-file buffer-file-name ".flowconfig")
|
||||
(or (company-grab-symbol-cons "\\." 1)
|
||||
'stop)))
|
||||
|
||||
(defun company-flow--annotation (candidate)
|
||||
(format " %s" (get-text-property 0 'meta candidate)))
|
||||
|
||||
(defun company-flow--meta (candidate)
|
||||
(format "%s: %s" candidate (get-text-property 0 'meta candidate)))
|
||||
|
||||
(defvar-local company-flow--debounce-state nil)
|
||||
|
||||
(defun company-flow--debounce-callback (prefix callback)
|
||||
(lambda (candidates)
|
||||
(let ((current-prefix (car company-flow--debounce-state))
|
||||
(current-callback (cdr company-flow--debounce-state)))
|
||||
(when (and current-prefix
|
||||
(company-flow--string-prefix-p prefix current-prefix))
|
||||
(setq company-flow--debounce-state nil)
|
||||
(funcall current-callback (all-completions current-prefix candidates))))))
|
||||
|
||||
(defun company-flow--prefix-to-string (prefix)
|
||||
"Return a string or nil from a prefix.
|
||||
`company-grab-symbol-cons' can return (\"prefix\" . t) or just
|
||||
\"prefix\", but we only care about the string."
|
||||
(if (consp prefix)
|
||||
(car prefix)
|
||||
prefix))
|
||||
|
||||
(defun company-flow--string-prefix-p (a b)
|
||||
(string-prefix-p (company-flow--prefix-to-string a) (company-flow--prefix-to-string b)))
|
||||
|
||||
(defun company-flow--debounce-async (prefix candidate-fn)
|
||||
"Return a function that will properly debounce candidate queries by comparing the
|
||||
in-flight query's prefix to PREFIX. CANDIDATE-FN should take two arguments, PREFIX
|
||||
and the typical async callback.
|
||||
|
||||
Note that the candidate list provided to the callback by CANDIDATE-FN will be
|
||||
filtered via `all-completions' with the most current prefix, so it is not necessary
|
||||
to do this filtering in CANDIDATE-FN.
|
||||
|
||||
Use like:
|
||||
|
||||
(cons :async (company-flow--debounce-async arg 'your-query-fn))"
|
||||
(lambda (callback)
|
||||
(let ((current-prefix (car company-flow--debounce-state)))
|
||||
(unless (and current-prefix
|
||||
(company-flow--string-prefix-p prefix current-prefix))
|
||||
(funcall candidate-fn prefix (company-flow--debounce-callback prefix callback)))
|
||||
(setq company-flow--debounce-state (cons (company-flow--prefix-to-string prefix) callback)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun company-flow (command &optional arg &rest _args)
|
||||
(interactive (list 'interactive))
|
||||
(pcase command
|
||||
(`interactive (company-begin-backend 'company-flow))
|
||||
(`prefix (company-flow--prefix))
|
||||
(`annotation (company-flow--annotation arg))
|
||||
(`meta (company-flow--meta arg))
|
||||
(`sorted t)
|
||||
(`candidates (cons :async (company-flow--debounce-async arg 'company-flow--candidates-query)))))
|
||||
|
||||
(provide 'company-flow)
|
||||
;;; company-flow.el ends here
|
||||
322
site-lisp/flow-minor-mode.el
Normal file
322
site-lisp/flow-minor-mode.el
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
;;; flow-minor-mode.el --- Flow type mode based on web-mode. -*- lexical-binding: t -*-
|
||||
|
||||
;; This source code is licensed under the BSD-style license found in
|
||||
;; the LICENSE file in the root directory of this source tree.
|
||||
|
||||
;; Version: 0.3
|
||||
;; URL: https://github.com/an-sh/flow-minor-mode
|
||||
|
||||
;; Package-Requires: ((emacs "25.1"))
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Minor mode for flowtype.org, derived from web-mode. Essentially a
|
||||
;; rewrite of an official flow-for-emacs snippet into a standalone
|
||||
;; mode with an improved usability.
|
||||
;;
|
||||
;; To enable this mode, enable it in your preferred javascript mode's
|
||||
;; hooks:
|
||||
;;
|
||||
;; (add-hook 'js2-mode-hook 'flow-minor-enable-automatically)
|
||||
;;
|
||||
;; This will enable flow-minor-mode for a file only when there is a
|
||||
;; "// @flow" declaration at the first line and a `.flowconfig` file
|
||||
;; is present in the project. If you wish to enable flow-minor-mode
|
||||
;; for all javascript files, use this instead:
|
||||
;;
|
||||
;; (add-hook 'js2-mode-hook 'flow-minor-mode)
|
||||
;;
|
||||
;;; Code:
|
||||
|
||||
(require 'xref)
|
||||
(require 'json)
|
||||
(require 'compile)
|
||||
|
||||
(defconst flow-minor-buffer "*Flow Output*")
|
||||
|
||||
(defcustom flow-minor-default-binary "flow"
|
||||
"Flow executable to use when no project-specific binary is found."
|
||||
:group 'flow-minor-mode
|
||||
:type 'string)
|
||||
|
||||
(defcustom flow-minor-jump-other-window nil
|
||||
"Jump to definitions in other window."
|
||||
:group 'flow-minor-mode
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom flow-minor-stop-server-on-exit t
|
||||
"Stop flow server when Emacs exits."
|
||||
:group 'flow-minor-mode
|
||||
:type 'boolean)
|
||||
|
||||
(defun flow-minor-column-at-pos (position)
|
||||
"Column number at position.
|
||||
POSITION point"
|
||||
(save-excursion (goto-char position) (current-column)))
|
||||
|
||||
(defun flow-minor-region ()
|
||||
"Format region data."
|
||||
(if (use-region-p)
|
||||
(let ((begin (region-beginning))
|
||||
(end (region-end)))
|
||||
(format ":%d:%d,%d:%d"
|
||||
(line-number-at-pos begin)
|
||||
(flow-minor-column-at-pos begin)
|
||||
(line-number-at-pos end)
|
||||
(flow-minor-column-at-pos end)))
|
||||
""))
|
||||
|
||||
(defun flow-minor-binary ()
|
||||
"Search for a local or global flow binary."
|
||||
(let* ((root (locate-dominating-file
|
||||
(or (buffer-file-name) default-directory)
|
||||
"node_modules"))
|
||||
(flow (and root
|
||||
(expand-file-name "node_modules/.bin/flow"
|
||||
root))))
|
||||
(if (and flow (file-executable-p flow))
|
||||
flow
|
||||
flow-minor-default-binary)))
|
||||
|
||||
(defun flow-minor-cmd (&rest args)
|
||||
"Run flow with arguments, outputs to flow buffer.
|
||||
ARGS"
|
||||
(apply #'call-process (flow-minor-binary) nil flow-minor-buffer t args))
|
||||
|
||||
(defun flow-minor-cmd-ignore-output (&rest args)
|
||||
"Run flow with arguments, ignore output.
|
||||
ARGS"
|
||||
(apply #'call-process (flow-minor-binary) nil nil nil args))
|
||||
|
||||
(defun flow-minor-cmd-to-string (&rest args)
|
||||
"Run flow with arguments, outputs to string.
|
||||
ARGS"
|
||||
(with-temp-buffer
|
||||
(apply #'call-process (flow-minor-binary) nil t nil args)
|
||||
(buffer-string)))
|
||||
|
||||
(defmacro flow-minor-with-flow (&rest body)
|
||||
"With flow.
|
||||
BODY progn"
|
||||
`(progn
|
||||
(flow-minor-cmd-ignore-output "start")
|
||||
,@body))
|
||||
|
||||
(defmacro flow-minor-region-command (region-sym &rest body)
|
||||
"Flow command on a region.
|
||||
REGION-SYM symbol
|
||||
BODY progn"
|
||||
(declare (indent defun))
|
||||
`(flow-minor-with-flow
|
||||
(let ((,region-sym (concat (buffer-file-name) (flow-minor-region))))
|
||||
(switch-to-buffer-other-window flow-minor-buffer)
|
||||
(setf buffer-read-only nil)
|
||||
(erase-buffer)
|
||||
,@body)))
|
||||
|
||||
(defun flow-minor-status ()
|
||||
"Show errors."
|
||||
(interactive)
|
||||
(flow-minor-region-command region
|
||||
(flow-minor-cmd "status" "--from" "emacs")
|
||||
(compilation-mode)
|
||||
(setf buffer-read-only t)))
|
||||
|
||||
(defun flow-minor-suggest ()
|
||||
"Fill types."
|
||||
(interactive)
|
||||
(flow-minor-region-command region
|
||||
(flow-minor-cmd "suggest" region)
|
||||
(diff-mode)
|
||||
(setf buffer-read-only t)))
|
||||
|
||||
(defun flow-minor-coverage ()
|
||||
"Show coverage."
|
||||
(interactive)
|
||||
(flow-minor-region-command region
|
||||
(message "%s" region)
|
||||
(flow-minor-cmd "coverage" region)
|
||||
(compilation-mode)
|
||||
(setf buffer-read-only t)))
|
||||
|
||||
(defvar flow-type-font-lock-highlight
|
||||
'(
|
||||
("\\([-_[:alnum:]]+\\)\\??:" . font-lock-variable-name-face)
|
||||
("\\_<\\(true\\|false\\|null\\|undefined\\|void\\)\\_>" . font-lock-constant-face)
|
||||
("<\\([-_[:alnum:]]+\\)>" . font-lock-type-face)
|
||||
))
|
||||
|
||||
(defun flow-minor-colorize-buffer ()
|
||||
(setq font-lock-defaults '(flow-type-font-lock-highlight))
|
||||
(font-lock-fontify-buffer))
|
||||
|
||||
(defun flow-minor-colorize-type (text)
|
||||
(with-temp-buffer
|
||||
(insert text)
|
||||
(flow-minor-colorize-buffer)
|
||||
(buffer-string)))
|
||||
|
||||
(defun flow-minor-type-at-pos ()
|
||||
"Show type at position."
|
||||
(interactive)
|
||||
(flow-minor-with-flow
|
||||
(let* ((file (buffer-file-name))
|
||||
(line (number-to-string (line-number-at-pos)))
|
||||
(col (number-to-string (1+ (current-column))))
|
||||
(type (flow-minor-cmd-to-string "type-at-pos" file line col)))
|
||||
(message "%s" (flow-minor-colorize-type (car (split-string type "\n")))))))
|
||||
|
||||
(defun flow-minor-jump-to-definition ()
|
||||
"Jump to definition."
|
||||
(interactive)
|
||||
(flow-minor-with-flow
|
||||
(let* ((file (buffer-file-name))
|
||||
(line (number-to-string (line-number-at-pos)))
|
||||
(col (number-to-string (1+ (current-column))))
|
||||
(location (json-read-from-string
|
||||
(flow-minor-cmd-to-string "get-def" "--json" file line col)))
|
||||
(path (alist-get 'path location))
|
||||
(line (alist-get 'line location))
|
||||
(offset-in-line (alist-get 'start location)))
|
||||
(if (> (length path) 0)
|
||||
(progn
|
||||
(xref-push-marker-stack)
|
||||
(funcall (if flow-minor-jump-other-window #'find-file-other-window #'find-file) path)
|
||||
(goto-line line)
|
||||
(when (> offset-in-line 0)
|
||||
(forward-char (1- offset-in-line))))
|
||||
(message "Not found")))))
|
||||
|
||||
(defvar flow-minor-mode-map (make-sparse-keymap)
|
||||
"Keymap for ‘flow-minor-mode’.")
|
||||
|
||||
(define-key flow-minor-mode-map (kbd "M-.") 'flow-minor-jump-to-definition)
|
||||
(define-key flow-minor-mode-map (kbd "M-,") 'xref-pop-marker-stack)
|
||||
|
||||
(define-key flow-minor-mode-map (kbd "C-c C-c s") 'flow-minor-status)
|
||||
(define-key flow-minor-mode-map (kbd "C-c C-c c") 'flow-minor-coverage)
|
||||
(define-key flow-minor-mode-map (kbd "C-c C-c t") 'flow-minor-type-at-pos)
|
||||
(define-key flow-minor-mode-map (kbd "C-c C-c f") 'flow-minor-suggest)
|
||||
|
||||
(define-key flow-minor-mode-map [menu-bar flow-minor-mode]
|
||||
(cons "Flow" flow-minor-mode-map))
|
||||
|
||||
(define-key flow-minor-mode-map [menu-bar flow-minor-mode flow-minor-mode-s]
|
||||
'(menu-item "Flow status" flow-minor-status))
|
||||
|
||||
(define-key flow-minor-mode-map [menu-bar flow-minor-mode flow-minor-mode-c]
|
||||
'(menu-item "Flow coverage" flow-minor-coverage))
|
||||
|
||||
(define-key flow-minor-mode-map [menu-bar flow-minor-mode flow-minor-mode-t]
|
||||
'(menu-item "Type at point" flow-minor-type-at-pos))
|
||||
|
||||
(define-key flow-minor-mode-map [menu-bar flow-minor-mode flow-minor-mode-f]
|
||||
'(menu-item "Type suggestions" flow-minor-suggest))
|
||||
|
||||
(defun flow-minor-stop-flow-server ()
|
||||
"Stop flow hook."
|
||||
(if flow-minor-stop-server-on-exit (ignore-errors (flow-minor-cmd-ignore-output "stop"))))
|
||||
|
||||
(add-hook 'kill-emacs-hook 'flow-minor-stop-flow-server t)
|
||||
|
||||
(defun flow-minor-maybe-delete-process (name)
|
||||
(when (get-process name)
|
||||
(delete-process name)))
|
||||
|
||||
(defun flow-minor-eldoc-sentinel (process _event)
|
||||
(when (eq (process-status process) 'exit)
|
||||
(if (eq (process-exit-status process) 0)
|
||||
(with-current-buffer "*Flow Eldoc*"
|
||||
(goto-char (point-min))
|
||||
(forward-line 1)
|
||||
(delete-region (point) (point-max))
|
||||
(flow-minor-colorize-buffer)
|
||||
(eldoc-message (car (split-string (buffer-substring (point-min) (point-max)) "\n")))))))
|
||||
|
||||
(defun flow-minor-eldoc-documentation-function ()
|
||||
"Display type at point with eldoc."
|
||||
(flow-minor-maybe-delete-process "flow-minor-eldoc")
|
||||
|
||||
(let* ((line (line-number-at-pos (point)))
|
||||
(col (+ 1 (current-column)))
|
||||
(buffer (get-buffer-create "*Flow Eldoc*"))
|
||||
(errorbuffer (get-buffer-create "*Flow Eldoc Error*"))
|
||||
(command (list (flow-minor-binary)
|
||||
"type-at-pos"
|
||||
"--path" buffer-file-name
|
||||
(number-to-string line)
|
||||
(number-to-string col)))
|
||||
(process (make-process :name "flow-minor-eldoc"
|
||||
:buffer buffer
|
||||
:command command
|
||||
:connection-type 'pipe
|
||||
:sentinel 'flow-minor-eldoc-sentinel
|
||||
:stderr errorbuffer)))
|
||||
(with-current-buffer buffer
|
||||
(erase-buffer))
|
||||
(with-current-buffer errorbuffer
|
||||
(erase-buffer))
|
||||
(save-restriction
|
||||
(widen)
|
||||
(process-send-region process (point-min) (point-max)))
|
||||
(process-send-string process "\n")
|
||||
(process-send-eof process))
|
||||
nil)
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode flow-minor-mode
|
||||
"Flow mode"
|
||||
nil " Flow" flow-minor-mode-map
|
||||
(if flow-minor-mode
|
||||
(progn
|
||||
(setq-local eldoc-documentation-function 'flow-minor-eldoc-documentation-function)
|
||||
(eldoc-mode))))
|
||||
|
||||
(defun flow-minor-tag-present-p ()
|
||||
"Return true if the '// @flow' tag is present in the current buffer."
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(let (stop found)
|
||||
(while (not stop)
|
||||
(when (not (re-search-forward "[^\n[:space:]]" nil t))
|
||||
(setq stop t))
|
||||
(if (equal (point) (point-min))
|
||||
(setq stop t)
|
||||
(backward-char))
|
||||
(cond ((or (looking-at "//+[ ]*@flow")
|
||||
(looking-at "/\\**[ ]*@flow"))
|
||||
(setq found t)
|
||||
(setq stop t))
|
||||
((looking-at "//")
|
||||
(forward-line))
|
||||
((looking-at "/\\*")
|
||||
(when (not (re-search-forward "*/" nil t))
|
||||
(setq stop t)))
|
||||
(t (setq stop t))))
|
||||
found)))
|
||||
|
||||
(defun flow-minor-configured-p ()
|
||||
"Predicate to check configuration."
|
||||
(locate-dominating-file
|
||||
(or (buffer-file-name) default-directory)
|
||||
".flowconfig"))
|
||||
|
||||
;;;###autoload
|
||||
(defun flow-minor-enable-automatically ()
|
||||
"Search for a flow marker and enable flow-minor-mode."
|
||||
(when (and (flow-minor-configured-p)
|
||||
(flow-minor-tag-present-p))
|
||||
(flow-minor-mode +1)))
|
||||
|
||||
(defun flow-status ()
|
||||
"Invoke flow to check types"
|
||||
(interactive)
|
||||
(let ((cmd "flow status")
|
||||
(regexp '(flow "^\\(Error:\\)[ \t]+\\(\\(.+\\):\\([[:digit:]]+\\)\\)"
|
||||
3 4 nil (1) 2 (1 compilation-error-face))))
|
||||
(add-to-list 'compilation-error-regexp-alist 'flow)
|
||||
(add-to-list 'compilation-error-regexp-alist-alist regexp)
|
||||
(compile cmd)))
|
||||
|
||||
(provide 'flow-minor-mode)
|
||||
;;; flow-minor-mode.el ends here
|
||||
173
site-lisp/flycheck-flow.el
Normal file
173
site-lisp/flycheck-flow.el
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
;;; flycheck-flow.el --- Support Flow in flycheck
|
||||
|
||||
;; Copyright (C) 2015 Lorenzo Bolla <lbolla@gmail.com>
|
||||
;;
|
||||
;; Author: Lorenzo Bolla <lbolla@gmail.com>
|
||||
;; Created: 16 Septermber 2015
|
||||
;; Version: 1.1
|
||||
;; Package-Requires: ((flycheck "0.18") (json "1.4"))
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This package adds support for flow to flycheck. It requires
|
||||
;; flow>=0.20.0.
|
||||
|
||||
;; To use it, add to your init.el:
|
||||
|
||||
;; (require 'flycheck-flow)
|
||||
;; (add-hook 'javascript-mode-hook 'flycheck-mode)
|
||||
|
||||
;; You want to use flow in conjunction with other JS checkers.
|
||||
;; E.g. to use with gjslint, add this to your init.el
|
||||
;; (flycheck-add-next-checker 'javascript-gjslint 'javascript-flow)
|
||||
|
||||
;; For coverage warnings add this to your init.el
|
||||
;; (flycheck-add-next-checker 'javascript-flow 'javascript-flow-coverage)
|
||||
|
||||
;;; License:
|
||||
|
||||
;; This file is not part of GNU Emacs.
|
||||
;; However, it is distributed under the same license.
|
||||
|
||||
;; GNU Emacs 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.
|
||||
|
||||
;; GNU Emacs 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 GNU Emacs; see the file COPYING. If not, write to the
|
||||
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
;; Boston, MA 02110-1301, USA.
|
||||
|
||||
;;; Code:
|
||||
(require 'flycheck)
|
||||
(require 'json)
|
||||
|
||||
(flycheck-def-args-var flycheck-javascript-flow-args javascript-flow)
|
||||
(customize-set-variable 'flycheck-javascript-flow-args '())
|
||||
|
||||
(defun flycheck-flow--parse-json (output checker buffer)
|
||||
"Parse flycheck json OUTPUT generated by CHECKER on BUFFER."
|
||||
(let* ((json-object-type 'alist)
|
||||
(json-array-type 'list)
|
||||
(flow-json-output (json-read-from-string output))
|
||||
(flow-errors-list (cdr (assq 'errors flow-json-output)))
|
||||
message-kind
|
||||
message-level
|
||||
message-code-reason
|
||||
message-filename
|
||||
message-line
|
||||
message-column
|
||||
message-descr
|
||||
errors)
|
||||
(dolist (error-message flow-errors-list)
|
||||
;; The structure for each `error-message' in `flow-errors-list' is like this:
|
||||
;; ((kind . `message-kind')
|
||||
;; (level . `message-level')
|
||||
;; (message ((descr . `message-code-reason')
|
||||
;; (loc (source . `message-filename')
|
||||
;; (start (line . `message-line') (column . `message-column'))))
|
||||
;; ((descr . `message-descr'))))
|
||||
(let-alist error-message
|
||||
(setq message-kind .kind)
|
||||
(setq message-level (intern .level))
|
||||
|
||||
(let-alist (car .message)
|
||||
(setq message-code-reason .descr
|
||||
message-filename .loc.source
|
||||
message-line .loc.start.line
|
||||
message-descr .descr
|
||||
message-column .loc.start.column))
|
||||
|
||||
(let-alist (car (cdr .message))
|
||||
(when (string= .type "Comment")
|
||||
(setq message-descr .descr))))
|
||||
|
||||
(when (string= message-kind "parse")
|
||||
(setq message-descr message-kind))
|
||||
|
||||
(push (flycheck-error-new-at
|
||||
message-line
|
||||
message-column
|
||||
message-level
|
||||
message-descr
|
||||
:id message-code-reason
|
||||
:checker checker
|
||||
:buffer buffer
|
||||
:filename message-filename)
|
||||
errors))
|
||||
(nreverse errors)))
|
||||
|
||||
(defun flycheck-flow--predicate ()
|
||||
"Shall we run the checker?"
|
||||
(and
|
||||
buffer-file-name
|
||||
(file-exists-p buffer-file-name)
|
||||
(locate-dominating-file buffer-file-name ".flowconfig")))
|
||||
|
||||
(flycheck-define-checker javascript-flow
|
||||
"A JavaScript syntax and style checker using Flow.
|
||||
|
||||
See URL `http://flowtype.org/'."
|
||||
:command (
|
||||
"flow"
|
||||
"check-contents"
|
||||
(eval flycheck-javascript-flow-args)
|
||||
"--json"
|
||||
"--from" "emacs"
|
||||
"--color=never"
|
||||
source-original)
|
||||
:standard-input t
|
||||
:predicate flycheck-flow--predicate
|
||||
:error-parser flycheck-flow--parse-json
|
||||
;; js3-mode doesn't support jsx
|
||||
:modes (js-mode js-jsx-mode js2-mode js2-jsx-mode js3-mode web-mode rjsx-mode))
|
||||
|
||||
(flycheck-define-checker javascript-flow-coverage
|
||||
"A coverage checker for Flow.
|
||||
|
||||
See URL `http://flowtype.org/'."
|
||||
:command (
|
||||
"flow"
|
||||
"coverage"
|
||||
(eval flycheck-javascript-flow-args)
|
||||
"--json"
|
||||
"--from" "emacs"
|
||||
"--path" source-original)
|
||||
:standard-input t
|
||||
:predicate flycheck-flow--predicate
|
||||
:error-parser
|
||||
(lambda (output checker buffer)
|
||||
(let* ((json-array-type 'list)
|
||||
(json-object-type 'alist)
|
||||
(locs (condition-case nil
|
||||
(let ((report (json-read-from-string output)))
|
||||
(alist-get 'uncovered_locs (alist-get 'expressions report)))
|
||||
(error nil))))
|
||||
(mapcar (lambda (loc)
|
||||
(let ((start (alist-get 'start loc))
|
||||
(end (alist-get 'end loc)))
|
||||
(flycheck-error-new
|
||||
:buffer buffer
|
||||
:checker 'javascript-flow-coverage
|
||||
:filename buffer-file-name
|
||||
:line (alist-get 'line start)
|
||||
:column (alist-get 'column start)
|
||||
:message (format "no-coverage-to (%s . %s)"
|
||||
(alist-get 'line end)
|
||||
(alist-get 'column end))
|
||||
:level 'warning)))
|
||||
locs)))
|
||||
;; js3-mode doesn't support jsx
|
||||
:modes (js-mode js-jsx-mode js2-mode js2-jsx-mode js3-mode rjsx-mode))
|
||||
|
||||
(add-to-list 'flycheck-checkers 'javascript-flow)
|
||||
(add-to-list 'flycheck-checkers 'javascript-flow-coverage t)
|
||||
|
||||
(provide 'flycheck-flow)
|
||||
;;; flycheck-flow.el ends here
|
||||
327
site-lisp/glsl-mode.el
Normal file
327
site-lisp/glsl-mode.el
Normal file
|
|
@ -0,0 +1,327 @@
|
|||
;;; glsl-mode.el --- major mode for Open GLSL shader files
|
||||
|
||||
;; Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2011, 2014 Jim Hourihan
|
||||
;;
|
||||
;; Authors: Xavier.Decoret@imag.fr,
|
||||
;; Jim Hourihan <jimhourihan ~at~ gmail.com> (updated for 4.5, etc)
|
||||
;; Keywords: languages
|
||||
;; Version: 2.0
|
||||
;; X-URL: http://artis.inrialpes.fr/~Xavier.Decoret/resources/glsl-mode/
|
||||
;;
|
||||
;; This software 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 GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
;;; 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.5
|
||||
;; * 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.5
|
||||
;; * 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 w3m
|
||||
|
||||
;;; 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))
|
||||
|
||||
;;; 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.5"
|
||||
"GLSL language version number.")
|
||||
|
||||
(defconst gl-version "4.5"
|
||||
"OpenGL major mode version number.")
|
||||
|
||||
(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 glsl-builtin-face))) "glsl: deprecated builtin 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 glsl-keyword-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 glsl-variable-name-face))) "glsl: deprecated variable 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)
|
||||
|
||||
(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-man-pages-base-url "http://www.opengl.org/sdk/docs/man/html/"
|
||||
"Location of GL man pages"
|
||||
: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" "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" "long" "short"
|
||||
"half" "fixed" "unsigned" "hvec2" "hvec3" "hvec4" "fvec2" "fvec3" "fvec4"
|
||||
"sampler3DRect"))
|
||||
|
||||
(defvar glsl-modifier-list
|
||||
'("attribute" "const" "uniform" "varying" "buffer" "shared" "coherent" "volatile" "restrict"
|
||||
"readonly" "writeonly" "atomic_uint" "layout" "centroid" "flat" "smooth"
|
||||
"noperspective" "patch" "sample" "break" "continue" "do" "for" "while"
|
||||
"switch" "case" "default" "if" "else" "subroutine" "in" "out" "inout"
|
||||
"invariant" "discard" "return" "lowp" "mediump" "highp" "precision"
|
||||
"struct" "common" "partition" "active" "asm" "class" "union" "enum"
|
||||
"typedef" "template" "this" "packed" "resource" "goto" "inline" "noinline"
|
||||
"public" "static" "extern" "external" "interface" "superp" "input" "output"
|
||||
"filter" "sizeof" "cast" "namespace" "using" "row_major"
|
||||
"early_fragment_tests"))
|
||||
|
||||
(defvar glsl-deprecated-modifier-list
|
||||
'("varying" "attribute")) ; centroid is deprecated when used with varying
|
||||
|
||||
(defvar glsl-builtin-list
|
||||
'("abs" "acos" "acosh" "all" "any" "asin" "asinh" "atan" "atanh"
|
||||
"atomicCounter" "atomicCounterDecrement" "atomicCounterIncrement"
|
||||
"barrier" "bitCount" "bitfieldExtract" "bitfieldInsert" "bitfieldReverse"
|
||||
"ceil" "clamp" "cos" "cosh" "cross" "degrees" "determinant" "dFdx" "dFdy"
|
||||
"dFdyFine" "dFdxFine" "dFdyCoarse" "dFdxCourse"
|
||||
"fwidthFine" "fwidthCoarse"
|
||||
"distance" "dot" "EmitStreamVertex" "EmitVertex" "EndPrimitive"
|
||||
"EndStreamPrimitive" "equal" "exp" "exp2" "faceforward" "findLSB"
|
||||
"findMSB" "floatBitsToInt" "floatBitsToUint" "floor" "fma" "fract"
|
||||
"frexp" "fwidth" "greaterThan" "greaterThanEqual" "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" "min"
|
||||
"mix" "mod" "modf" "noise" "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"
|
||||
"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
|
||||
'("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__"))
|
||||
|
||||
(autoload 'w3m-browse-url "w3m" "View URL using w3m")
|
||||
) ; eval-and-compile
|
||||
|
||||
(eval-when-compile
|
||||
(defun glsl-ppre (re)
|
||||
(format "\\<\\(%s\\)\\>" (regexp-opt re))))
|
||||
|
||||
(defvar glsl-font-lock-keywords-1
|
||||
(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-modifier-list))
|
||||
glsl-deprecated-keyword-face)
|
||||
(cons (eval-when-compile
|
||||
(glsl-ppre glsl-modifier-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)
|
||||
)
|
||||
"Minimal 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 ()
|
||||
(append glsl-builtin-list glsl-deprecated-builtin-list))
|
||||
|
||||
(defun glsl-find-man-page (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
|
||||
(browse-url
|
||||
(concat glsl-man-pages-base-url thing ".xhtml"))))
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode glsl-mode c-mode "GLSL"
|
||||
"Major mode for editing OpenGLSL shader files."
|
||||
(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) "")
|
||||
(add-to-list 'align-c++-modes 'glsl-mode)
|
||||
)
|
||||
|
||||
;(easy-menu-define c-glsl-menu glsl-mode-map "GLSL Mode Commands"
|
||||
; (cons "GLSL" (c-lang-const c-mode-menu glsl)))
|
||||
|
||||
;;; glsl-mode.el ends here
|
||||
213
site-lisp/prettier-js.el
Normal file
213
site-lisp/prettier-js.el
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
;;; prettier-js.el --- Minor mode to format JS code on file save
|
||||
|
||||
;; Version: 0.1.0
|
||||
|
||||
;; Copyright (c) 2014 The go-mode Authors. All rights reserved.
|
||||
;; Portions Copyright (c) 2015-present, Facebook, Inc. All rights reserved.
|
||||
|
||||
;; Redistribution and use in source and binary forms, with or without
|
||||
;; modification, are permitted provided that the following conditions are
|
||||
;; met:
|
||||
|
||||
;; * Redistributions of source code must retain the above copyright
|
||||
;; notice, this list of conditions and the following disclaimer.
|
||||
;; * Redistributions in binary form must reproduce the above
|
||||
;; copyright notice, this list of conditions and the following disclaimer
|
||||
;; in the documentation and/or other materials provided with the
|
||||
;; distribution.
|
||||
;; * Neither the name of the copyright holder nor the names of its
|
||||
;; contributors may be used to endorse or promote products derived from
|
||||
;; this software without specific prior written permission.
|
||||
|
||||
;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
;; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.)
|
||||
|
||||
;; Author: James Long and contributors
|
||||
;; Created: 10 January 2017
|
||||
;; Url: https://github.com/prettier/prettier-emacs
|
||||
;; Keywords: convenience wp edit js
|
||||
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;;; Commentary:
|
||||
;; Formats your JavaScript code using 'prettier' on file save.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defgroup prettier-js nil
|
||||
"Minor mode to format JS code on file save"
|
||||
:group 'languages
|
||||
:prefix "prettier-js"
|
||||
:link '(url-link :tag "Repository" "https://github.com/prettier/prettier"))
|
||||
|
||||
(defcustom prettier-js-command "prettier"
|
||||
"The 'prettier' command."
|
||||
:type 'string
|
||||
:group 'prettier-js)
|
||||
|
||||
(defcustom prettier-js-args '()
|
||||
"List of args to send to prettier command."
|
||||
:type '(repeat string)
|
||||
:group 'prettier-js)
|
||||
|
||||
(defcustom prettier-js-show-errors 'buffer
|
||||
"Where to display prettier error output.
|
||||
It can either be displayed in its own buffer, in the echo area, or not at all.
|
||||
Please note that Emacs outputs to the echo area when writing
|
||||
files and will overwrite prettier's echo output if used from inside
|
||||
a `before-save-hook'."
|
||||
:type '(choice
|
||||
(const :tag "Own buffer" buffer)
|
||||
(const :tag "Echo area" echo)
|
||||
(const :tag "None" nil))
|
||||
:group 'prettier-js)
|
||||
|
||||
(defcustom prettier-js-width-mode nil
|
||||
"Specify width when formatting buffer contents."
|
||||
:type '(choice
|
||||
(const :tag "Window width" window)
|
||||
(const :tag "Fill column" fill)
|
||||
(const :tag "None" nil))
|
||||
:group 'prettier-js)
|
||||
|
||||
(defun prettier-js--goto-line (line)
|
||||
"Move cursor to line LINE."
|
||||
(goto-char (point-min))
|
||||
(forward-line (1- line)))
|
||||
|
||||
(defun prettier-js--apply-rcs-patch (patch-buffer)
|
||||
"Apply an RCS-formatted diff from PATCH-BUFFER to the current buffer."
|
||||
(let ((target-buffer (current-buffer))
|
||||
;; Relative offset between buffer line numbers and line numbers
|
||||
;; in patch.
|
||||
;;
|
||||
;; Line numbers in the patch are based on the source file, so
|
||||
;; we have to keep an offset when making changes to the
|
||||
;; buffer.
|
||||
;;
|
||||
;; Appending lines decrements the offset (possibly making it
|
||||
;; negative), deleting lines increments it. This order
|
||||
;; simplifies the forward-line invocations.
|
||||
(line-offset 0))
|
||||
(save-excursion
|
||||
(with-current-buffer patch-buffer
|
||||
(goto-char (point-min))
|
||||
(while (not (eobp))
|
||||
(unless (looking-at "^\\([ad]\\)\\([0-9]+\\) \\([0-9]+\\)")
|
||||
(error "Invalid rcs patch or internal error in prettier-js--apply-rcs-patch"))
|
||||
(forward-line)
|
||||
(let ((action (match-string 1))
|
||||
(from (string-to-number (match-string 2)))
|
||||
(len (string-to-number (match-string 3))))
|
||||
(cond
|
||||
((equal action "a")
|
||||
(let ((start (point)))
|
||||
(forward-line len)
|
||||
(let ((text (buffer-substring start (point))))
|
||||
(with-current-buffer target-buffer
|
||||
(setq line-offset (- line-offset len))
|
||||
(goto-char (point-min))
|
||||
(forward-line (- from len line-offset))
|
||||
(insert text)))))
|
||||
((equal action "d")
|
||||
(with-current-buffer target-buffer
|
||||
(prettier-js--goto-line (- from line-offset))
|
||||
(setq line-offset (+ line-offset len))
|
||||
(let ((beg (point)))
|
||||
(forward-line len)
|
||||
(delete-region (point) beg))))
|
||||
(t
|
||||
(error "Invalid rcs patch or internal error in prettier-js--apply-rcs-patch")))))))))
|
||||
|
||||
(defun prettier-js--process-errors (filename errorfile errbuf)
|
||||
"Process errors for FILENAME, using an ERRORFILE and display the output in ERRBUF."
|
||||
(with-current-buffer errbuf
|
||||
(if (eq prettier-js-show-errors 'echo)
|
||||
(progn
|
||||
(message "%s" (buffer-string))
|
||||
(prettier-js--kill-error-buffer errbuf))
|
||||
(insert-file-contents errorfile nil nil nil)
|
||||
;; Convert the prettier stderr to something understood by the compilation mode.
|
||||
(goto-char (point-min))
|
||||
(insert "prettier errors:\n")
|
||||
(while (search-forward-regexp "^stdin" nil t)
|
||||
(replace-match (file-name-nondirectory filename)))
|
||||
(compilation-mode)
|
||||
(display-buffer errbuf))))
|
||||
|
||||
(defun prettier-js--kill-error-buffer (errbuf)
|
||||
"Kill buffer ERRBUF."
|
||||
(let ((win (get-buffer-window errbuf)))
|
||||
(if win
|
||||
(quit-window t win)
|
||||
(with-current-buffer errbuf
|
||||
(erase-buffer))
|
||||
(kill-buffer errbuf))))
|
||||
|
||||
(defun prettier-js ()
|
||||
"Format the current buffer according to the prettier tool."
|
||||
(interactive)
|
||||
(let* ((ext (file-name-extension buffer-file-name t))
|
||||
(bufferfile (make-temp-file "prettier" nil ext))
|
||||
(outputfile (make-temp-file "prettier" nil ext))
|
||||
(errorfile (make-temp-file "prettier" nil ext))
|
||||
(errbuf (if prettier-js-show-errors (get-buffer-create "*prettier errors*")))
|
||||
(patchbuf (get-buffer-create "*prettier patch*"))
|
||||
(coding-system-for-read 'utf-8)
|
||||
(coding-system-for-write 'utf-8)
|
||||
(width-args
|
||||
(cond
|
||||
((equal prettier-js-width-mode 'window)
|
||||
(list "--print-width" (number-to-string (window-body-width))))
|
||||
((equal prettier-js-width-mode 'fill)
|
||||
(list "--print-width" (number-to-string fill-column)))
|
||||
(t
|
||||
'()))))
|
||||
(unwind-protect
|
||||
(save-restriction
|
||||
(widen)
|
||||
(write-region nil nil bufferfile)
|
||||
(if errbuf
|
||||
(with-current-buffer errbuf
|
||||
(setq buffer-read-only nil)
|
||||
(erase-buffer)))
|
||||
(with-current-buffer patchbuf
|
||||
(erase-buffer))
|
||||
(if (zerop (apply 'call-process
|
||||
prettier-js-command bufferfile (list (list :file outputfile) errorfile)
|
||||
nil (append prettier-js-args width-args (list "--stdin" "--stdin-filepath" buffer-file-name))))
|
||||
(progn
|
||||
(call-process-region (point-min) (point-max) "diff" nil patchbuf nil "-n" "--strip-trailing-cr" "-"
|
||||
outputfile)
|
||||
(prettier-js--apply-rcs-patch patchbuf)
|
||||
(message "Applied prettier with args `%s'" prettier-js-args)
|
||||
(if errbuf (prettier-js--kill-error-buffer errbuf)))
|
||||
(message "Could not apply prettier")
|
||||
(if errbuf
|
||||
(prettier-js--process-errors (buffer-file-name) errorfile errbuf))
|
||||
))
|
||||
(kill-buffer patchbuf)
|
||||
(delete-file errorfile)
|
||||
(delete-file bufferfile)
|
||||
(delete-file outputfile))))
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode prettier-js-mode
|
||||
"Runs prettier on file save when this mode is turned on"
|
||||
:lighter " Prettier"
|
||||
:global nil
|
||||
(if prettier-js-mode
|
||||
(add-hook 'before-save-hook 'prettier-js nil 'local)
|
||||
(remove-hook 'before-save-hook 'prettier-js 'local)))
|
||||
|
||||
(provide 'prettier-js)
|
||||
;;; prettier-js.el ends here
|
||||
Loading…
Add table
Add a link
Reference in a new issue