none
コードスニペットを無効、またはキーアサインを変える方法を探しています。 RRS feed

  • 質問

  • Visual Studio 2012 proを使い始めたのですが、コードスニペットが邪魔くさくて、
    効率が悪くて困ってます。自動的に挿入されたコードを、
    すべて削除しなければならないので、一時間ほど使っただけで我慢できなくなりました。
    ほとんどC++ネイティブしか使いませんのでそれで説明させてもらうと、

    困っているケース
     スニペットに一致したキーワード直後にTabキーを押下すると
     Tabが挿入されずに(無視されて)スニペットコードが挿入されてしまいます。

    例(1).class宣言が邪魔される
     "class"と入力してTabキーを押下すると、MyClassの定義が挿入されます。
     "class"+"[TAB]"+"(クラス名称)";等の宣言を書くのを「妨害」されます。

      class[Tab]Foo; // 宣言のみ

     の様な簡単なコードが書きたいのですが、激しく妨害されるわけですね(笑)。

    例(2).関数の一行書きが邪魔される

     void Foo(){[Tab]で不要なスコープ{}が改行付きで挿入されます。

     BOOL Foo(){[Tab]return flg;}

      が簡単には書けません(vv;)。

    それで、よりエレガントで使いでのあるコードスニペットを記述するのは、
    とりあえず置いといて・・・、

    A.Tabキーではなく別のキーの組み合わせでスニペットが実行されるように
      できないでしょうか。
    B.スニペットの一部又は全部を無効にしたいのですが、どうしたらよいでしょう。

    A.B.の手段を2時間ほど探したのですが、Bについて、スニペットXMLファイルがあるところは
    みつかったのですが、これらを削除しても有効なままで、両社共解決にいたっていません。

    特にA.について、方法をご存知の方、ご教示頂きたいのです。
    もちろん、B.のもっと「穏やかで当たり前な」方法も教えてください。
    よろしくお願いします。

    2013年2月27日 16:49

すべての返信

  • あった。

    スニペットは InteliSence の機能の一つになります。

    オプション設定の テキストエディター - C/C++ - 詳細 で、InteliSence の細かな設定ができます。

    class など何もないところで書き始めた時の補完機能は「アグレッシブ メンバー一覧を無効にする」になります。

    これをTrueにしてやれば、class と入力しても何も出てきません。そのほかにもいろいろリミットさせることができますよ。


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/

    2013年2月27日 17:29
  • とっちゃんさん、回答ありがとうございます。
    その部分を全て試してみました。一部はご指摘の前に試していたのです。
    ところが、
     
    「アグレッシブメンバーを無効にする」
    「メンバー一覧のキーワードを無効にする」
    「メンバー一覧のコードスニペットを無効にする」
     
    を全て「True」に設定しましたが、効果が無いようです。
     
    相変わらずclass[Tab]と入力するとMyClassが挿入されてしまいます。
    void FOO(){[Tab]も同じ状態ですね。

    仕方がないので、「ツール」の「コードスニペットマネージャー」を表示させ、
    その一覧からC++対象のスニペットを全て削除しました。
    個々には有効無効が設定できないので、フォルダー毎削除しなければなりませんでした。
    プリプロセスは名残惜しいのですが(笑)、
    これをコピーしてうまく使えって事なんでしょうかねぇ
    (DOS時代のアプリのようで苦笑しちゃいました)。
    もっと柔軟な手段を用意してほしいと思います。

    ところで、 VC上のC++や他の言語を使っている方たちはこんな程度の機能で
    満足なのでしょうか、迷惑がっているふしもなさそうなので、やや不思議です。

    え~と、こちらの環境要因かもしれないので、
    ご提示の方法で無効化に成功したとの、他の方のご報告があれば、
    そののち「回答としてマーク」をさせていただきます。
    ありがとうございました。

    2013年2月27日 19:07
  • ところで、 VC上のC++や他の言語を使っている方たちはこんな程度の機能で
    満足なのでしょうか、迷惑がっているふしもなさそうなので、やや不思議です。
    行頭以外の場所でtabを入力する癖がないので、実害はあまりありませんねぇ…。もちろんスニペットの出番もあまりありませんが…。
    2013年2月27日 22:51
  • あ。。。だめですね。ちょっと調査が足りなかったようです。

    オリジナルを参照しないということができるので、都合の悪いものがある(若しくは、ちょっと書き換えたい)場合は、別の場所にコピーして、編集&参照が王道なのかもしれません。

    でも、あの class な補完はいらないw


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/

    2013年2月28日 1:21
  • 佐祐理さん、ご意見ありがとうございます。
    そうですか。行頭以外でのTabの使用率が低いわけですね。
    自分の場合、スペーサ(間を入れる程度の意味)として、
    あらゆるところにTabを使ってますので、
    はっきり言って「実害だらけ」の状態です。
    実際のところ「Tabキーだけはやめてほしかった」という感じです(泣)。

    ところで、

    A.Tabキーではなく別のキーの組み合わせでスニペットが実行されるように
      できないでしょうか。

    も、鋭意探索中なのですが、見つかりません。
    心当たりがあったらよろしくお願いします。

    2013年2月28日 1:25
  • >あ。。。だめですね。ちょっと調査が足りなかったようです。

    そうですか、それは残念です。

    「こうなったら、Tabキーが押下されたらTabコードをソースに入れる
    ってなスニペットを書けばいいんじゃないか・・・。」
    というおばかな妄想まで浮かんできました。


    2013年2月28日 2:16
  • こんにちは、仲澤さんが質問サイドというのはレアな気がするうえに、この内容は興味があるし検証にも時間があまりかからなそうなので、参加させていただきます。

    どちらもExpressでも再現しました。今まで気づかなかったので驚きました。
    既に無意識で反射的にやってるようなレベルのことだったので、自分自身普段どうやってるんだっけと調べてみると

    Aについては

    class[半角スペース]Foo; // 宣言のみ

    でやってました。私の場合、現状共通ライブラリは namespace Cmn { の配下、アプリ専用クラスとかは namespace App { の配下になるので、インデントに関しては、宣言のみの時は最低タブ一個分のスペースが基本左にはありがちですが、それはEnterキーで発生するものですね。

    Bについては

    1.単純なアクセサはできれば少なめにする(なるべくなら「処理内容」で関数を作る。といっても、仲澤さんぐらいであれば既にやっているとおもますが)

    2.「単純な」アクセサであれば、出来るだけclass クラス名{}; の内側(ヘッダの可能性が高め)に書きたい

    3.他のキーと比べて、Shiftキーがちょっと押しにくので、押す回数(や時間)を減らしたい

    という方針でやっています。なので、一つ目のゲッターの場合は
    bool Foo() const {}
    ここまで書いといてから、十字キー左で{}の内側に入って[半角スペース]return flg;[半角スペース]としていました。
    2度目以降のゲッターは、1行下とかに1つめのゲッターをコピペしてから戻り値・関数名・メンバ名を、これまたコピペで変更することが多いようです。

    ( 型 Getなんちゃら() const { return 変数名; }という形式が多く、このうち 型 変数名; はすでに近い位置にあるのと、「なんちゃら」の部分は変数名の一番最初だけ大文字にするというパターンが多いため、たぶん半分以上節約できている )


    これらの理由から、私はA,BのタイミングでのTabキーでの不都合に気づかなかったようです。Bについては、1行関数でなければむしろ得ですね。

    ただ、出来るだけTabキーを使いたい・・・というスタイルであれば、Proの場合拡張機能を作ってしまうという手で何とかできないのでしょうかね?(普段からやってる人じゃないと、目的の動作をさせる機能の作り方を調べるのは面倒そうですが)

    • 編集済み mr.setup 2013年2月28日 3:22
    2013年2月28日 3:09
  • 貴重なお時間で追試をしていただき、ありがとうございます。

    コードスニペットを有効にしたまま、スニペットコードの挿入を阻止するには

    void FOO(){[Space][Tab]

    等とすればかわすことはできるのですが、
    老人ゆえ旧来の習慣をなかなか変えられません(vv;)。
    とりあえずマネージャーからスニペットを削除することで、
    一息ついてます。

    問題は、このような重大な動作をするキーの割付が変更できないという点で、
    これが最も引っかかる点です。
    コードスニペットは、まぁまぁのできですが、工夫すれば色々とできそうなので、
    大変残念な気持ちです。
    スニペットコードの挿入は、他のキー操作、CTRL+K S 等でもできるため、
    Tabでの挿入のみを阻止したいわけなのです。

    まぁVS2012のエディターについては、他にもいくつかの懸案があるのですが、
    とりあえずこれを解決したいですね。

    2013年2月28日 5:32
  • おお、それなりにお年を召されていたのですかw あまり考えていませんでした。ちなみにですが、私は6年以上にわたる下積みをやっともうすぐ抜けれそうな状態、26歳です。下積み時代の人間には万単位の出費が重なるのは少々きついですが、たぶんもうちょいでなんとか・・・w

    Expressでなんとかやりくりしていましたが、以前から2012 でもPro以上で調べたい、ということが他にも何点かあったので、この際ということで、念のため状況を揃えるということで、先ほどPro評価版をインストールさせていただきました。

    Bに関してですが、要するにこれは、スニペットの挿入におけるスコープに対する反応に等しいんですよね。(↓以前作ったニュートン法とかのテストプロジェクトで動作確認)

    ①tabキー

    ②スニペットのスコープ( "Ctrl + K → Ctrl + X" または 右クリックから)

    なので、絡んでそうなとこを調べると、こちらでは

    C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\Snippets\1041\Visual C++

    の中に"{.snippet"を含むsnippetファイルが色々あったので、こいつ("{.snippet")だけを別のフォルダに適当に移動させてやったらこの機能だけ効かなくなりました。(ただ、保証のある行動かどうかは全く不明なので、もしやる場合は自己責任でお願いします。)

    ※②で若干右に写ってるのはプロ生ちゃん(Pronama-chan IDE 2012)です。2010のItaBackGroundみたいに自分で画像変えられると「痛くない 痛IDE」ができるんですがw  2012では画像変えれる拡張機能今のところ見つけていませんが、知ってる方いらっしゃいましたら教えていただけると嬉しいです。(プロ生ちゃんもかわいいので和むといえば和みますが。・・・ていうか画像動かすことも出来るんですね。)

    • 回答の候補に設定 gekkaMVP 2013年3月1日 4:27
    2013年2月28日 9:47
  • ところで、 VC上のC++や他の言語を使っている方たちはこんな程度の機能で
    満足なのでしょうか、迷惑がっているふしもなさそうなので、やや不思議です。

    本筋ではないところですみません。

    C++ は 2012 から搭載したようですが、C# は 2005 の時点には存在していたので、.NET Framework が広がり始めたと(私は思っている) 2.0 から始めた人には、Tab はインデントではなく、IntelliSense の候補確定と理解・受容しているのではないかと思います。
    参考:http://msdn.microsoft.com/ja-jp/library/dd229397.aspx
    (仕事ではまだ 2012 使える段階にないので、C++ に snippet がついたこと自体も知らないというような、私のような人々も世の中にはいると思います…)

    ところで、「Tab キー以外に割り当てる」という要望は Connect にリクエストしてみてはいかがでしょうか。
    Visual Studio 2012 は Update 1, 2 というように、頻繁なアップデートに取り組んでいるようなので、賛成意見が多ければそのうち載ってくるかもしれません。

    -----

    海外のフォーラムを見ていたら、 { } の補完をやめたいという意見があって、そこは snippet を消せというアドバイスになってましたね。Connnect も似ているかな。

    2013年2月28日 13:59
    モデレータ
  • >の中に"{.snippet"を含むsnippetファイルが色々あったので、こいつ("{.snippet")だけを別のフォルダに適当に移動させてやったらこの機能だけ効かなくなりました。(ただ、保証のある行動かどうかは全く不明なので、もしやる場合は自己責任でお願いします。)

    これは過去の自分の発言でもちょろと触れている通り、やってみました。
    こちらの環境では、この中身はシステム的にキャッシュされている様で、
    ファイルの削除や、XMLの中身の編集だけでは機能を変更することはできませんでした。
    スニペットマネージャでの操作が唯一の効果的な手段のようです。
    また、逆にスニペットマネージャで削除を行っても、スニペットファイル自体は
    無くなりません。遊ばれているようで悔しいです(vv;)。

    2013年3月1日 1:30
  • >Framework が広がり始めたと(私は思っている) 2.0 から始めた人には、Tab はインデントではなく、IntelliSense の候補確定と理解・受容しているのではないかと思います。

    やはりそうですか、すでに定着してしまった共通認識は覆すのが困難ですね。

    参照動作としてのインテリセンスは一呼吸おいた操作であり、重宝しているのですが、
    Tab押下時にいきなりコードが挿入される動作には、強い違和感を覚えます。

    EclipseでJavaをコードしているときも似たような補助がしてもらえるのですが、
    もう少し穏やかであたりさわりのないものです。
    それゆえ、classに対する蛮勇ともいえるコードには笑ってしまいました。

    >(仕事ではまだ 2012 使える段階にないので、C++ に snippet がついたこと自体も知らないというような、私のような人々も世の中にはいると思います…)

    自分も仕事上はVS2003とVS2008を使っています。VS2012は個人用です。
    経験から言うと「VC++6.0->VS2003」「VS2003->VS2008」のポーティングには
    結構手間がかかりました。
    いずれ、仕事上でもVS2012を使うことなると思いますが、
    まぁそのための人柱的調査も含めて購入しました。

    >ところで、「Tab キー以外に割り当てる」という要望は Connect にリクエストしてみてはいかがでしょうか。

    検討してみます。

    2013年3月1日 1:46
  • なるほど、そういうことでしたか。それは、削除や置き換えや名前変更などのあと、「一旦IDEを再起動してみて」やはりダメだった、という意味ですか?(こちらでも、再起動しないとそのままなので、一応)

    もしそうだとすると、Azuleanさんの情報と併せて、少なくとも現状すぐには"{直後"や"class直後"だけ無効化はやっぱり拡張機能で何かやれるかどうか、ぐらいになるかもしれません。後はリクエストしつつ公式対応待ち、という感じ・・・ということでしょうかね。

    (上の自分の「画像差し替え~」という内容に対する答えが見つかりました。ClaudiaIDEは説明のとこにある通り差し替えれるようです!WebMatrixManIDEならたくさんある画像を差し替えれて10秒おきに表示可で、しかもソースも提供されてるという充実っぷり。k.buchiさんgood job!てかWebMatrixManIDEデフォで意外と面白いです。デモ時の出オチは確かにありな気がw)

    • 編集済み mr.setup 2013年3月1日 1:56
    2013年3月1日 1:48
  • >なるほど、そういうことでしたか。それは、削除や置き換えや名前変更などのあと、「一旦IDEを再起動してみて」やはりダメだった、という意味ですか?(こちらでも、再起動しないとそのままなので、一応)

    再起動した結果です。
    Windows7なので、というか、最近ではこの手の外部設定で
    「なんかがぶっ壊れててもOK」的ギミックを使う場合がありえるので、
    プログラマとしては安心できません。

    2013年3月1日 2:11
  • 機能が邪魔なら乗っ取ればいいよね。というわけで、アドインで書いてみた。
    #VS2010までならキーボードのカスタマイズで、テキストエディターのTABキーの割り当てをマクロの呼び出しにして、そのマクロでTAB文字にしてしまうだけで済むんですが。

    エディタでTABキーを押すとはEdit.InsertTabというコマンドが実行されるので、そのコマンドが実行される前にTABを挿入して、デフォルト動作は無効にしてます。
    classの後だとかの限定された条件でのみ無効にしたい場合は、TextSelectionで前後の文字列を解析してやればできると思う。

    using System;
    using Extensibility;
    using EnvDTE;
    using EnvDTE80;
    namespace DisableTABSnippet
    {
        public class Connect : IDTExtensibility2
        {
            public Connect() { }
            public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
            {
                _applicationObject = (DTE2)application;
                _addInInstance = (AddIn)addInInst;
                ev = _applicationObject.Events.CommandEvents;
                ev.BeforeExecute += CommandEvents_BeforeExecute;
            }
            public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
            {
                ev.BeforeExecute -= CommandEvents_BeforeExecute;
                ev = null;
            }
            public void OnAddInsUpdate(ref Array custom) { }
            public void OnStartupComplete(ref Array custom) { }
            public void OnBeginShutdown(ref Array custom) { }
            private DTE2 _applicationObject;
            private AddIn _addInInstance;
            private EnvDTE.CommandEvents ev;
            void CommandEvents_BeforeExecute(string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault)
            {
                EnvDTE.Command cmdInsertTab = _applicationObject.Commands.Item("Edit.InsertTab");
                if (ID == cmdInsertTab.ID)
                {
                    try
                    {
                        EnvDTE.Window wnd = _applicationObject.ActiveWindow;
                        if (wnd != null)
                        {
                            EnvDTE.TextSelection sel = wnd.Selection as TextSelection;
                            if (sel != null)
                            {
                                if (sel.TopPoint.AbsoluteCharOffset == sel.BottomPoint.AbsoluteCharOffset)
                                {
                                    sel.Text = "\t";
                                    CancelDefault = true;
                                }
                            }
                        }
                    }
                    catch
                    {
                    }
                }
            }
        }
    }
    #マクロとかアドイン使ってる人少ないのかなぁ…

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答の候補に設定 mr.setup 2013年3月1日 5:39
    2013年3月1日 3:50
  • gekkaさん、コードまで書いていただき感謝にたえません。
    今週末、サンデープログラマに戻ってからテストしてみます。

    >#マクロとかアドイン使ってる人少ないのかなぁ…

    自分は使ったことはあまりありません。
    「テンポラリマクロ」を使うのが関の山といった感じです。

    アドインでコード生成等ができることは知ってはいたのですが、
    怠けて良く勉強してません。
    現在は、派生元やMFCの有無などの属性を指定してコードを自動生成する、
    自作のコードジェネレータをを使ってます。
    これがあるので、実際のところ、classをいちから手書きすることなどあまりないのですが、
    デバッグ用であったり、緊急なテスト用等のクラスは手書きします。
    今回は、この時にはまったわけです。
    VS2012の使用準備には、こいつもUNICODE対応しなければならないかもしれません(vv;)。

    2013年3月1日 5:09
  • お、少なくともこちらではgekkaさんのアドインで単純なTAB挿入になりました。

    この手は怪しいことがないという点で良さそうですね。
    個人的にはタブキーはそんなに頻繁には使っていないので、デフォルトでどういう機能が発生し得るかはあまり把握してないですが、とりあえずShift+Tabは普通にできるし複数行選択に対するTabやShift+Tabもそのまま使えるので、個人的にはこのままでも全然OKな使用感です。

    (アドイン生成用プロジェクトを作ったのは初なので方法 : アドインを作成する(日本語ページは2008までみたいですが、そう変わりはないかなと) とか特集:初めてのVisual Studioアドイン(前編)とかを参照して作って検証しました。)

    2013年3月1日 5:50