Skip to content

Commit

Permalink
Feature - Extension Host: Document enter event (#212)
Browse files Browse the repository at this point in the history
* Add typing for document deltas

* Formatting

* Uncomment other tests

* Send document enter event

* Formatting

* Switch to use option type for getBufferMetadata

* Rename to getBufferMetadataOpt

* Formatting

* Finish renaming method
  • Loading branch information
bryphe committed Apr 3, 2019
1 parent 7299561 commit d81f3ac
Show file tree
Hide file tree
Showing 6 changed files with 239 additions and 7 deletions.
14 changes: 11 additions & 3 deletions src/development_extensions/oni-dev-extension/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ const vscode = require('vscode');
* @param {vscode.ExtensionContext} context
*/
function activate(context) {
// let showData = (val) => {
// vscode.window.showInformationMessage(JSON.stringify(val));
// }
let showData = (val) => {
vscode.window.showInformationMessage(JSON.stringify(val));
}

// The command has been defined in the package.json file
// Now provide the implementation of the command with registerCommand
Expand All @@ -20,12 +20,20 @@ function activate(context) {
vscode.window.showInformationMessage('Hello World!');
});

let disposable2 = vscode.workspace.onDidOpenTextDocument((e) => {
showData({
type: "workspace.onDidOpenTextDocument",
filename: e.fileName,
});
});

// Create a simple status bar
let item = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 1000);
item.text = "Developer";
item.show();

context.subscriptions.push(disposable);
context.subscriptions.push(disposable2);
}

// this method is called when your extension is deactivated
Expand Down
6 changes: 6 additions & 0 deletions src/editor/Core/Types.re
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ module BufferNotification = {
bufferId: int,
buffers: list(BufferMetadata.t),
};

let getBufferMetadataOpt = (id, v: t) => {
let result =
v.buffers |> List.filter((b: BufferMetadata.t) => b.id == id);
List.nth_opt(result, 0);
};
};

module BufferUpdate = {
Expand Down
100 changes: 100 additions & 0 deletions src/editor/Extensions/ExtensionHostProtocol.re
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,67 @@ module Environment = {
};
};

module Uri = {
module Scheme = {
[@deriving (show({with_path: false}), yojson({strict: false}))]
type t =
| [@name "file"] File;

let toString = (v: t) =>
switch (v) {
| File => "file"
};
};

[@deriving (show({with_path: false}), yojson({strict: false}))]
type t = {
scheme: Scheme.t,
path: string,
};

let createFromFilePath = (path: string) => {scheme: Scheme.File, path};
};

module Eol = {
[@deriving (show({with_path: false}), yojson({strict: false}))]
type t =
| [@name "\n"] LF
| [@name "\r\n"] CRLF;

let default = Sys.win32 ? CRLF : LF;
};

module ModelAddedDelta = {
[@deriving (show({with_path: false}), yojson({strict: false}))]
type t = {
uri: Uri.t,
versionId: int,
lines: list(string),
[@key "EOL"]
eol: Eol.t,
modeId: string,
isDirty: bool,
};

let create =
(
~uri,
~versionId=0,
~lines=[],
~eol=Eol.default,
~modeId,
~isDirty=false,
(),
) => {
uri,
versionId,
lines,
eol,
modeId,
isDirty,
};
};

module OutgoingNotifications = {
let _buildNotification = (scopeName, methodName, payload) => {
`List([`String(scopeName), `String(methodName), payload]);
Expand All @@ -66,6 +127,45 @@ module OutgoingNotifications = {
};
};

module DocumentsAndEditors = {
module DocumentsAndEditorsDelta = {
[@deriving (show({with_path: false}), yojson({strict: false}))]
type t = {
removedDocuments: list(Uri.t),
addedDocuments: list(ModelAddedDelta.t),
removedEditors: list(string),
addedEditors: list(string),
};

let create = (~removedDocuments, ~addedDocuments, ()) => {
removedDocuments,
addedDocuments,
removedEditors: [],
addedEditors: [],
};
};

let acceptDocumentsAndEditorsDelta =
(
~removedDocuments: list(Uri.t),
~addedDocuments: list(ModelAddedDelta.t),
(),
) => {
let delta =
DocumentsAndEditorsDelta.create(
~removedDocuments,
~addedDocuments,
(),
);

_buildNotification(
"ExtHostDocumentsAndEditors",
"$acceptDocumentsAndEditorsDelta",
`List([DocumentsAndEditorsDelta.to_yojson(delta)]),
);
};
};

