LoginSignup
7
3

More than 1 year has passed since last update.

Ace.jsにスニペットを追加する

Last updated at Posted at 2019-05-21

##実行環境
・Electron
・Ace.js

#####2019/05/26 完全に書き換えました。
前回書いていたものはそれっぽく作ったもので、今回はちゃんと動くようになっています。

2022/9/10 下の方に改正版作った。もう少し使いやすく出来ないかなと思って

Ace.jsはHTML上で動作するエディターを追加するものです
ちょっと独特な感じだけど

前回の記事のコードをもとに構築してます

スニペット(Snippet)は

fun

と入力すると

function name() {
  // function
}

みたいになんか簡単に生成してくれるやつです(語彙力皆無)
その解説が何一つなかったので実際にそれらしく作ってみました
探しまくってありました

ace.config.loadModule('ace/ext/language_tools', function() {
	editor.setOptions({
		enableBasicAutocompletion: true,
		enableSnippets: true,
		enableLiveAutocompletion: true
	});
	const snippetManager = ace.require("ace/snippets").snippetManager;
	const config = ace.require("ace/config");
	ace.config.loadModule("ace/snippets/javascript", function(m) {
		if (m) {
			snippetManager.files.javascript = m;
			m.snippets = snippetManager.parseSnippetFile(m.snippetText);
			m.snippets.push(
				{
					"content": "const ${1:variable} = new Animation.base(x, y, z);",
					"name": "Animation",
					"tabTrigger": "Animation"
				}
			);
			snippetManager.register(m.snippets, m.scope);
		}
	});
});

##解説

m.snippets.push(
	{
		"content": "const ${1:variable} = new Animation.base(x, y, z);",
		"name": "Animation",
		"tabTrigger": "Animation"
	}
);

${番号:名前}
これは変数名や引数等に付ける物で、
ユーザー側がTABを押したときに自動的に${番号:名前}の場所へ移動します。
説明難しいけどとにかく使ったらわかる(適当)

スクリーンショット (324).png
スクリーンショット (325).png

##新しく作ったから改正版

/* acejsに機能を追加する */

// メモリ空間の作成(何度も読み込まなくていいように)
ace.memory = {
  data: {},
  set(name, data)
  {
    // なかったら保存
    if(name in this.data) return null;
    this.data[name] = data;
  },
  get(name)
  {
    // あれば返却
    if(!name in this.data) return null;
    return this.data[name];
  }
};
/**
 * @module モジュールの読み込み
 * @param {string} name - モジュール名
 * @param {any} option - 省略可
 * @param {function} callback - コールバック関数
 */
ace.on = function(name, option, callback = null)
{
  // 省略した書き方に対応する
  if(!callback) callback = option;
  // 長いから省略
  const md = ace.config.loadModule;
  switch (name)
  {
    case "load":
      // aceに機能追加する為のモジュールを読み込む
      md("ace/ext/language_tools", callback);
    break;
    case "snippets":
      // スニペットを追加する為のモジュールを読み込む
      md(`ace/snippets/${option}`, callback);
    break;
  }
}

/**
 * @module スニペットを追加
 * @param {any} snippets - スニペット
 * @param {string} language - 言語を指定 省略可(ace.languageから取得)
 */
ace.customSnippets = function(snippets, language = null)
{
  // スニペットを追加出来るように設定
  editor.setOptions({
    enableBasicAutocompletion: true,
    enableSnippets: true,
    enableLiveAutocompletion: true
  });
  // メモリ空間に保存
  ace.memory.set("snippets", ace.require("ace/snippets").snippetManager);
  ace.memory.set("config", ace.require("ace/config"));
  // メモリ空間から取得
  const snippetManager = ace.memory.get("snippets");
  const config = ace.memory.get("ace/config");
  // スニペットモジュールの読み込み
  // languageを指定されたらそれを優先する
  ace.on("snippets", language ? language: ace.language, function(m)
  {
    if(!m) return;
    snippetManager.files.javascript = m;
    // 既存のスニペットファイルの読み込み
    m.snippets = snippetManager.parseSnippetFile(m.snippetText);
    // ここでスニペットに追加してる
    if(!Array.isArray(snippets)) m.snippets.push(snippets)
    else m.snippets.push(...snippets);
    snippetManager.register(m.snippets, m.scope);
  });
}


/* メイン処理 */

// 対応する言語をデフォルトに設定
ace.language = "javascript";

// editorの作成
const editor = ace.edit("editor", {
  theme: "ace/theme/monokai", // テーマ
  mode: `ace/mode/${ace.language}`, // 言語
  minLines: 5, // 初期行数
});

// モジュールのロード後
ace.on("load", function()
{
  // 一つだけスニペットを追加する
  // 言語はデフォルトのace.languageから参照
  ace.customSnippets({
    "content": "const ${1:variable} = new Animation.base(x, y, z);",
    "name": "Animation",
    "tabTrigger": "Animation"
  });
  // 配列で複数のスニペットを追加する
  ace.customSnippets([
    {
      "content": "const ${1:variable} = new Animation.base(x, y, z);",
      "name": "Aaaa",
      "tabTrigger": "Aaaa"
    },
    {
      "content": "const ${1:variable} = new Animation.base(x, y, z);",
      "name": "Bbbb",
      "tabTrigger": "Bbbb"
    }
  ]);
  // スニペットを登録する言語を指定する
  ace.customSnippets({
    "content": "<!html><head></head><body></body>",
    "name": "html",
    "tabTrigger": "html"
  }, "html");
});
7
3
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
7
3