diff --git a/LICENSE.md b/LICENSE.md index 34ac523..949a4a5 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -19,4 +19,8 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. + +----- + +The contents of the spacemacs directory are derived from the fsharp layer in [Spacemacs](https://github.com/syl20bnr/spacemacs), and are licensed under the GPLv3. diff --git a/README.md b/README.md index 0f5e3dd..f91ca54 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,40 @@ Neovim with Deoplete completion:\ (alternatively there is another vim language server plugin [vim-lsp](https://github.com/prabirshrestha/vim-lsp) but this one hasn't been tried. ### Emacs -**Help wanted**--should be straightforward with [emacs-lsp](https://github.com/emacs-lsp/lsp-mode), a PR with instructions here would be appreciated. + +#### Spacemacs + +Clone this repo to your system and build it: + +``` +npm install + +# Pick the appropriate target based upon your OS +dotnet publish -c Release -r linux-x64 src/FSharpLanguageServer +dotnet publish -c Release -r osx.10.11-x64 src/FSharpLanguageServer +dotnet publish -c Release -r win10-x64 src/FSharpLanguageServer +``` + +Make sure that the FSharpLanguageServer (in `src/FSharpLanguageServer/bin/Release/netcoreapp2.0/PLATFORM/publish`) is in your PATH. Alternatively, you can set the path to the server executable manually within your .spacemacs user-config: + +``` +(setq fsharp2-lsp-executable "/path/to/FSharpLanguageServer") +``` + +Since the stock fsharp layer does not currently include LSP support, you will need to use the fsharp2 layer (a fork of fsharp) which does. To use fsharp2, copy the custom layer into your Spacemacs private layers directory. In order for this layer to work, you must be on the Spacemacs **develop** branch, since the LSP layer is not yet available in Spacemacs master. + +``` +cp -r spacemacs/fsharp2 ~/.emacs.d/private +``` + +Finally, make sure that you have these layers enabled in your dotspacemacs-configuration-layers. You will need to remove the fsharp layer if you have it, since fsharp2 conflicts with it. + +- lsp +- fsharp2 +- syntax-checking +- auto-completion + +![EmacsLspMode](videos/EmacsLspMode.gif) ## How is this project different than [Ionide](https://github.com/ionide)? Ionide is a suite of F# plugins for VSCode; F# language server is analagous to the [FSAC](https://github.com/fsharp/FsAutoComplete) component. While FSAC is based on a custom JSON protocol; F#LS is based on the [language server protocol](https://microsoft.github.io/language-server-protocol/specification) standard. diff --git a/spacemacs/fsharp2/config.el b/spacemacs/fsharp2/config.el new file mode 100644 index 0000000..0c0da66 --- /dev/null +++ b/spacemacs/fsharp2/config.el @@ -0,0 +1,17 @@ +;;; config.el --- fsharp Layer config File for Spacemacs +;; +;; Copyright (c) 2012-2018 Sylvain Benner & Contributors +;; +;; Author: Chris Marchetti +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(spacemacs|define-jump-handlers fsharp-mode) + +(defvar fsharp2-backend 'lsp + "The backend to use for IDE features. Possible values are `fsac' and `lsp'") + +(defvar fsharp2-lsp-executable "FSharpLanguageServer" + "The locatio nof the FSharpLanguageServer executable") diff --git a/spacemacs/fsharp2/funcs.el b/spacemacs/fsharp2/funcs.el new file mode 100644 index 0000000..362740d --- /dev/null +++ b/spacemacs/fsharp2/funcs.el @@ -0,0 +1,55 @@ +;;; funcs.el --- fsharp2 Layer config File for Spacemacs +;; +;; Copyright (c) 2012-2018 Sylvain Benner & Contributors +;; +;; Author: Chris Marchetti +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs//fsharp2-setup-intellisense () + "Conditionally enable fsharp-mode's built-in intellisense" + (pcase fsharp2-backend + (`lsp + (setq fsharp-ac-intellisense-enabled nil)) + (`fsac + (setq fsharp-ac-intellisense-enabled t)))) + +(defun spacemacs//fsharp2-setup-backend () + "Conditionally setup fsharp backend" + (pcase fsharp2-backend + (`lsp + (require 'lsp) + (lsp-register-client + (make-lsp-client + :new-connection (lsp-stdio-connection fsharp2-lsp-executable) + :major-modes '(fsharp-mode) + :server-id 'fsharp-lsp)) + (lsp)))) + +(defun spacemacs//fsharp2-setup-bindings () + "Conditionally setup fsharp bindings" + (pcase fsharp2-backend + (`fsac + (spacemacs/declare-prefix-for-mode 'fsharp-mode "mf" "find") + (spacemacs/declare-prefix-for-mode 'fsharp-mode "ms" "interpreter") + (spacemacs/declare-prefix-for-mode 'fsharp-mode "mx" "executable") + (spacemacs/declare-prefix-for-mode 'fsharp-mode "mc" "compile") + (spacemacs/declare-prefix-for-mode 'fsharp-mode "mg" "goto") + (spacemacs/declare-prefix-for-mode 'fsharp-mode "mh" "hint")) + + (`lsp + (spacemacs/lsp-bind-keys-for-mode 'fsharp-mode)))) + +(defun spacemacs//fsharp2-setup-company () + "Conditionally setup company mode" + (pcase fsharp2-backend + (`lsp + (spacemacs|add-company-backends + :backends company-lsp + :modes fsharp-mode + :append-hooks nil + :call-hooks t) + (company-mode)))) diff --git a/spacemacs/fsharp2/packages.el b/spacemacs/fsharp2/packages.el new file mode 100644 index 0000000..4f841e3 --- /dev/null +++ b/spacemacs/fsharp2/packages.el @@ -0,0 +1,89 @@ +;;; packages.el --- F# Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2018 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq fsharp2-packages + '( + fsharp-mode + ggtags + company + counsel-gtags + helm-gtags + flycheck-mode + )) + +(defun fsharp2/init-fsharp-mode () + (use-package fsharp-mode + :defer t + :init + (progn + (setq fsharp-doc-idle-delay .2) + (spacemacs/register-repl 'fsharp-mode 'fsharp-show-subshell "F#") + (spacemacs//fsharp2-setup-intellisense) + (spacemacs/add-to-hook 'fsharp-mode-hook + '(spacemacs//fsharp2-setup-backend)) + :config + (progn + (defun spacemacs/fsharp-load-buffer-file-focus () + "Send the current buffer to REPL and switch to the REPL in + `insert state'." + (interactive) + (fsharp-load-buffer-file) + (switch-to-buffer-other-window inferior-fsharp-buffer-name) + (evil-insert-state)) + + (defun spacemacs/fsharp-eval-phrase-focus () + "Send the current phrase to REPL and switch to the REPL in + `insert state'." + (interactive) + (fsharp-eval-phrase) + (switch-to-buffer-other-window inferior-fsharp-buffer-name) + (evil-insert-state)) + + (defun spacemacs/fsharp-eval-region-focus (start end) + "Send the current phrase to REPL and switch to the REPL in + `insert state'." + (interactive "r") + (fsharp-eval-region start end) + (switch-to-buffer-other-window inferior-fsharp-buffer-name) + (evil-insert-state)) + + (spacemacs//fsharp2-setup-bindings) + (spacemacs/set-leader-keys-for-major-mode 'fsharp-mode + ;; Compile + "cc" 'compile + + "fa" 'fsharp-find-alternate-file + + "ht" 'fsharp-ac/show-tooltip-at-point + + "'" 'fsharp-show-subshell + "sb" 'fsharp-load-buffer-file + "sB" 'spacemacs/fsharp-load-buffer-file-focus + "si" 'fsharp-show-subshell + "sp" 'fsharp-eval-phrase + "sP" 'spacemacs/fsharp-eval-phrase-focus + "sr" 'fsharp-eval-region + "sR" 'spacemacs/fsharp-eval-region-focus + "ss" 'fsharp-show-subshell + + "xf" 'fsharp-run-executable-file))))) + +(defun fsharp2/post-init-ggtags () + (add-hook 'fsharp-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun fsharp2/post-init-counsel-gtags () + (spacemacs/counsel-gtags-define-keys-for-mode 'fsharp-mode)) + +(defun fsharp2/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'fsharp-mode)) + +(defun fsharp2/post-init-company () + (spacemacs//fsharp2-setup-company)) diff --git a/videos/EmacsLspMode.gif b/videos/EmacsLspMode.gif new file mode 100644 index 0000000..5ee701a Binary files /dev/null and b/videos/EmacsLspMode.gif differ