diff --git a/app/src/ui/changes/changes-list.tsx b/app/src/ui/changes/changes-list.tsx index a7e0869605e..9970ca7b233 100644 --- a/app/src/ui/changes/changes-list.tsx +++ b/app/src/ui/changes/changes-list.tsx @@ -27,6 +27,8 @@ import { RevealInFileManagerLabel, OpenWithDefaultProgramLabel, CopyRelativeFilePathLabel, + CopySelectedPathsLabel, + CopySelectedRelativePathsLabel, } from '../lib/context-menu' import { CommitMessage } from './commit-message' import { ChangedFile } from './changed-file' @@ -51,6 +53,7 @@ import { hasConflictedFiles } from '../../lib/status' import { createObservableRef } from '../lib/observable-ref' import { Tooltip, TooltipDirection } from '../lib/tooltip' import { Popup } from '../../models/popup' +import { EOL } from 'os' const RowHeight = 29 const StashIcon: OcticonSymbol.OcticonSymbolType = { @@ -426,6 +429,32 @@ export class ChangesList extends React.Component< } } + private getCopySelectedPathsMenuItem = ( + files: WorkingDirectoryFileChange[] + ): IMenuItem => { + return { + label: CopySelectedPathsLabel, + action: () => { + const fullPaths = files.map(file => + Path.join(this.props.repository.path, file.path) + ) + clipboard.writeText(fullPaths.join(EOL)) + }, + } + } + + private getCopySelectedRelativePathsMenuItem = ( + files: WorkingDirectoryFileChange[] + ): IMenuItem => { + return { + label: CopySelectedRelativePathsLabel, + action: () => { + const paths = files.map(file => Path.normalize(file.path)) + clipboard.writeText(paths.join(EOL)) + }, + } + } + private getRevealInFileManagerMenuItem = ( file: WorkingDirectoryFileChange ): IMenuItem => { @@ -556,15 +585,21 @@ export class ChangesList extends React.Component< this.props.onIncludeChanged(file.path, false) ) }, - } + }, + { type: 'separator' }, + this.getCopySelectedPathsMenuItem(selectedFiles), + this.getCopySelectedRelativePathsMenuItem(selectedFiles) + ) + } else { + items.push( + { type: 'separator' }, + this.getCopyPathMenuItem(file), + this.getCopyRelativePathMenuItem(file) ) } const enabled = status.kind !== AppFileStatusKind.Deleted items.push( - { type: 'separator' }, - this.getCopyPathMenuItem(file), - this.getCopyRelativePathMenuItem(file), { type: 'separator' }, this.getRevealInFileManagerMenuItem(file), this.getOpenInExternalEditorMenuItem(file, enabled), diff --git a/app/src/ui/lib/context-menu.ts b/app/src/ui/lib/context-menu.ts index c92d86aee3a..6f96ecb139d 100644 --- a/app/src/ui/lib/context-menu.ts +++ b/app/src/ui/lib/context-menu.ts @@ -7,6 +7,12 @@ export const CopyRelativeFilePathLabel = __DARWIN__ ? 'Copy Relative File Path' : 'Copy relative file path' +export const CopySelectedPathsLabel = __DARWIN__ ? 'Copy Paths' : 'Copy paths' + +export const CopySelectedRelativePathsLabel = __DARWIN__ + ? 'Copy Relative Paths' + : 'Copy relative paths' + export const DefaultEditorLabel = __DARWIN__ ? 'Open in External Editor' : 'Open in external editor'