@@ -16,27 +16,90 @@ import * as vscode from "vscode";
1616import * as langclient from "vscode-languageclient/node" ;
1717import { PeekDocumentsParams , PeekDocumentsRequest } from "./lspExtensions" ;
1818
19+ /**
20+ * Opens a peeked editor in `uri` at `position` having contents from `locations`.
21+ *
22+ * **NOTE**:
23+ * - If the `uri` is not open in the editor, this opens the `uri` in the editor and then opens a peeked editor.
24+ * - This closes any previously displayed peeked editor in `uri` and then, reopens a peeked editor in `uri` at
25+ * the given `position` with contents from the new `locations`.
26+ *
27+ * @param uri The uri of the file in which a peeked editor is to be opened
28+ * @param position The position in the file in which a peeked editor is to be opened
29+ * @param locations The locations of the contents which has to be displayed by the peeked editor
30+ */
31+ async function openPeekedEditorIn (
32+ uri : vscode . Uri ,
33+ position : vscode . Position ,
34+ locations : vscode . Location [ ]
35+ ) {
36+ // #### NOTE - Undocumented behaviour of invoking VS Code's built-in "editor.action.peekLocations" command:
37+ // 1. If the `uri` is not open in the editor, it opens the `uri` in the editor and then opens a peeked editor.
38+ // 2. It always closes the previous peeked editor (If any)
39+ // 3. And after closing, It opens a new peeked editor having the contents of `locations` in `uri` **if and only
40+ // if** the previous peeked editor was displayed at a *different* `position` in `uri`.
41+ // 4. If it happens to be that the previous peeked editor was displayed at the *same* `position` in `uri`, then it
42+ // doesn't open the peeked editor window having the contents of new `locations` at all.
43+
44+ // As (4.) says above, if we invoke "editor.action.peekLocations" on a position in which another peeked editor
45+ // window is already being shown, it won't cause the new peeked editor window to show up at all. This is not the
46+ // ideal behaviour.
47+ //
48+ // For example:
49+ // If there's already a peeked editor window at the position (2, 2) in "main.swift", its impossible to close this
50+ // peeked editor window and open a new peeked editor window at the same position (2, 2) in "main.swift" by invoking
51+ // the "editor.action.peekLocations" command in a single call.
52+ //
53+ // *The ideal behaviour* is to close any previously opened peeked editor window and then open the new one without
54+ // any regard to its `position` in the `uri`.
55+
56+ // In order to achieve *the ideal behaviour*, we manually close the peeked editor window by ourselves before
57+ // opening a new peeked editor window.
58+ //
59+ // Since there isn't any API available to close the previous peeked editor, as a **workaround**, we open a dummy
60+ // peeked editor at a different position, causing the previous one to close irrespective of where it is. After
61+ // which we can invoke the command again to show the actual peeked window having the contents of the `locations`.
62+ await vscode . commands . executeCommand (
63+ "editor.action.peekLocations" ,
64+ uri ,
65+ position !== new vscode . Position ( 0 , 0 )
66+ ? new vscode . Position ( 0 , 0 )
67+ : new vscode . Position ( 1 , 1 ) ,
68+ [ new vscode . Location ( vscode . Uri . parse ( "" ) , new vscode . Position ( 0 , 0 ) ) ] ,
69+ "peek"
70+ ) ;
71+
72+ // Opens the actual peeked editor window
73+ await vscode . commands . executeCommand (
74+ "editor.action.peekLocations" ,
75+ uri ,
76+ position ,
77+ locations ,
78+ "peek"
79+ ) ;
80+ }
81+
1982export function activatePeekDocuments ( client : langclient . LanguageClient ) : vscode . Disposable {
2083 const peekDocuments = client . onRequest (
2184 PeekDocumentsRequest . method ,
2285 async ( params : PeekDocumentsParams ) => {
23- const locations = params . locations . map ( uri => {
24- const location = new vscode . Location (
25- client . protocol2CodeConverter . asUri ( uri ) ,
26- new vscode . Position ( 0 , 0 )
27- ) ;
28-
29- return location ;
30- } ) ;
31-
32- await vscode . commands . executeCommand (
33- "editor.action.peekLocations" ,
34- client . protocol2CodeConverter . asUri ( params . uri ) ,
35- new vscode . Position ( params . position . line , params . position . character ) ,
36- locations ,
37- "peek"
86+ const peekURI = client . protocol2CodeConverter . asUri ( params . uri ) ;
87+
88+ const peekPosition = new vscode . Position (
89+ params . position . line ,
90+ params . position . character
3891 ) ;
3992
93+ const peekLocations = params . locations . map (
94+ location =>
95+ new vscode . Location (
96+ client . protocol2CodeConverter . asUri ( location ) ,
97+ new vscode . Position ( 0 , 0 )
98+ )
99+ ) ;
100+
101+ openPeekedEditorIn ( peekURI , peekPosition , peekLocations ) ;
102+
40103 return { success : true } ;
41104 }
42105 ) ;
0 commit comments