@@ 1,208 @@
+Copyright 2011-2015
+
+
+ Robin Neatherway
+ Jurgen Hurtzel
+ Jason Imison
+ Chris Barrett
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+------------------------------------------------------------
+
+Apache License, Version 2.0
+===========================
+
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+### TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+
+**1. Definitions.**
+
+ - "License" shall mean the terms and conditions for use, reproduction,
+and distribution as defined by Sections 1 through 9 of this document.
+
+ - "Licensor" shall mean the copyright owner or entity authorized by
+the copyright owner that is granting the License.
+
+ - "Legal Entity" shall mean the union of the acting entity and all
+other entities that control, are controlled by, or are under common
+control with that entity. For the purposes of this definition,
+"control" means (i) the power, direct or indirect, to cause the
+direction or management of such entity, whether by contract or
+otherwise, or (ii) ownership of fifty percent (50%) or more of the
+outstanding shares, or (iii) beneficial ownership of such entity.
+
+ - "You" (or "Your") shall mean an individual or Legal Entity
+exercising permissions granted by this License.
+
+ - "Source" form shall mean the preferred form for making modifications,
+including but not limited to software source code, documentation
+source, and configuration files.
+
+ - "Object" form shall mean any form resulting from mechanical
+transformation or translation of a Source form, including but
+not limited to compiled object code, generated documentation,
+and conversions to other media types.
+
+ - "Work" shall mean the work of authorship, whether in Source or
+Object form, made available under the License, as indicated by a
+copyright notice that is included in or attached to the work
+(an example is provided in the Appendix below).
+
+ - "Derivative Works" shall mean any work, whether in Source or Object
+form, that is based on (or derived from) the Work and for which the
+editorial revisions, annotations, elaborations, or other modifications
+represent, as a whole, an original work of authorship. For the purposes
+of this License, Derivative Works shall not include works that remain
+separable from, or merely link (or bind by name) to the interfaces of,
+the Work and Derivative Works thereof.
+
+ - "Contribution" shall mean any work of authorship, including
+the original version of the Work and any modifications or additions
+to that Work or Derivative Works thereof, that is intentionally
+submitted to Licensor for inclusion in the Work by the copyright owner
+or by an individual or Legal Entity authorized to submit on behalf of
+the copyright owner. For the purposes of this definition, "submitted"
+means any form of electronic, verbal, or written communication sent
+to the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control systems,
+and issue tracking systems that are managed by, or on behalf of, the
+Licensor for the purpose of discussing and improving the Work, but
+excluding communication that is conspicuously marked or otherwise
+designated in writing by the copyright owner as "Not a Contribution."
+
+ - "Contributor" shall mean Licensor and any individual or Legal Entity
+on behalf of whom a Contribution has been received by Licensor and
+subsequently incorporated within the Work.
+
+**2. Grant of Copyright License.**
+Subject to the terms and conditions of
+this License, each Contributor hereby grants to You a perpetual,
+worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the
+Work and such Derivative Works in Source or Object form.
+
+**3. Grant of Patent License.**
+Subject to the terms and conditions of
+this License, each Contributor hereby grants to You a perpetual,
+worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+(except as stated in this section) patent license to make, have made,
+use, offer to sell, sell, import, and otherwise transfer the Work,
+where such license applies only to those patent claims licensable
+by such Contributor that are necessarily infringed by their
+Contribution(s) alone or by combination of their Contribution(s)
+with the Work to which such Contribution(s) was submitted. If You
+institute patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Work
+or a Contribution incorporated within the Work constitutes direct
+or contributory patent infringement, then any patent licenses
+granted to You under this License for that Work shall terminate
+as of the date such litigation is filed.
+
+**4. Redistribution.**
+You may reproduce and distribute copies of the
+Work or Derivative Works thereof in any medium, with or without
+modifications, and in Source or Object form, provided that You
+meet the following conditions:
+
+ - You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ - You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ - You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ - If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+You may add Your own copyright statement to Your modifications and
+may provide additional or different license terms and conditions
+for use, reproduction, or distribution of Your modifications, or
+for any such Derivative Works as a whole, provided Your use,
+reproduction, and distribution of the Work otherwise complies with
+the conditions stated in this License.
+
+**5. Submission of Contributions.**
+Unless You explicitly state otherwise,
+any Contribution intentionally submitted for inclusion in the Work
+by You to the Licensor shall be under the terms and conditions of
+this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify
+the terms of any separate license agreement you may have executed
+with Licensor regarding such Contributions.
+
+**6. Trademarks.**
+This License does not grant permission to use the trade
+names, trademarks, service marks, or product names of the Licensor,
+except as required for reasonable and customary use in describing the
+origin of the Work and reproducing the content of the NOTICE file.
+
+**7. Disclaimer of Warranty.**
+Unless required by applicable law or
+agreed to in writing, Licensor provides the Work (and each
+Contributor provides its Contributions) on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+implied, including, without limitation, any warranties or conditions
+of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+PARTICULAR PURPOSE. You are solely responsible for determining the
+appropriateness of using or redistributing the Work and assume any
+risks associated with Your exercise of permissions under this License.
+
+**8. Limitation of Liability.**
+In no event and under no legal theory,
+whether in tort (including negligence), contract, or otherwise,
+unless required by applicable law (such as deliberate and grossly
+negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special,
+incidental, or consequential damages of any character arising as a
+result of this License or out of the use or inability to use the
+Work (including but not limited to damages for loss of goodwill,
+work stoppage, computer failure or malfunction, or any and all
+other commercial damages or losses), even if such Contributor
+has been advised of the possibility of such damages.
+
+**9. Accepting Warranty or Additional Liability.**
+While redistributing
+the Work or Derivative Works thereof, You may choose to offer,
+and charge a fee for, acceptance of support, warranty, indemnity,
+or other liability obligations and/or rights consistent with this
+License. However, in accepting such obligations, You may act only
+on Your own behalf and on Your sole responsibility, not on behalf
+of any other Contributor, and only if You agree to indemnify,
+defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason
+of your accepting any such warranty or additional liability.
@@ 1,371 @@
+;;; fsharp-mode-font.el --- Syntax highlighting for F#
+
+;; Copyright (C) 1997 INRIA
+
+;; Author: 1993-1997 Xavier Leroy, Jacques Garrigue and Ian T Zimmerman
+;; 2010-2011 Laurent Le Brun <laurent@le-brun.eu>
+;; Maintainer: Robin Neatherway <robin.neatherway@gmail.com>
+;; Keywords: languages
+
+;; 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.
+
+;; 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.
+
+;;; Commentary:
+
+;;; Code:
+
+;; (require 'fsharp-mode)
+;; (require 'dash)
+
+(defgroup fsharp-ui nil
+ "F# UI group for the defcustom interface."
+ :prefix "fsharp-ui-"
+ :group 'fsharp
+ :package-version '(fsharp-mode . "1.9.2"))
+
+(defface fsharp-ui-generic-face
+ '((t (:inherit default)))
+ "Preprocessor face"
+ :group 'fsharp-ui)
+
+(defface fsharp-ui-operator-face
+ '((t (:foreground "LightSkyBlue")))
+ "Preprocessor face"
+ :group 'fsharp-ui)
+
+(defface fsharp-ui-warning-face
+ '((t (:inherit font-lock-warning-face)))
+ "Face for warnings."
+ :group 'fsharp-ui)
+
+(defface fsharp-ui-error-face
+ '((t (:inherit font-lock-error-face :underline t)))
+ "Face for errors"
+ :group 'fsharp-ui)
+
+(defmacro def-fsharp-compiled-var (sym init &optional docstring)
+ "Defines a SYMBOL as a constant inside an eval-and-compile form
+with initial value INITVALUE and optional DOCSTRING."
+ `(eval-and-compile
+ (defvar ,sym ,init ,docstring)))
+
+(def-fsharp-compiled-var fsharp-shebang-regexp
+ "\\(^#!.*?\\)\\([A-Za-z0-9_-]+\\)$"
+ "Capture the #! and path of a shebag in one group and the
+ executable in another.")
+
+(def-fsharp-compiled-var fsharp-access-control-regexp
+ "private\\s-+\\|internal\\s-+\\|public\\s-+"
+ "Match `private', `internal', or `public', followed by a space,
+ with no capture.")
+
+(def-fsharp-compiled-var fsharp-access-control-regexp-noncapturing
+ (format "\\(?:%s\\)" fsharp-access-control-regexp)
+ "Same as `fsharp-access-control-regexp', but captures")
+
+(def-fsharp-compiled-var fsharp-inline-rec-regexp
+ "inline\\s-+\\|rec\\s-+"
+ "Match `inline' or `rec', followed by a space.")
+
+(def-fsharp-compiled-var fsharp-inline-rec-regexp-noncapturing
+ (format "\\(?:%s\\)" fsharp-inline-rec-regexp)
+ "Match `inline' or `rec', followed by a space, with no capture.")
+
+(def-fsharp-compiled-var fsharp-valid-identifier-regexp
+ "[A-Za-z0-9_']+"
+ "Match a normal, valid F# identifier -- alphanumeric characters
+ plus ' and underbar. Does not capture")
+
+(def-fsharp-compiled-var fsharp-function-def-regexp
+ (concat "\\<\\(?:let\\|and\\|with\\)\\s-+"
+ fsharp-inline-rec-regexp-noncapturing "?"
+ fsharp-access-control-regexp-noncapturing "*"
+ (format "\\(%s\\)" fsharp-valid-identifier-regexp)
+ "\\(?:\\s-+[A-Za-z_]\\|\\s-*(\\)" ;; matches function arguments or open-paren; unclear why 0-9 not in class
+ ))
+
+(def-fsharp-compiled-var fsharp-pattern-function-regexp
+ (concat "\\<\\(?:let\\|and\\)\\s-+"
+ fsharp-inline-rec-regexp-noncapturing "?"
+ fsharp-access-control-regexp-noncapturing "*"
+ (format "\\(%s\\)" fsharp-valid-identifier-regexp)
+ "\\s-*=\\s-*function")
+ "Matches an implicit matcher, eg let foo m = function | \"cat\" -> etc.")
+
+;; Note that this regexp is used for iMenu. To font-lock active patterns, we
+;; need to use an anchored match in fsharp-font-lock-keywords.
+(def-fsharp-compiled-var fsharp-active-pattern-regexp
+ (concat "\\<\\(?:let\\|and\\)\\s-+"
+ fsharp-inline-rec-regexp-noncapturing "?"
+ fsharp-access-control-regexp-noncapturing "*"
+ "(\\(|[A-Za-z0-9_'|]+|\\))\\(?:\\s-+[A-Za-z_]\\|\\s-*(\\)"))
+
+(def-fsharp-compiled-var fsharp-member-access-regexp
+ "\\<\\(?:override\\|member\\|abstract\\)\\s-+"
+ "Matches members declarations and modifiers on classes.")
+
+(def-fsharp-compiled-var fsharp-member-function-regexp
+ (concat fsharp-member-access-regexp
+ fsharp-inline-rec-regexp-noncapturing "?"
+ fsharp-access-control-regexp-noncapturing "*"
+ "\\(?:" fsharp-valid-identifier-regexp "\\.\\)?"
+ "\\(" fsharp-valid-identifier-regexp "\\)")
+ "Captures the final identifier in a member function declaration.")
+
+(def-fsharp-compiled-var fsharp-overload-operator-regexp
+ (concat fsharp-member-access-regexp
+ fsharp-inline-rec-regexp-noncapturing "?"
+ fsharp-access-control-regexp-noncapturing "*"
+ "\\(([!%&*+-./<=>?@^|~]+)\\)")
+ "Match operators when overloaded by a type/class.")
+
+(def-fsharp-compiled-var fsharp-constructor-regexp
+ (concat "^\\s-*"
+ fsharp-access-control-regexp-noncapturing "*"
+ "\\<\\(new\\) *(.*)[^=]*=")
+ "Matches the `new' keyword in a constructor")
+
+(def-fsharp-compiled-var fsharp-type-def-regexp
+ (concat "^\\s-*\\<\\(?:type\\|inherit\\)\\s-+"
+ fsharp-access-control-regexp-noncapturing "*" ;; match access control 0 or more times
+ "\\([A-Za-z0-9_'.]+\\)"))
+
+(def-fsharp-compiled-var fsharp-var-or-arg-regexp
+ "\\_<\\([A-Za-z_][A-Za-z0-9_']*\\)\\_>")
+
+(def-fsharp-compiled-var fsharp-explicit-field-regexp
+ (concat "^\\s-*\\(?:val\\|abstract\\)\\s-*\\(?:mutable\\s-+\\)?"
+ fsharp-access-control-regexp-noncapturing "*" ;; match access control 0 or more times
+ "\\([A-Za-z_][A-Za-z0-9_']*\\)\\s-*:\\s-*\\([A-Za-z_][A-Za-z0-9_'<> \t]*\\)"))
+
+(def-fsharp-compiled-var fsharp-attributes-regexp
+ "\\(\\[<[A-Za-z0-9_]+[( ]?\\)\\(\".*\"\\)?\\()?>\\]\\)"
+ "Match attributes like [<EntryPoint>]; separately groups contained strings in attributes like [<Attribute(\"property\")>]")
+
+;; F# makes extensive use of operators, many of which have some kind of
+;; structural significance.
+;;
+;; In particular:
+;; (| ... |) -- banana clips for Active Patterns (handled separately)
+;; <@ ... @> and <@@ ... @@> -- quoted expressions
+;; <| and |> -- left and right pipe (also <||, <|||, ||>, |||>)
+;; << and >> -- function composition
+;; | -- match / type expressions
+
+(def-fsharp-compiled-var fsharp-operator-quote-regexp
+ "\\(<@\\{1,2\\}\\)\\(?:.*\\)\\(@\\{1,2\\}>\\)"
+ "Font lock <@/<@@ and @>/@@> operators.")
+
+(def-fsharp-compiled-var fsharp-operator-pipe-regexp
+ "<|\\{1,3\\}\\||\\{1,3\\}>"
+ "Match the full range of pipe operators -- |>, ||>, |||>, etc.")
+
+(def-fsharp-compiled-var fsharp-operator-case-regexp
+ "\\s-+\\(|\\)[A-Za-z0-9_' ]"
+ "Match literal | in contexts like match and type declarations.")
+
+(defun fsharp-var-pre-form ()
+ (save-excursion
+ (re-search-forward "\\(:\\s-*\\w[^)]*\\)?=" nil t)
+ (match-beginning 0)))
+
+(defun fsharp-fun-pre-form ()
+ (save-excursion
+ (search-forward "->")))
+
+;; Preprocessor directives (3.3)
+(def-fsharp-compiled-var fsharp-ui-preproessor-directives
+ '("#if" "#else" "#endif" "#light"))
+
+;; Compiler directives (12.4)
+(def-fsharp-compiled-var fsharp-ui-compiler-directives
+ '("#nowarn" "#load" "#r" "#reference" "#I"
+ "#Include" "#q" "#quit" "#time" "#help"))
+
+;; Lexical matters (18.4)
+(def-fsharp-compiled-var fsharp-ui-lexical-matters
+ '("#indent"))
+
+;; Line Directives (3.9)
+(def-fsharp-compiled-var fsharp-ui-line-directives
+ '("#line"))
+
+;; Identifier replacements (3.11)
+(def-fsharp-compiled-var fsharp-ui-identifier-replacements
+ '("__SOURCE_DIRECTORY__" "__SOURCE_FILE__" "__LINE__"))
+
+;; F# keywords (3.4)
+(def-fsharp-compiled-var fsharp-ui-fsharp-threefour-keywords
+ '("abstract" "and" "as" "assert" "base" "begin"
+ "class" "default" "delegate" "do" "do!" "done"
+ "downcast" "downto" "elif" "else" "end"
+ "exception" "extern" "false" "finally" "for" "fun"
+ "function" "global" "if" "in" "inherit" "inline"
+ "interface" "internal" "lazy" "let" "let!"
+ "match" "member" "module" "mutable" "namespace"
+ "new" "not" "null" "of" "open" "or" "override"
+ "private" "public" "rec" "return" "return!"
+ "select" "static" "struct" "then" "to" "true"
+ "try" "type" "upcast" "use" "use!" "val" "void"
+ "when" "while" "with" "yield" "yield!"))
+
+;; "Reserved because they are reserved in OCaml"
+(def-fsharp-compiled-var fsharp-ui-ocaml-reserved-words
+ '("asr" "land" "lor" "lsl" "lsr" "lxor" "mod" "sig"))
+
+;; F# reserved words for future use
+(def-fsharp-compiled-var fsharp-ui-reserved-words
+ '("atomic" "break" "checked" "component" "const"
+ "constraint" "constructor" "continue" "eager"
+ "event" "external" "fixed" "functor" "include"
+ "method" "mixin" "object" "parallel" "process"
+ "protected" "pure" "sealed" "tailcall" "trait"
+ "virtual" "volatile"))
+
+;; RMD 2016-09-30 -- This was pulled out separately with the following comment
+;; when I got here. Not clear to me why it's on it's own, or even precisely what
+;; the comment means. But: `async' is a valid F# keyword and needs to go someplace,
+;; so I've left it here. For now.
+;;
+;; Workflows not yet handled by fsautocomplete but async
+;; always present
+(def-fsharp-compiled-var fsharp-ui-async-words
+ '("async")
+ "Just the word async, in a list.")
+
+(def-fsharp-compiled-var fsharp-ui-word-list-regexp
+ (regexp-opt
+ `(,@fsharp-ui-async-words
+ ,@fsharp-ui-compiler-directives
+ ,@fsharp-ui-fsharp-threefour-keywords
+ ,@fsharp-ui-identifier-replacements
+ ,@fsharp-ui-lexical-matters
+ ,@fsharp-ui-ocaml-reserved-words
+ ,@fsharp-ui-preproessor-directives
+ ,@fsharp-ui-reserved-words
+ ,@fsharp-ui-line-directives)
+ 'symbols))
+
+(defconst fsharp-font-lock-keywords
+ (eval-when-compile
+ `((,fsharp-ui-word-list-regexp 0 font-lock-keyword-face)
+ ;; shebang
+ (,fsharp-shebang-regexp
+ (1 font-lock-comment-face)
+ (2 font-lock-keyword-face))
+ ;; attributes
+ (,fsharp-attributes-regexp
+ (1 font-lock-preprocessor-face)
+ (2 font-lock-string-face nil t)
+ (3 font-lock-preprocessor-face))
+ ;; ;; type defines
+ (,fsharp-type-def-regexp 1 font-lock-type-face)
+ (,fsharp-function-def-regexp 1 font-lock-function-name-face)
+ (,fsharp-pattern-function-regexp 1 font-lock-function-name-face)
+ ;; Active Pattern
+ ("(|" (0 'fsharp-ui-operator-face)
+ ("\\([A-Za-z'_]+\\)\\(|)?\\)"
+ nil nil
+ (1 font-lock-function-name-face)
+ (2 'fsharp-ui-operator-face)))
+ (,fsharp-operator-pipe-regexp . 'fsharp-ui-operator-face)
+ (,fsharp-member-function-regexp 1 font-lock-function-name-face)
+ (,fsharp-overload-operator-regexp 1 font-lock-function-name-face)
+ (,fsharp-constructor-regexp 1 font-lock-function-name-face)
+ (,fsharp-operator-case-regexp 1 'fsharp-ui-operator-face)
+ (,fsharp-operator-quote-regexp (1 'fsharp-ui-operator-face)
+ (2 'fsharp-ui-operator-face))
+ ("[^:]:\\s-*\\(\\<[A-Za-z0-9_' ]*[^ ;\n,)}=<-]\\)\\(<[^>]*>\\)?"
+ (1 font-lock-type-face)
+ ;; 'prevent generic type arguments from being rendered in variable face
+ (2 'fsharp-ui-generic-face nil t))
+ (,(format "^\\s-*\\<\\(let\\|use\\|override\\|member\\|and\\|\\(?:%snew\\)\\)\\_>"
+ (concat fsharp-access-control-regexp "*"))
+ (0 font-lock-keyword-face) ; let binding and function arguments
+ (,fsharp-var-or-arg-regexp
+ (fsharp-var-pre-form) nil
+ (1 font-lock-variable-name-face nil t)))
+ ("\\<fun\\>"
+ (0 font-lock-keyword-face) ; lambda function arguments
+ (,fsharp-var-or-arg-regexp
+ (fsharp-fun-pre-form) nil
+ (1 font-lock-variable-name-face nil t)))
+ (,fsharp-type-def-regexp
+ (0 'font-lock-keyword-face) ; implicit constructor arguments
+ (,fsharp-var-or-arg-regexp
+ (fsharp-var-pre-form) nil
+ (1 font-lock-variable-name-face nil t)))
+ (,fsharp-explicit-field-regexp
+ (1 font-lock-variable-name-face)
+ (2 font-lock-type-face))
+
+ ;; open namespace
+ ("\\<open\s\\([A-Za-z0-9_.]+\\)" 1 font-lock-type-face)
+
+ ;; module/namespace
+ ("\\_<\\(?:module\\|namespace\\)\s\\([A-Za-z0-9_.]+\\)" 1 font-lock-type-face)
+ )))
+
+(defun fsharp-ui-setup-font-lock ()
+ "Set up font locking for F# Mode."
+ (setq font-lock-defaults
+ '(fsharp-font-lock-keywords)))
+
+(add-hook 'fsharp-mode-hook #'fsharp-ui-setup-font-lock)
+
+(defun fsharp--syntax-propertize-function (start end)
+ (goto-char start)
+ (fsharp--syntax-string end)
+ (funcall (syntax-propertize-rules
+ ("\\(@\\)\"" (1 (prog1 "|" (fsharp--syntax-string end)))) ; verbatim string
+ ("\\(\"\\)\"\"" (1 (prog1 "|" (fsharp--syntax-string end)))) ; triple-quoted string
+ ("\\('\\)\\(?:[^\n\t\r\b\a\f\v\\\\]\\|\\\\[\"'ntrbafv\\\\]\\|\\\\u[0-9A-Fa-f]\\{4\\}\\|\\\\[0-9]\\{3\\}\\)\\('\\)"
+ (1 "|") (2 "|")) ; character literal
+ ("\\((\\)/" (1 "()"))
+ ("\\(\(\\)\\*[!%&*+-\\./<=>@^|~?]*[\n\t\r\b\a\f\v ]*\)" (1 "()")) ; symbolic operator starting (* is not a comment
+ ("\\(/\\)\\*" (1 ".")))
+ start end))
+
+(defun fsharp--syntax-string (end)
+ (let* ((pst (syntax-ppss))
+ (instr (nth 3 pst))
+ (start (nth 8 pst)))
+ (when (eq t instr) ; Then we are in a custom string
+ (cond
+ ((eq ?@ (char-after start)) ; Then we are in a verbatim string
+ (while
+ (when (re-search-forward "\"\"?" end 'move)
+ (if (> (- (match-end 0) (match-beginning 0)) 1)
+ t ;; Skip this "" and keep looking further.
+ (put-text-property (- (match-beginning 0) 1) (- (match-end 0) 1)
+ 'syntax-table (string-to-syntax "."))
+ (put-text-property (match-beginning 0) (match-end 0)
+ 'syntax-table (string-to-syntax "|"))
+ nil)))
+ )
+
+ (t ; Then we are in a triple-quoted string
+ (when (re-search-forward "\"\"\"" end 'move)
+ (put-text-property (- (match-beginning 0) 1) (match-beginning 0)
+ 'syntax-table (string-to-syntax "."))
+ (put-text-property (match-beginning 0) (match-end 0)
+ 'syntax-table (string-to-syntax "|")))
+ )))))
+
+(provide 'fsharp-mode-font)
+
+;;; fsharp-mode-font.el ends here
@@ 1,237 @@
+;;; fsharp-mode.el --- Support for the F# programming language
+
+;; Copyright (C) 1997 INRIA
+
+;; Author: 1993-1997 Xavier Leroy, Jacques Garrigue and Ian T Zimmerman
+;; 2010-2011 Laurent Le Brun <laurent@le-brun.eu>
+;; 2012-2014 Robin Neatherway <robin.neatherway@gmail.com>
+;; 2017-2019 Jürgen Hötzel
+;; Maintainer: Jürgen Hötzel
+;; Package-Requires: ((emacs "25") (s "1.3.1") (dash "1.1.0") (eglot))
+;; Keywords: languages
+;; Version: 1.9.15
+
+;; 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.
+
+;; 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 'compile)
+
+(defgroup fsharp nil
+ "Support for the Fsharp programming language, <http://www.fsharp.net/>"
+ :group 'languages)
+
+(defcustom fsharp-indent-offset 4
+ "Indent Elm code by this number of spaces."
+ :type 'integer
+ :group 'fsharp
+ :safe #'integerp)
+
+;;; ----------------------------------------------------------------------------
+
+(defvar fsharp-mode-map
+ (let ((map (make-keymap)))
+ (define-key map (kbd "C-c TAB") 'fsharp-indent-line)
+ (define-key map (kbd "<tab>") 'fsharp-indent-forward)
+ (define-key map (kbd "<backtab>") 'fsharp-indent-backward)
+ map)
+ "Keymap used in fsharp mode.")
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.fs[iylx]?\\'" . fsharp-mode))
+
+(defvar fsharp-mode-syntax-table
+ (let ((syntax-table (make-syntax-table)))
+ (modify-syntax-entry ?\\ "\\" syntax-table)
+ (modify-syntax-entry ?\( "()1n" syntax-table)
+ (modify-syntax-entry ?* ". 23n" syntax-table)
+ (modify-syntax-entry ?\) ")(4n" syntax-table)
+ (modify-syntax-entry ?/ ". 12b" syntax-table)
+ (modify-syntax-entry ?\n "> b" syntax-table)
+ (modify-syntax-entry ?' "_" syntax-table)
+ (modify-syntax-entry ?_ "_" syntax-table)
+ (modify-syntax-entry ?# "_" syntax-table)
+ (modify-syntax-entry ?! "_" syntax-table)
+
+ syntax-table))
+
+
+(defvar fsharp-mode-hook nil
+ "Hook for fsharp-mode")
+
+;;; Indentation
+
+(defun fsharp--find-indentation-of-list ()
+ (save-excursion
+ (backward-up-list 1)
+ (+ (- (current-column) (current-indentation))
+ (current-indentation))))
+
+(defmacro fsharp--find-indentation-of-tokens (tokens)
+ `(save-excursion
+ (re-search-backward (regexp-opt ',tokens) (point-min) t nil)
+ (+ (- (current-column) (current-indentation))
+ (current-indentation))))
+
+(defmacro fsharp--two-lines-same-token-p (token)
+ "Checks if line and previous line start with same token."
+ `(and (looking-at ,token)
+ (save-excursion
+ (forward-line -1)
+ (back-to-indentation)
+ (looking-at ,token))))
+
+(defmacro fsharp--previous-line-ends-with (tokens)
+ `(save-excursion
+ (forward-line -1)
+ (end-of-line)
+ (forward-comment (- (point)))
+ (looking-back (regexp-opt ',tokens))))
+
+(defmacro fsharp--previous-line-starts-with (tokens)
+ `(save-excursion
+ (forward-line -1)
+ (back-to-indentation)
+ (looking-at-p (regexp-opt ',tokens))))
+
+(defun fsharp-compute-indentation ()
+ "Return a column to indent to.
+
+The numbers we get are the positions we can determine from the
+given context. When we cannot find a context to indent to, we
+default to the indentation level of previous line."
+ (let* ((indent-level-previous-line
+ (save-excursion
+ (forward-line -1)
+ (current-indentation)))
+ (positive-offset (+ indent-level-previous-line fsharp-indent-offset)))
+ (save-excursion
+ (back-to-indentation)
+ ;; Now we are positioned at start of indentation.
+ ;; Logic below assumes this is true.
+ (cond
+ ((fsharp--previous-line-ends-with ("=" "<-" "[" "{" "of" "if" "else" ":" "->" "exposing")) positive-offset)
+ ((looking-at-p (regexp-opt '("(*" "*)"))) 0)
+ ((and (= indent-level-previous-line 0) (looking-at-p "=")) positive-offset)
+ ((fsharp--previous-line-starts-with ("type" "let")) positive-offset)
+ ((looking-at-p ")") (fsharp--find-indentation-of-list))
+ ((looking-at-p "}") (fsharp--find-indentation-of-list))
+ ((looking-at-p "]") (fsharp--find-indentation-of-list))
+ ((looking-at-p ",") (fsharp--find-indentation-of-list))
+ ((looking-at-p "else") (fsharp--find-indentation-of-tokens ("if")))
+ ((looking-at-p "then") (fsharp--find-indentation-of-tokens ("if")))
+ (t (fsharp-indent-lastly))))))
+
+(defun fsharp-indent-level-2-previous-lines ()
+ "Returns indent level of the two previous lines."
+ (save-excursion
+ ;; Since we save-excursion above, we can go back two lines one by one, and
+ ;; return the lines separately.
+ (cl-values
+ (progn
+ (forward-line -1)
+ (current-indentation))
+ (progn
+ (forward-line -1)
+ (current-indentation)))))
+
+(defun fsharp-indent-lastly ()
+ (interactive)
+ (cl-multiple-value-bind (previous-line 2nd-previous-line)
+ (fsharp-indent-level-2-previous-lines)
+ (cond
+ ((and (zerop previous-line) (zerop 2nd-previous-line)) 0)
+ ((zerop previous-line) 2nd-previous-line)
+ (t
+ previous-line))))
+
+(defun fsharp-do-indent (indent)
+ (if (<= (current-column) (current-indentation))
+ (ignore-errors (indent-line-to indent))
+ (save-excursion (ignore-errors (indent-line-to indent)))))
+
+(defun fsharp-indent-line ()
+ "Set indent levels for Elm source code.
+
+Try to indent to the correct level. If indent level is
+ambiguous, multiple invocations will indent tabstops forward."
+ (interactive)
+ (let ((indent (fsharp-compute-indentation)))
+ (fsharp-do-indent indent)))
+
+(defun fsharp-indent-forward (&optional arg)
+ "Indent line to the next tabstop."
+ (interactive "p")
+ (or arg (setq arg 1))
+ (fsharp-do-indent
+ (indent-next-tab-stop (* arg (current-indentation)))))
+
+(defun fsharp-indent-backward (&optional arg)
+ "Indent backwards to the nearest tabstop"
+ (interactive "p")
+ (or arg (setq arg 1))
+ (fsharp-do-indent
+ (indent-next-tab-stop
+ (save-excursion (back-to-indentation) (current-column)) t)))
+
+;;;###autoload
+(define-derived-mode fsharp-mode prog-mode "fsharp"
+ :group 'fsharp
+ :syntax-table fsharp-mode-syntax-table
+ "Major mode for editing fsharp code.
+
+\\{fsharp-mode-map}"
+
+ (require 'fsharp-mode-font)
+
+ ;; ;; Movement
+ ;; (setq-local beginning-of-defun-function #'elmo-beginning-of-defun)
+ ;; (setq-local end-of-defun-function #'elmo-end-of-defun)
+
+ ;; ;; Indentation
+ (when (boundp 'electric-indent-inhibit) (setq electric-indent-inhibit t))
+ (setq-local indent-line-function 'fsharp-indent-line)
+ (setq-local tab-width fsharp-indent-offset)
+
+ ;; Comments
+ (setq-local comment-start-skip "// ")
+ (setq-local comment-start "//")
+ (setq-local comment-end "")
+
+ ; Syntax highlighting
+ (setq font-lock-defaults '(fsharp-font-lock-keywords))
+ (setq syntax-propertize-function 'fsharp--syntax-propertize-function)
+
+ (run-hooks 'fsharp-mode-hook))
+
+
+(defconst fsharp-error-regexp-fs
+ "^\\([^(\n]+\\)(\\([0-9]+\\),\\([0-9]+\\)):"
+ "Regular expression matching the error messages produced by fsc.")
+
+(if (boundp 'compilation-error-regexp-alist)
+ (or (memq 'fsharp
+ compilation-error-regexp-alist)
+ (progn
+ (add-to-list 'compilation-error-regexp-alist 'fsharp)
+ (add-to-list 'compilation-error-regexp-alist-alist
+ `(fsharp ,fsharp-error-regexp-fs 1 2 3)))))
+
+(provide 'fsharp-mode)
+
+;;; fsharp-mode.el ends here