33 * Licensed under the MIT License. See License.txt in the project root for license information.
44 *--------------------------------------------------------------------------------------------*/
55
6+ import { basename } from 'path' ;
67import * as vscode from 'vscode' ;
78import { Remote } from '../api/api' ;
89import { GitApiImpl } from '../api/api1' ;
@@ -54,6 +55,7 @@ import { UserHoverProvider } from './userHoverProvider';
5455import {
5556 createGitHubLink ,
5657 createGithubPermalink ,
58+ createSinglePermalink ,
5759 getIssue ,
5860 IssueTemplate ,
5961 LinkContext ,
@@ -137,116 +139,116 @@ export class IssueFeatureRegistrar extends Disposable {
137139 this . _register (
138140 vscode . commands . registerCommand (
139141 'issue.copyGithubPermalink' ,
140- ( context : LinkContext ) => {
142+ ( context : LinkContext , additional : LinkContext [ ] | undefined ) => {
141143 /* __GDPR__
142144 "issue.copyGithubPermalink" : {}
143145 */
144146 this . telemetry . sendTelemetryEvent ( 'issue.copyGithubPermalink' ) ;
145- return this . copyPermalink ( this . manager , context ) ;
147+ return this . copyPermalink ( this . manager , additional && additional . length > 0 ? additional : [ context ] ) ;
146148 } ,
147149 this ,
148150 ) ,
149151 ) ;
150152 this . _register (
151153 vscode . commands . registerCommand (
152154 'issue.copyGithubHeadLink' ,
153- ( fileUri : any ) => {
155+ ( fileUri : vscode . Uri , additional : vscode . Uri [ ] | undefined ) => {
154156 /* __GDPR__
155157 "issue.copyGithubHeadLink" : {}
156158 */
157159 this . telemetry . sendTelemetryEvent ( 'issue.copyGithubHeadLink' ) ;
158- return this . copyHeadLink ( fileUri ) ;
160+ return this . copyHeadLink ( additional && additional . length > 0 ? additional : [ fileUri ] ) ;
159161 } ,
160162 this ,
161163 ) ,
162164 ) ;
163165 this . _register (
164166 vscode . commands . registerCommand (
165167 'issue.copyGithubPermalinkWithoutRange' ,
166- ( context : LinkContext ) => {
168+ ( context : LinkContext , additional : LinkContext [ ] | undefined ) => {
167169 /* __GDPR__
168170 "issue.copyGithubPermalinkWithoutRange" : {}
169171 */
170172 this . telemetry . sendTelemetryEvent ( 'issue.copyGithubPermalinkWithoutRange' ) ;
171- return this . copyPermalink ( this . manager , context , false ) ;
173+ return this . copyPermalink ( this . manager , additional && additional . length > 0 ? additional : [ context ] , false ) ;
172174 } ,
173175 this ,
174176 ) ,
175177 ) ;
176178 this . _register (
177179 vscode . commands . registerCommand (
178180 'issue.copyGithubHeadLinkWithoutRange' ,
179- ( fileUri : any ) => {
181+ ( fileUri : vscode . Uri , additional : vscode . Uri [ ] | undefined ) => {
180182 /* __GDPR__
181183 "issue.copyGithubHeadLinkWithoutRange" : {}
182184 */
183185 this . telemetry . sendTelemetryEvent ( 'issue.copyGithubHeadLinkWithoutRange' ) ;
184- return this . copyHeadLink ( fileUri , false ) ;
186+ return this . copyHeadLink ( additional && additional . length > 0 ? additional : [ fileUri ] , false ) ;
185187 } ,
186188 this ,
187189 ) ,
188190 ) ;
189191 this . _register (
190192 vscode . commands . registerCommand (
191193 'issue.copyGithubDevLinkWithoutRange' ,
192- ( context : LinkContext ) => {
194+ ( context : LinkContext , additional : LinkContext [ ] | undefined ) => {
193195 /* __GDPR__
194196 "issue.copyGithubDevLinkWithoutRange" : {}
195197 */
196198 this . telemetry . sendTelemetryEvent ( 'issue.copyGithubDevLinkWithoutRange' ) ;
197- return this . copyPermalink ( this . manager , context , false , true , true ) ;
199+ return this . copyPermalink ( this . manager , additional && additional . length > 0 ? additional : [ context ] , false , true , true ) ;
198200 } ,
199201 this ,
200202 ) ,
201203 ) ;
202204 this . _register (
203205 vscode . commands . registerCommand (
204206 'issue.copyGithubDevLink' ,
205- ( context : LinkContext ) => {
207+ ( context : LinkContext , additional : LinkContext [ ] | undefined ) => {
206208 /* __GDPR__
207209 "issue.copyGithubDevLink" : {}
208210 */
209211 this . telemetry . sendTelemetryEvent ( 'issue.copyGithubDevLink' ) ;
210- return this . copyPermalink ( this . manager , context , true , true , true ) ;
212+ return this . copyPermalink ( this . manager , additional && additional . length > 0 ? additional : [ context ] , true , true , true ) ;
211213 } ,
212214 this ,
213215 ) ,
214216 ) ;
215217 this . _register (
216218 vscode . commands . registerCommand (
217219 'issue.copyGithubDevLinkFile' ,
218- ( context : LinkContext ) => {
220+ ( context : LinkContext , additional : LinkContext [ ] | undefined ) => {
219221 /* __GDPR__
220222 "issue.copyGithubDevLinkFile" : {}
221223 */
222224 this . telemetry . sendTelemetryEvent ( 'issue.copyGithubDevLinkFile' ) ;
223- return this . copyPermalink ( this . manager , context , false , true , true ) ;
225+ return this . copyPermalink ( this . manager , additional && additional . length > 0 ? additional : [ context ] , false , true , true ) ;
224226 } ,
225227 this ,
226228 ) ,
227229 ) ;
228230 this . _register (
229231 vscode . commands . registerCommand (
230232 'issue.copyMarkdownGithubPermalink' ,
231- ( context : LinkContext ) => {
233+ ( context : LinkContext , additional : LinkContext [ ] | undefined ) => {
232234 /* __GDPR__
233235 "issue.copyMarkdownGithubPermalink" : {}
234236 */
235237 this . telemetry . sendTelemetryEvent ( 'issue.copyMarkdownGithubPermalink' ) ;
236- return this . copyMarkdownPermalink ( this . manager , context ) ;
238+ return this . copyMarkdownPermalink ( this . manager , additional && additional . length > 0 ? additional : [ context ] ) ;
237239 } ,
238240 this ,
239241 ) ,
240242 ) ;
241243 this . _register (
242244 vscode . commands . registerCommand (
243245 'issue.copyMarkdownGithubPermalinkWithoutRange' ,
244- ( context : LinkContext ) => {
246+ ( context : LinkContext , additional : LinkContext [ ] | undefined ) => {
245247 /* __GDPR__
246248 "issue.copyMarkdownGithubPermalinkWithoutRange" : {}
247249 */
248250 this . telemetry . sendTelemetryEvent ( 'issue.copyMarkdownGithubPermalinkWithoutRange' ) ;
249- return this . copyMarkdownPermalink ( this . manager , context , false ) ;
251+ return this . copyMarkdownPermalink ( this . manager , additional && additional . length > 0 ? additional : [ context ] , false ) ;
250252 } ,
251253 this ,
252254 ) ,
@@ -949,7 +951,7 @@ export class IssueFeatureRegistrar extends Disposable {
949951 }
950952 }
951953
952- contents += ( await createGithubPermalink ( this . manager , this . gitAPI , true , true , newIssue ) ) . permalink ;
954+ contents += ( await createSinglePermalink ( this . manager , this . gitAPI , true , true , newIssue ) ) . permalink ;
953955 return contents ;
954956 }
955957
@@ -1293,7 +1295,7 @@ ${options?.body ?? ''}\n
12931295 const body : string | undefined =
12941296 issueBody || newIssue ?. document . isUntitled
12951297 ? issueBody
1296- : ( await createGithubPermalink ( this . manager , this . gitAPI , true , true , newIssue ) ) . permalink ;
1298+ : ( await createSinglePermalink ( this . manager , this . gitAPI , true , true , newIssue ) ) . permalink ;
12971299 const createParams : OctokitCommon . IssuesCreateParams = {
12981300 owner : origin . owner ,
12991301 repo : origin . repo ,
@@ -1343,20 +1345,24 @@ ${options?.body ?? ''}\n
13431345 } ) ;
13441346 }
13451347
1346- private async getPermalinkWithError ( repositoriesManager : RepositoriesManager , includeRange : boolean , includeFile : boolean , context ?: LinkContext ) : Promise < PermalinkInfo > {
1347- const link = await createGithubPermalink ( repositoriesManager , this . gitAPI , includeRange , includeFile , undefined , context ) ;
1348- if ( link . error ) {
1349- vscode . window . showWarningMessage ( vscode . l10n . t ( 'Unable to create a GitHub permalink for the selection. {0}' , link . error ) ) ;
1348+ private async getPermalinkWithError ( repositoriesManager : RepositoriesManager , includeRange : boolean , includeFile : boolean , context ?: LinkContext [ ] ) : Promise < PermalinkInfo [ ] > {
1349+ const links = await createGithubPermalink ( repositoriesManager , this . gitAPI , includeRange , includeFile , undefined , context ) ;
1350+ const firstError = links . find ( link => link . error ) ;
1351+ if ( firstError ) {
1352+ vscode . window . showWarningMessage ( vscode . l10n . t ( 'Unable to create a GitHub permalink for the selection. {0}' , firstError . error ! ) ) ;
13501353 }
1351- return link ;
1354+ return links ;
13521355 }
13531356
1354- private async getHeadLinkWithError ( context ?: vscode . Uri , includeRange ?: boolean ) : Promise < PermalinkInfo > {
1355- const link = await createGitHubLink ( this . manager , context , includeRange ) ;
1356- if ( link . error ) {
1357- vscode . window . showWarningMessage ( vscode . l10n . t ( 'Unable to create a GitHub link for the selection. {0}' , link . error ) ) ;
1357+ private async getHeadLinkWithError ( context ?: vscode . Uri [ ] , includeRange ?: boolean ) : Promise < PermalinkInfo [ ] > {
1358+ const links = await createGitHubLink ( this . manager , context , includeRange ) ;
1359+ if ( links . length > 0 ) {
1360+ const firstError = links . find ( link => link . error ) ;
1361+ if ( firstError ) {
1362+ vscode . window . showWarningMessage ( vscode . l10n . t ( 'Unable to create a GitHub link for the selection. {0}' , firstError . error ! ) ) ;
1363+ }
13581364 }
1359- return link ;
1365+ return links ;
13601366 }
13611367
13621368 private async getContextualizedLink ( file : vscode . Uri , link : string ) : Promise < string > {
@@ -1376,19 +1382,30 @@ ${options?.body ?? ''}\n
13761382 return linkUri . with ( { authority, path : linkPath } ) . toString ( ) ;
13771383 }
13781384
1379- async copyPermalink ( repositoriesManager : RepositoriesManager , context ?: LinkContext , includeRange : boolean = true , includeFile : boolean = true , contextualizeLink : boolean = false ) {
1380- const link = await this . getPermalinkWithError ( repositoriesManager , includeRange , includeFile , context ) ;
1381- if ( link . permalink ) {
1382- const contextualizedLink = contextualizeLink && link . originalFile ? await this . getContextualizedLink ( link . originalFile , link . permalink ) : link . permalink ;
1383- Logger . debug ( `writing ${ contextualizedLink } to the clipboard` , PERMALINK_COMPONENT ) ;
1384- return vscode . env . clipboard . writeText ( contextualizedLink ) ;
1385+ private async permalinkInfoToClipboardText ( links : PermalinkInfo [ ] , shouldContextualize : boolean = false ) : Promise < string | undefined > {
1386+ const withPermalinks : ( PermalinkInfo & { permalink : string } ) [ ] = links . filter ( ( link ) : link is PermalinkInfo & { permalink : string } => ! ! link . permalink ) ;
1387+ if ( withPermalinks . length !== 0 ) {
1388+ const contextualizedLinks = await Promise . all ( withPermalinks . map ( async link => ( shouldContextualize && link . originalFile ) ? await this . getContextualizedLink ( link . originalFile , link . permalink ) : link . permalink ) ) ;
1389+ const clipboardText = contextualizedLinks . join ( '\n' ) ;
1390+ Logger . debug ( `Will write ${ clipboardText } to the clipboard` , PERMALINK_COMPONENT ) ;
1391+ return clipboardText ;
1392+ }
1393+ return undefined ;
1394+ }
1395+
1396+ async copyPermalink ( repositoriesManager : RepositoriesManager , context ?: LinkContext [ ] , includeRange : boolean = true , includeFile : boolean = true , contextualizeLink : boolean = false ) {
1397+ const links = await this . getPermalinkWithError ( repositoriesManager , includeRange , includeFile , context ) ;
1398+ const clipboardText = await this . permalinkInfoToClipboardText ( links , contextualizeLink ) ;
1399+ if ( clipboardText ) {
1400+ return vscode . env . clipboard . writeText ( clipboardText ) ;
13851401 }
13861402 }
13871403
1388- async copyHeadLink ( fileUri ?: vscode . Uri , includeRange = true ) {
1404+ async copyHeadLink ( fileUri ?: vscode . Uri [ ] , includeRange = true ) {
13891405 const link = await this . getHeadLinkWithError ( fileUri , includeRange ) ;
1390- if ( link . permalink ) {
1391- return vscode . env . clipboard . writeText ( link . permalink ) ;
1406+ const clipboardText = await this . permalinkInfoToClipboardText ( link ) ;
1407+ if ( clipboardText ) {
1408+ return vscode . env . clipboard . writeText ( clipboardText ) ;
13921409 }
13931410 }
13941411
@@ -1414,18 +1431,27 @@ ${options?.body ?? ''}\n
14141431 return undefined ;
14151432 }
14161433
1417- async copyMarkdownPermalink ( repositoriesManager : RepositoriesManager , context : LinkContext , includeRange : boolean = true ) {
1418- const link = await this . getPermalinkWithError ( repositoriesManager , includeRange , true , context ) ;
1419- const selection = this . getMarkdownLinkText ( ) ;
1420- if ( link . permalink && selection ) {
1421- return vscode . env . clipboard . writeText ( `[${ selection . trim ( ) } ](${ link . permalink } )` ) ;
1434+ async copyMarkdownPermalink ( repositoriesManager : RepositoriesManager , context : LinkContext [ ] , includeRange : boolean = true ) {
1435+ const links = await this . getPermalinkWithError ( repositoriesManager , includeRange , true , context ) ;
1436+ const withPermalinks : ( PermalinkInfo & { permalink : string } ) [ ] = links . filter ( ( link ) : link is PermalinkInfo & { permalink : string } => ! ! link . permalink ) ;
1437+
1438+ if ( withPermalinks . length === 1 ) {
1439+ const selection = this . getMarkdownLinkText ( ) ;
1440+ if ( selection ) {
1441+ return vscode . env . clipboard . writeText ( `[${ selection . trim ( ) } ](${ withPermalinks [ 0 ] . permalink } )` ) ;
1442+ }
14221443 }
1444+ const clipboardText = withPermalinks . map ( link => `[${ basename ( link . originalFile ?. fsPath ?? '' ) } ](${ link . permalink } )` ) . join ( '\n' ) ;
1445+ Logger . debug ( `writing ${ clipboardText } to the clipboard` , PERMALINK_COMPONENT ) ;
1446+ return vscode . env . clipboard . writeText ( clipboardText ) ;
14231447 }
14241448
14251449 async openPermalink ( repositoriesManager : RepositoriesManager ) {
1426- const link = await this . getPermalinkWithError ( repositoriesManager , true , true ) ;
1427- if ( link . permalink ) {
1428- return vscode . env . openExternal ( vscode . Uri . parse ( link . permalink ) ) ;
1450+ const links = await this . getPermalinkWithError ( repositoriesManager , true , true ) ;
1451+ const withPermalinks : ( PermalinkInfo & { permalink : string } ) [ ] = links . filter ( ( link ) : link is PermalinkInfo & { permalink : string } => ! ! link . permalink ) ;
1452+
1453+ if ( withPermalinks . length > 0 ) {
1454+ return vscode . env . openExternal ( vscode . Uri . parse ( withPermalinks [ 0 ] . permalink ) ) ;
14291455 }
14301456 return undefined ;
14311457 }
0 commit comments