0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C++でVsCode用のスニペットを自動作成するツール作った

Posted at

作った動機

競技プログラミングでいつも使う典型をコピペするのも面倒なので、vscodeのスニペット機能を使って、"@(アルゴリズムの名前)"と打てば貼り付けられるようにしたい。
でも、長いコードになるとスニペットにするための書式を調整するのが人間のやることじゃない。。(めっちゃだるい。。)
だから、スニペット用の書式に直すプログラムを書きました。

動き

ライブラリ化したいコード

struct uftree{
    int cou;
    vector<int> parent;
    vector<int> rank;
    vector<int> _size;
    uftree(int n){
        parent=vector<int>(n);
        rank=vector<int>(n,0);
        _size=vector<int>(n,1);
        cou=n;
        rep(i,n){
            parent[i]=i;
        }
    }
    int root(int i){
        return parent[i]==i?i:parent[i]=root(parent[i]);
    } 
    bool same(int i,int j){
        return root(i)==root(j);
    }
    void merge(int i,int j){
        i=root(i);j=root(j);
        if(i==j)return;
        cou--;
        if(rank[i]>=rank[j]){
            parent[j]=i;
            _size[i]+=_size[j];
        }else{
            parent[i]=j;
            _size[j]+=_size[i];
        }
        if(rank[i]==rank[j])rank[i]++;
        return;
    }
    int count(){
        return cou;
    }
    int unitsize(int i){
        return _size[root(i)];
    }
};

スニペット化ツールでスニペットの書式に直したもの


	"uftree":{
		"scope": "cpp",
		"prefix": "@uftree",
		"body": [
			"struct uftree{",
			"\tint cou;",
			"\tvector<int> parent;",
			"\tvector<int> rank;",
			"\tvector<int> _size;",
			"\tuftree(int n){",
			"\t\tparent=vector<int>(n);",
			"\t\trank=vector<int>(n,0);",
			"\t\t_size=vector<int>(n,1);",
			"\t\tcou=n;",
			"\t\trep(i,n){",
			"\t\t\tparent[i]=i;",
			"\t\t}",
			"\t}",
			"\tint root(int i){",
			"\t\treturn parent[i]==i?i:parent[i]=root(parent[i]);",
			"\t} ",
			"\tbool same(int i,int j){",
			"\t\treturn root(i)==root(j);",
			"\t}",
			"\tvoid merge(int i,int j){",
			"\t\ti=root(i);j=root(j);",
			"\t\tif(i==j)return;",
			"\t\tcou--;",
			"\t\tif(rank[i]>=rank[j]){",
			"\t\t\tparent[j]=i;",
			"\t\t\t_size[i]+=_size[j];",
			"\t\t}else{",
			"\t\t\tparent[i]=j;",
			"\t\t\t_size[j]+=_size[i];",
			"\t\t}",
			"\t\tif(rank[i]==rank[j])rank[i]++;",
			"\t\treturn;",
			"\t}",
			"\tint count(){",
			"\t\treturn cou;",
			"\t}",
			"\tint unitsize(int i){",
			"\t\treturn _size[root(i)];",
			"\t}",
			"};",
		],
	},

ソースコード

c++で書いているし、サンプルもc++のコードをスニペット化したけど、どんな言語でもスニペットの書式に直せると思う。
ぜひ使ってみてね。
改善した方法とかがあれば、いろいろ教えてください。
インデントの幅はコード内のインデント変数を変えて調整してね。

//2020724 スニペット自動作成
# include<iostream>
# include<string>
# include<fstream>

using namespace std;

# define rep(i, n) for (int i = 0; i < (int)(n); i++)

int intend=4;
string ifname,ofname;
string body,name,prefix,scope;

int makeSnipett(ifstream &in,ofstream &out){
    out << "\t\""+name+"\":{" << endl; 
    out << "\t\t\"scope\": \""+ scope + "\"," << endl;
    out << "\t\t\"prefix\": \""+ prefix + "\"," << endl;
    out << "\t\t\"body\": [" << endl;
    while(getline(in,body)){
        bool fixed=false;
        int cou=0;
        //空白文字の\tへの置き換え
        for(cou;body[cou]==' ';cou++);
        string a="";
        rep(i,(cou+intend-1)/intend)a+="\\t";
        body.replace(0,cou,a);
        cou=a.size();
        //その他の文字の置き換え
        while(body[cou]!='\0'){
            if(fixed){
                fixed=false;
                cou++;
                continue;
            }
            char s=body[cou];
            if(s=='\"'){
                body.insert(cou,"\\");
                fixed=true;
            }else if(s=='\\'){
                body.insert(cou,"\\");
                fixed=true;
            }
            cou++;
        }
        body="\t\t\t\""+body+"\",";
        //書き込み
        out<<body<<endl;
    }
    out << "\t\t]," <<endl;
    out << "\t}," <<endl;

    return 0;
}

void Main(){
    cout << "# where is code for snipett??" <<endl;
    cin >> ifname;
    ofname=ifname+"_snipett";

    ifstream ifs(ifname);
    ofstream ofs(ofname);
    if(!ifs){
        cerr<<"I failed to opne INPUT file"<<endl;
        return;
    }else if(!ofs){
        cerr<<"I failed to opne OUTPUT file"<<endl;
        return;
    }else{
        cout<<"success to open both files"<<endl;
    }
    //処理
    string ans;
    do{
        cout << "# What is snipett name ?" <<endl;
        cin >> name;
        cout << "# What language is used in this ? Exmple:cpp,python,javascript,etc.." <<endl;
        cin >> scope;
        cout << "# What is prefix ? " <<endl;
        cin >> prefix;
        cout << "==============" <<endl;
        cout << "  name:"+name+"\n  scope:"+scope+"\n  prefix:"+prefix <<endl;
        cout << "==============" <<endl;
        cout << "# Is this OK ?? (Y/n)\n";
        cin>>ans;
    }while(ans[0]=='n'||ans[0]=='N');

    cout << "making snipett ..." <<endl;
    
    if(makeSnipett(ifs,ofs)==0)cout << "success!!" <<endl;
}

int main(int ARGV,char* ARGC[]){
    Main();
}

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?