hubFS: THE place for F#

. . . are you on The Hub?
Welcome to hubFS: THE place for F# Sign in | Join | Help
in Search

F# and emacs

Last post 12-08-2007, 0:29 by kikimora. 5 replies.
Sort Posts: Previous Next
  •  05-29-2006, 2:58 298

    F# and emacs

    Being one of the few people (it appears) for who F# is their first entrance into the .net ecosystem, I am not in possesion of visual studio and have been hacking away in emacs. Not that I'm complaining, emacs rocks ;). However as there is currently no specifically designed mode for F# in emacs I have been using "Tuareg-mode" and have recently started customising it for F#. So below are some of the changes I've made, and was hoping that other people may find them handy, or even have some of their own.

    As an aside, the visual studio f# addin won't work with any of the express editions will it? and those are the only freely available versions?

    in my .emacs file (along with the other things to setup tuareg mode)

    (setq auto-mode-alist (cons '("\\.fs\\w?" . tuareg-mode) auto-mode-alist))

    so tuareg mode will auto load when any f# file is loaded

    (add-hook 'tuareg-mode-hook
           '(lambda ()
           (set (make-local-variable 'compile-command)
            (concat "fsc \""
                (file-name-nondirectory buffer-file-name)
                "\""))))

    customising the compile command of emacs "compile.el" compilation macros.
    So when you hit C-c C-c ...
       fsc "myFile.fs"
    comes up instead of the standard "make -k"


    And here are some customizations inside tuareg.el ...

    a rather quick hack that could be done better to support both f# and ocaml files. Just allows you to flick between .fs and .fsi files.

    (defun tuareg-find-alternate-file ()
      "Switch Implementation/Interface."
      (interactive)
      (let ((name (buffer-file-name)))
        (if (string-match "\\`\\(.*\\)\\.fs\\(i\\)?\\'" name)
        (find-file (concat (tuareg-match-string 1 name)
                   (if (match-beginning 2) ".fs" ".fsi"))))))

    just comment out the original and add this in.

    and
    (defvar tuareg-interactive-program "fsi"
      "*Default program name for invoking a FSharp toplevel from Emacs.")

    Again in this insanely huge tuareg.el file

    (defconst tuareg-error-regexp-fs
      "^\\([^(\n]+\\)(\\([0-9]+\\),\\([0-9]+\\)):"
      "Regular expression matching the error messages produced by fsc.")

    (if (boundp 'compilation-error-regexp-alist)
        (or (assoc tuareg-error-regexp-fs
                   compilation-error-regexp-alist)
            (setq compilation-error-regexp-alist
                  (cons (list tuareg-error-regexp-fs 1 2 3)
                   compilation-error-regexp-alist))))

    allowing the compilation system to parse the error messages from the f# compiler so that you can jump to them in your file with M-x`


    I've fiddled around with syntax highlighting and indentation... but nothing that works well and isn't an ugly hack. I've never written a language mode for emacs before... so really all I know is some lisp and a vague idea of what I want to do.

    Things that would be nice to get sorted are...
    supporting // style comments as well as (* *) style comments... which i believe involves modding the syntax table defined in the mode.
    The haskell mode has few more good features that would be nice to shamelessly steal, like displaying types in the minibuffer.

    I guess most people are using visual studio... but hopefully someone will find this useful or help me out.
  •  05-29-2006, 9:01 299 in reply to 298

    Re: F# and emacs

    Hi DeeJay!

    I use emacs too now and then Embarrassed [:$]  I still find it the best way to quickly open and search log files, and I also use it to develop the Visual Studio mode when something I've done has busted it!

    For F# code I use a version of an emacs OCaml mode ("caml-mode") I've been using for years - I haven't modified it for F#.  James Margetson also uses emacs and uses a modified version of Tuareg.  It would be great to get the bits and pieces to make a decent mode together.

    The F# VS Plugins won't work with VS Express editions, alas. I would love to work with the community to help someone develop an extension to CSharpDevelop by plugging into the F# Compiler APIs for interactive syntax highlighting, type checking and intellisense (we would help you with the API side, others would have to be responsible for developing the plugin that uses the API, "owning" the plugin over the long term, testing it, announcing it etc.).  I actually suspect we could have something up and running very quickly if someone puts their mind to it.

    Cheers!

    Don

  •  05-29-2006, 10:34 300 in reply to 299

    Re: F# and emacs

    Seems like a 'polished' emacs mode wouldn't be too much more effort... and I'd be up for being a part of that.

    Is a language even a reality if it doesn't have an emacs mode ;). I guess what I'm getting at is having a freely available editor with good support for said language can only help adoption. F# merges two worlds and one of those worlds is used to, and typically owns VS.net and the other does not. I am from the latter, and I can see people being turned away if it appears that a commercial tool is the only one with specific support.

    Boo and Nemerle are other .net languages developed by 3rd parties
    Boo has SharpDevelop and JEdit
    Nemerle has loads (http://nemerle.org/Editors)

    Having a ShapDevelop addin as well as an emacs mode would be great too.

    I spose I should really be spending more time revising... and I've signed myself for an intership this summer, however I'm more than willing to spend every other waking moment contributing to this (and yes if you haven't guessed already, I'm a CS ugrad).
  •  05-30-2006, 17:59 308 in reply to 300

    Re: F# and emacs

    Great!  Let me know if/when you want to start taking a crack at the SharpDevelop plug-in.  We can talk through the relevant functionality and APIs.  You could probably start on a project system by copying an existing sample.

    Cheers!

    Don

  •  03-27-2007, 6:59 2498 in reply to 298

    Re: F# and emacs

    Using plain old caml mode, I got highlighting to work by doing the following:

    1) Add the following after the existing comments regexp in caml-font.el
    ;comments
       '("\\(^\\|[^\"]\\)\\((\\*[^*]*\\*+\\([^)*][^*]*\\*+\\)*)\\)"
         2 font-lock-comment-face)
    ;fs comments
       '("//.*" . font-lock-comment-face)


    2) Comment out the following code farther down in the same file:
    ;(setq caml-mode-hook
    ;      '(lambda ()
    ;         (cond
    ;          ((fboundp 'global-font-lock-mode)
    ;           (make-local-variable 'font-lock-defaults)
    ;           (setq font-lock-defaults
    ;                 '(caml-font-lock-keywords nil nil ((?' . "w") (?_ . "w")))))
    ;          (t
    ;           (setq font-lock-keywords caml-font-lock-keywords)))
    ;         (make-local-variable 'font-lock-keywords-only)
    ;         (setq font-lock-keywords-only t)
    ;         (font-lock-mode 1)))

  •  12-08-2007, 0:29 4274 in reply to 298

    Re: F# and emacs

    Instead of modifying existing tuareg.el you can use elisp advice facility. Below is my customization of tuareg mode for F# (in ~/.emacs.d/init.el)
    ;; fsharp
    (setq auto-mode-alist (cons '("\\.fs\\w?" . tuareg-mode) auto-mode-alist))
    
    (defadvice tuareg-find-alternate-file (around fsharp-find-alternate-file)
      "Switch Implementation/Interface."
      (interactive)
      (let ((name (buffer-file-name)))
        (if (string-match "\\`\\(.*\\)\\.fs\\(i\\)?\\'" name)
            (find-file (concat (tuareg-match-string 1 name)
                               (if (match-beginning 2) ".fs" ".fsi"))))))
    
    (defconst tuareg-error-regexp-fs
      "^\\([^(\n]+\\)(\\([0-9]+\\),\\([0-9]+\\)):"
      "Regular expression matching the error messages produced by fsc.")
    
    (add-hook 'tuareg-mode-hook
              '(lambda ()
                 (ad-activate 'tuareg-find-alternate-file)
                 (setq tuareg-interactive-program "fsi")
                 (if (boundp 'compilation-error-regexp-alist)
                     (or (assoc tuareg-error-regexp-fs
                                compilation-error-regexp-alist)
                         (setq compilation-error-regexp-alist
                               (cons (list tuareg-error-regexp-fs 1 2 3)
                                     compilation-error-regexp-alist))))))
    
View as RSS news feed in XML
Powered by Community Server, by Telligent Systems