您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

156 行
5.0 KiB

  1. 'use strict';
  2. import { commands, ConfigurationChangeEvent } from 'vscode';
  3. import { configuration, FileHistoryViewConfig } from '../configuration';
  4. import { CommandContext, setCommandContext } from '../constants';
  5. import { Container } from '../container';
  6. import { GitUri } from '../git/gitUri';
  7. import { FileHistoryTrackerNode, LineHistoryTrackerNode } from './nodes';
  8. import { ViewBase } from './viewBase';
  9. const pinnedSuffix = ' (pinned)';
  10. export class FileHistoryView extends ViewBase<FileHistoryTrackerNode | LineHistoryTrackerNode, FileHistoryViewConfig> {
  11. protected readonly configKey = 'fileHistory';
  12. protected readonly showCollapseAll = false;
  13. constructor() {
  14. super('gitlens.views.fileHistory', 'File History');
  15. }
  16. getRoot(): LineHistoryTrackerNode | FileHistoryTrackerNode {
  17. return this._followCursor ? new LineHistoryTrackerNode(this) : new FileHistoryTrackerNode(this);
  18. }
  19. protected registerCommands() {
  20. void Container.viewCommands;
  21. commands.registerCommand(
  22. this.getQualifiedCommand('copy'),
  23. () => commands.executeCommand('gitlens.views.copy', this.selection),
  24. this,
  25. );
  26. commands.registerCommand(this.getQualifiedCommand('refresh'), () => this.refresh(true), this);
  27. commands.registerCommand(this.getQualifiedCommand('changeBase'), () => this.changeBase(), this);
  28. commands.registerCommand(
  29. this.getQualifiedCommand('setCursorFollowingOn'),
  30. () => this.setCursorFollowing(true),
  31. this,
  32. );
  33. commands.registerCommand(
  34. this.getQualifiedCommand('setCursorFollowingOff'),
  35. () => this.setCursorFollowing(false),
  36. this,
  37. );
  38. commands.registerCommand(
  39. this.getQualifiedCommand('setEditorFollowingOn'),
  40. () => this.setEditorFollowing(true),
  41. this,
  42. );
  43. commands.registerCommand(
  44. this.getQualifiedCommand('setEditorFollowingOff'),
  45. () => this.setEditorFollowing(false),
  46. this,
  47. );
  48. commands.registerCommand(
  49. this.getQualifiedCommand('setRenameFollowingOn'),
  50. () => this.setRenameFollowing(true),
  51. this,
  52. );
  53. commands.registerCommand(
  54. this.getQualifiedCommand('setRenameFollowingOff'),
  55. () => this.setRenameFollowing(false),
  56. this,
  57. );
  58. commands.registerCommand(
  59. this.getQualifiedCommand('setShowAllBranchesOn'),
  60. () => this.setShowAllBranches(true),
  61. this,
  62. );
  63. commands.registerCommand(
  64. this.getQualifiedCommand('setShowAllBranchesOff'),
  65. () => this.setShowAllBranches(false),
  66. this,
  67. );
  68. commands.registerCommand(this.getQualifiedCommand('setShowAvatarsOn'), () => this.setShowAvatars(true), this);
  69. commands.registerCommand(this.getQualifiedCommand('setShowAvatarsOff'), () => this.setShowAvatars(false), this);
  70. }
  71. protected filterConfigurationChanged(e: ConfigurationChangeEvent) {
  72. const changed = super.filterConfigurationChanged(e);
  73. if (
  74. !changed &&
  75. !configuration.changed(e, 'defaultDateFormat') &&
  76. !configuration.changed(e, 'defaultDateSource') &&
  77. !configuration.changed(e, 'defaultDateStyle') &&
  78. !configuration.changed(e, 'defaultGravatarsStyle') &&
  79. !configuration.changed(e, 'advanced', 'fileHistoryFollowsRenames') &&
  80. !configuration.changed(e, 'advanced', 'fileHistoryShowAllBranches')
  81. ) {
  82. return false;
  83. }
  84. return true;
  85. }
  86. protected initialize(options: { showCollapseAll?: boolean } = {}) {
  87. super.initialize(options);
  88. void setCommandContext(CommandContext.ViewsFileHistoryEditorFollowing, this._followEditor);
  89. void setCommandContext(CommandContext.ViewsFileHistoryCursorFollowing, this._followCursor);
  90. }
  91. async showHistoryForUri(uri: GitUri, baseRef?: string) {
  92. this.setCursorFollowing(false);
  93. this.setEditorFollowing(false);
  94. const root = this.ensureRoot(true);
  95. if (root instanceof FileHistoryTrackerNode) {
  96. await root.showHistoryForUri(uri, baseRef);
  97. }
  98. return this.show();
  99. }
  100. private changeBase() {
  101. void this.root?.changeBase();
  102. }
  103. private _followCursor: boolean = false;
  104. private setCursorFollowing(enabled: boolean) {
  105. this._followCursor = enabled;
  106. void setCommandContext(CommandContext.ViewsFileHistoryCursorFollowing, enabled);
  107. this.title = this._followCursor ? 'Line History' : 'File History';
  108. const root = this.ensureRoot(true);
  109. root.setEditorFollowing(this._followEditor);
  110. void root.ensureSubscription();
  111. void this.refresh(true);
  112. }
  113. private _followEditor: boolean = true;
  114. private setEditorFollowing(enabled: boolean) {
  115. this._followEditor = enabled;
  116. void setCommandContext(CommandContext.ViewsFileHistoryEditorFollowing, enabled);
  117. this.root?.setEditorFollowing(enabled);
  118. if (this.description?.endsWith(pinnedSuffix)) {
  119. if (enabled) {
  120. this.description = this.description.substr(0, this.description.length - pinnedSuffix.length);
  121. }
  122. } else if (!enabled) {
  123. this.description += pinnedSuffix;
  124. }
  125. }
  126. private setRenameFollowing(enabled: boolean) {
  127. return configuration.updateEffective('advanced', 'fileHistoryFollowsRenames', enabled);
  128. }
  129. private setShowAllBranches(enabled: boolean) {
  130. return configuration.updateEffective('advanced', 'fileHistoryShowAllBranches', enabled);
  131. }
  132. private setShowAvatars(enabled: boolean) {
  133. return configuration.updateEffective('views', this.configKey, 'avatars', enabled);
  134. }
  135. }