Skip to content

Commit

Permalink
Highlight current switch (ocamllabs#751)
Browse files Browse the repository at this point in the history
- The currently active OPAM switch in the workspace folder (project root) is shown first in the list of sandboxes when selecting a sandbox. (ocamllabs#751)

- Show a different icon for the currently active OPAM switch in the "OPAM Switches" tree view (ocamllabs#751)

Signed-off-by: Paul-Elliot <[email protected]>
Co-authored-by: Ulugbek Abdullaev <[email protected]>
  • Loading branch information
panglesd and ulugbekna authored Oct 30, 2021
1 parent 6862f23 commit 2ea1992
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 22 deletions.
7 changes: 7 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Change Log

## Unreleased

- Highlighted the UNREACHABLE element in cram .t files (#754)

- Activate extension on cram files, or when the workspace contains
Expand Down Expand Up @@ -41,6 +42,12 @@
launch a terminal within a certain sandbox set in the extension (#744, fixes
#655)

- The currently active OPAM switch in the workspace folder (project root) is
shown first in the list of sandboxes when selecting a sandbox. (#751)

- Show a different icon for the currently active OPAM switch in the "OPAM
Switches" tree view (#751)

## 1.8.4

- Fix inclusion of files in extension package
Expand Down
1 change: 1 addition & 0 deletions assets/dependency-dark-selected.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/dependency-light-selected.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/extension_commands.ml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ let _select_sandbox =
| None (* sandbox selection cancelled *) -> Promise.return ()
| Some new_sandbox ->
Extension_instance.set_sandbox instance new_sandbox;
let (_ : unit Promise.t) = Sandbox.save_to_settings new_sandbox in
let* () = Sandbox.save_to_settings new_sandbox in
Extension_instance.start_language_server instance
in
()
Expand Down
3 changes: 3 additions & 0 deletions src/extension_instance.ml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ let set_sandbox t new_sandbox =
let (_ : Ojs.t option Promise.t) =
Vscode.Commands.executeCommand
~command:Extension_consts.Commands.refresh_sandbox ~args:[]
and (_ : Ojs.t option Promise.t) =
Vscode.Commands.executeCommand
~command:Extension_consts.Commands.refresh_switches ~args:[]
in
()

Expand Down
69 changes: 57 additions & 12 deletions src/sandbox.ml
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ let of_settings () : t option Promise.t =
| Some Global -> Promise.return (Some Global)
| Some (Custom template) -> Promise.return (Some (Custom template))

(** If [Workspace.workspaceFolders()] returns a list with a single element,
returns it; otherwise, returns [None]. *)
let workspace_root () =
match Workspace.workspaceFolders () with
| [] -> None
Expand Down Expand Up @@ -305,17 +307,27 @@ module Candidate = struct
; status : (unit, string) result
}

let to_quick_pick { sandbox; status } =
let to_quick_pick current_switch { sandbox; status } =
let create = QuickPickItem.create in
let description =
match status with
| Error s -> Some (Printf.sprintf "Invalid sandbox: %s" s)
| Ok () -> (
match sandbox with
| Opam (_, Local _) -> Some "Local switch"
| Opam (_, Named _) -> Some "Global switch"
| Esy _ -> Some "Esy"
| _ -> None)
| Opam (_, switch) ->
let switch_kind_s =
match switch with
| Local _ -> "Local switch"
| Named _ -> "Global switch"
in
if Option.exists current_switch ~f:(Opam.Switch.equal switch) then
Some (switch_kind_s ^ " | Currently active switch in project root")
else
Some switch_kind_s
| Esy (_, _) -> Some "Esy"
| Global
| Custom _ ->
None)
in
match sandbox with
| Opam (_, Named name) -> create ~label:name ?description ()
Expand All @@ -342,10 +354,17 @@ let select_sandbox (choices : Candidate.t list) =
let placeHolder =
"Which package manager would you like to manage the sandbox?"
in
let open Promise.Syntax in
let* current_switch =
let open Promise.Option.Syntax in
let* opam = Opam.make () in
let* cwd = workspace_root () |> Promise.return in
Opam.switch_show ~cwd opam
in
let choices =
List.map
~f:(fun (sandbox : Candidate.t) ->
let quick_pick = Candidate.to_quick_pick sandbox in
let quick_pick = Candidate.to_quick_pick current_switch sandbox in
(quick_pick, sandbox))
choices
in
Expand Down Expand Up @@ -376,12 +395,36 @@ let sandbox_candidates ~workspace_folders =
let opam =
let* opam = available.opam in
match opam with
| None -> Promise.return []
| Some opam ->
| None -> Promise.return ([], None)
| Some opam -> (
let* current_switch =
match workspace_root () with
| None -> Promise.return None
| Some cwd -> Opam.switch_show ~cwd opam
in
let+ switches = Opam.switch_list opam in
List.map switches ~f:(fun sw ->
match current_switch with
| None ->
let switches =
List.map switches ~f:(fun sw ->
let sandbox = Opam (opam, sw) in
{ Candidate.sandbox; status = Ok () })
in
(switches, None)
| Some current_switch ->
let f sw =
let sandbox = Opam (opam, sw) in
{ Candidate.sandbox; status = Ok () })
if Opam.Switch.equal current_switch sw then
None
else
Some { Candidate.sandbox; status = Ok () }
in
let sandboxes = List.filter_map switches ~f
and current_switch_sandbox =
let sandbox = Opam (opam, current_switch) in
Some { Candidate.sandbox; status = Ok () }
in
(sandboxes, current_switch_sandbox))
in
let global = Candidate.ok Global in
let custom =
Expand All @@ -390,8 +433,10 @@ let sandbox_candidates ~workspace_folders =
custom commands in [select] *)
in

let+ esy, opam = Promise.all2 (esy, opam) in
(global :: custom :: esy) @ opam
let+ esy, (opam, current_switch) = Promise.all2 (esy, opam) in
let cs = (global :: custom :: esy) @ opam in
Option.value_map current_switch ~default:cs ~f:(fun current_switch ->
current_switch :: cs)

let select_sandbox () =
let open Promise.Syntax in
Expand Down
37 changes: 30 additions & 7 deletions src/treeview_switches.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ module Dependency = struct
| Package : Opam.Package.t -> t
| Switch : Opam.t * Opam.Switch.t -> t

let equals_opam_sandbox t sandbox =
match (t, sandbox) with
| Switch (opam, switch), Sandbox.Opam (opam_, switch_) ->
Opam.equal opam opam_ && Opam.Switch.equal switch switch_
| _ -> false

let t_of_js : Ojs.t -> t = Stdlib.Obj.magic

let t_to_js : t -> Ojs.t = Stdlib.Obj.magic
Expand Down Expand Up @@ -32,11 +38,24 @@ module Dependency = struct
| Some _ -> "package-with-doc"
| None -> "package")

let icon = function
let icon dependency is_current_sandbox =
match dependency with
| Switch _ ->
let selected =
if is_current_sandbox then
"-selected"
else
""
in
TreeItem.LightDarkIcon.
{ light = `String (Path.asset "dependency-light.svg" |> Path.to_string)
; dark = `String (Path.asset "dependency-dark.svg" |> Path.to_string)
{ light =
`String
(Path.asset @@ "dependency-light" ^ selected ^ ".svg"
|> Path.to_string)
; dark =
`String
(Path.asset @@ "dependency-dark" ^ selected ^ ".svg"
|> Path.to_string)
}
| Package _ ->
TreeItem.LightDarkIcon.
Expand All @@ -52,9 +71,11 @@ module Dependency = struct
else
TreeItemCollapsibleState.None

let to_treeitem dependency =
let to_treeitem instance dependency =
let open Promise.Syntax in
let icon = `LightDark (icon dependency) in
let current_sandbox = Extension_instance.sandbox instance in
let is_current_sandbox = equals_opam_sandbox dependency current_sandbox in
let icon = `LightDark (icon dependency is_current_sandbox) in
let collapsibleState = collapsible_state dependency in
let label =
`TreeItemLabel (Vscode.TreeItemLabel.create ~label:(label dependency) ())
Expand Down Expand Up @@ -155,7 +176,8 @@ module Command = struct
~id:Extension_consts.Commands.open_switches_documentation handler
end

let getTreeItem ~element = `Promise (Dependency.to_treeitem element)
let getTreeItem instance ~element =
`Promise (Dependency.to_treeitem instance element)

let getChildren ?opam ?element () =
match (opam, element) with
Expand All @@ -172,11 +194,12 @@ let getChildren ?opam ?element () =
in
`Promise items

let register extension =
let register extension instance =
let (_ : unit Promise.t) =
let open Promise.Syntax in
let+ opam = Opam.make () in
let getChildren = getChildren ?opam in
let getTreeItem = getTreeItem instance in
let module EventEmitter =
Vscode.EventEmitter.Make (Interop.Js.Or_undefined (Dependency)) in
let event_emitter = EventEmitter.make () in
Expand Down
2 changes: 1 addition & 1 deletion src/treeview_switches.mli
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
(** Register the ocaml-switches tree view *)
val register : Vscode.ExtensionContext.t -> unit
val register : Vscode.ExtensionContext.t -> Extension_instance.t -> unit
2 changes: 1 addition & 1 deletion src/vscode_ocaml_platform.ml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ let activate (extension : ExtensionContext.t) =
Dune_formatter.register extension instance;
Dune_task_provider.register extension instance;
Extension_commands.register_all_commands extension instance;
Treeview_switches.register extension;
Treeview_switches.register extension instance;
Treeview_sandbox.register extension instance;
Treeview_commands.register extension;
Treeview_help.register extension;
Expand Down

0 comments on commit 2ea1992

Please sign in to comment.