Skip to content

Commit

Permalink
SCM: File Explorer decorations (onivim#1282)
Browse files Browse the repository at this point in the history
* handle decoration provider registration

* add some list theme colors

* use list theme colors in FileTReeView

* hard-code custom gitDecoration colors

* retrieve decorations

* hard-code git refresh on BufferUpdate

* use decoration foreground color in FileTreeView
  • Loading branch information
glennsl authored Feb 3, 2020
1 parent 1d25970 commit 45c3a36
Show file tree
Hide file tree
Showing 11 changed files with 352 additions and 25 deletions.
1 change: 1 addition & 0 deletions src/Core/Oni_Core.re
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ module LineNumber = LineNumber;
module Log = Kernel.Log;
module Ripgrep = Ripgrep;
module Scheduler = Scheduler;
module SCMDecoration = SCMDecoration;
module Setup = Setup;
module ShellUtility = ShellUtility;
module StringMap = Kernel.StringMap;
Expand Down
8 changes: 8 additions & 0 deletions src/Core/SCMDecoration.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[@deriving show]
type t = {
handle: int, // provider handle
tooltip: string,
letter: string,
color: string, // TODO: ThemeColor.t?
source: string,
};
55 changes: 55 additions & 0 deletions src/Core/Theme.re
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ type t = {
editorFindMatchHighlightBackground: Color.t,
editorIndentGuideBackground: Color.t,
editorIndentGuideActiveBackground: Color.t,
listActiveSelectionBackground: Color.t,
listActiveSelectionForeground: Color.t,
listFocusBackground: Color.t,
listFocusForeground: Color.t,
listHoverBackground: Color.t,
listHoverForeground: Color.t,
menuBackground: Color.t,
menuForeground: Color.t,
menuSelectionBackground: Color.t,
Expand Down Expand Up @@ -140,6 +146,12 @@ let default: t = {
editorOverviewRulerBracketMatchForeground: Color.hex("#A0A0A0"),
editorActiveLineNumberForeground: Color.hex("#737984"),
editorSelectionBackground: Color.hex("#687595"),
listActiveSelectionBackground: Color.hex("#495162"),
listActiveSelectionForeground: Color.hex("#FFFFFF"),
listFocusBackground: Color.hex("#495162"),
listFocusForeground: Color.hex("#FFFFFF"),
listHoverBackground: Color.hex("#495162"),
listHoverForeground: Color.hex("#FFFFFF"),
scrollbarSliderBackground: Color.rgba(0., 0., 0., 0.2),
scrollbarSliderActiveBackground: Color.hex("#2F3440"),
editorIndentGuideBackground: Color.hex("#3b4048"),
Expand Down Expand Up @@ -393,6 +405,36 @@ let ofColorTheme = (uiTheme, ct: Textmate.ColorTheme.t) => {
editorSuggestWidgetBorder,
editorSuggestWidgetHighlightForeground,
editorSuggestWidgetSelectedBackground,
listActiveSelectionBackground:
getColor(
defaultBackground,
["list.activeSelectionBackground", "menu.selectionBackground"],
),
listActiveSelectionForeground:
getColor(
defaultForeground,
["list.activeSelectionForeground", "menu.foreground"],
),
listFocusBackground:
getColor(
defaultBackground,
["list.focusBackground", "menu.selectionBackground"],
),
listFocusForeground:
getColor(
defaultForeground,
["list.focusForeground", "menu.foreground"],
),
listHoverBackground:
getColor(
defaultBackground,
["list.hoverBackground", "menu.selectionBackground"],
),
listHoverForeground:
getColor(
defaultForeground,
["list.hoverForeground", "menu.foreground"],
),
menuBackground,
menuForeground,
menuSelectionBackground,
Expand Down Expand Up @@ -431,3 +473,16 @@ let getColorsForMode = (theme: t, mode: Vim.Mode.t) => {

(background, foreground);
};

let getCustomColor = (color, _theme) =>
switch (color) {
| "gitDecoration.addedResourceForeground" => Some(Color.hex("#81b88b"))
| "gitDecoration.modifiedResourceForeground" => Some(Color.hex("#E2C08D"))
| "gitDecoration.deletedResourceForeground" => Some(Color.hex("#c74e39"))
| "gitDecoration.untrackedResourceForeground" => Some(Color.hex("#73C991"))
| "gitDecoration.ignoredResourceForeground" => Some(Color.hex("#8C8C8C"))
| "gitDecoration.conflictingResourceForeground" =>
Some(Color.hex("#6c6cc4"))
| "gitDecoration.submoduleResourceForeground" => Some(Color.hex("#8db9e2"))
| _ => None
};
80 changes: 79 additions & 1 deletion src/Extensions/ExtHostClient.re
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,16 @@ type msg =
handle: int,
scheme: string,
})
| UnregisterTextContentProvider({handle: int});
| UnregisterTextContentProvider({handle: int})
| RegisterDecorationProvider({
handle: int,
label: string,
})
| UnregisterDecorationProvider({handle: int})
| DecorationsDidChange({
handle: int,
uris: list(Uri.t),
});

type unitCallback = unit => unit;
let noop = () => ();
Expand Down Expand Up @@ -223,6 +232,35 @@ let start =
dispatch(UnregisterTextContentProvider({handle: handle}));
Ok(None);

| (
"MainThreadDecorations",
"$registerDecorationProvider",
[`Int(handle), `String(label)],
) =>
dispatch(RegisterDecorationProvider({handle, label}));
Ok(None);

| (
"MainThreadDecorations",
"$unregisterDecorationProvider",
[`Int(handle)],
) =>
dispatch(UnregisterDecorationProvider({handle: handle}));
Ok(None);

| (
"MainThreadDecorations",
"$onDidChange",
[`Int(handle), `List(resources)],
) =>
let uris =
resources
|> List.filter_map(json =>
Uri.of_yojson(json) |> Utility.Result.to_option
);
dispatch(DecorationsDidChange({handle, uris}));
Ok(None);

| (scope, method, argsAsJson) =>
Log.warnf(m =>
m(
Expand Down Expand Up @@ -298,6 +336,46 @@ let provideCompletions = (id, uri, position, client) => {
promise;
};

let provideDecorations = (handle, uri, client) => {
let decodeItem =
fun
| (
_requestId,
`List([
`Int(_),
`Bool(_),
`String(tooltip),
`String(letter),
`Assoc([("id", `String(color))]),
`String(source),
]),
) =>
Some(SCMDecoration.{handle, tooltip, letter, color, source})
| (_, json) => {
Log.error("Unexpected data: " ++ Yojson.Safe.to_string(json));
None;
};

ExtHostTransport.request(
~msgType=MessageType.requestJsonArgsWithCancellation,
client,
Out.Decorations.provideDecorations(handle, uri),
json =>
switch (json) {
| `Assoc(items) => items |> List.filter_map(decodeItem)

| _ =>
failwith(
Printf.sprintf(
"Unexpected response from provideDecorations for %s: \n %s",
Uri.toString(uri),
Yojson.Safe.to_string(json),
),
)
}
);
};

