You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
3.2 KiB

  1. 'use strict';
  2. import { ConfigurationChangeEvent, Disposable, languages } from 'vscode';
  3. import { configuration } from '../configuration';
  4. import { ContextKeys, setContext } from '../constants';
  5. import { Container } from '../container';
  6. import { Logger } from '../logger';
  7. import {
  8. DocumentBlameStateChangeEvent,
  9. DocumentDirtyIdleTriggerEvent,
  10. GitDocumentState,
  11. } from '../trackers/gitDocumentTracker';
  12. import { GitCodeLensProvider } from './codeLensProvider';
  13. export class GitCodeLensController implements Disposable {
  14. private _canToggle: boolean = false;
  15. private _disposable: Disposable | undefined;
  16. private _provider: GitCodeLensProvider | undefined;
  17. private _providerDisposable: Disposable | undefined;
  18. constructor(private readonly container: Container) {
  19. this._disposable = Disposable.from(
  20. container.onReady(this.onReady, this),
  21. configuration.onDidChange(this.onConfigurationChanged, this),
  22. );
  23. }
  24. dispose() {
  25. this._providerDisposable?.dispose();
  26. this._disposable?.dispose();
  27. }
  28. private onReady(): void {
  29. this.onConfigurationChanged();
  30. }
  31. private onConfigurationChanged(e?: ConfigurationChangeEvent) {
  32. if (
  33. configuration.changed(e, 'codeLens') ||
  34. configuration.changed(e, 'defaultDateFormat') ||
  35. configuration.changed(e, 'defaultDateSource') ||
  36. configuration.changed(e, 'defaultDateStyle')
  37. ) {
  38. if (e != null) {
  39. Logger.log('CodeLens config changed; resetting CodeLens provider');
  40. }
  41. const cfg = this.container.config.codeLens;
  42. if (cfg.enabled && (cfg.recentChange.enabled || cfg.authors.enabled)) {
  43. this.ensureProvider();
  44. } else {
  45. this._providerDisposable?.dispose();
  46. this._provider = undefined;
  47. }
  48. this._canToggle = cfg.recentChange.enabled || cfg.authors.enabled;
  49. void setContext(ContextKeys.DisabledToggleCodeLens, !this._canToggle);
  50. }
  51. }
  52. private onBlameStateChanged(e: DocumentBlameStateChangeEvent<GitDocumentState>) {
  53. // Only reset if we have saved, since the CodeLens won't naturally be re-rendered
  54. if (this._provider === undefined || !e.blameable) return;
  55. Logger.log('Blame state changed; resetting CodeLens provider');
  56. this._provider.reset('saved');
  57. }
  58. private onDirtyIdleTriggered(e: DocumentDirtyIdleTriggerEvent<GitDocumentState>) {
  59. if (this._provider === undefined || !e.document.isBlameable) return;
  60. const maxLines = this.container.config.advanced.blame.sizeThresholdAfterEdit;
  61. if (maxLines > 0 && e.document.lineCount > maxLines) return;
  62. Logger.log('Dirty idle triggered; resetting CodeLens provider');
  63. this._provider.reset('idle');
  64. }
  65. toggleCodeLens() {
  66. if (!this._canToggle) return;
  67. Logger.log('toggleCodeLens()');
  68. if (this._provider !== undefined) {
  69. this._providerDisposable?.dispose();
  70. this._provider = undefined;
  71. return;
  72. }
  73. this.ensureProvider();
  74. }
  75. private ensureProvider() {
  76. if (this._provider !== undefined) {
  77. this._provider.reset();
  78. return;
  79. }
  80. this._providerDisposable?.dispose();
  81. this._provider = new GitCodeLensProvider(this.container);
  82. this._providerDisposable = Disposable.from(
  83. languages.registerCodeLensProvider(GitCodeLensProvider.selector, this._provider),
  84. this.container.tracker.onDidChangeBlameState(this.onBlameStateChanged, this),
  85. this.container.tracker.onDidTriggerDirtyIdle(this.onDirtyIdleTriggered, this),
  86. );
  87. }
  88. }