LoginSignup
5
3

More than 5 years have passed since last update.

VimでFSharpを実行(Run)・テスト(Test)・デバッグ(Debug)する

Last updated at Posted at 2018-05-21
=== 2018/05/21 Mon ===
はてなブログに以前書いたものを大幅に加筆・訂正したものです
======================

この記事はF# Advent Calendar2017 2日目の記事です ( see : F# Advent Calendar 2017 - Qiita )
この記事はVim2 Advent Calendar2017 2日目の記事です ( see : Vim2 Advent Calendar 2017 - Qiita )

IDEを使わなければ、コンピュータが自動でやってくれることなどほとんどなく、あとは自分の手でやるしかないのです。プログラミングとは元々そういうものだったはずです

see : Hello, Worldから始めよう | プログラマが知るべき97のこと

Greeting

こんにちは!最近ポンド円でほぼ死にかけのcallmekoheiです!みなさまいかがお過ごしでしょうか?今回はF#VimAdvent Calendarに同時にポストします!

思えばなんで僕、VimF#のコード書いてるんでしょうね?Visual StudioとかVisual Studio Codeとか他にも書きやすい環境があるのに。。。なんというかですね、なんというかですね、VimF#はウイスキーに生ハムぐらい合うんですよ。も、もちろん個人の意見ですがwww。まぁ、あれですよ。僕が複雑なこと理解できないやつなんでシンプルな環境の方が好きなんですよね。

というわけで、VimF#のコード書くときのちょっとした環境構築について書いてみます。というか僕自身が趣味でコード書いてるのでお仕事とかで使うには辛いかもですが、まぁすごくシンプルな環境なんでお勉強とかちょっとしたテストとかにはいいと思ふのですよ。

それと環境構築はMac OSXで書いてますが、WindowsでもLinuxでもおんなじ感じですっ(だと思う・・・)

もしなにかあれば @callmekohei ( twitter )まで〜

Environment

$ sw_vers 
ProductName:    Mac OS X
ProductVersion: 10.13.4
BuildVersion:   17E202

00 - Install

まずは下地を整えませう〜

01. インストーラーをゲッツ!

Mac の場合Homebrewというインストーラーがあるのでこれをまずゲッツします。
Homebrewのホームページからコマンドをterminalで実行します。

Example of install Homebrew ( 2018/05/21 Mon )

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 

02. 各種アプリ・コマンドをゲッツ

vimはテキストエディタ、monoF#の実行環境、そしてPaket.NET libraryダウンローダーです。

$ brew install vim
$ brew install mono
$ brew install paket

.bash_profile or .bashrcに書く

export MONO_GAC_PREFIX="/usr/local"

03. Vimのプラグインをゲッツ

see also : Vim におけるプラグイン管理についてまとめてみた

ここでは例えばdein.vimというプラグインダウンローダー(plugin manager)を使ってみます。

01. deinフォルダーとdein.tomlファイルを作成します。たとえばこんな感じ。

$ mkdir -p $HOME/.config/nvim/dein/
$ touch $HOME/.config/nvim/dein.toml

02. .vimrcに下記を書きます。

" setting of dein

" ====== Fit your path!!! =====
let s:dein_dir = $HOME . '/.config/nvim/dein'
let s:toml     = $HOME . '/.config/nvim/dein.toml'
" =============================

let s:dein_repo_dir = s:dein_dir . '/repos/github.com/Shougo/dein.vim'

if !isdirectory(s:dein_repo_dir)
    execute '!git clone https://github.com/Shougo/dein.vim' s:dein_repo_dir
endif

execute 'set runtimepath+=' . s:dein_repo_dir

if dein#load_state(s:dein_dir)
    call dein#begin(s:dein_dir)
    call dein#load_toml(s:toml, {'lazy': 0})
    call dein#end()
    call dein#save_state()
endif

if dein#check_install()
    call dein#install()
endif

" turn on plugins
set nocompatible
syntax enable
filetype plugin indent on

03. dein.toml ファイルにゲッツしたいプラグインを書いてみる

[[plugins]]
repo = 'Shougo/dein.vim'

#----------------------------------------------------------
# Aquires for running Neovim-plugins on Vim8
#----------------------------------------------------------
[[plugins]]
repo = 'roxma/nvim-yarp'

[[plugins]]
repo = 'roxma/vim-hug-neovim-rpc'

#----------------------------------------------------------
# Auto-complete for F# script
#----------------------------------------------------------
[[plugins]]
repo = 'Shougo/deoplete.nvim'
hook_add = '''
    let g:deoplete#enable_at_startup = 1
'''

[[plugins]]
repo = 'callmekohei/deoplete-fsharp'
build = 'bash install.bash'
hook_add = '''
    call deoplete#custom#option({
    \ 'auto_complete_delay': 0,
    \ 'ignore_case': v:true,
    \ })

    " remove duplicate candidates
    call deoplete#custom#source('_',
    \ 'converters', ['remove_overlap'])

    " Disable the candidates in Comment/String syntaxes.
    call deoplete#custom#source('_',
    \ 'disabled_syntaxes', ['Comment', 'String'])
'''

#----------------------------------------------------------
# Debug for F# script
#----------------------------------------------------------
[[plugins]]
repo = 'callmekohei/tigaDebugger'

