From 17ee0e400bef47c371afcae76037f9ea6a44ad13 Mon Sep 17 00:00:00 2001 From: William Carroll Date: Mon, 10 Sep 2018 14:51:14 -0400 Subject: Support Vim, Tmux, Emacs with Stow After moving off of Meta, Dotfiles has a greater responsibility to manage configs. Vim, Tmux, and Emacs are now within Stow's purview. --- .../flow-minor-mode.el | 323 +++++++++++++++++++++ 1 file changed, 323 insertions(+) create mode 100644 configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode.el (limited to 'configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode.el') diff --git a/configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode.el b/configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode.el new file mode 100644 index 000000000000..0bc3d73d69d2 --- /dev/null +++ b/configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode.el @@ -0,0 +1,323 @@ +;;; 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 +;; Package-Version: 20180315.1124 +;; 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 -- cgit 1.4.1