let provideDefinition = (id, uri, position, client) => {
let f = (json: Yojson.Safe.t) => {
let json =
Expand Down
13 changes: 12 additions & 1 deletion src/Extensions/ExtHostClient.rei
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,16 @@ type msg =
handle: int,
scheme: string,
})
| UnregisterTextContentProvider({handle: int});
| UnregisterTextContentProvider({handle: int})
| RegisterDecorationProvider({
handle: int,
label: string,
})
| UnregisterDecorationProvider({handle: int})
| DecorationsDidChange({
handle: int,
uris: list(Core.Uri.t),
});

type unitCallback = unit => unit;

Expand Down Expand Up @@ -68,6 +77,8 @@ let updateDocument:
let provideCompletions:
(int, Core.Uri.t, Protocol.OneBasedPosition.t, t) =>
Lwt.t(option(list(Protocol.SuggestionItem.t)));
let provideDecorations:
(int, Core.Uri.t, t) => Lwt.t(list(Core.SCMDecoration.t));
let provideDefinition:
(int, Core.Uri.t, Protocol.OneBasedPosition.t, t) =>
Lwt.t(Protocol.DefinitionLink.t);
Expand Down
17 changes: 17 additions & 0 deletions src/Extensions/ExtHostProtocol.re
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,23 @@ module OutgoingNotifications = {
};
};

