• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pascalre / vscode-yaml-sort / 3934113253

pending completion
3934113253

push

github

GitHub
Merge pull request #115 from pascalre/refactor

141 of 172 branches covered (81.98%)

Branch coverage included in aggregate %.

188 of 188 new or added lines in 8 files covered. (100.0%)

400 of 427 relevant lines covered (93.68%)

19.72 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.33
/src/controller.ts
1
import { TextEditor, TextEdit, Uri, window } from "vscode"
1✔
2
import { JsYamlAdapter } from "./adapter/js-yaml-adapter"
1✔
3
import { Severity, VsCodeAdapter } from "./adapter/vs-code-adapter"
1✔
4
import { prependWhitespacesOnEachLine, removeLeadingLineBreakOfFirstElement } from "./lib"
1✔
5
import { Settings } from "./settings"
1✔
6
import { FileUtil } from "./util/file-util"
1✔
7
import { getDelimiters, splitYaml, validateTextRange, YamlUtil } from "./util/yaml-util"
1✔
8

9
const settings = new Settings()
1✔
10
const jsyamladapter = new JsYamlAdapter()
1✔
11
const outterVscodeadapter = new VsCodeAdapter()
1✔
12
const yamlutil = new YamlUtil()
1✔
13

14
export class Controller {
1✔
15
  editor: TextEditor | undefined
16
  fileutil: FileUtil
17
  vscodeadapter: VsCodeAdapter
18

19
  constructor(fileutil = new FileUtil(), vscodeadapter = new VsCodeAdapter()) {
6✔
20
    this.editor = window.activeTextEditor
3✔
21
    this.fileutil = fileutil
3✔
22
    this.vscodeadapter = vscodeadapter
3✔
23
  }
24

25
  validateYamlWrapper(): boolean {
26
    if (this.editor) {
2!
27
      const text = VsCodeAdapter.getActiveDocument(this.editor)
2✔
28
      try {
2✔
29
        jsyamladapter.validateYaml(text)
2✔
30
        this.vscodeadapter.showMessage(Severity.INFO, "YAML is valid.")
2✔
31
        return true
2✔
32
      } catch (e) {
33
        if (e instanceof Error) {
×
34
          this.vscodeadapter.showMessage(Severity.INFO, `YAML is invalid. ${e.message}`)
×
35
        }
36
      }
37
    }
38
    return false
×
39
  }
40

41
  /**
42
   * Sorts all yaml files in a directory
43
   * @param {Uri} uri Base URI
44
   */
45
  sortYamlFiles(uri: Uri) {
46
    const files = this.fileutil.getFiles(uri.fsPath)
1✔
47
    files.forEach((file: string) => {
1✔
48
      this.sortFile(file)
2✔
49
    })
50
  }
51

52
  sortFile(file: string) {
53
    try {
2✔
54
      this.fileutil.sortFile(file)
2✔
55
    } catch (e) {
56
      if (e instanceof Error) {
×
57
        this.vscodeadapter.showMessage(Severity.ERROR, e.message)
×
58
      }
59
    }
60
  }
61
}
62

63
export function sortYamlWrapper(customSort = 0): TextEdit[] {
1✔
64
  const activeEditor = window.activeTextEditor
4✔
65

66
  if (activeEditor) {
4!
67
    const textRange = VsCodeAdapter.getRange(activeEditor)
4✔
68
    let text = VsCodeAdapter.getText(activeEditor, textRange)
4✔
69

70
    try {
4✔
71
      validateTextRange(text)
4✔
72
      jsyamladapter.validateYaml(text)
2✔
73
    } catch (e) {
74
      if (e instanceof Error) {
2!
75
        outterVscodeadapter.showMessage(Severity.ERROR, e.message)
2✔
76
      }
77
      return [] as TextEdit[]
2✔
78
    }
79

80
    let delimiters = getDelimiters(text, activeEditor.selection.isEmpty, settings.getUseLeadingDashes())
2✔
81
    // remove yaml metadata tags
82
    const matchMetadata = /^%.*\n/gm
2✔
83
    // set metadata tags, if there is no metadata tag it should be an emtpy array
84
    if (matchMetadata.test(text)) {
2!
85
      delimiters.shift()
×
86
      delimiters = removeLeadingLineBreakOfFirstElement(delimiters)
×
87
    }
88
    text = text.replace(matchMetadata, "")
2✔
89
    text = text.replace(/^\n/, "")
2✔
90

91
    // sort yaml
92
    let newText = ""
2✔
93
    splitYaml(text).forEach((unsortedYaml) => {
2✔
94
      let sortedYaml = yamlutil.sortYaml(unsortedYaml, customSort)
2✔
95
      if (sortedYaml) {
2!
96
        if (!activeEditor.selection.isEmpty) {
2✔
97
          // get number of leading whitespaces, these whitespaces will be used for indentation
98
          const indentation = YamlUtil.getNumberOfLeadingSpaces(unsortedYaml)
1✔
99
          sortedYaml = prependWhitespacesOnEachLine(sortedYaml, indentation)
1✔
100
        }
101
        newText += delimiters.shift() + sortedYaml
2✔
102
      } else {
103
        return [] as TextEdit[]
×
104
      }
105
    })
106
    if (activeEditor.selection.isEmpty && settings.getUseLeadingDashes()) {
2✔
107
      newText = `---\n${newText}`
1✔
108
    }
109
    outterVscodeadapter.showMessage(Severity.INFO, "Keys resorted successfully")
2✔
110
    return updateText(activeEditor, newText)
2✔
111
  }
112
  return [] as TextEdit[]
×
113
}
114

115
export function updateText(editor: TextEditor, text: string) {
1✔
116
  const edits = VsCodeAdapter.getEdits(editor, text)
4✔
117
  VsCodeAdapter.applyEdits([edits])
4✔
118
  return [edits]
4✔
119
}
120

121
export function formatYamlWrapper(): TextEdit[] {
1✔
122
  const activeEditor = window.activeTextEditor
2✔
123

124
  if (activeEditor) {
2!
125
    let doc = VsCodeAdapter.getActiveDocument(activeEditor)
2✔
126
    let delimiters = getDelimiters(doc, true, settings.getUseLeadingDashes())
2✔
127
    // remove yaml metadata tags
128
    const matchMetadata = /^%.*\n/gm
2✔
129
    // set metadata tags, if there is no metadata tag it should be an emtpy array
130
    if (matchMetadata.test(doc)) {
2!
131
      delimiters.shift()
×
132
      delimiters = removeLeadingLineBreakOfFirstElement(delimiters)
×
133
    }
134
    doc = doc.replace(matchMetadata, "")
2✔
135
    doc = doc.replace(/^\n/, "")
2✔
136

137
    let formattedYaml
138
    const yamls = splitYaml(doc)
2✔
139
    let newText = ""
2✔
140
    for (const unformattedYaml of yamls) {
2✔
141
      formattedYaml = yamlutil.formatYaml(unformattedYaml, false)
3✔
142
      if (formattedYaml) {
3!
143
        newText += delimiters.shift() + formattedYaml
3✔
144
      } else {
145
        return []
×
146
      }
147
    }
148
    if (settings.getUseLeadingDashes()) {
2!
149
      newText = `---\n${newText}`
2✔
150
    }
151
    return updateText(activeEditor, newText)
2✔
152
  }
153
  return []
×
154
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc