@@ -16,27 +16,88 @@ 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+ new vscode . Position ( position . line , position . character !== 0 ? position . character - 1 : 1 ) ,
66+ [ new vscode . Location ( vscode . Uri . parse ( "" ) , new vscode . Position ( 0 , 0 ) ) ] ,
67+ "peek"
68+ ) ;
69+
70+ // Opens the actual peeked editor window
71+ await vscode . commands . executeCommand (
72+ "editor.action.peekLocations" ,
73+ uri ,
74+ position ,
75+ locations ,
76+ "peek"
77+ ) ;
78+ }
79+
1980export function activatePeekDocuments ( client : langclient . LanguageClient ) : vscode . Disposable {
2081 const peekDocuments = client . onRequest (
2182 PeekDocumentsRequest . method ,
2283 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"
84+ const peekURI = client . protocol2CodeConverter . asUri ( params . uri ) ;
85+
86+ const peekPosition = new vscode . Position (
87+ params . position . line ,
88+ params . position . character
3889 ) ;
3990
91+ const peekLocations = params . locations . map (
92+ location =>
93+ new vscode . Location (
94+ client . protocol2CodeConverter . asUri ( location ) ,
95+ new vscode . Position ( 0 , 0 )
96+ )
97+ ) ;
98+
99+ openPeekedEditorIn ( peekURI , peekPosition , peekLocations ) ;
100+
40101 return { success : true } ;
41102 }
42103 ) ;
0 commit comments