module Decorations = {
let provideDecorations = (handle: int, uri: Uri.t) =>
_buildNotification(
"ExtHostDecorations",
"$provideDecorations",
`List([
`List([
`Assoc([
("id", `Int(0)),
("handle", `Int(handle)),
("uri", Uri.to_yojson(uri)),
]),
]),
]),
);
};

module Documents = {
let acceptModelChanged =
(uri: Uri.t, modelChangedEvent: ModelChangedEvent.t, isDirty: bool) => {
Expand Down
20 changes: 11 additions & 9 deletions src/Model/FileExplorer.re
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ type t = {
isOpen: bool,
scrollOffset: [ | `Start(float) | `Middle(float) | `Reveal(int)],
active: option(string), // path
focus: option(string) // path
focus: option(string), // path
decorations: StringMap.t(list(SCMDecoration.t)),
};

[@deriving show({with_path: false})]
Expand All @@ -20,6 +21,15 @@ type action =
| ScrollOffsetChanged([ | `Start(float) | `Middle(float) | `Reveal(int)])
| KeyboardInput(string);

let initial = {
tree: None,
isOpen: true,
scrollOffset: `Start(0.),
active: None,
focus: None,
decorations: StringMap.empty,
};

let getFileIcon = (languageInfo, iconTheme, filePath) => {
let fileIcon =
LanguageInfo.getLanguageFromFilePath(languageInfo, filePath)
Expand Down Expand Up @@ -121,11 +131,3 @@ let getDirectoryTree = (cwd, languageInfo, iconTheme, ignored) => {

FsTreeNode.directory(cwd, ~icon=getIcon(cwd), ~children, ~isOpen=true);
};

let initial = {
tree: None,
isOpen: true,
scrollOffset: `Start(0.),
active: None,
focus: None,
};
4 changes: 3 additions & 1 deletion src/Model/FileExplorer.rei
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
open Oni_Core;
open Oni_Extensions;

type t = {
tree: option(FsTreeNode.t),
isOpen: bool,
scrollOffset: [ | `Start(float) | `Middle(float) | `Reveal(int)],
active: option(string), // path
focus: option(string) // path
focus: option(string), // path
decorations: StringMap.t(list(SCMDecoration.t)),
};

[@deriving show]
Expand Down
29 changes: 27 additions & 2 deletions src/Model/SCM.re
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,21 @@ module Provider = {
};
};

module DecorationProvider = {
[@deriving show({with_path: false})]
type t = {
handle: int,
label: string,
};
};

[@deriving show({with_path: false})]
type t = {providers: list(Provider.t)};
type t = {
providers: list(Provider.t),
decorationProviders: list(DecorationProvider.t),
};

let initial = {providers: []};
let initial = {providers: [], decorationProviders: []};

[@deriving show({with_path: false})]
type msg =
Expand Down Expand Up @@ -57,4 +68,18 @@ type msg =
| GotOriginalContent({
bufferId: int,
lines: [@opaque] array(string),
})
| NewDecorationProvider({
handle: int,
label: string,
})
| LostDecorationProvider({handle: int})
| DecorationsChanged({
handle: int,
uris: list(Uri.t),
})
| GotDecorations({
handle: int,
uri: Uri.t,
decorations: list(SCMDecoration.t),
});
Loading

0 comments on commit 45c3a36

Please sign in to comment.