Change:
VSCode Version: Code 1.17.1 (, 2017-10-10T14:24:41.632Z) OS Version: WindowsNT ia32 6.3.9600 Currently, snippets allow you to resolve the current directory or filepath with and respectively. It would be great to be able to get the path for these relative to the root folder, whether directly (e.g. ) or by providing a variable with the root folder. I'm trying to write a snippet to create a new C# file. Visual Studio will auto-populate the file with , but that doesn't seem possible in Visual Studio Code right now.
We have for thing like this. Please give it a try
I'm not sure how that would help in this case. If resolves to , how can I know where the project begins? If I have the project root at , I would expect the namespace to be , but I don't see any way of reliably generating that without making assumptions about base folder structure.
I could also see this used for other situations, like generating a JavaScript file that imports a common file, like . In this case, if I had the relative directory, I could easily use the Variable Transformations to generate
Well, how would we know? Do you suggest to take the current folder? What if your project start one level deeper, like and ? I like the idea of having a variable that resolves the active (workspace) folder but I don't know if it will help you. Tho, it might make it easier to craft a snippet with transforms
Sorry, when I said project root, I meant workspace root. You're right, it wouldn't solve every situation, but I think it could be handy to have.
Any idea how to make this works using variable transformations?
if you hardcode root foder, you can use the next transformation:
"variable that resolves the active (workspace) folder" is definitely missing. How about 'custom' variable that could read string from another file? Usually, if source root is not the relative folder, it is written in some (json, xml..) file in relative folder. Beside resolving this issue, probably that new variable would provide many more options in snippets.
Workspace-related snippet variables would be very handy for plenty of cases, I was surprised they weren't included already when I went looking for them
Add a new variable pointing to the root path of the workspace will be awesome!
I would expect the output to be the same as from the "File: Copy Relative Path of Active File" command. So can't that be used for this snippet too?
This would be great. If we could also get a , that would be super amazing, and provide a better basis for doing what the OP is trying to do. It would only contain the portion of the path after the workspace root of the directory, so it would be the relative path of the directory of the current document. Honestly, I can't believe something like this wasn't one of the very first variables ever made for snippets. How can so many programmers be relying on an editor that doesn't even help you write your boilerplate code with the correct namespace? The whole point of programming is to automate away the mindless repetitive stuff. Actually the entire way snippets were conceived was ridiculous from the start. Why was the TextMate snippet syntax chosen? Were they intentionally trying to make it as annoying and useless as possible? I mean really, we're supposed to write snippets as values in a JSON format? We are programmers, just lets us write code in an actual programming language that can output the text as a string, with some helpful pre-made variables we can concatenate in the outputted strings. Then we would have the ability to actually write code to format/produce the text rather than to have rely on cryptic transformations and regular expressions. But it gets even worse from there. Why should the OP have to go out of their way to make and then activate a snippet at all, when all they are really doing is creating a new file? They already chose to create the new file, and to give it an appropriate name and file extension. That should be enough information for VS Code to be able to activate an appropriate template for the most common case you would be creating a new file of that file type for, as the OP is describing, no snippets necessary. We also shouldn't need to go searching through user made extensions to try to find something like that. This makes it seem like MS is intentionally leaving out the most obvious features to prevent it from competing with Visual Studio.
When editing other settings for VS Code, you can sometimes use . That is what we need here. I tried just using them, but they didn't work for me here.
2 years ago I asked about getting the base directory (not the full path). Having the current directory name (and not the full path) seems to be in demand. Sure people are giving their upvote for the transform but what we really want is a simple, relatively short variable to get it. The snippets are not that obvious with these transforms repeated everywhere and not the simplest thing to maintain. Please, consider adding some variables like the ones mentioned here.
I don't mind trying to put together a PR, but I tend to have a hard time getting started in a new code base (new for me). Is someone able to point me both to the code that makes the in other parts of VS Code, and the code that makes available to snippets?
Did a quick search and it is likely to be here: EDIT: and here
I just realized something. Even if I had a variable that provided the relative path after project directory, I would still need to use the incomprehensible variable transformations feature to remove 'src/' from the start of that variable, so it wouldn't actually help me.
I'm trying to make a snippet always locate a file no matter where it's created. Is there any way to say something like and have it automatically produce an output like if we're located in when triggering the snippet?
I borrowed the transformation from and it worked pretty well for my case. It's not perfect because neighboring components will use and then come back down the path, but that Okay, let's say you have: Workspace path: Path to relative library I want to create a snippet for: Current file: The following snippet should work up to 6 levels deep: Upon running the snippet, you should get The regex is assuming forward slashes in the directory—would need to be adjusted to backslashes on Windows or adjusted to be agnostic. A backward slash escaped in regex in JSON looks like and would replace in all instances above. This will work 6-subdirectories deep. If you need fewer or more, you can copy-paste the optional groups and then place more variable insertions . The regex is just trying to find as many groups beyond the common directory ( in the example above) and replacing them with . It's very simple. Having to escape the backslashes and putting it into JSON makes it hard to read. Basically we're saying: Transforming → Then the group for further directories needs to be repeated until you've reached what's practical for your project. Hope this helps!
I want to do something similar but if I use this one. It results in const myCommonLib = require('../,../,,'); No idea how but I am getting those commas. Is there a way to remove them?
Verified that the RELATIVE_FILEPATH works

