auto-select-file.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import _ from 'lodash'
  2. import type { Nullable } from '../../../../../types/utils'
  3. import type { FileDiff } from '../services/types/file'
  4. import type { FileOperation } from '../services/types/file-operation'
  5. import type { LoadedUpdate, Version } from '../services/types/update'
  6. import { fileFinalPathname } from './file-diff'
  7. type FileWithOps = {
  8. pathname: FileDiff['pathname']
  9. operation: FileOperation
  10. }
  11. function getFilesWithOps(
  12. files: FileDiff[],
  13. toV: Version,
  14. comparing: boolean,
  15. updateForToV: LoadedUpdate | undefined
  16. ): FileWithOps[] {
  17. if (toV && !comparing) {
  18. const filesWithOps: FileWithOps[] = []
  19. if (updateForToV) {
  20. for (const pathname of updateForToV.pathnames) {
  21. filesWithOps.push({
  22. pathname,
  23. operation: 'edited',
  24. })
  25. }
  26. for (const op of updateForToV.project_ops) {
  27. let fileWithOps: Nullable<FileWithOps> = null
  28. if (op.add) {
  29. fileWithOps = {
  30. pathname: op.add.pathname,
  31. operation: 'added',
  32. }
  33. } else if (op.remove) {
  34. fileWithOps = {
  35. pathname: op.remove.pathname,
  36. operation: 'removed',
  37. }
  38. } else if (op.rename) {
  39. fileWithOps = {
  40. pathname: op.rename.newPathname,
  41. operation: 'renamed',
  42. }
  43. }
  44. if (fileWithOps !== null) {
  45. filesWithOps.push(fileWithOps)
  46. }
  47. }
  48. }
  49. return filesWithOps
  50. } else {
  51. const filesWithOps = _.reduce(
  52. files,
  53. (curFilesWithOps, file) => {
  54. if ('operation' in file) {
  55. curFilesWithOps.push({
  56. pathname: file.pathname,
  57. operation: file.operation,
  58. })
  59. }
  60. return curFilesWithOps
  61. },
  62. <FileWithOps[]>[]
  63. )
  64. return filesWithOps
  65. }
  66. }
  67. const orderedOpTypes: FileOperation[] = [
  68. 'edited',
  69. 'added',
  70. 'renamed',
  71. 'removed',
  72. ]
  73. export function autoSelectFile(
  74. files: FileDiff[],
  75. toV: Version,
  76. comparing: boolean,
  77. updateForToV: LoadedUpdate | undefined
  78. ): FileDiff {
  79. let fileToSelect: Nullable<FileDiff> = null
  80. const filesWithOps = getFilesWithOps(files, toV, comparing, updateForToV)
  81. for (const opType of orderedOpTypes) {
  82. const fileWithMatchingOpType = _.find(filesWithOps, {
  83. operation: opType,
  84. })
  85. if (fileWithMatchingOpType != null) {
  86. fileToSelect =
  87. _.find(
  88. files,
  89. file => fileFinalPathname(file) === fileWithMatchingOpType.pathname
  90. ) ?? null
  91. break
  92. }
  93. }
  94. if (!fileToSelect) {
  95. const mainFile = _.find(files, function (file) {
  96. return /main\.tex$/.test(file.pathname)
  97. })
  98. if (mainFile) {
  99. fileToSelect = mainFile
  100. } else {
  101. const anyTeXFile = _.find(files, function (file) {
  102. return /\.tex$/.test(file.pathname)
  103. })
  104. if (anyTeXFile) {
  105. fileToSelect = anyTeXFile
  106. } else {
  107. fileToSelect = files[0]
  108. }
  109. }
  110. }
  111. return fileToSelect
  112. }