Vim script で明示的に補完ウィンドウを呼び出す

昨日、LingrVim 部屋で出てきてたのですが Vim script の組み込み関数に complete() というのがあります。

:help complete()
complete({startcol}, {matches})            *complete()* *E785*
        挿入モード補完の候補を設定する。
        挿入モードでのみ使用できる。CTRL-R = |i_CTRL-R|と組み合わせて
        マッピングを作る必要がある。CTRL-Oの後や、<expr>マッピングの中
        では正しく動作しない。
        {startcol}は補完すべき単語の開始位置を示す、行内のバイトオフセッ
        トである。その位置からカーソルまでのテキストが補完すべき単語と
        なる。
        {matches}はリスト|List|でなければならない。リストの各要素が1つ
        の候補となる。この要素として許される値については
        |complete-items|を参照。
        Note この関数を呼んだ後は補完を停止させるようなテキストの挿入
        をしないように注意しなければならない。
        この関数で設定した候補は普通の挿入モード補完と同じ様にCTRL-Nと
        CTRL-Pで選択できる。設定されていればポップアップメニューが表示
        される。|ins-completion-menu|を参照。
        例: >
    inoremap <F5> <C-R>=ListMonths()<CR>
    func! ListMonths()
      call complete(col('.'), ['January', 'February', 'March',
        \ 'April', 'May', 'June', 'July', 'August', 'September',
        \ 'October', 'November', 'December'])
      return ''
    endfunc
<        この例はそれほど役には立たないが、使い方を示している。Note 0が
        挿入されてしまわないように空文字列を返していることに注意。


これを利用すれば明示的に任意の候補の補完ウィンドウを呼び出す事ができます。
使い方は上のヘルプに載っている通り補完位置と補完候補のリストを渡して呼び出します。
コード補完とか 'omnifunc' に設定しないでこれで呼び出してしまった方が楽なのではないだろうか。

C++14 で名前付き引数

標準ライブラリでできる範囲で書いてみました。

[ソース]

#include <tuple>


template<typename T, typename Uniq>
struct holder{
    T value;
    operator T(){
        return value;
    }

    holder&
    operator =(T t){
        value = t;
        return *this;
    }
};


template<typename T, typename Uniq, typename ...Args>
T
get(holder<T, Uniq>, Args... args){
    return std::get<holder<T, Uniq>>(std::make_tuple(args...));
}


#include <iostream>
#include <string>

holder<int, struct age_> age;
holder<int, struct index_> id;
holder<std::string, struct name_> name;


template<typename ...Args>
void
func(Args... args){
    std::cout << "id = "    << ::get(id, args...)    << std::endl;
    std::cout << "age = "   << ::get(age, args...)   << std::endl;
    std::cout << "name = "  << ::get(name, args...)  << std::endl;
}


int
main(){
    func(age = 13, name = "homu", id = 0);
    func(id = 1, name = "mami", age = 14);
    return 0;
}

[出力]

id = 0
age = 13
name = homu
id = 1
age = 14
name = mami


思ったよりもスッキリと書くことができた。
C++14 依存といっても必要なのは std::get() の部分だけなのでそこを何とかすれば C++11 でも動作するはず。
デフォルト引数なんかに対応したい場合はもうちょっと工夫が必要かなー。

std::unique のデフォルトのデリータ

std::unique のデフォルトのデリータは何なのか調べてみたら次のように定義されているみたい。


template<
    class T,
    class Deleter = std::default_delete<T>
> class unique_ptr;

template <
    class T,
    class Deleter
> class unique_ptr<T[],Deleter>;


と、いうことでデフォルトでは std::default_delete が使用されているみたいです。
std::default_delete は delete を行うための関数オブジェクトで次のように利用できます。

[ソース]

#include <iostream>
#include <memory>

struct X{
    X(){
        std::cout << "new X" << std::endl;
    }
    ~X(){
        std::cout << "delete X" << std::endl;
    }
};

int
main(){
    std::cout << "start" << std::endl;
    auto xp = new X{};
    std::default_delete<X> deleter;
    deleter(xp);
    std::cout << "end" << std::endl;
    return 0;
}

[出力]

start
new X
delete X
end


std::default_delete なんて標準ライブラリにあったのか。

std::unique_ptr のデリータをあとから設定する

と、いうのが Lingr の C++ 部屋に貼られていたので覚書。

[ソース]

#include <memory>
#include <functional>
#include <iostream>

int
main(){
    auto p = std::unique_ptr<int, std::function<void(int*)>>{ new int{42}, std::default_delete<int>{} };

    // deleter を設定
    p.get_deleter() = [](int* p){
        std::cout << "call deleter" << std::endl;
        delete p;
    };

    std::cout << *p << std::endl;

    return 0;
}

[出力]

42
call deleter


get_deleter() は参照オブジェクトを返すのでこんな感じで代入する事ができます。
便利……なのかな?

std::unique_ptr のデリータをあとから設定する

と、いうのが Lingr の C++ 部屋に貼られていたので覚書。

[ソース]

#include <memory>
#include <functional>
#include <iostream>

int
main(){
    auto p = std::unique_ptr<int, std::function<void(int*)>>{ new int{42}, std::default_delete<int>{} };

    // deleter を設定
    p.get_deleter() = [](int* p){
        std::cout << "call deleter" << std::endl;
        delete p;
    };

    std::cout << *p << std::endl;

    return 0;
}

[出力]

42
call deleter


get_deleter() は参照オブジェクトを返すのでこんな感じで代入する事ができます。
便利……なのかな?

Boost 1.56.0 がリリース

Boost 1.56.0 がリリースされました。


結構久しぶりのリリース。
AlignType_Index の 2 つが新しいライブラリとして追加されました。

  • Align:
    • Memory alignment functions, allocators, and adaptors, from Glen Fernandes.
  • Type_Index:
    • Runtime/Compile time copyable type info, from Antony Polukhin.


その他、リリースノートはここら辺を参照してください。
最近 C++ に飢えているのでモチベーション上げたいなぁ…。

jedi.vim の自動補完で第一候補を選択肢ないようにする

某所で話題になって調べてみたんですが、以下の記事が参考になりました。


これで動作するようになります。
ただ、jedi.vim 側の設定の仕組みがなんかおかしいような気がするのでもうちょい調べてみる必要がありそう。