Skip to content

Commit 14579f2

Browse files
authored
fix(scm/#2525): Fix 'Git: Checkout to' command (#3791)
__Issue:__ The 'Git: Checkout to...' command wasn't working as expected. __Defect:__ The checkout branch QuickPick menu uses some menu extension APIs that weren't currently supported, including: 1) Exthost -> Main: `$createOrUpdate` 2) Main -> Exthost: `$onDidChangeActive`, `$onDidAccept` __Fix:__ - Refactor the extension menus to `Feature_QuickOpen` - Implement the missing APIs Related to #3785 Fixes #2525
1 parent 8ce42bc commit 14579f2

13 files changed

+165
-131
lines changed

CHANGES_CURRENT.md

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
### Bug Fixes
44

5+
- #3791 - SCM: Fix 'Git: Checkout to' command (fixes #2525)
6+
57
### Performance
68

79
### Documentation

bench/lib/FilterJobBench.re

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ let createItem = name => {
1515
command: _ => Oni_Model.Actions.Noop,
1616
icon: None,
1717
highlight: [],
18-
handle: None,
1918
};
2019
ret;
2120
};

src/Exthost/Exthost.rei

+7
Original file line numberDiff line numberDiff line change
@@ -2216,6 +2216,13 @@ module Request: {
22162216
Lwt.t(option(list(Edit.SingleEditOperation.t)));
22172217
};
22182218

2219+
module QuickOpen: {
2220+
let onItemSelected: (~handle: int, Client.t) => unit;
2221+
let onDidChangeActive:
2222+
(~session: int, ~handles: list(int), Client.t) => unit;
2223+
let onDidAccept: (~session: int, Client.t) => unit;
2224+
};
2225+
22192226
module SCM: {
22202227
let provideOriginalResource:
22212228
(~handle: int, ~uri: Uri.t, Client.t) => Lwt.t(option(Uri.t));

src/Exthost/Request.re

+33
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,39 @@ module LanguageFeatures = {
678678
};
679679
};
680680

