callmekohei's blog

callmekoheiのひとりごと

人間万事塞翁が馬っ

そういえば

最近 iPhone の調子悪くて Twitter とか Camera とかたちあがらない

容量オーバーですって表示が出るので写真をパソコンに保存・削除しましたっ

パソコンに iPhone の写真を保存

iPhoneに5000枚ほど写真がある状態

iPhoto.appを立ち上げて写真をパソコンに転送

で、iPhoneの写真をどうやって削除するかわからなかったので

image Capture.app で一括削除

1時間近くかかりました (^_^;;

パソコンから外付けHDDへ

下記に保存されてたので外付けHDD

Masters$ pwd
/Users/callmekohei/Pictures/iPhoto Library.photolibrary/Masters
Masters$ tree | head
.
└── 2018
    └── 02
        └── 24
            └── 20180224-053004
                ├── IMG_0001.JPG
                ├── IMG_0002.JPG
                ├── IMG_0003.JPG
                ├── IMG_0004.JPG
                ├── IMG_0005.PNG

写真をリサイズ

このブログ記事用に写真の容量を抑えたかったのでリサイズしました

こんな感じのコマンドで。

$ for file in *.JPG; do sips --resampleWidth 580 $file ; done

5000枚ほどで20分ほどかかりました (^_^;;





で、この3年間ふりかえってみた

この5000枚ほどの写真って、僕が会社辞めた直後からの記録なんですよね。

写真ってすごくて、記憶が鮮明によみがえってきますね、、、

いいことも、わるいことも。

というわけで、まずは自分の3年間を振り返ってみようかなと。

2016/01/20

お酒飲みながら書いた 初期の頃の似顔絵

f:id:callmekohei00:20180224102805j:plain

2016/01/09

まだトレード始めたばかりで 意味もわからず 本読んでた頃

f:id:callmekohei00:20180224103014j:plain

f:id:callmekohei00:20180224103017j:plain

2016/02/12

トレードで 一番負けた時

f:id:callmekohei00:20180224103201j:plain

2016/03/09

シードルというワインを 初めて飲んだ おいしかった

f:id:callmekohei00:20180224103249j:plain

2016/03/11

うちの猫くん ぱちりっ かわいい (((o(゚▽゚)o)))♡

f:id:callmekohei00:20180224103325j:plain

2016/03/24

となりのおじさんに

「   

    仕事もしないのに  
     
    寿司なんか食うな   

    お前みたいなのがいるから
      
    日本の国力がおちるんだ

」

と30分説教された

思い出の寿司屋さん

f:id:callmekohei00:20180224103441j:plain

2016/04/06

Javaなきしださんに F#の本を持ってもらった

f:id:callmekohei00:20180224103510j:plain

2016/04/13

お部屋の様子を ぱちり

f:id:callmekohei00:20180224103541j:plain

2016/06/12

はじめて 一人焼肉をした おいしかった

f:id:callmekohei00:20180224103640j:plain

f:id:callmekohei00:20180224104034j:plain

2016/07/01

お酒を飲みながら 似顔絵〜

f:id:callmekohei00:20180224103710j:plain

2016/07/03

F#談話室に 参加するために 東京へ

ぺこさんと飲んだ〜

空港でもお絵かき

f:id:callmekohei00:20180224103759j:plain

f:id:callmekohei00:20180224103804j:plain

f:id:callmekohei00:20180224103806j:plain

2016/07/09

天神のエルボラーチョという

メキシカンなお店でテキーラ

で、店員さんをお絵かき〜

f:id:callmekohei00:20180224103912j:plain

f:id:callmekohei00:20180224103915j:plain

2016/08/17

はじめてバーという ところに入った

結局このバーは いきつけになっちゃったwww

f:id:callmekohei00:20180224104010j:plain

f:id:callmekohei00:20180224104012j:plain

2016/09/23

はじめてさんまを 焼いてみた でもなんか生臭かった

f:id:callmekohei00:20180224104108j:plain

2016/11/08

わかる人にはわかる 至福の瞬間www

f:id:callmekohei00:20180224104143j:plain

2017/01/28

OANDAのサーバーが おかしくなった?

多分値洗いで まちがった Balance updateが

されたんだと思う

あとで訂正されましたけどwww

f:id:callmekohei00:20180224104225j:plain

2017/03/06

いつものバーの 天井いっぱいに 風船を敷きつめた

大変だった 親指が痛くなったwww

f:id:callmekohei00:20180224104252j:plain

2017/08/01

コーヒー飲みながら ラクダの絵っ

f:id:callmekohei00:20180224104315j:plain

2017/09/04

はじめて3けた 勝てたとき

これ一回しかないのが 悲しいところ (^_^;;

f:id:callmekohei00:20180224104345j:plain

2017/10/13

お酒飲みながら 馬の絵っ

f:id:callmekohei00:20180224104422j:plain

2017/10/31

ワインバーの女の子

f:id:callmekohei00:20180224104449j:plain

2017/11/04

VimConfに参加するために 東京へ〜

憧れの暗黒さんと お酒飲めた!

けど酔いすぎて 話した内容覚えてないwww

f:id:callmekohei00:20180224104535j:plain

f:id:callmekohei00:20180224104538j:plain

f:id:callmekohei00:20180224104540j:plain

2017/11/28

ランチに カツサンドとドロナック

うますぎっ

f:id:callmekohei00:20180224104648j:plain

f:id:callmekohei00:20180224104651j:plain

f:id:callmekohei00:20180224104653j:plain

2018/01/06

たしか前の日 魔女の宅急便やってて

ジジが描きたくなって 描いてみたのだ〜

f:id:callmekohei00:20180224104734j:plain

f:id:callmekohei00:20180224104737j:plain

2018/01/17 2018/02/10

ラブリーなふたり

f:id:callmekohei00:20180224104808j:plain

f:id:callmekohei00:20180224104811j:plain

ふりかえってみて・・・

トレードで負けまくる

お酒飲む

お絵描きする

な感じの3年間だったな〜

この先どうやって生きていこっと

ふむ〜




Remove all ads

Python's pdb debugger using pdbpp ( pdb の見た目をかえたみた!)

Summary

Pythonの標準デバッガのpdbの見た目をかえてみた!

こんなかんじ

f:id:callmekohei00:20180219101724g:plain

Vimを使うことでさらに便利〜

f:id:callmekohei00:20180219102626g:plain

使ってみたい方はこちら〜

github.com

使い方

// github からダウンロードする
$ git clone --depth 1 https://github.com/callmekohei/pdb

// ブランチの確認
$ git branch -a

// ブランチの切り替え
$ git checkout origin tiny_display_mode
$ git pull origin tiny_display_mode

// パスをとおす
$ vim .bash_profile

export PYTHONPATH=/path/to/pdb

// 設定ファイルを作成 & 下記を書く
$ vim .pdbrc.py

import pdb

class Config(pdb.DefaultConfig):

    sticky_by_default = True
    enable_tiny_display = True
    divinding_line = "─"

実際に動かしてみる

// サンプルファイル
$ vim foo.py

def foo():
    x = 1
    x = 2
    x = 3
    x = 4
    x = 5
    print('world')
    return x

y = foo()

print(y)

print('hello')

// 動かしてみる
$ python3 -m pdb foo.py
Remove all ads

MQL on Vim ( VimでMQLをかいてみる )

f:id:callmekohei00:20180208173913g:plain

Summary

MQLという言語をVimで書いて実行する環境を作ってみました〜

MQLとはMetaTraderというソフトの言語です

Thanks

@haxe

@matthn

@raa0121

Environment

nvim$ sw_vers 
ProductName:    Mac OS X
ProductVersion: 10.13.3
BuildVersion:   17D47

nvim$ wine --version
wine-3.0

nvim$ mono --version
Mono JIT compiler version 5.4.1.6 (tarball Mon Dec 11 14:59:42 GMT 2017)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
    TLS:           normal
    SIGSEGV:       altstack
    Notification:  kqueue
    Architecture:  amd64
    Disabled:      none
    Misc:          softdebug 
    LLVM:          supported, not enabled.
    GC:            sgen (concurrent by default)


nvim$ wine cmd
Microsoft Windows 10.0.15063 (3.0)

Z:\Users\callmekohei\.config\nvim>

MetaEditorに F5 を送る

こんな感じ

F#で書いてます

// file name is abc.fsx

open System.Runtime.InteropServices
open System.Windows.Forms

[<DllImport "user32.dll">]
extern nativeint FindWindow(string className, string windowName)

[<DllImport "user32.dll">]
extern bool SetForegroundWindow(nativeint hwnd)

FindWindow("MetaQuotes::MetaEditor::5.00", null) |> SetForegroundWindow |> ignore
SendKeys.Send "{F5}"

Quickrunの設定

こんな感じ

 let g:quickrun_config.mql4 = {
        \  'exec': [ '%c %o %s:p:t' ]
        \ ,'command':'bash'
        \ ,'cmdopt' :'$HOME/tmp/quickrunMQL/quickrunMQL.bash'
    \}

foo.bash

^Mは ctrl V , ctrl M で入力する

# ===========================================================================
#  FILE    : mql
#  AUTHOR  : callmekohei <callmekohei at gmail.com>
#  License : MIT license
# ===========================================================================

file=$1
MetaTraderHOME=("$WINEPREFIX/drive_c/Program Files/OANDA - MetaTrader")
MetaEditor=("${MetaTraderHOME[@]}"/metaeditor.exe)
SendsKeyCMD=$(cd $(dirname $0) && pwd)/quickrunMQL

wine "${MetaEditor[@]}" /s /log:foo.log /compile:$file 2>/dev/null
iconv -f utf-16 -t utf-8 foo.log | sed -e "s/^M//g" > bar.log

echo "───── MetaEditor Compiler ─────"
cat bar.log

if cat bar.log | fgrep 'Result 0 error(s), 0 warning(s)' 1>/dev/null ; then

    echo "───── MetaTrader Terminal ─────"
    echo $SendsKeyCMD | wine cmd 1>/dev/null
    echo $SendsKeyCMD | wine cmd 1>/dev/null
    echo $SendsKeyCMD | wine cmd 1>/dev/null
    cat "${MetaTraderHOME[@]}"/MQL4/Logs/$(date +"%Y%m%d").log | tail -4 | sed -e "s/\\^M//g"

fi

rm foo.log
rm bar.log

課題

とりあえず動く、という程度なのでもっと洗練させたい

Remove all ads

MacOSXでMetatrader4をつかう(2018年1月)

f:id:callmekohei00:20180129082327p:plain

Summary

MacOSXでMetatrader4をつかう

terminalに慣れてない人はPlayOnMacを使った作業がおすすめ

Prepare

// xquartzをインストール
$ brew cask install xquartz

// wineをインストール
$ brew install wine

// winetricksをインストール
$ brew install winetricks

// create 32-bit wine prefix
WINEPREFIX="$HOME/.wine" WINEARCH=win32 wine wineboot

// windows10にする
$ winecfg
—> Guiがたちあがる
—> 右下のポップアップでwindows10を選ぶ

Font

// フォントをインストール
$ winetricks allfonts

// フォントを滑らかな表示にする
$ winetricks fontsmooth-rgb

// 日本語を表示できるようにする
.wine$ pwd
/Users/callmekohei/.wine

.wine$ vim user.reg

[Software\\Wine\\Fonts\\Replacements] 1517178030
#time=1d3988634f50dc0
"Arial Unicode MS"                            = "Meiryo"
"Batang"                                      = "Meiryo"
"BatangChe"                                   = "Meiryo"
"DFKai-SB"                                    = "Meiryo"
"Dotum"                                       = "Meiryo"
"DotumChe"                                    = "Meiryo"
"FangSong"                                    = "Meiryo"
"Gulim"                                       = "Meiryo"
"GulimChe"                                    = "Meiryo"
"KaiTi"                                       = "Meiryo"
"Meiryo"                                      = "Meiryo"
"Meiryo UI"                                   = "Meiryo"
"Microsoft JhengHei"                          = "Meiryo"
"Microsoft YaHei"                             = "Meiryo"
"MingLiU"                                     = "Meiryo"
"MS Gothic"                                   = "Meiryo"
"MS Mincho"                                   = "Meiryo"
"MS PGothic"                                  = "Meiryo"
"MS PMincho"                                  = "Meiryo"
"MS UI Gothic"                                = "Meiryo"
"NSimSun"                                     = "Meiryo"
"PMingLiU"                                    = "Meiryo"
"SimHei"                                      = "Meiryo"
"SimKai"                                      = "Meiryo"
"SimSun"                                      = "Meiryo"
"\x30e1\x30a4\x30ea\x30aa"                    = "Meiryo"
"\xff2d\xff33 \x30b4\x30b7\x30c3\x30af"       = "Meiryo"
"\xff2d\xff33 \x660e\x671d"                   = "Meiryo"
"\xff2d\xff33 \xff30\x30b4\x30b7\x30c3\x30af" = "Meiryo"
"\xff2d\xff33 \xff30\x660e\x671d"             = "Meiryo"

metatrader4をインストール

// exeファイルの場所まで移動
$ cd ~/Downloads/

// インストール開始
$ wine oanda4setup.exe

ショートカットの作成

$ touch metatrader
$ chmod 777 metatrader
$ vim metatrader 

cd "/Users/callmekohei/.wine/drive_c/Program Files/OANDA - MetaTrader"
wine "/Users/callmekohei/.wine/drive_c/Program Files/OANDA - MetaTrader/terminal.exe”

$ mv metatrader /usr/local/bin

実行

// at terminal

metatrader






metaeditorでmqlのエラーチェック

$ vim hello.mq4

void start()
{
  Print("Hello World")
}

$ wine "/Users/callmekohei/.wine/drive_c/Program Files/OANDA - MetaTrader/metaeditor.exe" /s /log:CON /compile:"hello.mq4" 

0017:fixme:mountmgr:harddisk_ioctl Unsupported ioctl 2d1400 (device=2d access=0 func=500 method=0)
0031:fixme:ver:GetCurrentPackageId (0x38afefc 0x0): stub
hello.mq4 : information: Checking 'hello.mq4'
hello.mq4(4,1) : error 154: ')' - semicolon expected
hello.mq4(4,1) : error 161: ')' - unexpected end of program
 : information: Result 2 error(s), 0 warning(s)

uninstall

$ brew cask uninstall xquartz

$ brew uninstall winetricks

$ brew uninstall wine

~$ rm -rf .wine/

Reference

myuon-myon.hatenablog.com

www.davidbaumgold.com

MacOS/Building - WineHQ Wiki

stackoverflow.com

Remove all ads

Vim8 / Neovim でリモートプラグインを書くときのメモ

サンプルをやってみる

see also : python-client

Create folder

$ mkdir -p foo/rplugin/python3

Create plugin file

$ nvim foo/rplugin/python3/foo.py
### from https://github.com/neovim/python-client#remote-new-style-plugins
import neovim

@neovim.plugin
class TestPlugin(object):

    def __init__(self, nvim):
        self.nvim = nvim

    @neovim.function("TestFunction", sync=True)
    def testfunction(self, args):
        return 3

    @neovim.command("TestCommand", range='', nargs='*')
    def testcommand(self, args, range):
        self.nvim.current.line = ('Command with args: {}, range: {}'
                                  .format(args, range))

    @neovim.autocmd('BufEnter', pattern='*.py', eval='expand("<afile>")', sync=True)
    def on_bufenter(self, filename):
        self.nvim.out_write("testplugin is in " + filename + "\n")

Set path

$ nvim init.vim

set runtimepath+=/path/to/foo

UpdateRemotePlugins

$ nvim

:UpdateRemotePlugins

usage

function

$ nvim

:echo TestFunction()
3

command

$ nvim

:TestCommand

// written in buffer
Command with args: [], range: [1, 1]

autocommand

$ nvim abc.py

// display in command line
testplugin is in abc.py

他のファイルをインポートする

こんな感じで

rplugin$ tree
.
└── python3
    └── tigaDebugger
        ├── __init__.py
        └── greeting.py

__init__.py

import neovim
import tigaDebugger.greeting

@neovim.plugin
class TestPlugin(object):

    def __init__(self, nvim):
        self.nvim = nvim

    @neovim.function("TestFunction", sync=True)
    def testfunction(self, args):
        return greeting.daytime()

greeting.py

def daytime():
    return "hey!"

usage

$ nvim

: echo TestFunction()
hey!

インポートファイルを切り替える

こんな感じ

rplugin$ tree
.
└── python3
    └── tigaDebugger
        ├── __init__.py
        ├── greeting00.py
        └── greeting01.py

__init__

import neovim

@neovim.plugin
class TestPlugin(object):

    def __init__(self, nvim):
        self.nvim = nvim

    @neovim.function("OnInit", sync=True)
    def on_init(self,arg):
        if arg[0] == 0:
            import tigaDebugger.greeting00 as greeting
        elif arg[0] == 1:
            import tigaDebugger.greeting01 as greeting

        self.greeting = greeting

    @neovim.function("TestFunction", sync=True)
    def testfunction(self, args):
        return self.greeting.daytime()

greeting00

def daytime():
    return "hey!"

greeting01

def daytime():
    return "hello!"

usage

$ nvim

: call OnInit(0)
: echo TestFunction()
hey!

: call OnInit(1)
: echo TestFunction()
hello!

グローバル変数のセット

Create global variable

foo.vim

$ mkdir -p foo/plugin/
$ nvim foo/plugin/foo.vim

let msg = 'set by vim'

foo.py

import neovim

@neovim.plugin
class TestPlugin(object):

    def __init__(self, nvim):
        self.nvim = nvim

    @neovim.function("Bar", sync=True)
    def bar(self, args):
        self.nvim.vars['msg'] = 'set by python'

usage

$ nvim
:echo msg
set by vim

: call bar()
: echo msg
set by python

Vim8でリモートプラグインをつかう

see : sample

Reference

nvim manual

:h remote_plugin.txt
:h python

github.com

syfm.hatenablog.com

qiita.com

github.com

Remove all ads

git add -p の使い方

Summary

git add -p を使ってコードの変更管理を綺麗にする

準備

実験フォルダjikkenをつくってgit管理する

$ mkdir jikken
$ cd jikken
$ git init

テキストファイルfoo.txtを作ってコミットする

$ vim foo.txt
aaa
bbb
ccc

$ git add foo.txt

$ git commit -m 'first'

How to

foo.txtに追記する

$ vim foo.txt
aaa
bbb
ccc
ddd
eee
fff

add -pする

$ git add -p foo.txt

e(edit)を選んでコミットしたい部分だけ残して他は消す

// この状態から
+ddd
+eee
+fff

// こんな感じにする
+eee

コミットする

$ git commit -m 'add eee'

diffしてみる

$ git diff foo.txt

aaa
bbb
ccc
+ddd
eee
+fff

ちなみに

長いファイルだと一回でadd -pを実行した時にコミットしたい場所が出てこないかもしれないのでその場合はnをおしてどんどん先に進む。

Remove all ads

(Python : get stdout) 標準出力を取得する

Summary

Pythonで標準出力を取得する方法

その1(イベントを利用する)

こんな感じ

from queue import Queue
from threading import Thread, Event


class Util:

    def __init__(self, p, wait):

        self.wait     = wait
        self.event    = Event()
        self.q        = Queue()

        self.t        = Thread(target=self.enqueue_output, args=(self,))
        self.t.daemon = True
        self.t.start()


    def enqueue_output(self,_):
        while True:
            data = self.p.stdout.readline()
            self.q.put(data, True)
            self.event.set()


    def send(self,txt):
        self.event.clear()
        self.p.stdin.write(txt + '\n')
        self.p.stdin.flush()


    def read(self):
        self.event.wait(self.wait)

        list = []
        while True:
            if self.q.empty():
                break
            else:
                list.append( self.q.get_nowait() )

        return list

その2(エンドマークを利用する)

イベントを使っても取得しきれない場合

泥臭い方法かもかも

こんな感じ

from queue import Queue, Empty
from threading import Thread

class GreedyReader:

    def __init__(self, p, wait):

        self.q    = Queue()
        self.wait = wait
        self.p    = p

        t         = Thread(target=self.enqueue_output, args=(self.p.stdout, self.q))
        t.daemon  = True
        t.start()


    def enqueue_output(self, out, queue):
        for line in iter(out.readline, b''):
            queue.put(line)
        out.close()


    def send(self, txt):
        self.p.stdin.write('{txt}\n'.format(txt=txt))
        self.p.stdin.flush()


    def read_imple(self):
        try:  line = self.q.get_nowait()
        except Empty:
            return 'no output yet'
        else:
            return line


    def vacuumeCleaner(self,lst):
        l = lst[-20:]
        if len(set(l)) == 1 and l[0] == 'no output yet':
            for v in range(0,lst.count("no output yet")):
                lst.remove("no output yet")
            return (True,lst)
        else:
            return (False,lst)


    def read(self):

        timeout = 5
        start   = time.time()
        lst     = []

        while True:

            if time.time() - start > timeout:
                break

            lst.append( self.read_imple().strip() )
            msg = lst[-1].split(' ')

            if msg[0] == 'no output yet':
                time.sleep(self.wait)

            elif len(lst) > 20:
                flg,l = self.vacuumeCleaner(lst)
                if flg:
                    lst = l
                    break

            else:
                pass

        return lst

感想

Pythonよくわからないので、もしかしたらダメダメな方法かも、、、。

もっといい方法あったら是非教えてください〜

使用例

github.com

github.com

参考

subprocess – Work with additional processes - Python Module of the Week

18.5.6. Subprocess — Python 3.6.4 documentation

stackoverflow.com

Remove all ads

I make F# debugger client with vim ( fsdebugger )

This article is F# Advent Calendar2017 18th day ( see : F# Advent Calendar 2017 - Qiita )

Summary

I make F# debugger client with vim ( fsdebugger )

テキストエディタF#コードを書く人のためのデバッガークライアントを作ってみました!

名前はfsdebuggerといいます。

チョ〜お手軽デバッガークライアントです。

Screenshot

f:id:callmekohei00:20171223113508g:plain

Thanks

@yukios

@ShougoMatsu

@thinca

@mattn_jp

@ujm

@yoshitia

etc.

Motivation

I would like to debug F# code with vim.

たぶんお仕事でF#を書くときは、いわゆる開発環境(VS, VSC and Rider etc)などを使ってると思うんですけど、趣味とか、スクリプトとかの書き捨てコードを書く場合、テキストエディタで十分だと思うのですよ。ただテキストエディタでコード書くときデバッガーがないなと思ったので作ってみました!

fsdebugger

github.com

Requirements

テキストエディタText editor

vim8 or Noevim

テキストエディタの条件 ( requirements of Vim8/Neovim

has('python3')

もし Vim8だったらさらに下記の条件になります ( if you use Vim8

01. `roxma/nvim-yarp`
02. `roxma/vim-hug-neovim-rpc`
03. g:python3_host_prog pointed to your python3 executable, or echo exepath('python3') is not empty.
04. neovim python client (pip3 install neovim)

Install

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

$ vim .vimrc

set runtimepath+=/path/to/quickdebug

Usage

こんな感じ。。。 Like this...

// open .fs or .fsx file
$ vim foo.fsx

// start debug mode
: SDB
: SDBRun foo.exe

or 

: SDB foo.exe

or

// if fsx file with no #r
: SDB -g

// sdb command
: SDBCOMMAND bp add at foo.fsx 3

// quit sdb
: SDBQuit

Add --optimize- parameter to fsharp comiler

注意点としてはコンパイルするときは下記のように--optimize-としてください。ここ試験にでます。

// create exe file
$ fsharpc -g --optimize- foo.fs

// create dll file
$ fsharpc -a -g --optimize- foo.fs

Setting

Try it if fsdebugger do not work well.

mono/sdbというプログラムとプロセス通信という通信の仕方をしてるので遅いです(よくわかってない)。でfsdebuggerでウエイトタイムを適当にとってるのですがそれでもダメな場合はウエイトタイムを増やして動作を安定させるといいと思います。

// wait for running application
// default 1s
: SDBWait run 2

// wait for reading data from mono/sdb
// defalut 0.05s
: SDBWait read 0.1

// wait for printing variable
// defalut 0.5s
: SDBWait print 0.1

Debugger Shortcut Keys

下記のショートカットキーで動作させます ( shortcut keys is like this )

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

Extra

You need to attach namespace to top-level mutable variable to see value.

トップレベルのミュータブル変数をウオッチするときはネームスペースをつけないと見れません

例えばこういうコードだとして(for example

// foo.fsx
let mutable x = "hello"
x <- "world"

File name is namespace on fsharp script file ( fsx file ) . Namespace starts with big letter.

スクリプトファイルの場合、ファイル名がネームスペースになるので(それもイニシャル大文字)下記になります

// no...
:SDBWatchAdd x

// o.k!
:SDBWatchAdd Foo.x

I wrote it on Microsoft issue.

一応Microsoftにイシュー投げてます

github.com

Tutorial

コードはこんな感じで (Code example following:

let abc s =
    s

let str = abc("hello")

stdout.WriteLine(str)

コンパイルしつつのデバッグモードにはいります(compile and debug-mode)

:SDB -g

4行目にブレイクポイントを置きます(4行目にカーソルをもってきて <C-b>) (set cursor at line 4 and press control + b

    let abc s =
        s

>>  let str = abc("hello")

    stdout.WriteLine(str)

コードを実行します(<C-r>) (press control r and run application

    let abc s =
        s

>>  let str = abc("hello")  <--- cursor

    stdout.WriteLine(str)

変数strと変数sをウオッチします(<C-y> Foo.str, <C-y> s)(press control y and input Foo.str , press control y and input s to watch variables

右上のwatch-outウインドウに下記が表示されます (You see following strings at right upper window

#0 'Foo.str': object it = (null)
#1 's': <namespace> it = s

ステップイントゥー(<C-i>)して関数abcにはいります (press control + i and step into abc function)

    let abc s =
        s                  <--- cursor

>>  let str = abc("hello")

    stdout.WriteLine(str)

ステップオーバー(<C-n>)して次の行にいきます (press control + n and step over next line

    let abc s =
        s

>>  let str = abc("hello")

    stdout.WriteLine(str)  <--- cursor

変数strの内容をhelloからworldに書き換えます(<C-p> Foo.str = "world")( press control + p and input Foo.str = "world" and rewrite str value to world from hello

右上のwatch-outウインドウは下記になります (You see following strings at right upper window

#0 'Foo.str': string it = "world"
#1 's': <namespace> it = s

ステップオーバー(<C-n>)します (press control + n and step over

プログラムが終了します (program over

右下のquickrunfsウインドウに下記が表示されます (You see following strings at right down window)

Inferior process '2613' ('foo.exe') resumed
world
Inferior process '2613' ('foo.exe') exited with code '0'

Impressions

If there is something I will be happy to contact me ( @callmekohei ).

デバッガークライアント作ったのはいいけど、どういう感じで使えばいいのかまだまだよくわかってないのでこれから使い込んでいきたいです!この記事見てもし使ってみて色々感想・不満・要望等ありましたらぜひツイッター(@callmekohei)とかで教えてもらえると嬉しいです!

ぜひぜひF#テキストエディタで書いてみませう!

とくにスクリプトを書き捨てるにはうってつけです!

Fun F#!

Remove all ads

Build F# code with dotnet and msbuild

This article is F# Advent Calendar2017 8th day ( see : F# Advent Calendar 2017 - Qiita )


f:id:callmekohei00:20171209065402p:plain


Summary

I just try to build F# code with dotnet and msbuild.

Thanks

@yukitos

What is Build?

Build is compile and link.

3 ways of build

I understand a little bit of it. (^_^::

command TargetFramework reference
dotnet netstandard
dotnet msbuild net -p:FrameworkPathOverride
msbuild net Microsoft.FSharp.Targets

Environment

$ sw_vers 
ProductName:    Mac OS X
ProductVersion: 10.13.1
BuildVersion:   17B1003

$ uname -a
Darwin callmekoheis-MacBook-Air.local
17.2.0 Darwin Kernel
Version 17.2.0:
Fri Sep 29 18:27:05 PDT 2017;
root:xnu-4570.20.62~3/RELEASE_X86_64 x86_64

$ mono --version
Mono JIT compiler version 5.0.1.1 (2017-02/5077205 Sun Sep 17 18:29:46 BST 2017)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
    TLS:           normal
    SIGSEGV:       altstack
    Notification:  kqueue
    Architecture:  amd64
    Disabled:      none
    Misc:          softdebug 
    LLVM:          supported, not enabled.
    GC:            sgen (concurrent by default)

Prepare

install msbuild

// download source
$ git clone https://github.com/Microsoft/msbuild.git 

// build ( ignore errors )
$./cibuild.sh --target Mono

// create msbuild command
$ vim msbuild

$HOME/msbuild/packages/msbuild/MSBuild.exe $@

$ chmod 777 msbuild
$ mv msbuild /usr/local/bin/

// check
$ msbuild /version
Microsoft (R) Build Engine version 14.1.0.0
Copyright (C) Microsoft Corporation. All rights reserved.

14.1.0.0

install dotnet

// download binary
https://github.com/dotnet/core/blob/master/release-notes/download-archives/2.0.3.md

// install from a binary archive
$ mkdir dotnet
$ tar zxf ~/Downloads/dotnet-sdk-2.0.3-osx-x64.tar.gz -C $HOME/dotnet

// add PATH
$ vim .bash_profile

export PATH=$PATH:$HOME/dotnet

// check
$ dotnet --version
2.0.3

$ dotnet msbuild /version
Microsoft (R) Build Engine version 15.4.8.50001 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

15.4.8.50001

dotenet

use dotnet core library

// write F# code
$ vim sample.fsx

printfn "hello"

// write build script
$ vim sample.fsproj

<Project Sdk="Microsoft.NET.Sdk" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netstandard1.6</TargetFramework>
        <DebugType>full</DebugType>
    </PropertyGroup>

    <PropertyGroup Condition="$(OS)=='Unix'">
        <FscToolPath>/usr/local/bin/</FscToolPath>
        <FscToolExe>fsharpc</FscToolExe>
    </PropertyGroup>

    <Target Name="Copy MDBs" AfterTargets="Build">
        <Copy SourceFiles="$(IntermediateOutputPath)/$(AssemblyName).dll.mdb" DestinationFolder="$(OutputPath)" ContinueOnError="true" />
    </Target>

    <ItemGroup>
        <Compile Include="./sample.fsx" />
    </ItemGroup>

</Project>

// create  dependencies specified in the .NET project
$ dotnet restore sample.fsproj

$ tree
.
├── obj
│   ├── project.assets.json
│   ├── sample.fsproj.nuget.cache
│   ├── sample.fsproj.nuget.g.props
│   └── sample.fsproj.nuget.g.targets
├── sample.fsproj
└── sample.fsx

1 directory, 6 files

// build
$ dotnet build sample.fsproj

$ tree
.
├── bin
│   └── Debug
│       └── netstandard1.6
│           ├── sample.deps.json
│           ├── sample.dll
│           └── sample.dll.mdb
├── obj
│   ├── Debug
│   │   └── netstandard1.6
│   │       ├── sample.dll
│   │       ├── sample.dll.mdb
│   │       ├── sample.fsproj.CoreCompileInputs.cache
│   │       └── sample.fsproj.FileListAbsolute.txt
│   ├── project.assets.json
│   ├── sample.fsproj.nuget.cache
│   ├── sample.fsproj.nuget.g.props
│   └── sample.fsproj.nuget.g.targets
├── sample.fsproj
└── sample.fsx

6 directories, 13 files

// run
$ mono ./bin/Debug/netstandard1.6/sample.dll
hello

dotenet msbuild

use dotnet library

// write F# code
$ vim sample.fsx

printfn "hello"

// write build script
$ vim sample.fsproj

<Project Sdk="Microsoft.NET.Sdk" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net45</TargetFramework>
        <DebugType>full</DebugType>
    </PropertyGroup>

    <PropertyGroup Condition="$(OS)=='Unix'">
        <FscToolPath>/usr/local/bin/</FscToolPath>
        <FscToolExe>fsharpc</FscToolExe>
    </PropertyGroup>

    <Target Name="Copy MDBs" AfterTargets="Build">
        <Copy SourceFiles="$(IntermediateOutputPath)/$(AssemblyName).exe.mdb" DestinationFolder="$(OutputPath)" ContinueOnError="true" />
    </Target>

    <ItemGroup>
        <Compile Include="./sample.fsx" />
    </ItemGroup>

</Project>

// download .NET library
$ svn export https://github.com/mono/reference-assemblies/trunk/v4.5

// create  dependencies specified in the .NET project
$ dotnet restore sample.fsproj

$ tree
.
├── obj
│   ├── project.assets.json
│   ├── sample.fsproj.nuget.cache
│   ├── sample.fsproj.nuget.g.props
│   └── sample.fsproj.nuget.g.targets
├── sample.fsproj
├── sample.fsx
└── v4.5
    ├── Accessibility.dll
    ├── CustomMarshalers.dll
    ├── Facades
    │   ├── System.Collections.Concurrent.dll
    ...

// build
$ dotnet msbuild -p:FrameworkPathOverride=./v4.5 sample.fsproj 

$ tree
.
├── bin
│   └── Debug
│       └── net45
│           ├── FSharp.Core.dll
│           ├── System.Core.dll
│           ├── System.Data.dll
│           ├── System.Drawing.dll
│           ├── System.EnterpriseServices.dll
│           ├── System.IO.Compression.FileSystem.dll
│           ├── System.IO.Compression.dll
│           ├── System.Numerics.dll
│           ├── System.Runtime.Serialization.dll
│           ├── System.Transactions.dll
│           ├── System.ValueTuple.dll
│           ├── System.Xml.Linq.dll
│           ├── System.Xml.dll
│           ├── System.dll
│           ├── mscorlib.dll
│           ├── sample.exe
│           └── sample.exe.mdb
├── obj
│   ├── Debug
│   │   └── net45
│   │       ├── sample.exe
│   │       ├── sample.exe.mdb
│   │       ├── sample.fsproj.CopyComplete
│   │       ├── sample.fsproj.CoreCompileInputs.cache
│   │       └── sample.fsproj.FileListAbsolute.txt
│   ├── project.assets.json
│   ├── sample.fsproj.nuget.cache
│   ├── sample.fsproj.nuget.g.props
│   └── sample.fsproj.nuget.g.targets
├── sample.fsproj
├── sample.fsx
└── v4.5
    ├── Accessibility.dll
    ├── CustomMarshalers.dll
    ├── Facades
    ....

// run
$ mono ./bin/Debug/net45/sample.exe
hello

msbuild

use dotnet library

// write F# code
$ vim sample.fsx

printfn "hello"

// write build script
$ vim sample.fsproj

<Project Sdk="Microsoft.NET.Sdk" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net45</TargetFramework>
        <DebugType>full</DebugType>
    </PropertyGroup>

    <PropertyGroup Condition="$(OS)=='Unix'">
        <FscToolPath>/usr/local/bin/</FscToolPath>
        <FscToolExe>fsharpc</FscToolExe>
    </PropertyGroup>

    <Target Name="Copy MDBs" AfterTargets="Build">
        <Copy SourceFiles="$(IntermediateOutputPath)/$(AssemblyName).exe.mdb" DestinationFolder="$(OutputPath)" ContinueOnError="true" />
    </Target>

    <ItemGroup>
        <Compile Include="./sample.fsx" />
    </ItemGroup>

    <Import Project="/usr/local/Cellar/mono/5.0.1.1/lib/mono/fsharp/Microsoft.FSharp.Targets" />

</Project>

// build
$ msbuild sample.fsproj 

$ tree
.
├── bin
│   └── Debug
│       ├── sample.exe
│       └── sample.exe.mdb
├── obj
│   └── Debug
│       ├── sample.exe
│       ├── sample.exe.mdb
│       ├── sample.fsproj.FileListAbsolute.txt
│       └── sample.fsprojResolveAssemblyReference.cache
├── sample.fsproj
└── sample.fsx

4 directories, 8 files

// run
$ mono ./bin/Debug/sample.exe
hello
Remove all ads

Debug F# with sdb!

This article is F# Advent Calendar2017 7th day ( see : F# Advent Calendar 2017 - Qiita )

Summary

I just try to debug F# code with sdb!

Like this

f:id:callmekohei00:20171207200313p:plain

What is mono/sdb?

A command line client for the Mono soft debugger.

github.com

Environment

$ sw_vers 
ProductName:    Mac OS X
ProductVersion: 10.13.1
BuildVersion:   17B1003

$ uname -a
Darwin callmekoheis-MacBook-Air.local
17.2.0 Darwin Kernel
Version 17.2.0:
Fri Sep 29 18:27:05 PDT 2017;
root:xnu-4570.20.62~3/RELEASE_X86_64 x86_64

$ mono --version
Mono JIT compiler version 5.0.1.1 (2017-02/5077205 Sun Sep 17 18:29:46 BST 2017)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
    TLS:           normal
    SIGSEGV:       altstack
    Notification:  kqueue
    Architecture:  amd64
    Disabled:      none
    Misc:          softdebug 
    LLVM:          supported, not enabled.
    GC:            sgen (concurrent by default)

Prepare

install mono/sdb

$ git clone https://github.com/mono/sdb

$ cd sdb

$ git submodule update --init --recursive

$ make

check

$ sdb --version
Mono soft debugger (sdb) 1.5.6503.20649

$ which sdb
/usr/local/bin/sdb

setting

$ which mono
/usr/local/bin/mono

// set location of mono
$ sdb
(sdb) cfg s RuntimePrefix /usr/local/ ( was /usr )

Debug

// write code
$ vim sample.fsx 

namespace ABC

module DEF =
    let bar() =
        stdout.WriteLine("abc")

    let foo (str:string) =
        stdout.WriteLine(str)
        bar()

    [<EntryPointAttribute>]
    let main _ =
        let s = "Foo!"
        foo s
        stdout.WriteLine("callmekohei")
        0

// compile
$ fsharpc -g --optimize- sample.fsx 

// launch sdb
$ sdb
Welcome to the Mono soft debugger (sdb 1.5.6548.37600)
Type 'help' for a list of commands or 'quit' to exit

// set break point
(sdb) bp add func ABC.DEF.foo
Breakpoint '0' added for method 'ABC.DEF.foo'

// run 
(sdb) r sample.exe
Inferior process '8743' ('sample.exe') started
Hit method breakpoint on 'ABC.DEF.foo'
#0 [0x00000000] ABC.DEF.foo at /Users/callmekohei/tmp/xxx/sample.fsx:8
        stdout.WriteLine(str)

// look source code
(sdb) src
       1:    namespace ABC
       2:    
       3:    module DEF =
       4:        let bar() =
       5:            stdout.WriteLine("abc")
       6:    
       7:        let foo (str:string) =
       8:            stdout.WriteLine(str)  // <--- color green!
       9:            bar()
      10:    
      11:        [<EntryPointAttribute>]
      12:        let main _ =
      13:            let s = "Foo!"
      14:            foo s
      15:            stdout.WriteLine("callmekohei")
      16:            0

// continue
(sdb) c
Inferior process '8743' ('sample.exe') resumed
Foo!
abc
callmekohei
Inferior process '8743' ('sample.exe') exited with code '0'

// quiet
(sdb) q
Bye

Point

compile option --optimize-

$ fsharpc -g --optimize- sample.fsx 

WIP

I want to debug in Vim/Neovim with sdb.




Remove all ads

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

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

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



f:id:callmekohei00:20171130201645g:plain





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

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



Greeting

こんにちは!最近ポンド円でほぼ死にかけのcallmekoheiです!

みなさまいかがお過ごしでしょうか?

今回はFSharpVimAdvent Calenderに同時にポストします!

思えばなんで僕、VimFSharpのコード書いてるんでしょうね?

VSとかVSCとか他にも書きやすい環境があるのに。。。

なんというかですね、なんというかですね、VimFSharp

ウイスキー生ハムぐらい合うんですよ。

も、もちろん個人の意見ですがwww

まぁ、あれですよ。僕が複雑なこと理解できないやつなんで

シンプルな環境の方が好きなんですよね。

というわけで、VimFSharp のコード書くときの

ちょっとした環境構築について書いてみます。

というか僕自身が趣味でコード書いてるので

お仕事とかで使うには辛いかもですが

まぁすごくシンプルな環境なんでお勉強とか

ちょっとしたテストとかにはいいと思ふのですよ。

それと環境構築はOSXで書いてますが

WinでもLinuxでもおんなじ感じですっ

Environment

$ sw_vers 
ProductName:    Mac OS X
ProductVersion: 10.12.6
BuildVersion:   16G1036

Prepare

00: brewコマンドのインストール

下記のホームページからコマンドをterminalで実行しませう

brew.sh


01: Monoのインストール

brewコマンドで一発です〜

$ brew install mono


02: paketコマンドの作成

F#のライブラリをナゲットするためのコマンドを作りませう

see also : OSXでのF#(FSharp)環境整備 · GitHub

// nuget.exeのダウンロード
$ wget https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
$ sudo mv nuget.exe /usr/local/bin

// nuget スクリプト作成
$ touch nuget
$ vim nuget
#!/bin/sh
script_dir="$(cd "$(dirname "${BASH_SOURCE:-${(%):-%N}}")"; pwd)"
mono --runtime=v4.0 ${script_dir}/nuget.exe $*

$ chmod 777 nuget
$ sudo mv nuget /usr/local/bin

// nugetinstall スクリプト作成
$ touch nugetinstall
$ vim nugetinstall
#!/bin/sh
nuget install $* -OutputDirectory packages -ExcludeVersion

$ chmod 777 nugetinstall
$ sudo mv nugetinstall /usr/local/bin

// packetスクリプトの作成
$ touch paket
$ vin paket
#!/bin/sh
paket_path=./packages/Paket/tools/paket.exe
if [ ! -e $paket_path ]; then
  echo "Paket installing..."
  nugetinstall Paket
fi
mono $paket_path $*

$ chmod 777 paket
$ sudo mv paket /usr/local/bin


03: Vimプラグインのインストール

VimPython3enableにしたvimをインストール

$ brew install vim --with-python3

vimプラグインは下記をインストール(すきなプラグイン管理ソフトでどうぞ)

// NeovimのプラグインをVim8で使うのに必要
roxma/nvim-yarp
roxma/vim-hug-neovim-rpc

// FSharpの補完に必要
Shougo/deoplete.nvim
callmekohei/deoplete-fsharp

// 実行するときに必要
thinca/vim-quickrun
Shougo/vimproc.vim

ちなみにthinca/vim-quickrunの設定はちょっとコツがあるので下記を丸写ししてください。

set splitright
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
\     }
\
\     , 'fsharp' : {
\           'command'                         : 'fsharpi --readline-'
\         , 'tempfile'                        : '%{tempname()}.fsx'
\         , 'runner'                          : 'concurrent_process'
\         , 'runner/concurrent_process/load'  : '#load "%S:gs?\\?/?";;'
\         , 'runner/concurrent_process/prompt': '> '
\     }
\ }

Windowsのかたは、上記commandのところを下記に変えてください

fsi.exeのパスはよしなに・・・

'command': 'mono "C:\Program Files\Mono\lib\mono\fsharp\fsi.exe" --readline-'






実行 Run してみよう!

$ vim abc.fsx

code

stdout.WriteLine("hello")

vim command

: QuickRun

result

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


*** time : 0.118874 s ***

テスト Test してみよう!

// create foo folder ( プロジェクトフォルダ foo を作成 )
$ mkdir foo

// move foo folder ( プロジェクトフォルダ foo に移動 )
$ cd  foo

// init paket ( paket を初期化 )
$ paket init

// nuget test package - persimmon.script ( perssimon.script を nuget )
$ vim paket.dependencies 

write paket.dependencies ( paket.dependencies を記入 )

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

download library ( ライブラリをダウンロード )

$ paket install

wirte code ( コードをかく )

$ vim abc.fsx

code

#r "./packages/Persimmon/lib/net45/Persimmon.dll"
#r "./packages/Persimmon.Runner/lib/net40/Persimmon.Runner.dll"
#r "./packages/Persimmon.Script/lib/net45/Persimmon.Script.dll"

open System.Reflection
open Persimmon
open UseTestNameByReflection


/// 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() )

result

[Loading /Users/callmekohei/tmp/foo/abc.fsx]
x
begin FSI_0003.Abc
 Assertion Violated: a unit test
 1. Expect: 1
    Actual: 2
end FSI_0003.Abc
============================== summary ===============================
run: 1, error: 0, violated: 1, skipped: 0, duration: 00:00:00.0005501
namespace FSI_0003
  val ( a unit test ) : Persimmon.TestCase<unit>


*** time : 0.128949 s ***

デバッグ Debug してみよう!

わかりません・・・(^_^;;

ここ見てずっこけた方、すみません。。。

どうなんでしょ?

VimDebug それもFSharp

2つ課題があるのですよ。

まずFSharpそのもののデバッグ

mono/sdb というのがあるのですが

いまのところうまく動かないです・・・。

これはIssueだしてるので改善に期待してます!

2点目はVim8デバッグ環境。。。

mono/sdbを動かすのがないのですよね〜(僕が知らないだけだと思う・・)

で、まず最近の:TermDebugという機能になんとかmono/sdbを動作させるか

もしくはまた別の形で動かすか・・・。

ちなみにこんな活動もあるみたいなのですが動いてないみたいです・・・。

github.com

ぜひぜひVimに詳しい方はmono/sdbがうごくdebuggerをお願いします!

ぼ、僕も頑張りますっ (^_^;;

感想

いかがでしたでしょうか?

VimFSharp書くの本当に楽ですよ!

ぜひ試してみてください!


追記 ( 2017/12/18 )

vim8/Neovimのデバッガークライアントつくりました〜

よかったらぜひ〜

callmekohei00.hatenablog.com






Remove all ads

callmekohei のこれは飲んどけ🥃

Summary

callmekoheiが最近飲んでるお酒のまとめ



f:id:callmekohei00:20171130234148p:plain

No.0001
ドロナック

おすすめ(5段階)
5

特徴
辛さの中に甘みがある


f:id:callmekohei00:20171202164501j:plain

No.0002
シングルトン

おすすめ(5段階)
5

特徴
辛さの中に甘みがあるがややライト


f:id:callmekohei00:20171202164553j:plain

No.0003
フィディック

おすすめ(5段階)
4

特徴
世界で一番飲まれてる
飲みやすい


f:id:callmekohei00:20171202164646j:plain

No.0004
マッカラン ダブルカスク

おすすめ(5段階)
5

特徴
少し辛いが甘い
最初に飲むべきものの一つ


f:id:callmekohei00:20171202164757j:plain

No.0005
リベット

おすすめ(5段階)
5

特徴
程よい辛味
最初に飲むべきものの一つ



最近よくいくお店

ja.foursquare.com

bar-navi.suntory.co.jp






Remove all ads

単語補完をやってみた!

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



f:id:callmekohei00:20171130201341g:plain

Summary

こんにちは!ポンド円で負けまくって死にそうなcallmekoheiです!

ここ一年ほどF#の単語補完できたらいいな〜とすこしコード書いてました。

そのことを書いてみたいと思いマフ (^_^)/

単語補完とは?

F#のコードを書くじゃないですか?

で、そのとき例えばList.と書いて候補が出ると嬉しいですよね?

その候補を文脈から引き出します。

上記の映像が単語補完のサンプルです。

単語補完をやっている様子がつかめると思います。

どうやってるか?

今回やった環境はVimです。

Vimというのはメモ帳の機能をアップさせたようなものです。

で、このVimで単語補完するときの仕組みをdeopleteが提供してくれます。

で、実際に文脈から単語候補を提供してくれるのは

FSharp.Compiler.Serviceというライブラリ群です。

実際にやってみよう!

実際やってみるのはとても簡単です。

まずFSharp.Compiler.Servieライブラリをナゲットします。

で、次のようなコードを書きます。

// sample code from : https://github.com/fsharp/FSharp.Compiler.Service/blob/master/fcs/samples/EditorService/Program.fs

// Open the namespace with InteractiveChecker type
#r "./packages/FSharp.Compiler.Service/lib/net45/FSharp.Compiler.Service.dll"
open System
open Microsoft.FSharp.Compiler
open Microsoft.FSharp.Compiler.SourceCodeServices
open Microsoft.FSharp.Compiler.QuickParse

// Create an interactive checker instance (ignore notifications)
let checker = FSharpChecker.Create()

let parseWithTypeInfo (file, input) = 
    let checkOptions, _errors = checker.GetProjectOptionsFromScript(file, input) |> Async.RunSynchronously
    let parsingOptions, _errors = checker.GetParsingOptionsFromProjectOptions(checkOptions)
    let untypedRes = checker.ParseFile(file, input, parsingOptions) |> Async.RunSynchronously
    
    match checker.CheckFileInProject(untypedRes, file, 0, input, checkOptions) |> Async.RunSynchronously with 
    | FSharpCheckFileAnswer.Succeeded(res) -> untypedRes, res
    | res -> failwithf "Parsing did not finish... (%A)" res

はい。なんとなくよくわからないですけど、気にしない気にしない。

で次のコードを書きます。

// sample code from : https://github.com/fsharp/FSharp.Compiler.Service/blob/master/fcs/samples/EditorService/Program.fs

let input = 
  """
  let foo() = 
    let msg = "Hello world"
    if true then 
      printfn "%s" msg.
  """
let inputLines = input.Split('\n')
let file = "./Test.fsx" // <--- このファイルは実際にあるかどうかは問題ない

let untyped, parsed = parseWithTypeInfo (file, input)

let partialName = GetPartialLongNameEx(inputLines.[4], 22)

// Get declarations (autocomplete) for a location
let decls = 
    parsed.GetDeclarationListInfo(Some untyped, 5, inputLines.[4], partialName, (fun () -> [])) 
    |> Async.RunSynchronously

for item in decls.Items do
    printfn " - %s" item.Name

結果

 - Length
 - Chars
 - Clone
 - CompareTo
 - Contains
 - CopyTo
 - EndsWith
 - Equals
 - GetEnumerator
 - GetHashCode
...

このコードで重要な関数はGetDeclarationListInfo です。これが単語候補を引き出します。





longname, partial nameで考える

まずpartial nameとはみたいな。。下記を見たらわかるはず・・。

QuickParse.GetPartialLongNameEx("System.Test.",11)
|> printfn "%A"
(*
    {QualifyingIdents = ["System"; "Test"];
     PartialIdent = "";
     EndColumn = 11;
     LastDotPos = Some 11;}
*)


QuickParse.GetPartialLongNameEx("System.Test",10)
|> printfn "%A"

(*
    {QualifyingIdents = ["System"];
     PartialIdent = "Test";
     EndColumn = 10;
     LastDotPos = Some 6;}
*)



ではでは、このGetDeclarationListInfoがかえす4つのケースを考えてみます。

CASE1

よみこんでる namespace すべてをかえす

row = 0, col = 0でやってます。

昔はbase1だったんでrow=0にするとエラーがでてたけど最近変わった????

let file = "./Test.fsx" // <--- このファイルは実際にあるかどうかは問題ない

let input = ""
let row = 0
let partialName = QuickParse.GetPartialLongNameEx(input,0)
let untyped, parsed = parseWithTypeInfo (file, input)

// Get declarations (autocomplete) for a location
let decls = 
    parsed.GetDeclarationListInfo(Some untyped, row, input, partialName,  (fun () -> []))
    |> Async.RunSynchronously

for item in decls.Items do
    printfn " - %s" item.Name

結果

 - Choice1Of2
 - Choice1Of3
 - Choice1Of4
 - Choice1Of5
 - Choice1Of6
 - Choice1Of7
...

CASE2

namespace を指定している場合、その補完リストをかえす

let file = "./Test.fsx" // <--- このファイルは実際にあるかどうかは問題ない

let input = "Microsoft.FSharp."
let row = 1
let partialName = QuickParse.GetPartialLongNameEx(input,16)
let untyped, parsed = parseWithTypeInfo (file, input)

// Get declarations (autocomplete) for a location
let decls = 
    parsed.GetDeclarationListInfo(Some untyped, row, input, partialName,  (fun () -> []))
    |> Async.RunSynchronously

for item in decls.Items do
    printfn " - %s" item.Name

結果

 - Compiler
 - Reflection
 - Quotations
 - NativeInterop
 - Linq
 - Data
 - Core
 - Control
 - Collections

CASE3

dotを入力したとき推論できる場合は、その分の補完リストをかえす

let file = "./Test.fsx" // <--- このファイルは実際にあるかどうかは問題ない

let input =
    """
    let x = "abc"
    x.
    """
let inputLines = input.Split('\n')
let row = 3
let partialName = QuickParse.GetPartialLongNameEx(inputLines.[2],5)
let untyped, parsed = parseWithTypeInfo (file, input)

// Get declarations (autocomplete) for a location
let decls = 
    parsed.GetDeclarationListInfo(Some untyped, row, inputLines.[2], partialName,  (fun () -> []))
    |> Async.RunSynchronously

for item in decls.Items do
    printfn " - %s" item.Name

結果

 - Length
 - Chars
 - Clone
 - CompareTo
 - Contains
 - CopyTo
 - EndsWith
...

CASE4

dotを入力したとき推論できない場合は、なにもかえさない

let file = "./Test.fsx" // <--- このファイルは実際にあるかどうかは問題ない

let input = "a."
let row = 1
let partialName = QuickParse.GetPartialLongNameEx(input,1)
let untyped, parsed = parseWithTypeInfo (file, input)

// Get declarations (autocomplete) for a location
let decls = 
    parsed.GetDeclarationListInfo(Some untyped, row, input, partialName,  (fun () -> []))
    |> Async.RunSynchronously

for item in decls.Items do
    printfn " - %s" item.Name

結果

nothing

こんな感じです!

参考

github.com

fsharp.github.io

Remove all ads

OSX High Sierra で gdb を動かしてみた!

f:id:callmekohei00:20171124122811p:plain

Summary

OSX Hihg Sierragdbをうごかす

上記画像のようなエラー回避の方法

下準備

// xcodeが入ってるか確認
tmp$ xcode-select --install
xcode-select: error: command line tools are already installed, use "Software Update" to install updates

// gdbが入ってるか確認
$ gdb --version
GNU gdb (GDB) 8.0.1
Copyright (C) 2017 Free Software Foundation, Inc.

// gdbがなければインストール
$ brew install gdb

// .gdbinitに下記を記入
echo "set startup-with-shell off" >> ~/.gdbinit

gdbを動かす(スーパーユーザーとして)

スーパーユーザーとして動かす

$ sudo gdb ./a.out

この場合設定は不要

gdbを動かす(ユーザーとして)

Certificateを作成する

1. Open Keychain Access
2. In the menu, open **Keychain Access > Certificate Assistant > Create a certificate**
3. Give it a name (e.g. `gdb-cert`)
    + Identity type: Self Signed Root
    + Certificate type: Code Signing
    + Check: let me override defaults
4. Continue until it prompts you for: "specify a location for..."
5. Set Keychain location to Login  <---- ここ重要!

Keychainの左カラムのloginに今作ったgdb-certがあるのでSystemにドラックアンドドロップする!

ここでいろいろあるけどtrustみたいな感じでボタンを押す

Systemカラムの中に移動したgdb-certを右クリック > get info > trust で Always Trustにする


gdbcodesign

$ sudo codesign -s gdb-cert /usr/local/bin/gdb 

で、再起動

動かしてみる

f:id:callmekohei00:20171124124320p:plain

うごいた!

参考

qiita.com

Remove all ads

Windows10でVim8でF#のコードをかいてみる

f:id:callmekohei00:20171112150054p:plain

Summary

visual studio code だと楽はらくなのですが

もっとシンプルな vim8 で fsharp のコードを書く!

それもwindowsで!

環境

Microsoft Windows [Version 10.0.16299.19]

windowsvim

windowsvimを扱うのは意外と大変でした!

必要なもの

vim(64bit, kaoriya version)

mono

Python 3.5.4 - 2017-08-08: Windows x86-64 executable installer

Git

必要なこと

パスを通す

control panel > system properties > advance > environment variablesPATHに書き込みます

つまりこういうことです

コマンドプロンプトmonoと入力しても認識されませんが、パスを通すことでコマンドが通るようになります。

下記ができたらオーケー

C:\Users\callmekohei>mono --version
Mono JIT compiler version 5.4.1 (Visual Studio built mono)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           normal
        SIGSEGV:       normal
        Notification:  Thread + polling
        Architecture:  amd64
        Disabled:      none
        Misc:          softdebug
        LLVM:          supported, not enabled.
        GC:            sgen

C:\Users\callmekohei>vim --version
VIM - Vi IMproved 8.0 (2016 Sep 12, compiled May  2 2017 12:56:07)
MS-Windows 64-bit console version
Included patches: 1-596
Modified by koron.kaoriya@gmail.com
Compiled by koron.kaoriya@gmail.com

C:\Users\callmekohei>python
Python 3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> quit()

C:\Users\callmekohei>git --version
git version 2.15.0.windows.1

.vimrcをかく

$HOME.vimrcを書く

$HOMEの場所はコマンドプロンプトでチェック

C:\Users\callmekohei>echo %HOMEPATH%
\Users\callmekohei

こんな感じ

"----------------------------------------------------------
" Plugin manager ( Shougo/dein.vim )
"----------------------------------------------------------

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

filetype plugin indent on
syntax   enable


set guifont=Mig_2M:h12

set shellpipe=\|\ tee


"----------------------------------------------------------
" General
"----------------------------------------------------------
" Tab
set shiftwidth=4
set tabstop=4
set softtabstop=4
set expandtab

" Clipbord ( see : help clipboard )
set clipboard+=unnamed

" Mouse ( see :help mouse-using )
set mouse=nvic

set nowrap
set number
set noswapfile
set cmdheight=2

"----------------------------------------------------------
" Seek
"----------------------------------------------------------
set wrapscan
set ignorecase
set smartcase
nnoremap <silent> <C-l> :nohlsearch<CR>

"----------------------------------------------------------
" Appearance
"----------------------------------------------------------
"colorscheme Apprentice
colorscheme Wombat


" English menu display
source $VIMRUNTIME/delmenu.vim
set    langmenu=none
source $VIMRUNTIME/menu.vim

"if has("multi_lang")
"    language en_gb
"endif

"----------------------------------------------------------
" Char code
"----------------------------------------------------------
set encoding=utf-8
set fileencodings=utf-8,iso-2022-jp,euc-jp,sjis

"----------------------------------------------------------
" Vim8 
"----------------------------------------------------------
set backspace=indent,eol,start
set hlsearch

set laststatus=2
set wildmenu
set statusline=%f
set statusline+=%m
set statusline+=%r
set statusline+=%h
set statusline+=%w
set statusline+=%=
set statusline+=%l,%c\ \ \ \ \ \ \ \ \ \ \ \ %P

"---------------------------------------------------------
" Python config
" --------------------------------------------------------
"
let g:python_host_prog='C:\Users\callmekohei\AppData\Local\Programs\Python\Python27\python.exe'
let g:python3_host_prog='C:\Users\callmekohei\AppData\Local\Programs\Python\Python35-32\python.exe'

dein.tomlをかく

dein.tomlとはプラグイン管理用の文書

場所はC:\Users\callmekohei\.config\nvimに書いておく

こんな感じ

#----------------------------------------------------------
# Shougo ware
#----------------------------------------------------------

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

[[plugins]]
repo = 'Shougo/denite.nvim'

[[plugins]]
repo = 'Shougo/deoplete.nvim'
hook_add = '''
    let g:deoplete#enable_at_startup = 1
'''

[[plugins]]
repo = 'callmekohei/deoplete-fsharp'
hook_post_update = '''
  if dein#util#_is_windows()
    let cmd = 'install.cmd'
  else
    let cmd = 'bash install.bash'
  endif
  let g:dein#plugin.build = cmd
'''


[[plugins]]
repo = 'roxma/nvim-yarp'

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


#----------------------------------------------------------
# Color scheme
#----------------------------------------------------------

[[plugins]]
repo = 'romainl/Apprentice'

[[plugins]]
repo = 'vim-scripts/Wombat'

#----------------------------------------------------------
# QuickRun
#----------------------------------------------------------

[[plugins]]
repo = 'thinca/vim-quickrun'
hook_add = '''
    set splitright
    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
    \     }
    \
    \     , 'fsharp' : {
    \           'command'                         : 'fsharpi --readline-'
    \         , 'tempfile'                        : '%{tempname()}.fsx'
    \         , 'runner'                          : 'concurrent_process'
    \         , 'runner/concurrent_process/load'  : '#load "%S:gs?\\?/?";;'
    \         , 'runner/concurrent_process/prompt': '> '
    \     },
    \
    \}
'''

感想

マックと違って環境構築がすごく大変 (^_^;;

あとwindows's vimdeoplete2017/11/12現在は発展途中な感じです。今からに期待!ちなみにwindows's neovimだと完璧に動作します。

こんな感じ

Editor Windows Mac
neovim
vim8
Remove all ads