diff --git a/main.js b/main.js
index 87ad530c3140651ac7151befa35c6bc3452a13f1..94c44c48056acbda016942b9413bdaa62dbc508b 100644
--- a/main.js
+++ b/main.js
@@ -1,6 +1,7 @@
 var audioButton = false;
 var midiButton = false;
 var activateButton;
+var dataMidi;
 var editor;
 
 /**
@@ -10,42 +11,47 @@ function loadEditor() {
 	editor = ace.edit("editor");
 	editor.setTheme("ace/theme/tomorrow_night");
 	editor.session.setMode("ace/mode/css");
+	const langTools = ace.require('ace/ext/language_tools');
+	
+	const cssTemplate = {
+		getCompletions: (editor, session, pos, prefix, callback) => {
+			// note, won't fire if caret is at a word that does not have these letters
+			callback(null, [
+				{ value: '[loud,0,1]', score: 1, meta: 'Audio meter between 0 and 1.' },
+				{ value: '[low,0,1]', score: 1, meta: 'Audio energy low between 0 and 1.' },
+				{ value: '[lomi,0,1]', score: 1, meta: 'Audio energy low-mid between 0 and 1.' },
+				{ value: '[mid,0,1]', score: 1, meta: 'Audio energy mid between 0 and 1.' },
+				{ value: '[mihi,0,1]', score: 1, meta: 'Audio energy mid-high between 0 and 1.' },
+				{ value: '[hi,0,1]', score: 1, meta: 'Audio energy treble between 0 and 1.' },
+				{ value: '[onset:C]', score: 1, meta: 'Audio note C' },
+				{ value: '[onset:C#]', score: 1, meta: 'Audio note C#' },
+				{ value: '[onset:D]', score: 1, meta: 'Audio note D' },
+				{ value: '[onset:D#]', score: 1, meta: 'Audio note D#' },
+				{ value: '[onset:E]', score: 1, meta: 'Audio note E' },
+				{ value: '[onset:F]', score: 1, meta: 'Audio note F' },
+				{ value: '[onset:F#]', score: 1, meta: 'Audio note F#' },
+				{ value: '[onset:G]', score: 1, meta: 'Audio note G' },
+				{ value: '[onset:G#]', score: 1, meta: 'Audio note G#' },
+				{ value: '[onset:A]', score: 1, meta: 'Audio note A' },
+				{ value: '[onset:A#]', score: 1, meta: 'Audio note A#' },
+				{ value: '[onset:B]', score: 1, meta: 'Audio note B' },
+				{ value: '[note:24,0,1]', score: 1, meta: 'MIDI Note C between 0 and 1.' },
+				{ value: '[note:26,0,1]', score: 1, meta: 'MIDI Note D between 0 and 1.' },
+				{ value: '[note:28,0,1]', score: 1, meta: 'MIDI Note E between 0 and 1.' },
+				{ value: '[note:29,0,1]', score: 1, meta: 'MIDI Note F between 0 and 1.' },
+				{ value: '[note:31,0,1]', score: 1, meta: 'MIDI Note G between 0 and 1.' },
+				{ value: '[note:33,0,1]', score: 1, meta: 'MIDI Note A between 0 and 1.' },
+				{ value: '[note:35,0,1]', score: 1, meta: 'MIDI Note B between 0 and 1.' },
+			]);
+		},
+	};
+	langTools.addCompleter(cssTemplate);
 	editor.setOptions({
-		enableBasicAutocompletion: [{
-			getCompletions: (editor, session, pos, prefix, callback) => {
-				// note, won't fire if caret is at a word that does not have these letters
-				callback(null, [
-					{ value: '[loud,0,1]', score: 1, meta: 'Audio meter between 0 and 1.' },
-					{ value: '[low,0,1]', score: 1, meta: 'Audio energy low between 0 and 1.' },
-					{ value: '[lomi,0,1]', score: 1, meta: 'Audio energy low-mid between 0 and 1.' },
-					{ value: '[mid,0,1]', score: 1, meta: 'Audio energy mid between 0 and 1.' },
-					{ value: '[mihi,0,1]', score: 1, meta: 'Audio energy mid-high between 0 and 1.' },
-					{ value: '[hi,0,1]', score: 1, meta: 'Audio energy treble between 0 and 1.' },
-					{ value: '[onset:C]', score: 1, meta: 'Audio note C' },
-					{ value: '[onset:C#]', score: 1, meta: 'Audio note C#' },
-					{ value: '[onset:D]', score: 1, meta: 'Audio note D' },
-					{ value: '[onset:D#]', score: 1, meta: 'Audio note D#' },
-					{ value: '[onset:E]', score: 1, meta: 'Audio note E' },
-					{ value: '[onset:F]', score: 1, meta: 'Audio note F' },
-					{ value: '[onset:F#]', score: 1, meta: 'Audio note F#' },
-					{ value: '[onset:G]', score: 1, meta: 'Audio note G' },
-					{ value: '[onset:G#]', score: 1, meta: 'Audio note G#' },
-					{ value: '[onset:A]', score: 1, meta: 'Audio note A' },
-					{ value: '[onset:A#]', score: 1, meta: 'Audio note A#' },
-					{ value: '[onset:B]', score: 1, meta: 'Audio note B' },
-					{ value: '[note:24,0,1]', score: 1, meta: 'MIDI Note C between 0 and 1.' },
-					{ value: '[note:26,0,1]', score: 1, meta: 'MIDI Note D between 0 and 1.' },
-					{ value: '[note:28,0,1]', score: 1, meta: 'MIDI Note E between 0 and 1.' },
-					{ value: '[note:29,0,1]', score: 1, meta: 'MIDI Note F between 0 and 1.' },
-					{ value: '[note:31,0,1]', score: 1, meta: 'MIDI Note G between 0 and 1.' },
-					{ value: '[note:33,0,1]', score: 1, meta: 'MIDI Note A between 0 and 1.' },
-					{ value: '[note:35,0,1]', score: 1, meta: 'MIDI Note B between 0 and 1.' },
-				]);
-			},
-		}],
+		enableBasicAutocompletion: true,
 		enableSnippets: true,
 		enableLiveAutocompletion: true
 	});
+
 	chrome.storage.sync.get(['css'], function (result) {
 		editor.setValue(result.css)
 	});
@@ -121,7 +127,17 @@ function onMessage({ type, data }) {
 			break;
 		}
 		case 'midiEvent': {
-			$('#midiEvent').text(data);
+			if (dataMidi != data) {
+				$('#midiEvent').text(data);
+				if (editor.isFocused()) {
+					editor.session.insert(editor.getCursorPosition(), data)
+				}
+				dataMidi = data;
+			}
+			break;
+		}
+		case 'midiDevices': {
+			$('#midiDevices').text(data);
 			break;
 		}
 	}