681+
module QuickOpen = {
682+
let onItemSelected = (~handle, client) => {
683+
Client.notify(
684+
~usesCancellationToken=false,
685+
~rpcName="ExtHostQuickOpen",
686+
~method="$onItemSelected",
687+
~args=`List([`Int(handle)]),
688+
client,
689+
);
690+
};
691+
692+
let onDidChangeActive = (~session, ~handles, client) => {
693+
let handlesJson = handles |> List.map(handle => `Int(handle));
694+
Client.notify(
695+
~usesCancellationToken=false,
696+
~rpcName="ExtHostQuickOpen",
697+
~method="$onDidChangeActive",
698+
~args=`List([`Int(session), `List(handlesJson)]),
699+
client,
700+
);
701+
};
702+
703+
let onDidAccept = (~session, client) => {
704+
Client.notify(
705+
~usesCancellationToken=false,
706+
~rpcName="ExtHostQuickOpen",
707+
~method="$onDidAccept",
708+
~args=`List([`Int(session)]),
709+
client,
710+
);
711+
};
712+
};
713+
681714
module SCM = {
682715
let provideOriginalResource = (~handle, ~uri, client) => {
683716
Client.request(

src/Feature/QuickOpen/Feature_QuickOpen.re

+115-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
1-
type model = unit;
1+
module Model = {
2+
type session = {
3+
id: int,
4+
resolver: Lwt.u(Exthost.Reply.t),
5+
};
6+
7+
type t = option(session);
8+
let start = (~id, ~resolver, current) =>
9+
switch (current) {
10+
| Some({id: previousId, _}) when previousId == id => current
11+
| Some({id: previousId, _}) when previousId != id => Some({id, resolver})
12+
| None => Some({id, resolver})
13+
| _ => failwith("Never hit this")
14+
};
215

3-
let initial = ();
16+
let reset = (_: t) => None;
17+
18+
let initial = None;
19+
};
20+
21+
type model = Model.t;
22+
23+
let initial = Model.initial;
424

525
exception UserCancelled;
626

@@ -12,9 +32,16 @@ type msg =
1232
resolver: [@opaque] Lwt.u(Exthost.Reply.t),
1333
})
1434
| Cancelled({resolver: [@opaque] Lwt.u(Exthost.Reply.t)})
35+
| MenuCancelled
36+
| MenuItemSelected({item: Exthost.QuickOpen.Item.t})
1537
| ShowInput({
1638
options: Exthost.InputBoxOptions.t,
1739
resolver: [@opaque] Lwt.u(Exthost.Reply.t),
40+
})
41+
| ShowQuickPick({
42+
instance: int,
43+
items: list(Exthost.QuickOpen.Item.t),
44+
resolver: [@opaque] Lwt.u(Exthost.Reply.t),
1845
});
1946

2047
type outmsg =
@@ -27,6 +54,29 @@ module Msg = {
2754
Exthost.Msg.QuickOpen.(
2855
switch (msg) {
2956
| Input({options, _}) => ShowInput({options, resolver})
57+
| SetItems({instance, items}) =>
58+
ShowQuickPick({instance, items, resolver})
59+
| Show({instance, _}) => ShowQuickPick({instance, items: [], resolver})
60+
| CreateOrUpdate({params}) =>
61+
Exthost.QuickOpen.(
62+
{
63+
switch (params) {
64+
| QuickInput(input) =>
65+
ShowInput({
66+
options: {
67+
ignoreFocusOut: false,
68+
password: false,
69+
placeHolder: input.placeholder,
70+
prompt: input.prompt,
71+
value: input.value,
72+
},
73+
resolver,
74+
})
75+
| QuickPick({id, items, _}) =>
76+
ShowQuickPick({instance: id, items, resolver})
77+
};
78+
}
79+
)
3080
| _ => Noop
3181
}
3282
);
@@ -42,16 +92,75 @@ module Effects = {
4292
Isolinear.Effect.create(~name="Feature_QuickOpen.accept", () => {
4393
Lwt.wakeup(resolver, Exthost.Reply.okJson(`String(text)))
4494
});
95+
96+
let selectItem =
97+
(~session, ~resolver, ~item: Exthost.QuickOpen.Item.t, client) =>
98+
Isolinear.Effect.create(~name="Feature_QuickOpen.select", () => {
99+
Exthost.Request.QuickOpen.onDidChangeActive(
100+
~session,
101+
~handles=[item.handle],
102+
client,
103+
);
104+
105+
Exthost.Request.QuickOpen.onDidAccept(~session, client);
106+
107+
Lwt.wakeup(resolver, Exthost.Reply.okJson(`Int(item.handle)));
108+
});
45109
};
46110

47-
let update = (msg, model) =>
111+
let update = (~client, msg, model) =>
48112
switch (msg) {
49113
| Accepted({resolver, text}) => (
50-
model,
114+
model |> Model.reset,
51115
Effect(Effects.accept(~resolver, text)),
52116
)
53117

54-
| Cancelled({resolver}) => (model, Effect(Effects.cancel(~resolver)))
118+
| Cancelled({resolver}) => (
119+
model |> Model.reset,
120+
Effect(Effects.cancel(~resolver)),
121+
)
122+
123+
| MenuItemSelected({item}) =>
124+
let eff =
125+
switch (model) {
126+
| None => Isolinear.Effect.none
127+
| Some({resolver, id}) =>
128+
Effects.selectItem(~session=id, ~resolver, ~item, client)
129+
};
130+
131+
(model |> Model.reset, Effect(eff));
132+
133+
| MenuCancelled =>
134+
let eff =
135+
switch (model) {
136+
| None => Isolinear.Effect.none
137+
| Some({resolver, _}) => Effects.cancel(~resolver)
138+
};
139+
(model |> Model.reset, Effect(eff));
140+
141+
| ShowQuickPick({instance, items, resolver}) =>
142+
let placeholderText = "";
143+
let menu =
144+
Feature_Quickmenu.Schema.(
145+
menu(
146+
~onItemFocused=_item => Noop,
147+
~onAccepted=
148+
(~text as _, ~item) => {
149+
switch (item) {
150+
| Some(item) => MenuItemSelected({item: item})
151+
| None => MenuCancelled
152+
}
153+
},
154+
~onCancelled=_item => {Cancelled({resolver: resolver})},
155+
~placeholderText,
156+
~itemRenderer=Renderer.default,
157+
~toString=
158+
(item: Exthost.QuickOpen.Item.t) =>
159+
Exthost.QuickOpen.Item.(item.label),
160+
items,
161+
)
162+
);
163+
(model |> Model.start(~id=instance, ~resolver), ShowMenu(menu));
55164

56165
| ShowInput({options, resolver}) =>
57166
let placeholderText =
@@ -69,7 +178,7 @@ let update = (msg, model) =>
69178
[],
70179
)
71180
);
72-
(model, ShowMenu(menu));
181+
(model |> Model.reset, ShowMenu(menu));
73182

74183
| Noop => (model, Nothing)
75184
};