#----------------------------------------------------------
# Run fsharp command
#----------------------------------------------------------
[[plugins]]
repo = 'Shougo/vimproc.vim'
build = 'make'

[[plugins]]
repo = 'thinca/vim-quickrun'
hook_add = '''
    set splitright
    let g:quickrun_config = {}

    let g:quickrun_config._ = {
        \  'runner'                          : 'vimproc'
        \ ,'runner/vimproc/updatetime'       : 60
        \ ,'hook/time/enable'                : 1
        \ ,'hook/time/format'                : "\n*** time : %g s ***"
        \ ,'hook/time/dest'                  : ''
        \ ,"outputter/buffer/split"          : 'vertical'
        \ ,'outputter/buffer/close_on_empty' : 1
    \}

    let g:quickrun_config.fsharp = {
        \  'command'                         : 'fsharpi --readline-'
        \ ,'tempfile'                        : '%{tempname()}.fsx'
        \ ,'runner'                          : 'concurrent_process'
        \ ,'runner/concurrent_process/load'  : '#load "%S";;'
        \ ,'runner/concurrent_process/prompt': '> '
    \}
'''

#----------------------------------------------------------
# Show indent guide lines
#----------------------------------------------------------
[[plugins]]
repo = 'nathanaelkane/vim-indent-guides'
hook_add = '''
    let g:indent_guides_enable_on_vim_startup = 1
    let g:indent_guides_start_level = 2
    let g:indent_guides_guide_size = 1
    let g:indent_guides_auto_colors = 0
    autocmd VimEnter,Colorscheme * :hi IndentGuidesOdd  guibg=black ctermbg=0
    autocmd VimEnter,Colorscheme * :hi IndentGuidesEven guibg=black ctermbg=0
'''

01 - 実行Runしてみよう!

sample.gif

01.コードを書いてみる

$ vim foo.fsx

foo.fsx

"hello" |> stdout.WriteLine

02.vim commandを実行

:w
:QuickRun

result

[Loading /Users/callmekohei/tmp/foo.fsx]
hello
namespace FSI_0003


*** time : 0.134435 s ***

02 - テストTestしてみよう!

image.png

01.fooフォルダを作成し移動

$ mkdir foo/
$ cd foo/

02.persimmon.scriptをダウンロード

$ paket init
$ vim paket.dependencies 

    generate_load_scripts: true
    source https://www.nuget.org/api/v2
    nuget persimmon.script

$ paket install

03.コードを書いてみる

$ vim foo.fsx

foo.fsx

#load "./.paket/load/net471/main.group.fsx"

open Persimmon
open UseTestNameByReflection
open System.Reflection

/// write your test code here.
let ``a unit test`` = test {
  do! assertEquals 1 2
}

/// print out test report.
new Persimmon.ScriptContext()
|> FSI.collectAndRun( fun _ -> Assembly.GetExecutingAssembly() )

04.vim commandを実行

:w
:QuickRun

result

[Loading /Users/callmekohei/tmp/deopletefs/.paket/load/net471/main.group.fsx
 Loading /Users/callmekohei/tmp/foo/foo.fsx]
x
begin FSI_0003.Foo
 Assertion Violated: a unit test
 1. Line Number: 9
    Expect: 1
    Actual: 2
end FSI_0003.Foo
============================== summary ===============================
run: 1, error: 0, violated: 1, skipped: 0, duration: 00:00:00.0008641
namespace FSI_0003.Main

namespace FSI_0003
  val ( a unit test ) : Persimmon.TestCase<unit>


*** time : 0.491798 s ***

03 - デバッグDebugしてみよう!

tigadebugger.gif

01. install

sdbsdbplgが必要です。

sdb

// download
$ git clone --depth 1 https://github.com/mono/sdb

// clone the submodules
$ cd ./sdb/
$ git submodule update --init --recursive

// build
$ make
$ make install

sdbplg

// download
$ git clone --depth 1 https://github.com/callmekohei/sdbplg

// build
$ cd ./sdbplg/
$ bash build.bash

// put `.sdb.rc` file on `$HOME`
$ cp .sdb.rc $HOME/

// set path
$ vim $HOME/.bash_profile
    export SDB_PATH=/PATH/TO/sdbplg/bin/

2. デバッグしてみる!

01.コードを書いてみる

$ mkdir foo/
$ cd foo/
$ vim foo.fsx

foo.fsx

let foo() =
    let mutable x = 1
    x <- 2
    x <- 3
    x

foo ()
|> stdout.WriteLine

02.vim commandを実行( デバッグシンボル.mdbを作成し、debugger(tigaDebugger)を起動 )

:! sharpc -g --optimize- %
:TigaSetDebugger sdb
:Tiga foo.exe

03.デバッガーコマンドを入力

" set break point
: TigaCommand bp add at foo.fsx 3

" run
: TigaCommand r

" next
: TigaCommand n

" quit debug mode
: TigaQuit

ショートカットでらくらく操作〜

Press To
ctrl b Add or delete Breakpoint
ctrl d Delete all breakpoints
ctrl r Run
ctrl k Kill (Break)
ctrl p Replace watch variable
ctrl y Add watch variable
ctrl t Delete watch variable
ctrl n Step over ( Next )
ctrl i Step In
ctrl u Step out ( Up )
ctrl c Continue
5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3