naoya_t@hatenablog

いわゆるチラシノウラであります

Atomパッケージ自作入門記

  int N, K; string s;

まで書いたら

  int N, K; string s; cin >> N >> K >> s;

とか、

  N,K,s

まで書いたら

#ifdef DEBUG
    cerr << "N=" << N << ", "
         << "K=" << K << ", "
         << "s=" << s << endl;
#endif

みたいな補完をしてくれるやつを作った。

GitHubに置いておくので
GitHub - naoyat/procon-support: A procon support package for Atom
作りたいツールの叩き台にどうぞ

Atom Packageを作成

この辺りを参考に

まず、Package generatorというのが Packages メニューにあるのでそれを使ってパッケージを作成する。
パッケージを作成したら、Package generatorが既に実装してくれている toggle コマンドを参考にしつつ追加したい機能の実装を lib/procon-support.js に書く。(.js とある通り中身は JavaScript である)

テキストの追加や編集には AtomのTextEditor API を利用する。

// lib/procon-support.js

  ...

  cin() {
    var ed = atom.workspace.getActiveTextEditor();
    var cursor = ed.getCursorBufferPosition();
    var line = ed.lineTextForBufferRow(cursor.row).trim();

    var var_list = [];
    var exprs = line.split(/; */);
    exprs.pop();
    for (var k in exprs) {
        var expr = exprs[k];
        var type = expr.split(' ', 1)[0];
        var vars = expr.substr(type.length + 1).split(/, */);
        Array.prototype.push.apply(var_list, vars);
    }

    ed.insertText(' cin');
    for (var k in var_list) {
        ed.insertText(' >> ' + var_list[k]);
    }
    ed.insertText(';\n');
  },

  cerr() {
    console.log('ProconSupport:cerr (only valid for debugging)!');
    var ed = atom.workspace.getActiveTextEditor()
    var cursor = ed.getCursorBufferPosition();
    var line = ed.lineTextForBufferRow(cursor.row).trimRight();

    var matched = line.match(/^(\s*)(.*)/);
    var indent = matched[1], vars_to_print = matched[2].split(/, */);

    ed.selectLinesContainingCursors();
    ed.delete();

    ed.insertText('#ifdef DEBUG\n');
    for (var k in vars_to_print) {
        var v = vars_to_print[k];

        if (k == 0) {
            ed.insertText(indent + 'cerr');
        } else {
            ed.insertText(indent + '    ');
        }

        ed.insertText(' << "' + v + '=" << ' + v);

        if (k < vars_to_print.length-1) {
            ed.insertText(' << ", "\n');
        } else {
            ed.insertText(' << endl;\n');
        }
    }
    ed.insertText('#endif\n');
    ed.moveUp(2);
    ed.moveRight(21);
  },

これらの関数を(同じファイルの)activate() でコマンドとして登録し

// lib/procon-support.js

  activate(state) {
    ...

    // Register command that toggles this view
    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'procon-support:toggle': () => this.toggle(),
      'procon-support:cin': () => this.cin(),
      'procon-support:cout': () => this.cout(),
      'procon-support:cerr': () => this.cerr(),
      'procon-support:fprintf': () => this.fprintf()
    }));
  },

あとは keymaps/procon-support.json

    "ctrl-cmd-9": "procon-support:cin",
    "ctrl-cmd--": "procon-support:cerr",

みたいなのを追加すればOK。
Atom起動時にアクティベートしてほしいので package.json の activationCommandsの項は削除。

あとはAtomを再起動するなり、コマンドパレットからWindow: Reloadするなりすれば反映される。

f:id:n4_t:20180811104343p:plain:w320