src/Feature/QuickOpen/Feature_QuickOpen.rei

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ module Msg: {
1515
(~resolver: Lwt.u(Exthost.Reply.t), Exthost.Msg.QuickOpen.msg) => msg;
1616
};
1717

18-
let update: (msg, model) => (model, outmsg);
18+
let update: (~client: Exthost.Client.t, msg, model) => (model, outmsg);

src/Model/Actions.re

-10
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,6 @@ type t =
8787
| QuickmenuCommandlineUpdated(string, int)
8888
| QuickmenuUpdateRipgrepProgress(progress)
8989
| QuickmenuUpdateFilterProgress([@opaque] array(menuItem), progress)
90-
| QuickmenuUpdateExtensionItems({
91-
id: int,
92-
items: list(Exthost.QuickOpen.Item.t),
93-
})
9490
| QuickmenuSearch(string)
9591
| QuickmenuClose
9692
| QuickOpen(Feature_QuickOpen.msg)
@@ -179,19 +175,13 @@ and menuItem = {
179175
command: option(SplitDirection.t) => t,
180176
icon: [@opaque] option(IconTheme.IconDefinition.t),
181177
highlight: list((int, int)),
182-
handle: option(int),
183178
}
184179
and quickmenuVariant =
185180
| CommandPalette
186181
| EditorsPicker
187182
| FilesPicker
188183
| OpenBuffersPicker
189184
| Wildmenu([@opaque] Vim.Types.cmdlineType)
190-
| Extension({
191-
id: int,
192-
hasItems: bool,
193-
resolver: [@opaque] Lwt.u(int),
194-
})
195185
and progress =
196186
| Loading
197187
| InProgress(float)

src/Model/Quickmenu.re

+1-6
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,7 @@ and variant =
1616
| EditorsPicker
1717
| FilesPicker
1818
| OpenBuffersPicker
19-
| Wildmenu(Vim.Types.cmdlineType)
20-
| Extension({
21-
id: int,
22-
hasItems: bool,
23-
resolver: Lwt.u(int),
24-
});
19+
| Wildmenu(Vim.Types.cmdlineType);
2520

2621
let placeholderText =
2722
fun

src/Store/ExtensionClient.re

+5-30
Original file line numberDiff line numberDiff line change
@@ -148,36 +148,11 @@ let create =
148148
)
149149

150150
| QuickOpen(msg) =>
151-
switch (msg) {
152-
| QuickOpen.Show({instance, _}) =>
153-
let (promise, resolver) = Lwt.task();
154-
dispatch(
155-
QuickmenuShow(
156-
Extension({id: instance, hasItems: false, resolver}),
157-
),
158-
);
159-
160-
promise |> Lwt.map(handle => Reply.okJson(`Int(handle)));
161-
| QuickOpen.SetItems({instance, items}) =>
162-
dispatch(QuickmenuUpdateExtensionItems({id: instance, items}));
163-
Lwt.return(Reply.okEmpty);
164-
165-
// | QuickOpen.Input(_) => Lwt.return(Reply.okJson(`String("Testing")))
166-
| msg =>
167-
let (promise, resolver) = Lwt.task();
168-
dispatch(
169-
Actions.QuickOpen(Feature_QuickOpen.Msg.exthost(~resolver, msg)),
170-
);
171-
// TODO: Additional quick open messages
172-
// Log.warnf(m =>
173-
// m(
174-
// "Unhandled QuickOpen message: %s",
175-
// Exthost.Msg.QuickOpen.show_msg(msg),
176-
// )
177-
// );
178-
// TODO: Pass resolver to feature
179-
promise;
180-
}
151+
let (promise, resolver) = Lwt.task();
152+
dispatch(
153+
Actions.QuickOpen(Feature_QuickOpen.Msg.exthost(~resolver, msg)),
154+
);
155+
promise;
181156

182157
| StatusBar(
183158
SetEntry({

src/Store/Features.re

+1-1
Original file line numberDiff line numberDiff line change
@@ -2354,7 +2354,7 @@ let update =
23542354

23552355
| QuickOpen(msg) =>
23562356
let (quickOpen', outmsg) =
2357-
Feature_QuickOpen.update(msg, state.quickOpen);
2357+
Feature_QuickOpen.update(~client=extHostClient, msg, state.quickOpen);
23582358

23592359
let (state', eff) =
23602360
switch (outmsg) {

0 commit comments

Comments
 (0)