<commit_before>import * as vscode from 'vscode'
import * as cp from 'child_process'
import * as path from 'path'
import * as fs from 'fs'
import * as os from 'os'

import { Extension } from '../main'

const fullRange = doc => doc.validateRange(new vscode.Range(0, 0, Number.MAX_VALUE, Number.MAX_VALUE))

export class OperatingSystem {
    public name
    public fileExt
    public checker

    constructor(name: string, fileExt: string, checker: string) {
        this.name = name
        this.fileExt = fileExt
        this.checker = checker
    }
}

const windows: OperatingSystem = new OperatingSystem('win32', '.exe', 'where')
const linux: OperatingSystem = new OperatingSystem('linux', '.pl', 'which')
const mac: OperatingSystem = new OperatingSystem('darwin', '.pl', 'which')

export class LaTexFormatter {
    private extension: Extension
    private machineOs: string
    private currentOs: OperatingSystem
    private formatter: string

    constructor(extension: Extension) {
        this.extension = extension
        this.machineOs = os.platform()
        this.formatter = 'latexindent'
    }

    public formatDocument(document: vscode.TextDocument) : Thenable<vscode.TextEdit[]> {
        return new Promise((resolve, _reject) => {
            const filename = document.fileName

            if (this.machineOs === windows.name) {
                this.currentOs = windows
            } else if (this.machineOs === linux.name) {
                this.currentOs = linux
            }  else if (this.machineOs === mac.name) {
                this.currentOs = mac
            }

            this.checkPath(this.currentOs.checker).then((latexindentPresent) => {
                if (!latexindentPresent) {
                    this.extension.logger.addLogMessage('Can not find latexindent in PATH!')
                    vscode.window.showErrorMessage('Can not find latexindent in PATH!')
                    return resolve()
                }
                this.format(filename, document).then((edit) => {
                    return resolve(edit)
                })

            })
        })
    }

    private checkPath(checker: string) : Thenable<boolean> {
        return new Promise((resolve, _reject) => {
            cp.exec(checker + ' ' + this.formatter, (_err, stdout, _stderr) => {
                if (stdout === '') {
                    this.formatter += this.currentOs.fileExt
                    this.checkPath(checker).then((res) => {
                        if (res) {
                            resolve(true)
                        } else {
                            resolve(false)
                        }
                    })
                }
                resolve(true)
            })
        })

    }

    private format(filename: string, document: vscode.TextDocument) : Thenable<vscode.TextEdit[]> {
        return new Promise((resolve, _reject) => {
            cp.exec(this.formatter + ' "' + filename + '"', (_err, stdout, _stderr) => {
                if (stdout !== '') {
                    const edit = [vscode.TextEdit.replace(fullRange(document), stdout)]
                    try {
                        fs.unlinkSync(path.dirname(filename) + path.sep + 'indent.log')
                    } catch (ignored) {
                    }
                    return resolve(edit)
                }
                return resolve()<commit_msg>Respect tab / space workspace settings<commit_after>import * as vscode from 'vscode'
import * as cp from 'child_process'
import * as path from 'path'
import * as fs from 'fs'
import * as os from 'os'

import { Extension } from '../main'

const fullRange = doc => doc.validateRange(new vscode.Range(0, 0, Number.MAX_VALUE, Number.MAX_VALUE))

export class OperatingSystem {
    public name
    public fileExt
    public checker

    constructor(name: string, fileExt: string, checker: string) {
        this.name = name
        this.fileExt = fileExt
        this.checker = checker
    }
}

const windows: OperatingSystem = new OperatingSystem('win32', '.exe', 'where')
const linux: OperatingSystem = new OperatingSystem('linux', '.pl', 'which')
const mac: OperatingSystem = new OperatingSystem('darwin', '.pl', 'which')

export class LaTexFormatter {
    private extension: Extension
    private machineOs: string
    private currentOs: OperatingSystem
    private formatter: string

    constructor(extension: Extension) {
        this.extension = extension
        this.machineOs = os.platform()
        this.formatter = 'latexindent'
    }

    public formatDocument(document: vscode.TextDocument) : Thenable<vscode.TextEdit[]> {
        return new Promise((resolve, _reject) => {
            const filename = document.fileName

            if (this.machineOs === windows.name) {
                this.currentOs = windows
            } else if (this.machineOs === linux.name) {
                this.currentOs = linux
            }  else if (this.machineOs === mac.name) {
                this.currentOs = mac
            }

            this.checkPath(this.currentOs.checker).then((latexindentPresent) => {
                if (!latexindentPresent) {
                    this.extension.logger.addLogMessage('Can not find latexindent in PATH!')
                    vscode.window.showErrorMessage('Can not find latexindent in PATH!')
                    return resolve()
                }
                this.format(filename, document).then((edit) => {
                    return resolve(edit)
                })

            })
        })
    }

    private checkPath(checker: string) : Thenable<boolean> {
        return new Promise((resolve, _reject) => {
            cp.exec(checker + ' ' + this.formatter, (_err, stdout, _stderr) => {
                if (stdout === '') {
                    this.formatter += this.currentOs.fileExt
                    this.checkPath(checker).then((res) => {
                        if (res) {
                            resolve(true)
                        } else {
                            resolve(false)
                        }
                    })
                }
                resolve(true)
            })
        })

    }

    private format(filename: string, document: vscode.TextDocument) : Thenable<vscode.TextEdit[]> {
        return new Promise((resolve, _reject) => {
            const configuration = vscode.workspace.getConfiguration('editor', document.uri)
            const useSpaces = configuration.get<boolean>('insertSpaces')
            const tabSize = configuration.get<number>('tabSize') || 4
            const indent = useSpaces ? ' '.repeat(tabSize) : '\\t'

            cp.exec(this.formatter + ' "' + filename + '"' + ' -y="defaultIndent: \'' + indent + '\'"',
             (_err, stdout, _stderr) => {
                if (stdout !== '') {
                    const edit = [vscode.TextEdit.replace(fullRange(document), stdout)]
                    try {
                        fs.unlinkSync(path.dirname(filename) + path.sep + 'indent.log')
                    } catch (ignored) {
                    }
                    return resolve(edit)
                }
                return resolve()
{'fraction_non_alphanumeric': 0.11283340315598381, 'fraction_numerical': 0.0012568077084206116, 'mean_word_length': 1.7440613026819924, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '948889', 'n_tokens_mistral': 1938, 'n_tokens_neox': 1818, 'n_words': 433}