module Workspace = {
[@deriving
(show({with_path: false}), yojson({strict: false, exn: true}))
Expand Down
59 changes: 55 additions & 4 deletions src/editor/Store/ExtensionClientStoreConnector.re
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
module Core = Oni_Core;
module Model = Oni_Model;

module Extensions = Oni_Extensions;

open Oni_Extensions;
module Extensions = Oni_Extensions;
module Protocol = Extensions.ExtensionHostProtocol;

let start = (extensions, setup: Core.Setup.t) => {
let (stream, dispatch) = Isolinear.Stream.create();
Expand Down Expand Up @@ -67,13 +67,64 @@ let start = (extensions, setup: Core.Setup.t) => {
setup,
);

let _bufferMetadataToModelAddedDelta = (bm: Core.Types.BufferMetadata.t) =>
switch (bm.filePath, bm.fileType) {
| (Some(fp), Some(ft)) =>
Some(
Protocol.ModelAddedDelta.create(
~uri=Protocol.Uri.createFromFilePath(fp),
~versionId=bm.version,
~lines=[],
~modeId=ft,
~isDirty=bm.modified,
(),
),
)
/* TODO: filetype detection */
| (Some(fp), _) =>
Some(
Protocol.ModelAddedDelta.create(
~uri=Protocol.Uri.createFromFilePath(fp),
~versionId=bm.version,
~lines=[],
~modeId="unknown",
~isDirty=bm.modified,
(),
),
)
| _ => None
};

let pumpEffect =
Isolinear.Effect.create(~name="exthost.pump", () =>
Extensions.ExtensionHostClient.pump(extHostClient)
ExtensionHostClient.pump(extHostClient)
);

let updater = (state, action) =>
let sendBufferEnterEffect = (bu: Core.Types.BufferNotification.t) =>
Isolinear.Effect.create(~name="exthost.bufferEnter", () => {
let metadata =
Core.Types.BufferNotification.getBufferMetadataOpt(bu.bufferId, bu);
switch (metadata) {
| None => ()
| Some(bm) =>
switch (_bufferMetadataToModelAddedDelta(bm)) {
| None => ()
| Some(v) =>
ExtensionHostClient.send(
extHostClient,
Protocol.OutgoingNotifications.DocumentsAndEditors.acceptDocumentsAndEditorsDelta(
~removedDocuments=[],
~addedDocuments=[v],
(),
),
)
}
};
});

let updater = (state: Model.State.t, action) =>
switch (action) {
| Model.Actions.BufferEnter(bm) => (state, sendBufferEnterEffect(bm))
| Model.Actions.Tick => (state, pumpEffect)
| _ => (state, Isolinear.Effect.none)
};
Expand Down
66 changes: 66 additions & 0 deletions test/editor/Extensions/ExtensionClientTest.re
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,18 @@ open Oni_Extensions;
open TestFramework;

open ExtensionClientHelper;
open ExtensionHostProtocol;
open ExtensionHostProtocol.OutgoingNotifications;

module JsonInformationMessageFormat = {
[@deriving (show({with_path: false}), yojson({strict: false, exn: true}))]
type t = {
[@key "type"]
messageType: string,
filename: string,
};
};

describe("Extension Client", ({describe, _}) => {
describe("commands", ({test, _}) =>
test("executes simple command", _ =>
Expand Down Expand Up @@ -35,6 +45,62 @@ describe("Extension Client", ({describe, _}) => {
})
)
);

describe("DocumentsAndEditors", ({test, _}) =>
test("document added successfully", _
/*({expect}) =>*/
=>
withExtensionClient(api => {
let waitForCommandRegistration =
api.createWaiterForMessage(
"MainThreadCommands", "$registerCommand", args =>
switch (args) {
| [`String("extension.helloWorld"), ..._] => true
| _ => false
}
);

let waitForShowMessage =
api.createWaiterForMessage(
"MainThreadMessageService", "$showMessage", args =>
switch (args) {
| [_, `String(s), ..._] =>
let json = Yojson.Safe.from_string(s);
open JsonInformationMessageFormat;
let info = JsonInformationMessageFormat.of_yojson_exn(json);

String.equal(info.filename, "test.txt")
&& String.equal(
info.messageType,
"workspace.onDidOpenTextDocument",
);
| _ => failwith("Unknown message")
}
);

api.start();
waitForCommandRegistration();
api.send(
DocumentsAndEditors.acceptDocumentsAndEditorsDelta(
~removedDocuments=[],
~addedDocuments=[
ModelAddedDelta.create(
~uri=Uri.createFromFilePath("test.txt"),
~lines=["hello world"],
~modeId="test_language",
~isDirty=false,
(),
),
],
(),
),
);

waitForShowMessage();
})
)
);

describe("lifecycle", ({test, _}) => {
test("gets initialized message", ({expect}) =>
Helpers.repeat(() => {
Expand Down
1 change: 1 addition & 0 deletions test/editor/Extensions/dune
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
(name Oni_Extensions_Test)
(library_flags (-linkall -g))
(modules (:standard))
(preprocess (pps ppx_deriving_yojson ppx_deriving.show))
(libraries msgpck Oni_Extensions Oni_Core_Test rely.lib))

0 comments on commit d81f3ac

Please sign in to comment.