Discussion:
'TM_FILENAME_BASE': true, 'TM_DIRECTORY': true, 'TM_FILEPATH': true, <ins> 'RELATIVE_FILEPATH': true, </ins> 'BLOCK_COMMENT_START': true, 'BLOCK_COMMENT_END': true, 'LINE_COMMENT': true,

} else if (name === 'TM_FILEPATH' && this._labelService) { return this._labelService.getUriLabel(this._model.uri); <ins> } else if (name === 'RELATIVE_FILEPATH' && this._labelService) { return this._labelService.getUriLabel(this._model.uri, { relative: true, noPrefix: true }); </ins> } return undefined;

import { createTextModel } from 'vs/editor/test/common/editorTestUtils'; import { Workspace } from 'vs/platform/workspace/test/common/testWorkspace'; import { extUriBiasedIgnorePathCase } from 'vs/base/common/resources'; <ins> import { sep } from 'vs/base/common/path'; </ins> suite('Snippet Variables Resolver', function () {

assertVariableResolve(resolver, 'WORKSPACE_FOLDER', '/'); } }); <ins> test('Add RELATIVE_FILEPATH snippet variable #114208', function () { let resolver: VariableResolver; // Mock a label service (only coded for file uris) const workspaceLabelService = ((rootPath: string): ILabelService => { const labelService = new class extends mock<ILabelService>() { getUriLabel(uri: URI, options: { relative?: boolean } = {}) { const rootFsPath = URI.file(rootPath).fsPath + sep; const fsPath = uri.fsPath; if (options.relative && rootPath && fsPath.startsWith(rootFsPath)) { return fsPath.substring(rootFsPath.length); } return fsPath; } }; return labelService; }); const model = createTextModel('', undefined, undefined, URI.parse('file:///foo/files/text.txt')); // empty workspace resolver = new ModelBasedVariableResolver( workspaceLabelService(''), model ); if (!isWindows) { assertVariableResolve(resolver, 'RELATIVE_FILEPATH', '/foo/files/text.txt'); } else { assertVariableResolve(resolver, 'RELATIVE_FILEPATH', 'foofilestext.txt'); } // single folder workspace resolver = new ModelBasedVariableResolver( workspaceLabelService('/foo'), model ); if (!isWindows) { assertVariableResolve(resolver, 'RELATIVE_FILEPATH', 'files/text.txt'); } else { assertVariableResolve(resolver, 'RELATIVE_FILEPATH', 'filestext.txt'); } }); </ins> });