diff --git a/autoload/ale/util.vim b/autoload/ale/util.vim index 27517ef7..6c6f20b0 100644 --- a/autoload/ale/util.vim +++ b/autoload/ale/util.vim @@ -8,7 +8,7 @@ function! s:FindWrapperScript() abort if filereadable(l:path) if has('win32') - return l:path . '.bat' + return l:path . '.exe' endif return l:path diff --git a/stdin-wrapper.bat b/stdin-wrapper.bat deleted file mode 100644 index eca8d717..00000000 --- a/stdin-wrapper.bat +++ /dev/null @@ -1,22 +0,0 @@ -@echo off - -REM Get a unique directory name in the temporary directory -:loop -set "directory=%tmp%\ale_%RANDOM%" -if exist "%directory%" goto :loop - -REM Use a filename with the same file extension -mkdir "%directory%" -set filename="%directory%\file%1" - -REM Get all arguments after the first to run as a command -for /f "tokens=1,* delims= " %%a in ("%*") do set command_args=%%b - -REM Read all stdin data to the filename -more > "%filename%" - -REM Run the command on the file -%command_args% "%filename%" - -REM Delete the temporary directory -rmdir "%directory%" /s /q diff --git a/stdin-wrapper.exe b/stdin-wrapper.exe new file mode 100644 index 00000000..d79f6785 Binary files /dev/null and b/stdin-wrapper.exe differ diff --git a/stdin_wrapper.d b/stdin_wrapper.d new file mode 100644 index 00000000..8714bc2a --- /dev/null +++ b/stdin_wrapper.d @@ -0,0 +1,84 @@ +// Author: w0rp +// Description: This file provides a D program for implementing +// the stdin-wrapper on Windows. + +import std.algorithm; +import std.array; +import std.file; +import std.process; +import std.stdio; +import std.path; + +@safe +auto createTemporaryFilename(string fileExtension) { + import std.uuid; + + string filename; + + do { + const randomPart = randomUUID().toString.replace("-", "_"); + + filename = buildPath(tempDir(), "ale_" ~ randomPart ~ fileExtension); + } while (exists(filename)); + + return filename; +} + +@trusted +void readStdinToFile(ref File tempFile) { + stdin.byChunk(4096).copy(tempFile.lockingTextWriter()); +} + +// Expand program names like "csslint" to "csslint.cmd" +// D is not able to perform this kind of expanstion in spawnProcess +@safe +string expandedProgramName(string name) { + auto extArray = environment["PATHEXT"].split(";"); + + foreach(pathDir; environment["PATH"].split(";")) { + foreach(extension; extArray) { + const candidate = buildPath(pathDir, name ~ extension); + + if (exists(candidate)) { + return candidate; + } + } + } + + // We were given a full path for a program name, so use that. + if (exists(name)) { + return name; + } + + return ""; +} + +@trusted +int runLinterProgram(string[] args) { + const expandedName = expandedProgramName(args[0]); + + writeln(expandedName); + + if (expandedName) { + return wait(spawnProcess([expandedName] ~ args[1..$])); + } + + return 1; +} + +@safe +int main(string[] args) { + const filename = createTemporaryFilename(args[1]); + + auto tempFile = File(filename, "w"); + + scope(exit) { + tempFile.close(); + remove(filename); + } + + readStdinToFile(tempFile); + tempFile.close(); + + return runLinterProgram(args[2..$] ~ [filename]); +}