@@ -16,27 +16,88 @@ import * as vscode from "vscode";
16
16
import * as langclient from "vscode-languageclient/node" ;
17
17
import { PeekDocumentsParams , PeekDocumentsRequest } from "./lspExtensions" ;
18
18
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
+
19
80
export function activatePeekDocuments ( client : langclient . LanguageClient ) : vscode . Disposable {
20
81
const peekDocuments = client . onRequest (
21
82
PeekDocumentsRequest . method ,
22
83
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
38
89
) ;
39
90
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
+
40
101
return { success : true } ;
41
102
}
42
103
) ;
0 commit comments