mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[terminal] IJPL-176779 Use EEL file system API for getting files instead of executing 'ls'
GitOrigin-RevId: 591cd542b344b5ea234110385f0a65f4d5ea00ef
This commit is contained in:
committed by
intellij-monorepo-bot
parent
da424e161f
commit
2dd1540154
+15
@@ -0,0 +1,15 @@
|
||||
package com.intellij.terminal.completion.spec
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Experimental
|
||||
@ApiStatus.NonExtendable
|
||||
interface ShellFileInfo {
|
||||
val name: String
|
||||
val type: Type
|
||||
|
||||
@ApiStatus.Experimental
|
||||
enum class Type {
|
||||
FILE, DIRECTORY, OTHER
|
||||
}
|
||||
}
|
||||
+5
@@ -27,6 +27,11 @@ interface ShellRuntimeContext {
|
||||
*/
|
||||
suspend fun runShellCommand(@Language("ShellScript") command: String): ShellCommandResult
|
||||
|
||||
/**
|
||||
* @param path absolute os-dependent path to the directory.
|
||||
*/
|
||||
suspend fun listDirectoryFiles(path: String): List<ShellFileInfo>
|
||||
|
||||
/**
|
||||
* Used to implement custom extensions of [ShellRuntimeContext].
|
||||
* See the extensions in this [file][org.jetbrains.plugins.terminal.block.completion.spec.getFileSuggestions]
|
||||
|
||||
+3
-1
@@ -15,9 +15,11 @@ import com.intellij.terminal.completion.spec.ShellCommandExecutor
|
||||
import com.intellij.terminal.completion.spec.ShellCommandResult
|
||||
import com.intellij.util.execution.ParametersListUtil
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
|
||||
internal class ShellCommandExecutorReworked(private val eelDescriptor: EelDescriptor) : ShellCommandExecutor {
|
||||
@ApiStatus.Internal
|
||||
class ShellCommandExecutorReworked(private val eelDescriptor: EelDescriptor) : ShellCommandExecutor {
|
||||
override suspend fun runShellCommand(directory: String, command: String): ShellCommandResult {
|
||||
val commandList = ParametersListUtil.parse(command)
|
||||
val commandName = commandList.firstOrNull() ?: return emptyResult()
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package com.intellij.terminal.frontend.completion
|
||||
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.platform.eel.EelDescriptor
|
||||
import com.intellij.platform.eel.fs.EelFileInfo
|
||||
import com.intellij.platform.eel.fs.listDirectoryWithAttrs
|
||||
import com.intellij.platform.eel.getOrNull
|
||||
import com.intellij.platform.eel.path.EelPath
|
||||
import com.intellij.platform.eel.path.EelPathException
|
||||
import com.intellij.terminal.completion.spec.ShellFileInfo
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.plugins.terminal.block.completion.spec.impl.ShellFileInfoImpl
|
||||
import org.jetbrains.plugins.terminal.block.completion.spec.impl.ShellFileSystemSupport
|
||||
|
||||
@ApiStatus.Internal
|
||||
class ShellFileSystemSupportImpl(private val eelDescriptor: EelDescriptor) : ShellFileSystemSupport {
|
||||
override suspend fun listDirectoryFiles(path: String): List<ShellFileInfo> {
|
||||
val eelPath = try {
|
||||
EelPath.parse(path, eelDescriptor)
|
||||
}
|
||||
catch (_: EelPathException) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
return try {
|
||||
val eelApi = eelDescriptor.toEelApi()
|
||||
val result = eelApi.fs.listDirectoryWithAttrs(eelPath).doNotResolve().eelIt()
|
||||
val files = result.getOrNull() ?: emptyList()
|
||||
files.map { (name, info) ->
|
||||
ShellFileInfoImpl(name, info.type.toShellFileType())
|
||||
}
|
||||
}
|
||||
catch (e: CancellationException) {
|
||||
throw e
|
||||
}
|
||||
catch (e: Exception) {
|
||||
LOG.error("Failed to get child files for path: $path", e)
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun EelFileInfo.Type.toShellFileType(): ShellFileInfo.Type {
|
||||
return when (this) {
|
||||
is EelFileInfo.Type.Regular -> ShellFileInfo.Type.FILE
|
||||
is EelFileInfo.Type.Directory -> ShellFileInfo.Type.DIRECTORY
|
||||
else -> ShellFileInfo.Type.OTHER
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOG = logger<ShellFileSystemSupportImpl>()
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -5,7 +5,6 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.platform.eel.EelDescriptor
|
||||
import com.intellij.terminal.completion.ShellRuntimeContextProvider
|
||||
import com.intellij.terminal.completion.spec.ShellRuntimeContext
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.plugins.terminal.block.completion.TerminalCompletionUtil.toShellName
|
||||
import org.jetbrains.plugins.terminal.block.completion.spec.IS_REWORKED_KEY
|
||||
import org.jetbrains.plugins.terminal.block.completion.spec.PROJECT_KEY
|
||||
@@ -19,6 +18,7 @@ internal class ShellRuntimeContextProviderReworkedImpl(
|
||||
eelDescriptor: EelDescriptor,
|
||||
) : ShellRuntimeContextProvider {
|
||||
private val shellCommandExecutor = ShellCommandExecutorReworked(eelDescriptor)
|
||||
private val fileSystemSupport = ShellFileSystemSupportImpl(eelDescriptor)
|
||||
|
||||
override fun getContext(typedPrefix: String): ShellRuntimeContext {
|
||||
return ShellRuntimeContextImpl(
|
||||
@@ -26,6 +26,7 @@ internal class ShellRuntimeContextProviderReworkedImpl(
|
||||
typedPrefix,
|
||||
ShellType.ZSH.toShellName(),
|
||||
shellCommandExecutor,
|
||||
fileSystemSupport,
|
||||
).apply {
|
||||
putUserData(PROJECT_KEY, project)
|
||||
putUserData(IS_REWORKED_KEY, true)
|
||||
|
||||
+5
-4
@@ -51,11 +51,12 @@ object ShellDataGenerators {
|
||||
replacementIndexDelta: Int = 0,
|
||||
): List<ShellCompletionSuggestion> {
|
||||
val path = getParentPath(pathPrefix)
|
||||
val files: List<String> = context.getChildFiles(path, onlyDirectories)
|
||||
val files: List<ShellFileInfo> = context.getChildFiles(path, onlyDirectories)
|
||||
val prefixReplacementIndex = path.length + (if (isStartWithQuote(context.typedPrefix)) 1 else 0) + replacementIndexDelta
|
||||
val suggestions = files.flatMap {
|
||||
val type = if (it.endsWith(File.separatorChar)) ShellSuggestionType.FOLDER else ShellSuggestionType.FILE
|
||||
val suggestion = ShellCompletionSuggestion(name = it, type = type, prefixReplacementIndex = prefixReplacementIndex)
|
||||
val type = if (it.type == ShellFileInfo.Type.DIRECTORY) ShellSuggestionType.FOLDER else ShellSuggestionType.FILE
|
||||
val name = it.name + if (type == ShellSuggestionType.FOLDER) File.separator else ""
|
||||
val suggestion = ShellCompletionSuggestion(name, type = type, prefixReplacementIndex = prefixReplacementIndex)
|
||||
if (type == ShellSuggestionType.FILE) {
|
||||
listOf(suggestion)
|
||||
}
|
||||
@@ -63,7 +64,7 @@ object ShellDataGenerators {
|
||||
// Directory suggestion has a trailing file separator, but suggestion without it is also valid.
|
||||
// It is needed for the parser to consider it as a valid suggestion and not mark it as something unknown.
|
||||
val hiddenSuggestion = ShellCompletionSuggestion(
|
||||
name = it.removeSuffix(File.separator),
|
||||
name = it.name,
|
||||
type = ShellSuggestionType.FOLDER,
|
||||
prefixReplacementIndex = prefixReplacementIndex,
|
||||
isHidden = true
|
||||
|
||||
+28
-16
@@ -5,10 +5,14 @@ import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.terminal.completion.spec.ShellFileInfo
|
||||
import com.intellij.terminal.completion.spec.ShellRuntimeContext
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.plugins.terminal.block.completion.spec.impl.ShellFileInfoImpl
|
||||
import org.jetbrains.plugins.terminal.block.session.ShellIntegrationFunctions.GET_DIRECTORY_FILES
|
||||
import java.io.File
|
||||
import java.nio.file.InvalidPathException
|
||||
import kotlin.io.path.Path
|
||||
|
||||
@get:ApiStatus.Experimental
|
||||
val ShellRuntimeContext.project: Project
|
||||
@@ -26,8 +30,8 @@ val IS_REWORKED_KEY: Key<Boolean> = Key.create("isReworked")
|
||||
|
||||
/**
|
||||
* Returns the list of [path] child file names.
|
||||
* [path] can be either an absolute path or relative path.
|
||||
* In case of relative path, it is related to [ShellRuntimeContext.currentDirectory].
|
||||
* [path] can be either an absolute path, relative path or home-relative path like `~/abc`.
|
||||
* In case of the relative path, it is related to [ShellRuntimeContext.currentDirectory].
|
||||
*
|
||||
* Use [ShellDataGenerators.getParentPath] utility to get the right [path] from the user typed prefix.
|
||||
*/
|
||||
@@ -35,7 +39,7 @@ val IS_REWORKED_KEY: Key<Boolean> = Key.create("isReworked")
|
||||
suspend fun ShellRuntimeContext.getChildFiles(
|
||||
path: String,
|
||||
onlyDirectories: Boolean = false,
|
||||
): List<String> {
|
||||
): List<ShellFileInfo> {
|
||||
if (isReworkedTerminal) {
|
||||
return getChildFilesReworked(path, onlyDirectories)
|
||||
}
|
||||
@@ -44,26 +48,30 @@ suspend fun ShellRuntimeContext.getChildFiles(
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun ShellRuntimeContext.getChildFilesReworked(path: String, onlyDirectories: Boolean): List<String> {
|
||||
private suspend fun ShellRuntimeContext.getChildFilesReworked(path: String, onlyDirectories: Boolean): List<ShellFileInfo> {
|
||||
check(isReworkedTerminal)
|
||||
|
||||
val adjustedPath = FileUtil.expandUserHome(path.ifEmpty { "." })
|
||||
val command = "ls -1ap $adjustedPath"
|
||||
val result = runShellCommand(command)
|
||||
if (result.exitCode != 0) {
|
||||
// it is a regular case: the user entered an invalid path
|
||||
val adjustedPath = FileUtil.expandUserHome(path)
|
||||
val absolutePath = try {
|
||||
val nioPath = Path(adjustedPath)
|
||||
if (nioPath.isAbsolute) {
|
||||
nioPath.toString()
|
||||
}
|
||||
else {
|
||||
Path(currentDirectory, path).toString()
|
||||
}
|
||||
}
|
||||
catch (_: InvalidPathException) {
|
||||
return emptyList()
|
||||
}
|
||||
val separator = File.separatorChar
|
||||
return result.output.splitToSequence("\n")
|
||||
.filter { it.isNotBlank() }
|
||||
.filter { !onlyDirectories || it.endsWith(separator) }
|
||||
// do not suggest './' and '../' choices, there is no need to show them in the completion popup.
|
||||
.filter { it != ".$separator" && it != "..$separator" }
|
||||
|
||||
val files = listDirectoryFiles(absolutePath)
|
||||
return files.asSequence()
|
||||
.filter { !onlyDirectories || it.type == ShellFileInfo.Type.DIRECTORY }
|
||||
.toList()
|
||||
}
|
||||
|
||||
private suspend fun ShellRuntimeContext.getChildFilesExp(path: String, onlyDirectories: Boolean): List<String> {
|
||||
private suspend fun ShellRuntimeContext.getChildFilesExp(path: String, onlyDirectories: Boolean): List<ShellFileInfo> {
|
||||
check(!isReworkedTerminal)
|
||||
|
||||
val adjustedPath = path.ifEmpty { "." }
|
||||
@@ -79,5 +87,9 @@ private suspend fun ShellRuntimeContext.getChildFilesExp(path: String, onlyDirec
|
||||
.filter { !onlyDirectories || it.endsWith(separator) }
|
||||
// do not suggest './' and '../' directories if the user already typed some path
|
||||
.filter { path.isEmpty() || (it != ".$separator" && it != "..$separator") }
|
||||
.map {
|
||||
val type = if (it.endsWith(separator)) ShellFileInfo.Type.DIRECTORY else ShellFileInfo.Type.FILE
|
||||
ShellFileInfoImpl(it.removeSuffix(separator.toString()), type)
|
||||
}
|
||||
.toList()
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.plugins.terminal.block.completion.spec.impl
|
||||
|
||||
import com.intellij.terminal.completion.spec.ShellFileInfo
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Internal
|
||||
data class ShellFileInfoImpl(
|
||||
override val name: String,
|
||||
override val type: ShellFileInfo.Type,
|
||||
) : ShellFileInfo
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.plugins.terminal.block.completion.spec.impl
|
||||
|
||||
import com.intellij.terminal.completion.spec.ShellFileInfo
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Internal
|
||||
interface ShellFileSystemSupport {
|
||||
/**
|
||||
* @param path absolute os-dependent path to the directory.
|
||||
*/
|
||||
suspend fun listDirectoryFiles(path: String): List<ShellFileInfo>
|
||||
}
|
||||
+7
-4
@@ -2,10 +2,7 @@
|
||||
package org.jetbrains.plugins.terminal.block.completion.spec.impl
|
||||
|
||||
import com.intellij.openapi.util.UserDataHolderBase
|
||||
import com.intellij.terminal.completion.spec.ShellCommandExecutor
|
||||
import com.intellij.terminal.completion.spec.ShellCommandResult
|
||||
import com.intellij.terminal.completion.spec.ShellName
|
||||
import com.intellij.terminal.completion.spec.ShellRuntimeContext
|
||||
import com.intellij.terminal.completion.spec.*
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Internal
|
||||
@@ -14,12 +11,18 @@ class ShellRuntimeContextImpl(
|
||||
override val typedPrefix: String,
|
||||
override val shellName: ShellName,
|
||||
private val generatorCommandsRunner: ShellCommandExecutor,
|
||||
private val fileSystemSupport: ShellFileSystemSupport? = null,
|
||||
) : ShellRuntimeContext, UserDataHolderBase() {
|
||||
|
||||
override suspend fun runShellCommand(command: String): ShellCommandResult {
|
||||
return generatorCommandsRunner.runShellCommand(currentDirectory, command)
|
||||
}
|
||||
|
||||
override suspend fun listDirectoryFiles(path: String): List<ShellFileInfo> {
|
||||
return fileSystemSupport?.listDirectoryFiles(path)
|
||||
?: error("Supported only in Reworked Terminal")
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "ShellRuntimeContextImpl(currentDirectory='$currentDirectory', typedPrefix='$typedPrefix')"
|
||||
}
|
||||
|
||||
+2
-2
@@ -24,9 +24,9 @@ internal fun cdCommandSpec() = ShellCommandSpec("cd") {
|
||||
val directories = context.getChildFiles(path, onlyDirectories = true)
|
||||
val prefixReplacementIndex = path.length + if (context.typedPrefix.startsWith('"')) 1 else 0
|
||||
val suggestions = directories.flatMap {
|
||||
val suggestion = ShellCompletionSuggestion(name = it, type = ShellSuggestionType.FOLDER, prefixReplacementIndex = prefixReplacementIndex)
|
||||
val suggestion = ShellCompletionSuggestion(name = it.name + File.separator, type = ShellSuggestionType.FOLDER, prefixReplacementIndex = prefixReplacementIndex)
|
||||
val hiddenSuggestion = ShellCompletionSuggestion(
|
||||
name = it.removeSuffix(File.separator),
|
||||
name = it.name,
|
||||
type = ShellSuggestionType.FOLDER,
|
||||
prefixReplacementIndex = prefixReplacementIndex,
|
||||
isHidden = true
|
||||
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
package com.intellij.terminal.tests.reworked.frontend.completion
|
||||
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.platform.eel.provider.LocalEelDescriptor
|
||||
import com.intellij.terminal.completion.spec.ShellFileInfo
|
||||
import com.intellij.terminal.completion.spec.ShellFileInfo.Type.DIRECTORY
|
||||
import com.intellij.terminal.completion.spec.ShellFileInfo.Type.FILE
|
||||
import com.intellij.terminal.completion.spec.ShellName
|
||||
import com.intellij.terminal.frontend.completion.ShellCommandExecutorReworked
|
||||
import com.intellij.terminal.frontend.completion.ShellFileSystemSupportImpl
|
||||
import com.intellij.testFramework.fixtures.BasePlatformTestCase
|
||||
import com.intellij.testFramework.utils.io.createDirectory
|
||||
import com.intellij.testFramework.utils.io.createFile
|
||||
import com.intellij.testFramework.utils.io.deleteRecursively
|
||||
import com.intellij.util.SystemProperties
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.jetbrains.plugins.terminal.block.completion.spec.IS_REWORKED_KEY
|
||||
import org.jetbrains.plugins.terminal.block.completion.spec.getChildFiles
|
||||
import org.jetbrains.plugins.terminal.block.completion.spec.impl.ShellFileInfoImpl
|
||||
import org.jetbrains.plugins.terminal.block.completion.spec.impl.ShellRuntimeContextImpl
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.Path
|
||||
import kotlin.io.path.createTempDirectory
|
||||
import kotlin.io.path.deleteIfExists
|
||||
import kotlin.io.path.name
|
||||
|
||||
/**
|
||||
* Test for [org.jetbrains.plugins.terminal.block.completion.spec.getChildFiles] in Reworked Terminal.
|
||||
*/
|
||||
@RunWith(JUnit4::class)
|
||||
internal class TerminalCompletionFilesCalculationTest : BasePlatformTestCase() {
|
||||
@Test
|
||||
fun `get child files by absolute path`() {
|
||||
val root = createTempDirStructure()
|
||||
val actualFiles = getChildFiles(root.toString(), root.toString())
|
||||
val expectedFiles = listOf(
|
||||
fileInfo("file1.txt", FILE),
|
||||
fileInfo(".file2", FILE),
|
||||
fileInfo("file with spaces", FILE),
|
||||
fileInfo("dir1", DIRECTORY),
|
||||
fileInfo("dir with spaces", DIRECTORY),
|
||||
fileInfo("dir2", DIRECTORY),
|
||||
)
|
||||
|
||||
assertThat(actualFiles).hasSameElementsAs(expectedFiles)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get child files by relative path`() {
|
||||
val root = createTempDirStructure()
|
||||
val actualFiles = getChildFiles(root.toString(), "")
|
||||
val expectedFiles = listOf(
|
||||
fileInfo("file1.txt", FILE),
|
||||
fileInfo(".file2", FILE),
|
||||
fileInfo("file with spaces", FILE),
|
||||
fileInfo("dir1", DIRECTORY),
|
||||
fileInfo("dir with spaces", DIRECTORY),
|
||||
fileInfo("dir2", DIRECTORY),
|
||||
)
|
||||
|
||||
assertThat(actualFiles).hasSameElementsAs(expectedFiles)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get child files from nested dir by a relative path`() {
|
||||
val root = createTempDirStructure()
|
||||
val actualFiles = getChildFiles(root.toString(), "dir2")
|
||||
val expectedFiles = listOf(
|
||||
fileInfo("nestedFile1.txt", FILE),
|
||||
fileInfo(".nestedFile2", FILE),
|
||||
fileInfo("nestedFile with spaces", FILE),
|
||||
fileInfo("nestedDir", DIRECTORY),
|
||||
)
|
||||
|
||||
assertThat(actualFiles).hasSameElementsAs(expectedFiles)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get child files from nested dir by a relative path with trailing path separator`() {
|
||||
val root = createTempDirStructure()
|
||||
val actualFiles = getChildFiles(root.toString(), "dir2" + File.separator)
|
||||
val expectedFiles = listOf(
|
||||
fileInfo("nestedFile1.txt", FILE),
|
||||
fileInfo(".nestedFile2", FILE),
|
||||
fileInfo("nestedFile with spaces", FILE),
|
||||
fileInfo("nestedDir", DIRECTORY),
|
||||
)
|
||||
|
||||
assertThat(actualFiles).hasSameElementsAs(expectedFiles)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get child files from home related path`() {
|
||||
val tempFile = createTempFileInUserHome()
|
||||
val actualFiles = getChildFiles("/", "~")
|
||||
assertThat(actualFiles).contains(fileInfo(tempFile.name, FILE))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get child files from home related path with trailing path separator`() {
|
||||
val tempFile = createTempFileInUserHome()
|
||||
val actualFiles = getChildFiles("/", "~" + File.separator)
|
||||
assertThat(actualFiles).contains(fileInfo(tempFile.name, FILE))
|
||||
}
|
||||
|
||||
private fun getChildFiles(currentDirectory: String, path: String): List<ShellFileInfo> = runBlocking {
|
||||
val eelDescriptor = LocalEelDescriptor
|
||||
val context = ShellRuntimeContextImpl(
|
||||
currentDirectory,
|
||||
typedPrefix = path,
|
||||
ShellName("test"),
|
||||
ShellCommandExecutorReworked(eelDescriptor),
|
||||
ShellFileSystemSupportImpl(eelDescriptor)
|
||||
)
|
||||
context.putUserData(IS_REWORKED_KEY, true)
|
||||
context.getChildFiles(path)
|
||||
}
|
||||
|
||||
private fun createTempDirStructure(): Path {
|
||||
val root = createTempDirectory("terminal-completion")
|
||||
Disposer.register(testRootDisposable) { root.deleteRecursively() }
|
||||
return root.apply {
|
||||
createFile("file1.txt")
|
||||
createFile(".file2")
|
||||
createFile("file with spaces")
|
||||
createDirectory("dir1")
|
||||
createDirectory("dir with spaces")
|
||||
createDirectory("dir2").apply {
|
||||
createFile("nestedFile1.txt")
|
||||
createFile(".nestedFile2")
|
||||
createFile("nestedFile with spaces")
|
||||
createDirectory("nestedDir")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createTempFileInUserHome(): Path {
|
||||
val userHome = Path(SystemProperties.getUserHome())
|
||||
val tempFile = userHome.createFile("terminal-completion-test-file")
|
||||
Disposer.register(testRootDisposable) { tempFile.deleteIfExists() }
|
||||
return tempFile
|
||||
}
|
||||
|
||||
private fun fileInfo(name: String, type: ShellFileInfo.Type): ShellFileInfo {
|
||||
return ShellFileInfoImpl(name, type)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user