Skip to content
| Marketplace
Sign in
Visual Studio Code>Formatters>Code ValetNew to Visual Studio Code? Get it now.
Code Valet

Code Valet

Sophodoros

|
1,051 installs
| (3) | Free
Editing and formatting tools for developers. Code aesthetics matter.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Code Valet for Visual Studio Code

A Visual Studio Code extension containing an eclectic set of editing and formatting tools for developers.

The short video below shows just a very small subset of the available tools. If this piques your interest, the Valet invites you to take a look at the Tool Summary or the full Tools List in the Table of Contents -- you just might find something there you didn't know you were missing.

The fact that many of the Valet's tools deal with simple formatting is no accident -- the Valet is a bit of snob when it comes to code aesthetics.

Take, for example, the Valet's Comment: Wrap tool. Why wrap comments? Because aesthetics matter. How would you feel if you opened a blog and found wildly uneven, ragged right margins? That may work if the blogger is a poet, but the Valet seriously doubts your code comments are poetry.

At the other extreme, do you enjoy reading online content that spans the full width of your wide screen monitor? Do you find it annoying when you are forced to scroll horizontally to read an entire line of text?

Although your comments may be written for a small audience, show your readers (and yourself) some respect. Professional authors wouldn't tolerate sloppy formatting in their published work. Neither should you.

However, even if you don't share the Valet's obsession with formatting, the Valet has much more to offer. C'mon, it's free. What are you waiting for?



Table of Contents

  • Tool Summary
    • Align Tools
    • Comment Tools
    • Encode Tools
    • Escape Tools
    • Filter Tools
    • Generate Tools
    • Hash Tools
    • Line Tools
    • Morph Tools
    • Text Case Tools
    • Word Case Tools
  • Tools List
    • Align: Columns
    • Align: On "="
    • Align: Text
    • Comment: Toggle
    • Comment: Transmogrify
    • Comment: Wrap
    • Encode: Base64
    • Encode: JWT
    • Escape: C/C++
    • Escape: C#
    • Escape: HTML
    • Escape: Java
    • Escape: JSON
    • Escape: Python
    • Escape: URI
    • Escape: XML
    • Filter: Double-spaced lines
    • Filter: Duplicate lines
    • Filter: Keep
    • Filter: Remove
    • Generate: GUID
    • Generate: Lorem ipsum
    • Generate: UUID
    • Hash: CRC
    • Hash: HMAC
    • Hash: MD5
    • Hash: SHA
    • Hash: UUID
    • Line: Count
    • Line: Index
    • Line: Join
    • Line: Sort
    • Morph: Adhoc template
    • Morph: Merge lists
    • Morph: Tab cleanup
    • Morph: Unicode
    • Text: lowercase
    • Text: Sentence case
    • Text: Title Case
    • Text: UPPERCASE
    • Word: camelCase
    • Word: CONSTANT_CASE
    • Word: dot.case
    • Word: kebab-case
    • Word: no case
    • Word: PascalCase
    • Word: path/case
    • Word: snake_case
  • Miscellany
    • Buttons on status bar
    • Extension settings
    • JSON languageIds property
    • Disabling shortcuts
    • Modifying the tools menu
    • Internationalization - i18n
    • Localization - l10n
    • Escaping non-ASCII Unicode
    • Text field history
    • Smart select
    • Tab manifesto
    • Logging and Privacy
    • Acknowledgments
    • Support
    • License


Tool Summary

The Valet's tools are listed here by category.

Once you've installed the Code Valet extension, you can bring up a selectable list of all tools using the "Valet" button on VS Code's status bar. Entering the Valet's help shortcut [alt+v h] brings up the same list.

Some of the more useful tools have shortcuts that start with alt+v. For those that don't, VS Code lets you add your own shortcuts; see here for more info.

Align Tools

Tools for aligning text.

ToolShortcutDescription
Align: Textalt+v aAlign text vertically on a specified string.
Align: On "="alt+v =Align text vertically on the "=" string.
Align: Columns--Align tabular data in columns.

Comment Tools

Tools for manipulating comments.

ToolShortcutDescription
Comment: Wrapalt+v wWrap comments at a specified column.
Comment: Togglealt+v /Toggle unique comments (e.g. "//TEST").
Comment: Transmogrify--Convert comments into regular text or regular text into comments.

Encode Tools

Tools for encoding and decoding strings.

ToolShortcutDescription
Encode: Base64--Encode or decode Base64 strings.
Encode: JWT--Decode JSON Web Token strings.

Escape Tools

Tools for escaping and un-escaping strings.

ToolShortcutDescription
Escape: C/C++--Escape or unescape C or C++ strings.
Escape: C#--Escape or unescape C# strings. Handles regular or verbatim strings.
Escape: HTML--Escape or unescape HTML strings.
Escape: Java--Escape or unescape Java.
Escape: JavaScript--Escape or unescape JavaScript or Typescript strings.
Escape: JSON--Escape or unescape JSON value strings.
Escape: Python--Escape or unescape Python strings.
Escape: URI--Escape or unescape URI query parameter strings.
Escape: XML--Escape or unescape XML strings.

Filter Tools

Tools that filter lines of text.

ToolShortcutDescription
Filter: Keepalt+v kKeep lines that match the filter.
Filter: Removealt+v xRemove lines that match the filter.
Filter: Duplicate lines--Remove duplicate lines.
Filter: Double-spaced lines--Remove blank lines that occur every other line.

Generate Tools

This category includes GUID and UUID generators, and a lorem ipsum generator for those needing a quick dose of mangled Cicero.

..
ToolShortcutDescription
Generate: GUID--Generate a random Microsoft-style GUID.
Generate: UUID--Generate a random v1 or v4 UUID.
Generate: Lorem Ipsum--Generate lorem ipsum text based on a character or word count.

Hash Tools

Tools for generating a hash value from a string.

ToolShortcutDescription
Hash: CRC--Hash a string using CRC-32 or CRC-32c.
Hash: HMAC--Hash a string and key using MD5, SHA-1, SHA-256, SHA-384, or SHA-512.
Hash: MD5--Has a string using MD5.
Hash: SHA--Hash a string using SHA-1, SHA-256, SHA-384, or SHA-512.
Hash: UUID--Hash a string and namespace to create a v3 or v5 UUID. See the Generate: UUID tool for random UUIDs

Line Tools

Tools that are typically used on multi-line selections.

ToolShortcutDescription
Line: Countalt+v nShow the number of lines, words, and characters.
Line: Indexalt+v jAdd indices to the start of each line.
Line: Joinalt+v jJoin multiple lines. Removes comment characters and trims whitespace.
Line: Sort (A -> Z)alt+v upSort lines in ascending order.
Line: Sort (Z -> A)alt+v downSort lines in descending order.

Morph Tools

These tools convert text from one form to another. When it comes to morphing, the tab cleanup tool is admittedly a bit subtle compared to the others.

ToolShortcutDescription
Morph: Adhoc template alt+v tRepetitive code generation with user-defined templates.
Morph: Merge lists--Merge two or more lists using the first column of each list as keys.
Morph: Tab cleanupalt+v tabNormalize tabs and spaces.
Morph: Unicode values--Show Unicode hex values of the selected characters.

Text Case Tools

Tools for changing the case of text. Only the Sentence case tool recognizes periods ("full stops" in UK English); the others don't care about sentence structure.

ToolShortcutDescription
Text: lowercasealt+v lconvert to lowercase.
Text: Sentence case--Capitalize the first word.
Text: Title Case--Capitalize Every Word.
Text: UPPERCASEalt+v uCONVERT TO UPPER CASE.

Word Case Tools

Unlike the text case tools, these tools apply case conversions on a word-by-word basis within the selected text. The formats listed here are mostly used for code variable names.

ToolShortcutDescription
Word: camel-case--Convert to camel-case.
Word: CONSTANT_CASE--Convert to CONSTANT_CASE.
Word: dot.case--Convert to dot.case.
Word: kebab-case--Convert to kebab-case.
Word: no case--Convert to no case.
Word: PascalCase--Convert to PascalCase.
Word: path/case--Convert to path/case.
Word: snake_case--Convert to snake_case.


Tools List


Align: Columns

Aligns tabular data into columns. You will be prompted for the following parameters:

OptionDefaultDescription
Delimiter?SpacesThe delimiter used to separate columns. (Spaces or Tabs)
Alignment?LeftText alignment within the columns. (Left, Center, or Right)
All columns same width?NoIf enabled, all columns will be as wide as the widest column; otherwise each column will be the width of the longest string in the column
Minimum column width?0If set to 0, this value is ignored.
Column spacing?1The number of spaces between each column.

The default settings for the minimum column width and column spacing can be set using the tool.align.columns.minWidth and tool.align.columns.spacing properties in the Valet's extension settings.

As noted in the Valet's tab manifesto, text containing embedded tabs doesn't travel well, so if space delimiters is selected then the text is first run through tab cleanup before the data is arranged in columns. If tab delimiters are specified there is no pre-processing of tabs, but after the tool is applied the inter-column tabs will be gone.

Example:

Align columns using column spacing of 2.

---------------------------------------------------------
Before 
---------------------------------------------------------
// COL-1 COL-2 COL-3 COL-4 COL-5
// aa a aaaa a a
// bb bbb b b
// cc c ccccc ccc c
// dd dd dddddd d
// e eeee e eeee e

---------------------------------------------------------
After align columns
---------------------------------------------------------
// COL-1  COL-2  COL-3   COL-4  COL-5
// aa     a      aaaa    a      a
// bb     bbb    b       b
// cc     c      ccccc   ccc    c
// dd     dd     dddddd  d
// e      eeee   e       eeee   e

A typical use for this tool is to re-format data pasted into your code from a spreadsheet, which usually destroys column alignment when converted to plain text. Without this tool, the code aesthetes among you will tediously insert spaces to manually restore the columns, all the while telling yourself that seeking perfection is not at all the same thing as being obsessive-compulsive.

This tool uses the Valet's smart select feature to determine what text to process.

Return to 'Align Tools'



Align: On Equals

This is identical to the Align: Text tool. The Valet found that aligning on "=" was so popular that it has its own dedicated shortcut [alt+v =] that will avoid the prompt.

Return to 'Align Tools'



Align: Text

Modifies the selected text so that the first occurrence of a string in each line are lined-up in the same column.

The Valet will prompt you for the following:

OptionDefaultDescription
Alignment text--The character or sub-string to align on.

Aligning on a common element such as an equal sign or a keyword can make blocks of repetitive code much easier to read, at least for humans -- your compiler or interpreter will likely maintain an air of haughty indifference.

Example 1:

Align text on "="

---------------------------------------------------------
Before
---------------------------------------------------------
const int incididunt = 1;
const int ut = 2;
const int labore = 3;
const int et = 4;

---------------------------------------------------------
After align text on "="
---------------------------------------------------------
const int incididunt = 1;
const int ut         = 2;
const int labore     = 3;
const int et         = 4;

Example 2:

Align text on "return"

---------------------------------------------------------
Before
---------------------------------------------------------
case HttpCode.OK: return "Ok";
case HttpCode.ServerError: return "Server error";
case HttpCode.NotAcceptable: return "Not acceptable";
case HttpCode.NotFound: return "Not found";

---------------------------------------------------------
After align text on "return"
---------------------------------------------------------
case HttpCode.OK:            return "Ok";
case HttpCode.ServerError:   return "Server error";
case HttpCode.NotAcceptable: return "Not acceptable";
case HttpCode.NotFound:      return "Not found";

You can provide multiple alignment strings separated by commas to apply the alignment tool multiple times to the same text.

Example 3:

Align text on "version" and "exclude"

---------------------------------------------------------
Before
---------------------------------------------------------
id="NETCore" version="2.2" exclude="Build"
id="JavaScript" version="5.8.6.234" exclude="Build"
id="Json" version="45.0.216.43" exclude="Build"

---------------------------------------------------------
After align text on "version,exclude"
---------------------------------------------------------
id="NETCore"    version="2.2"         exclude="Build"
id="JavaScript" version="5.8.6.234"   exclude="Build"
id="Json"       version="45.0.216.43" exclude="Build"

This tool uses the Valet's smart select feature to determine what text to process.

Return to 'Align Tools'



Comment: Toggle

Toggle comments on a block of code.

VS Code can already toggle comments on-and-off; this is usually bound to the [ctrl+/] shortcut. Why does the Valet need this tool?

The Valet's comment toggle tool appends a tag to the comment to allow you to differentiate between its comments and regular comments. This is useful when you want to temporarily comment-out code and want the comments to stand out from regular comments.

Example:

Add comments using the Valet's comment toggle tool.

----------------------------     ------------------------------
Before                           After
----------------------------     ------------------------------
if (ipsum == lorum) {            //TEST if (ipsum == lorum) {
    dolor = "sit amet";          //TEST     dolor = "sit amet";
}                                //TEST }

Like the VS Code version, the Valet's comment toggle tool will use the line comment characters for the document's selected language -- i.e. "//" for C-style languages, "#" for Python, etc.

The default comment tag is "TEST", but you can change this using the tool.comment.toggle.tag option in the extension settings. For example, you might want to change the tag to your initials to denote comments added by you.

If you do change the tag, please keep it clean. Temporary comments intended for your-eyes-only have been known to sneak their way into code reviews and production code. At the very least, the Valet strongly recommends that you avoid tags containing references to your boss's anatomy or sexual proclivities.

This tool uses the Valet's smart select feature to determine what text to process.

Return to 'Comment Tools'



Comment: Transmogrify

The transmogrify tool converts regular text into comments or comments into regular text.

To convert regular text into comments, first copy text from an external source such as a document or web page into the clipboard. Then, go into VS Code and place the cursor on a line in your code containing the comment characters you want to use; be sure to indent the comment to the desired level. Then, invoke the Transmogrify tool and select "Import (from clipboard)". You will be prompted for the following options:

OptionDefaultDescription
Wrap column?80The column where wrapping will occur.
Start index string?Optional index to apply to the imported text. See the 'Line: Index' tool for more on how this is used.

Once you've entered the import options, the Valet will do the following:

  1. Copy the clipboard text into a local buffer.
  2. Prepend comment characters to each line of text in the buffer.
  3. Run the "Lines: Index" tool on the buffer if you've provided an index string.
  4. Run the "Comment: Wrap" tool on the buffer.
  5. Write the buffer to your file.

To convert code comments into regular text, select the comments you want to convert, invoke the Transmogrify tool and select "Export (to clipboard)". When you do this, the Valet will do the following:

  1. Copy the selected comments into a local buffer.
  2. Run the "Line: Join" tool on the text in the buffer.
  3. Remove the comment characters from the text in the buffer.
  4. Write the buffer to the clipboard.

You can then paste the transmogrified text from the clipboard into wherever you need it. The transmogrify export feature can be used to convert comments for use in release notes or other documentation.

You may find yourself asking, why is this process called "transmogrify"? The Valet was hard-pressed to come up with an appropriate name for this tool. "Converter", the obvious choice, seemed too bland and generic. "Transmogrify" started out as a placeholder, but in the end it just felt right.

The tool's name originated as a wistful reference to Calvin's magical Transmogrifier box in the classic comic strip, Calvin and Hobbes. For those who don't see the humor in the name, just be thankful the Valet didn't turn for inspiration to another one of Calvin's inventions, the "Cerebral Enhance-o-tron".

Return to 'Comment Tools'



Comment: Wrap

This tool wraps comments at the specified column in the selected text. Text is wrapped at word breaks. After wrapping, each line will still start with comment characters and have the same level of indentation. Plain text that does not contain comment characters can also be wrapped using this tool.

When you run the wrap tool, you will be prompted for the following:

OptionDefaultDescription
Wrap column?80The column where wrapping will occur.

If the default wrap column value of 80 is too old-school for you, it can be changed by setting the tool.comment.wrap.column option in the Valet's extension settings.

Example 1:

Wrapping comments in a file whose target language uses "//" 
for line comments.

------------------------------------------------------------
Before
------------------------------------------------------------
// Lorem ipsum dolor sit 
// amet. Consectetur adipiscing elit. Sed do eiusmod tempor 
// incididunt ut labore et 
// dolore 
// magna aliqua. Ut enim ad minim veniam. 

------------------------------------------------------------
After wrap at column 45
------------------------------------------------------------
// Lorem ipsum dolor sit amet. Consectetur
// adipiscing elit. Sed do eiusmod tempor
// incididunt ut labore et dolore magna
// aliqua. Ut enim ad minim veniam.

This tool uses the Valet's smart select feature to determine what text to process.

If like the Valet you've acquired the bad habit of adding comments to your code and you are a bit obsessive about comment aesthetics, the wrap tool can save you from lots of tedious manual re-formatting. And if not? Move along -- these aren't the droids you're looking for.

Another use for the wrap tool is to split a block of text so that each word is on its own line. This is done by setting the wrap column to 0.

Example 2:

---------------------------------------------
Before
---------------------------------------------
Lorem ipsum dolor sit amet consectetur 

---------------------------------------------
After wrap at column 0
---------------------------------------------
Lorem
ipsum
dolor
sit
amet
consectetur

If the first line of a selection starts with a list index or list symbol, the wrap tool will attempt to preserve the list indentation, as shown in the following example.

Example 3:

---------------------------------------------------------------------
Before
---------------------------------------------------------------------
// 1. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do 
//    eiusmod tempor incididunt ut labore et
// 2. dolore magna 
//    aliqua. Ut enim ad minim veniam.

---------------------------------------------------------------------
After wrap at column 45
---------------------------------------------------------------------
// 1. Lorem ipsum dolor sit amet, consectetur
//    adipiscing elit. Sed do eiusmod tempor
//    incididunt ut labore et
// 2. dolore magna aliqua. Ut enim ad minim
//    veniam.

If you want to ignore lists, disable the comment.wrap.list option in the Valet's extension settings.

The Valet realizes it is the rare developer indeed that is compelled by some inner daemon to add comments containing lists or similar levels of detail to their code. For those who do, welcome to the resistance, you fighters of the good fight, you keepers of the guttering flame.

Adding additional comment wrap prefixes

Line comment prefixes are sets of one or more characters that indicate what follows are comments that should be ignored by a language's interpreter or compiler. A classic example is //, which denotes a line comment in many languages belonging to the C family tree.

When wrapping comments, the Valet uses the line comment prefixes defined by VS Code for a document's language to help it determine how to wrap the text. However, sometimes you may want other character sets to be treated as line comments that do not belong to a language's official set of line comments.

For example, C# uses /// for documentation comments, but VS Code's C# extension does not include this in its lineComment property. Also, some languages like TypeScript use block comments for documentation comments where the block starts and ends with /* and */, and the lines within the block start with *. Although technically * is not a line comment, you might want to treat it as one when using the Valet to wrap comments.

Since the Valet doesn't pretend to know all the alternate comment strings found in the wild, you can add your own to the tool.comment.wrap.prefixes property in the Valet's extension settings. The property is a JSON string that defines an array of JSON objects. Each object contains an array of languageIds and a list of prefixes to use with those languages.

Here's an example of a tool.comment.wrap.prefixes property that adds /// and * as line comment prefixes for C, C#, Java, and TypeScript:

[
	{ 
		"languageIds": ["c", "csharp", "java", "typescript"], 
		"prefixes": [ "///", "*" ]
	}
] 

Ignore lines when wrapping

When using the wrap tool, you may want to ignore some types of lines when wrapping is applied to block comments.

For example, C# documentation comments use XML elements like <summary> to define blocks of comments and <para/> to put breaks between paragraphs. As shown in the following example, normally this text will be wrapped by the Valet unless you tell the Valet to ignore those lines.

Example 4:

---------------------------------------------------------------------
Before
---------------------------------------------------------------------
/// <summary>
/// This is a C# comment with paragraph breaks. We want to keep 
/// it separate from the 2nd paragraph when it's wrapped.
/// <para/>
/// This is the 2nd paragraph of this comment. 
/// </summary>

---------------------------------------------------------------------
After wrapping at column 45 when the wrap-ignore configuration
is not set.
---------------------------------------------------------------------
/// <summary> This is a C# comment with
/// paragraph breaks. We want to keep it
/// separate from the 2nd paragraph when it's
/// wrapped. <para/> This is the 2nd
/// paragraph of this comment. </summary>

---------------------------------------------------------------------
After wrapping at column 45, but with the wrap-ignore configuration 
set to ignore lines containing <summary>, </summary>, or <para/>.
---------------------------------------------------------------------
/// <summary>
/// This is a C# comment with paragraph
/// breaks. We want to keep it separate from
/// the 2nd paragraph when it's wrapped.
/// <para/>
/// This is the 2nd paragraph of this
/// comment.
/// </summary>

The tool.comment.wrap.ignore option in the Valet's extension settings is used to define which lines to ignore when wrapping. The option takes a JSON string that defines an array of objects. Each object has a languageIds array and a regexes array.

Shown below is the tool.comment.wrap.ignore JSON for C# that was used for example 4 above:

[
	{ 
		"languageIds": ["csharp"], 
		"regexes": [
			"^[ \t]*<para/>[ \t]*$", 
			"^[ \t]*<[/]?summary>[ \t]*$"
		]
	}
]

The regular expressions match the text following the comment characters. Thus, for the C# example shown above, the "///" line comment characters were not included in the regexes. See section xxx for details on how to define languageIds.

Return to 'Comment Tools'



Encoder: Base64

Encode or decode Base64 strings. When using this tool, you will be prompted for the following:

OptionDefaultDescription
Encode or decode?EncodeEncode or decode the selected string
Use URL-safe encoding?Yes(Encode only) Use standard base64 encoding or URL-safe base64 encoding.
Wrap line width (0 = no wrap)?0(Encode only) The line width used to wrap encoded base64. Wrapping usually isn't required, but makes it easier for humans to handle long encoded strings.
Output target?To clipboardSpecify the destination for the tool's output. See Output target for details.

The result of the decode operation is usually copied to the target you select in the "Output target" prompt. However, if the decoded result is binary data, the Valet will give you the option of saving the binary data to a file.

Return to 'Encode Tools'



Encode: JWT

Decode a JWT (JSON Web Token).

You will be prompted for the destination (clipboard or current file) of the tool's output. See the Output target section for details.

The decoded JWT string is JSON containing the JWT's header, payload, and signature. No validation is performed on the JWT by the Valet.

Despite being in the Valet's "Encode" tool category, this tool does not provide an option to encode JWTs. There are just too many variables associated with creating JWTs, so for once the Valet heeded the sweet whispers of "YAGNI" in its ear.

Return to 'Encode Tools'



Escape: C/C++

Escape or unescape C or C++ strings. When using this tool, you will be prompted for the following:

OptionDefaultDescription
Escape or unescape?EscapeEscape or unescape the target string.
Escape non-ASCII Unicode?No(Escape only) See Escaping non-ASCII Unicode for details.
Output target?To clipboardSpecify the destination for the tool's output. See Output target for details.

Return to 'Escape Tools'



Escape: C#

Escape or unescape C# strings. When using this tool, you will be prompted for the following:

OptionDefaultDescription
Escape or unescape?EscapeEscape or unescape the target string.
Regular or verbatim?RegularSpecify whether the string is a standard string or a verbatim string.
Escape non-ASCII Unicode?No(Escape only) See Escaping non-ASCII Unicode for details.
Output target?To clipboardSpecify the destination for the tool's output. See Output target for details.

A C# verbatim string is prefixed with an "@" and causes the escape rules to change compared to a standard string. The following example shows how they differ.

Example:

// Print the following string to the console:
// A "\n" is a newline and a "\t" is a tab.

// Use an escaped standard string literal.
string s = "A \"\\n\" is a newline and a \"\\t\" is a tab.";
Console.WriteLine(s);

// Use an escaped verbatim string literal.
string v = @"A ""\n"" is a newline and a ""\t"" is a tab.";
Console.WriteLine(v);

When escaping verbatim strings you will not see the prompt, "Escape non-ASCII Unicode?" That is because in verbatim strings escaped Unicode is not un-escaped when it is written or displayed to the user.

C# also uses the "$" prefix to define format strings with data embedded in curly braces. If you need to escape format strings, the Valet suggests you run this tool on the substrings outside the curly braces.

Return to 'Escape Tools'



Escape: HTML

Escape or unescape HTML strings for use in an element where text content is expected or in attributes. When using this tool, you will be prompted for the following:

OptionDefaultDescription
Escape or unescape?EscapeEscape or unescape the target string.
Escape non-ASCII Unicode?No(Escape only) See Escaping non-ASCII Unicode for details.
Output target?To clipboardSpecify the destination for the tool's output. See Output target for details.

Example:

	-----------------------------------------------------
	Before escape
	-----------------------------------------------------
	Here's the test: a < b && b < c

	-----------------------------------------------------
	After escape
	-----------------------------------------------------
	Here&apos;s the test: a &lt; b &amp;&amp; b &lt; c

Return to 'Escape Tools'



Escape: Java

Escape or unescape Java strings. When using this tool, you will be prompted for the following:

OptionDefaultDescription
Escape or unescape?EscapeEscape or unescape the target string.
Escape non-ASCII Unicode?No(Escape only) See Escaping non-ASCII Unicode for details.
Output target?To clipboardSpecify the destination for the tool's output. See Output target for details.

Return to 'Escape Tools'



Escape: JavaScript

Escape or unescape JavaScript strings. When using this tool, you will be prompted for the following:

OptionDefaultDescription
Escape or unescape?EscapeEscape or unescape the target string.
Escape non-ASCII Unicode?No(Escape only) See Escaping non-ASCII Unicode for details.
Output target?To clipboardSpecify the destination for the tool's output. See Output target for details.

JavaScript strings are encoded in UTF-16, but JavaScript source code files are almost always encoded in UTF-8. Should you care? Probably not, except perhaps if you are using Node.js. If you want to learn more about the confusion this can cause, see Kevin Burke's post titled "Let’s talk about Javascript string encoding".

Return to 'Escape Tools'



Escape: JSON

Escape or unescape JSON value strings. When using this tool, you will be prompted for the following:

OptionDefaultDescription
Escape or unescape?EscapeEscape or unescape the target string.
Escape non-ASCII Unicode?No(Escape only) See Escaping non-ASCII Unicode for details.
Output target?To clipboardSpecify the destination for the tool's output. See Output target for details.

Return to 'Escape Tools'



Escape: Python

Escape or unescape Python strings. When using this tool, you will be prompted for the following:

OptionDefaultDescription
Escape or unescape?EscapeEscape or unescape the target string.
Escape non-ASCII Unicode?NoOnly used when escaping. See Escaping non-ASCII Unicode for details.
Output target?To clipboardSpecify the destination for the tool's output. See Output target for details.

Python uses the "f" prefix to define format strings with data embedded in curly braces. If you need to escape format strings, the Valet suggests you run this tool on the substrings outside the curly braces.

To avoid escapes altogether, consider using the Python "r" (raw) prefix. The Valet only has a nodding acquaintance with Python, so it won't even pretend to try to tell you the escape rules associated with raw strings.

Return to 'Escape Tools'



Escape: URI

Escape or unescape URI query parameter strings. When using this tool, you will be prompted for the following:

OptionDefaultDescription
Escape or unescape?EscapeEscape or unescape the target string.
Output target?To clipboardSpecify the destination for the tool's output. See Output target for details.

Internally, the Valet simply uses JavaScript's encodeURIComponent and decodeURIComponent functions to do the dirty work. This is not the same as using JavaScript's encodeURI and decodeURI functions. This means that when dealing with URLs you typically should only use this tool to escape the individual query parameters, not the entire URL.

For example, in the example below you would not want to select the entire URL and run the Valet's URI tool to escape the full string. Instead, you should individually select only the query parameters.

Example:

Individually run the URI tool on the strings "R&D" and "σοφο" to 
escape the URL.

----------------------------------------------------------------------
Before escaping query parameters
----------------------------------------------------------------------
https://microsoft.com/dummy?cmd1=R&D&cmd2=σοφο

----------------------------------------------------------------------
After escaping query parameters
----------------------------------------------------------------------
https://microsoft.com/dummy?cmd1=R%26D&cmd2=%CF%83%CE%BF%CF%86%CE%BF

When escaping URI query parameters, every character that isn't ASCII must be escaped. This is a sad state of affairs -- even the Valet, old soul that it is, finds it hard to believe that in a world where Unicode reigns supreme, the spec for query parameters appears to be a product of the days when coders still used keypunch cards.

Fortunately, as shown in the example above, the full URL does not have to follow the same rules for escaping characters as the URL's query parameters. For a good explanation of the hows and whys of the escape rules for URLs and URIs, see Mark Amery's StackOverflow post on the topic.

Return to 'Escape Tools'



Escape: XML

Escape or unescape XML content or attribute strings. When using this tool, you will be prompted for the following:

OptionDefaultDescription
Escape or unescape?EscapeEscape or unescape the target string.
Escape non-ASCII Unicode?No(Escape only) See Escaping non-ASCII Unicode for details.
Output target?To clipboardSpecify the destination for the tool's output. See Output target for details.

Return to 'Escape Tools'



Filter: Keep or Remove

Keep or remove lines based on a filter string. When using this tool, you will be prompted for the following:

OptionDefaultDescription
Filter?--The text to use as the filter.
Is RegEx?NoTreat the filter as a regular expression.
Ignore case?YesIgnore case when matching the filter.
Add deleted lines marker?NoReplace contiguous sets of deleted lines with a line showing how many lines were deleted.
Lines before?0The number of lines before a match to include in the filtered lines.
Lines after?0The number of lines after a filter match to include in the filtered lines.

A line matches the filter if the filter string appears anywhere in the line unless your filter is a regex and your regex says otherwise.

By default, when a filter is applied lines are simply deleted, leaving no trace that they ever existed. However, if you say Yes to the "Add deleted lines marker" option, contiguous sets of deleted lines will be replaced with a line that shows the number of deleted lines.

The "lines before" and "lines after" options are used to treat lines before and/or after a filter match as if they also matched the filter. When used with the Filter:Keep tool, this is useful in keeping context around the line that matches the filter.

The following example shows how these various options work.

Example

Use the Filter:Keep tool with the filter string 'INFO' 

-----------------------------------------------------
List before filtering
-----------------------------------------------------
    08:53:03 TRACE: event timer T1 expired
    08:53:05 TRACE: router forward
    08:53:06 INFO:  mail monitor
    08:53:08 TRACE: rsvp action hop
    08:53:09 TRACE: event timer T2 expired
    08:53:11 TRACE: rsvp action end
    08:53:12 INFO:  rsvp flow state machine
    08:53:14 TRACE: event timer T3 expired
    08:53:17 WARN:  monitor level updated

-----------------------------------------------------
After filtering on 'INFO', no deleted lines markers
-----------------------------------------------------
    08:53:06 INFO:  mail monitor
    08:53:12 INFO:  rsvp flow state machine

-----------------------------------------------------
After filtering on 'INFO', with deleted lines markers
-----------------------------------------------------
    ---- Deleted 2 line(s) ----
    08:53:06 INFO:  mail monitor
    ---- Deleted 3 line(s) ----
    08:53:12 INFO:  rsvp flow state machine
    ---- Deleted 2 line(s) ----

-----------------------------------------------------
After filtering on 'INFO', with deleted lines markers 
and with "Lines after" set to 1
-----------------------------------------------------
    ---- Deleted 2 line(s) ----
    08:53:06 INFO:  mail monitor
    08:53:08 TRACE: rsvp action hop
    ---- Deleted 2 line(s) ----
    08:53:12 INFO:  rsvp flow state machine
    08:53:14 TRACE: event timer T3 expired
    ---- Deleted 1 line(s) ----

By default, the deleted lines marker is not added. This default can be changed using the tool.filter.deletedMarkerEnabled property in the Valet's extension settings.

The marker text itself can be overridden using the tool.filter.deletedMarkerOverride property. If you include '{0}' in the override string it will be replaced with the deleted lines count.

Return to 'Filter Tools'



Filter: Double-spaced lines

Convert double-spaced lines to single-spaced. This tool comes in useful when code that's copied from a web site gets converted into double-spaced lines when pasted into VS Code.

Return to 'Filter Tools'



Filter: Duplicate lines

Remove duplicate lines from the selected text. When using this tool, you will be prompted for the following:

OptionDefaultDescription
Ignore case?YesIgnore case when comparing lines of text.

The default setting for ignore case can be overridden via the tool.filter.ignoreCase property in the Valet's extension settings.

Example

--------------
Before
--------------
one
two
one
three
three

--------------
After
--------------
one
two
three

Return to 'Filter Tools'



Generate: GUID

This tool generates a random Microsoft-style GUID, a 128-bit number rendered as 32 hexadecimal digits in five groups separated by hyphens. Shown below is an example:

E6A80C09-99E7-49C8-8A5E-A48572915EAF

The output of this tool is written to the document at the current cursor location.

UUIDs vs GUIDs -- you say YOU-id, I say GOO-id

The terms UUID and GUID are often used interchangeably. However, historically UUID refers to a unique ID defined by RFC 4122, while GUID refers to Microsoft's implementation. The two types of IDs are virtually identical except for one obvious difference: The hex digits in RFC 4122 UUIDs are lowercase while Microsoft's GUIDs are uppercase.

RFC 4122 defines two UUID versions (v1 and v4) that are intended to be randomly generated, as are Microsoft's GUIDs. The RFC specs on the valid values of UUIDs are more restrictive than Microsoft's GUID requirements, so ignoring case a v1 or v4 UUID is always a Microsoft GUID but the reverse is not always true.

To keep things simple, the Valet generates a GUID by generating a v4 UUID and converting it to uppercase. Hopefully, Microsoft fanboys and fangirls will forgive this harmless example of lèse-majesté.

Return to 'Generate Tools'



Generate: UUID

This tool generates a random UUID, a 128-bit number rendered as 32 hexadecimal digits in five groups separated by hyphens. Shown below is an example:

e6a80c09-99e7-49c8-8a5e-a48572915eaf

You will be prompted for the UUID version you want to generate, v1 or v4. The output of this tool is written to the document at the current cursor location.

See the GUID generate tool for an overview of the difference between UUIDs and GUIDs.

Return to 'Generate Tools'



Generate: Lorem Ipsum

Generate lorem ipsum text, the de facto standard filler text for developers. You will be prompted for the following:

OptionDefaultDescription
Count by?WordsSelect whether you want the text to be generated according to a character count or a word count.
Count?--The number of characters or words to generate
Start at beginning?trueIf true, start at the beginning of the lorem ipsum passage. If false, the first request starts at the beginning but each new request starts with the next word in the passage.
Add delimiters?falseIf true, add a prefix and suffix to the text. The default delimiters are "INCIPE" and "FINIS".

The default text used by this tool is the classic lorem ipsum text based on Cicero's De finibus bonorum et malorum ("On the ends of good and evil").

The text is defined in the tool.lorumIpsum.text property of the Valet's extension settings. You can edit the lorem ipsum text or replace it entirely -- knowledge of Latin is not required. However, be careful what you write, lest you suffer Cicero's fate and have your severed hands nailed to the rostra of the Roman Forum.

This tool offers the option to add delimiting words to the start and end of the text. By default these delimiters are "INCIPE" and "FINIS", but these can be changed via the tool.lorumIpsum.prefix and tool.lorumIpsum.suffix properties in the Valet's extension settings.

For example, if you request 5 words with delimiters, using the default settings the lorem ipsum tool will generate the following text:

INCIPE Lorem ipsum dolor FINIS    

Adding delimiting words makes it easy to see if the text is being truncated in tests that display or manipulate text. For example, the Valet's manual test of the wrap tool uses lorem ipsum text with delimiting words to verify that none of the text is being truncated when the text is wrapped.

The generated text is NOT random; the words and word order are always the same. If you ask for 10 words and set the "Start at beginning" option to true, you will get the same 10 words in the same order every time. Set "Start at beginning" to false if you require a little variety.

Return to 'Generate Tools'



Hash: CRC

Generate a CRC-32 or CRC-32C hash from the selected string. You will be prompted for the CRC type.

You will also be prompted for the destination (clipboard or current file) of the hash string. See the Output target section for details.

Return to 'Hash Tools'



Hash: HMAC

Generate an HMAC (Hash-Based Message Authentication Code) from the selected string. You will be prompted for the following:

OptionDefaultDescription
Algorithm?SHA-256Select the hash algorithm from the following list: MD5, SHA-1, SHA-256, SHA-384, or SHA-512
Key?--The secret key.
Output target?To clipboardSpecify the destination for the tool's output. See Output target for details.

As noted in the table above, the default algorithm is SHA-256. However, the default can be changed via the tool.hmac.algorithm property in the Valet's extension settings.

Keys can be saved for easy access by clicking on the "Edit HMAC keys" option at the bottom of the Valet tool menu. JSON is used to define name/key pairs. For example, the following JSON string defines two keys named "My Key 1" and "My Key 2":

{ "My Key 1": "abcd123", "My Key 2": "987wxyz" }

If you define any user defined HMAC keys, the key names will be displayed in a drop-down list when you are prompted for the HMAC key.

WARNING: User-defined HMAC keys can be viewed by anyone who has access to your computer account and knows how to use Code Valet. So, it's up to you to weigh the convenience of saving your HMAC keys against the level of security you require.

Return to 'Hash Tools'



Hash: MD5

Generate a MD5 hash from the selected string. You will be prompted for the destination (clipboard or current file) of the hash string; see the Output target section for details.

Although the Valet isn't usually one to spread malicious gossip, the word on the street is that the MD5 algorithm is cryptographically broken and has been for many, many years. Just sayin'.

Return to 'Hash Tools'



Hash: SHA

Generate a SHA-1, SHA-256, SHA-384, or SHA-512 hash from the selected string. You will be asked to select which SHA algorithm to use. The default is SHA-256, but the default can be changed by setting the tool.sha.algorithm property in the Valet's extension settings.

You will be prompted for the destination (clipboard or current file) of the hash string; see the Output target section for details.

Cryptographic weaknesses exist in SHA-1 and after 2010 it was no longer approved for most cryptographic uses. However, like the Valet's preferred diet of whisky and cigarettes, some bad habits are harder to break than others.

Return to 'Hash Tools'



Hash: UUID

Generate an v3 or v5 UUID from a selected string and a namespace. A UUID is a 128-bit value with the following format:

e6a80c09-99e7-49c8-8a5e-a48572915eaf

You will be prompted for the destination (clipboard or current file) of the UUID string; see the Output target section for details.

Repeatedly running the tool on the same string and namespace will always generate the same UUID. Thus, unlike the UUID generate tool, the UUIDs produced by this tool are not random.

You will be prompted for the UUID version (v3 or v5) and the namespace. A namespace is simply another UUID. When asked for the namespace, you can either enter one manually or select one of the following pre-defined namespaces:

  • DNS
  • URL
  • OID
  • X500

These four namespace names represent "potentially interesting" UUIDs defined in Appendix C of RFC 4122, the spec for UUIDs. The Valet isn't quite sure what makes these UUIDs "interesting"; perhaps it was just an inside joke between the RFC's authors.

Additional named namespaces can be defined by clicking on the "Edit UUID namespaces" option at the bottom of the Valet tool menu. JSON is used to define name/namespace pairs. For example, the following JSON string defines two namespaces named "My namespace 1" and "My namespace 2":

{ "My namespace 1": "e6a80c09-99e7-49c8-8a5e-a48572915eaf", 
  "My namespace 2": "9a92f64b-1a3d-4a41-9c60-dfe3e6b8e22f" }

User-defined namespace names will be included in the namespace selection list when the UUID hash tool prompts you for a namespace.

WARNING: User-defined namespaces can be viewed by anyone who has access to your computer account and knows how to use Code Valet. So, it's up to you to weigh the convenience of saving your UUID namespaces against the level of security you require.

Return to 'Hash Tools'



Line: Count

Counts the number of lines, words, and characters in the selected text. Line and character counts are done pretty much as you would expect. However, word counts require an explanation.

There are some very sophisticated algorithms out in the wild for counting words, but none are perfect. For example, an early incarnation of this tool used an uber-complex regex that counted words like "isn't" as 2 words. Some say it is, some say it ain't. Coders aren't paid by the word, so the Valet sides with those who say "isn't" ain't.

To keep it simple, the Valet assumes words are any jumble of characters delimited by whitespace. It's easy to understand and -- better yet, from the Valet's perspective -- easy to implement. If this admittedly unsophisticated approach doesn't meet your word counting needs, c'est la guerre.

Return to 'Line Tools'



Line: Index

Add indices to the start of each line. You will be prompted for the following options:

OptionDefaultDescription
Start index string?1.The start index plus prefix or suffix characters. The start index may be a number or a single letter.
Delimiter?NewlinesThe delimiter for list items (Newlines, Commas, Semicolons, Spaces, or Tabs).

The index number or letter will be incremented for each entry in the list. Shown below are some examples.

Example 1:

Add indices to each line using "1." as the start index string.

------------------------------
Before 
------------------------------
// Lorem ipsum dolor 
// sit amet consectetur 
// adipiscing elit

------------------------------
After 
------------------------------
// 1. Lorem ipsum dolor 
// 2. sit amet consectetur 
// 3. adipiscing elit

Example 2:

Add indices to each line using "(a)" as the start index string.

------------------------------
Before 
------------------------------
// Lorem ipsum dolor 
// sit amet consectetur 
// adipiscing elit

------------------------------
After 
------------------------------
// (a) Lorem ipsum dolor 
// (b) sit amet consectetur 
// (c) adipiscing elit

The default starting index string is "1.", but that can be changed via the tool.line.index.default property in the Valet's extension settings.

The tool will strip indices that match the index pattern you provide if all lines already match the pattern. Not only is index stripping useful in and of itself, but it makes it possible to re-index a set of lines by running the tool twice against the same input.

Example 3:

Re-sequence indices using the start index string "(a)".

------------------------------
Before 
------------------------------
// (u) Lorem ipsum dolor 
// (x) sit amet consectetur 
// (n) adipiscing elit

------------------------------
After 1st run
------------------------------
// Lorem ipsum dolor 
// sit amet consectetur 
// adipiscing elit

------------------------------
After 2nd run
------------------------------
// (a) Lorem ipsum dolor 
// (b) sit amet consectetur 
// (c) adipiscing elit

The default delimiter is newline, and that's what was used in the previous examples. However, commas, semicolons, or spaces can also be used as the delimiter as shown in the following example.

Example 4:

Add indices starting with "1." to a comma-separated list

------------------------------
Before 
------------------------------
// Lorem, ipsum, dolor, 
// sit, amet

------------------------------
After
------------------------------
// 1. Lorem
// 2. ipsum
// 3. dolor
// 4. sit
// 5. amet

This tool was a relatively late arrival to the Valet's stable of thoroughbreds. It does one thing and it does it well. However, don't set your expectations too high -- fancy multi-level lists with sub-indices are way beyond its modest capabilities.

Return to 'Line Tools'



Line: Join

Joins selected lines into a single line. If the lines all begin with comment characters, the comment characters will be removed before joining the lines.

If there are spaces anywhere in the lines to be joined, then the joined lines will be trimmed front and back and then joined by a space. For text that doesn't contain spaces, the lines will be joined without spaces.

Example:

Join comment lines into a single line.

-----------------------------------------------------------
Before 
-----------------------------------------------------------
// Lorem ipsum dolor 
// sit amet, consectetur 
// adipiscing elit.

-----------------------------------------------------------
After 
-----------------------------------------------------------
// Lorem ipsum dolor sit amet, consectetur adipiscing elit.

If you think the Join tool looks suspiciously like the Comment Wrap tool, you are correct. Invoking the Join tool is no different than using Comment Wrap with the column value set to infinity. And, as even the ancients knew, infinity is exactly 231-1.

This tool uses the Valet's smart select feature to determine what text to process.

Return to 'Line Tools'



Line: Sort

Sorts the selected lines of text. You will be prompted for one of the following options when using this tool:

OptionDefaultDescription
Numeric sort?YesSort numerically instead of alphabetically if all lines start with a number.
Start column number?1The starting column for the comparisons.

The default setting for numeric sort can be overridden in the Valet's extension settings using the tool.sort.numericSort property. The tab cleanup tool is run on the selected lines prior to sorting.

Numeric sorting
When text containing numbers is sorted lexically it won't be sorted by the numbers' values if they have different lengths. Shown below is a simple example:

Example 1:

Different methods of sorting text.

----------------   ---------------
Lexical sorting    Numeric sorting
----------------   ---------------
      1                  1
      1111               2
      2                  3
      222                33
      3                  222
      33                 1111

If you set this tool's "Numeric Sort" option to "Yes", then the Valet will determine if all the text to be sorted starts with numeric values. If it does, then the data will be sorted numerically.

Sorting delimiter-separated lists (DSLs)
Although the typical use of the sort tool is for sorting lines, it can also be used to sort DSLs embedded in strings. The sort tool will assume it's sorting a DSL if the text selected for sorting is entirely on a single line.

Example 2:

Sort a comma-separated list using ascending sort.

---------------     ------------------------
CSL before          CSL after ascending sort
---------------     ------------------------
q,w,e,r,t,y         e,q,r,t,w,y

The default delimiters are comma and semicolon. The list of delimiters can be modified or augmented via the tool.sort.delimiters property in the Valet's extension settings.

The same rules used to sort lines apply when sorting DSLs.

Return to 'Line Tools'



Morph: Adhoc template

The Valet's adhoc templates are a quick-and-dirty way to perform repetitive code generation when it's just not worth the trouble to create a VS Code snippet or macro.

To use this tool, select one or more lines of data that you want to use as the input arguments to the template, then launch the tool. You will be prompted for the following options:

OptionDefaultDescription
Template?--The template to apply to the selected lines.
Delimiter?CommasThe delimiter for multiple arguments. (Commas, Semicolons, Spaces, or Tabs)

The template format is simple and easy to use. Replacement arguments are specified by {n}, where {0} is the first argument, {1} is the second, etc. (If you've used C#'s positional string formatting, this will seem very familiar.)

Example 1:

Assume we've defined a class named HttpCode with integer
constants for the return codes. To display the codes as
strings, build case statements for a switch block using
the adhoc template tool.

Template: case HttpCode.{0}: return "{0}";

-----------------------------------------------------
Before
-----------------------------------------------------
OK
ServerError
NotAcceptable
NotFound

-----------------------------------------------------
After running the Template tool
-----------------------------------------------------
case HttpCode.OK: return "OK";
case HttpCode.ServerError: return "ServerError";
case HttpCode.NotAcceptable: return "NotAcceptable";
case HttpCode.NotFound: return "NotFound";

To help make the return text a bit more muggle-friendly, use one of the adhoc template tool's functions that convert variables to non-variable cases.

Example 2:

Same as Example 1, but use the adhoc template tool's $SC 
function to convert the return string to sentence case.

Template: case HttpCode.{0}: return "$SC{0}";

-----------------------------------------------------
Before
-----------------------------------------------------
OK
ServerError
NotAcceptable
NotFound

-----------------------------------------------------
After running the Template tool
-----------------------------------------------------
case HttpCode.OK: return "Ok"
case HttpCode.ServerError: return "Server error"
case HttpCode.NotAcceptable: return "Not acceptable"
case HttpCode.NotFound: return "Not found"

The template tool recognizes the following functions:

FunctionPurposeExample
$LClower case"No_Fish_Today" >> "no_fish_today"
$UCUPPER CASE"No_Fish_Today" >> "NO_FISH_TODAY"
$NCno case"NoFishToday" >> "no fish today"
$SCSentence case"NoFishToday" >> "No fish today"
$TCTitle Case"NoFishToday" >> "No Fish Today"
$CAMcamel-case"NoFishToday" >> "noFishToday"
$CONCONSTANT_CASE"NoFishToday" >> "NO_FISH_TODAY"
$DOTdot.case"NoFishToday" >> "no.fish.today"
$KEBkebab-case"NoFishToday" >> "no-fish-today"
$PASPascalCase"noFishToday" >> "NoFishToday"
$PATpath/case"NoFishToday" >> "no/fish/today"
$SNAsnake_case"NoFishToday" >> "no_fish_today"

The adhoc template functions simply proceed the position arguments; parentheses are not used. For example, in the template "Test $SC{0}" the sentence case function will be applied to positional argument 0.

Other features of the adhoc template tool include the following:

  • Multiple arguments are delimited with either commas, semicolons, spaces, or tabs.
  • The same argument can be used multiple times in the template.
  • Input arguments can be skipped (e.g. a template could use {2} without using {0} or {1})
  • The template will convert "\n" to linefeeds and "\t" to tabs.

Example 3:

This example uses a template to generate a Python if/else block 
from arguments 0, 1, and 3 of a comma-separated list.

Template: 
if {1} is not None:\n\t{0} = len({1})\nelse:\n\t{0} = {3}\n

-----------------------------------------------------
Before
-----------------------------------------------------
aLth, aStr, ignore this arg, 0
bLth, bStr, skip me too, -1

-----------------------------------------------------
After running the Template tool
-----------------------------------------------------
if aStr is not None:
	aLth = len(aStr)
else:
	aLth = 0

if bStr is not None:
	bLth = len(bStr)
else:
	bLth = -1

Now, before any of you purists start whining about this last admittedly contrived example, the Valet agrees that code duplication is inherently evil. However, sometimes despite your best intentions you just have to dance with the devil and generate code based on a boilerplate pattern. But please, use this tool wisely -- with great power comes great responsibility.

And yes, Pythonistas, when creating that last example the Valet was well aware that Python has a ternary conditional operator. However, its syntax is an abomination that is rightfully shunned by anyone for whom C is the paterfamilias of their software family tree.

Finally, regex gurus may question the need for the template tool. They will extol the virtues of "capturing groups" and "back references". Let them have their fun. The Valet counts itself a member of the unrepentant developer demimonde that would rather binge-watch the Star Wars sequels than wrestle with a complex regex; this tool is for us.

Return to 'Morph Tools'



Morph: Merge lists

Merge two or more lists by using the first column of each list as keys to the list data. This is best explained by an example.

Example 1:

----------------------------------------------
Two lists, each with three keys plus a header.
----------------------------------------------
	keys   col-1
	key-a  1.1
	key-b  1.2
	key-c  1.3

	keys   col-2
	key-a  2.1
	key-b  2.2
	key-c  2.3

----------------------------------------------
After applying the merge lists tool on these
two lists.
----------------------------------------------
	keys   col-1  col-2
	key-a  1.1    2.1
	key-b  1.2    2.2
	key-c  1.3    2.3

Here are the basic rules for using the merge lists tool:

  • Each list needs to be separated by one or more blank lines.
  • A list must have two or more columns.
  • The first column of each list is assumed to contain the keys used to collate the lists.
  • Merging can be performed on two or more lists.
  • Not every key needs to be defined in each list. If a key is missing, a "-" string will be put in the corresponding table cell.

Example 2:

----------------------------------------------
Three lists that don't all have the same 
four keys.
----------------------------------------------
	key-a  1.1  2.1
	key-b  1.2  2.2
	key-c  1.3  2.3

	key-a  3.1 
	key-b  3.2 
	key-d  3.4 

	key-b  4.2  5.2
	key-c  4.3

----------------------------------------------
After applying the merge lists tool on these 
three lists.
----------------------------------------------
	key-a  1.1  2.1  3.1  -    -
	key-b  1.2  2.2  3.2  4.2  5.2
	key-c  1.3  2.3  -    4.3  -
	key-d  -    -    3.4  -    -

By default, the '-' string is used in table cells that do not have data. This string can be changed using the tool.mergeLists.emptyCell property of the Valet's extension settings.

When using this tool, you will be prompted for the following options:

OptionDefaultDescription
Delimiter?SpacesThe delimiter used to parse the list items into columns. (Spaces, Commas, Semicolons, or Tabs)
Change marker?A string (e.g. "*") used to mark values that are different from the previous column of the same row. Leave this blank if you don't want to mark changes.
Column spacing?1Spacing between columns in the generated table. Only applies if the Delimiter is Spaces

This tool uses the Valet's smart select feature to determine what text to process.

Return to 'Morph Tools'



Morph: Tab cleanup

This tool cleans-up tabs in the selected text as follows:

  • Leading tabs are kept as-is.
  • Leading spaces intermingled with leading tabs are removed or converted to tabs.
  • After the first non-space/non-tab character, all tabs are converted to spaces so that characters remain in the same place on the line relative to other lines.
  • Trailing spaces and tabs are removed from each line. (This is not done in markdown docs, where trailing spaces mean something).

After this tool is run, tabs will only be used for indenting the text at the start of the line, unless you've enabled VS Code's insertSpaces option. The philosophy behind these cleanup steps is described in the Valet's tab manifesto.

Return to 'Morph Tools'



Morph: Unicode values

Show the Unicode hexadecimal values for each character in the selected text. The conversion is done in-line in your document, which is probably not something you want to be permanent. So, don't forget to UNDO once you're done.

Example:

-----------------------------------------------------
Before
-----------------------------------------------------
Hello, Γεια, Привет

-----------------------------------------------------
After
-----------------------------------------------------
H     e     l     l     o     ,           Γ     
0048  0065  006C  006C  006F  002C  0020  0393  

ε     ι     α     ,           П     р     и     
03B5  03B9  03B1  002C  0020  041F  0440  0438  

в     е     т     [cr]  [lf]  
0432  0435  0442  000D  000A 

You'll be prompted for the following option when using this tool:

OptionDefaultDescription
Chars per line8The max number of Unicode hex values printed per line before wrapping to the next line. (0 = no wrapping)

The hex value for each character takes 6 characters (4 digits plus 2 spaces) when printed by this tool. So, by default the text is wrapped to avoid the need for horizontal scrolling to view the results when converting long lines of text. However, should you not share the Valet's disdain for horizontal scrolling, the default wrapping value can be set using the tool.unicodeValue.charsPerLine property in the Valet's extension settings.

Also, as noted in the Valet's comments on localization, the glyphs for some languages may not align correctly when printed above the hex values. Wrapping the output of this tool can help reduce the effects of incorrect alignment.

Microsoft's HexEditor extension provides a full-featured custom editor for viewing and editing files as hex values. The Valet suggests you consider using that extension if your needs go beyond an occasional peek behind the Unicode curtain.

Return to 'Morph Tools'



Text: lowercase

Converts all selected text to lowercase.

This tool exists because back when the Valet first donned the bowtie, VS Code didn't have a command for converting to lowercase. Yes, that was just after VS Code emerged from the primordial ooze, but trust us, it wasn't there. UPPERCASE was missing as well. The Valet keeps these tools around both for sentimental reasons and because the list of case conversion tools seems incomplete without them.

Return to 'Text Case Tools'



Text: Sentence case

Convert all words except the first word in a sentence to lowercase.

In English and many other languages converting to sentence case is complicated by exceptions to the case rules that include the following:

  • Proper names should always be capitalized. (Example: Bill Gates)
  • Acronyms and abbreviations that are all uppercase. (Example: ASCII)
  • Rogue words that defy normal case rules. (Example: iPhone)

The number of words that belong to these categories is almost infinite. Thus, more out of expediency than any sense of fair play, all words are created equal in the eyes of the Valet and it uses standard case rules for them all.

Return to 'Text Case Tools'



Text: Title Case

Converts every word so that the first letter is uppercase and the remaining letters are lowercase.

In literary English, title case usually involves leaving simple words (a, and, in, on) in lowercase unless they start a sentence. Don't look for any such refinement here -- the Valet will convert every word. Strunk & White would not be amused.

Also, like the sentence case tool, the title case tool has no respect for special words. For example, "ASCII" will be converted to "Ascii" and "iPhone" will become "Iphone".

Return to 'Text Case Tools'



Text: UPPERCASE

Converts all selected text to uppercase, or as the Valet somewhat superciliously likes to call it, majuscule.

No shouting, please.

Return to 'Text Case Tools'



Word: camelCase

Convert words to camel-case.

Examples

--------------   --------------
Before           After
--------------   --------------
No fish today    noFishToday
NO_FISH_TODAY    noFishToday
no.fish.today    noFishToday
no/fish/today    noFishToday
NoFishToday      noFishToday

Return to 'Word Case Tools'



Word: CONSTANT_CASE

Converts words to constant case format.

Examples

--------------   --------------
Before           After
--------------   --------------
No fish today    NO_FISH_TODAY
no.fish.today    NO_FISH_TODAY
NoFishToday      NO_FISH_TODAY
no/fish/today    NO_FISH_TODAY

Return to 'Word Case Tools'



Word: dot.case

Converts words to dot case format.

Examples

--------------   --------------
Before           After
--------------   --------------
No fish today    no.fish.today
NO_FISH_TODAY    no.fish.today
NoFishToday      no.fish.today
no/fish/today    no.fish.today

Return to 'Word Case Tools'



Word: kebab-case

Converts words to kebab-case format.

Examples

--------------   --------------
Before           After
--------------   --------------
No fish today    no-fish-today
NO_FISH_TODAY    no-fish-today
NoFishToday      no-fish-today
no/fish/today    no-fish-today

Why the name "kebab-case"? Etymology is not the Valet's strong suit, but it clearly comes from the fact that the dashes resemble skewers used to hold together cubes of meat in a shish kebab.

Blake Embrey's npm change-case library (the basis for the Valet's word case tools) refers to this format as "param-case" to avoid conflicts with an existing npm kebab-case library. However, the Valet doesn't operate under the same restrictions as Blake's library, so it will stick with the whimsical kebab-case over the dull and generic param-case.

Return to 'Word Case Tools'



Word: no case

Convert words to no case. This means variable-like words will be split into multiple words. The easiest way to explain this is via some examples.

Examples

--------------   --------------------------
Before           After running no case tool
--------------   --------------------------
NO_FISH_TODAY    no fish today
no.fish.today    no fish today
no/fish/today    no fish today
NoFishToday      no fish today
noFishToday      no fish today
No fish today    no fish today

When you use this tool, you will be asked to select a case type for the conversion from the following options:

Case typeDescription
lowercaseConvert all chars to lowercase. This is the option used for the examples above.
Sentence caseConvert the first char of the first word to upper case, the remainder to lower case.
Title CaseConvert the first char of each word to upper case, the remainder to lower case.
UPPERCASEConvert all chars to UPPERCASE.

As you can see, these case options match the tools found in the Text Case tool set. The only difference is that this tool will split variable names, while the Text Case tools will not.

Return to 'Word Case Tools'



Word: PascalCase

Convert words to PascalCase, which is simply camel-case with attitude.

Examples

--------------   --------------
Before           After
--------------   --------------
No fish today    NoFishToday
NO_FISH_TODAY    NoFishToday
no.fish.today    NoFishToday
no/fish/today    NoFishToday
noFishToday      NoFishToday

Return to 'Word Case Tools'



Word: path/case

Converts words to path case format.

This tool also converts annoying DOS/Windows paths with backslashes (thanks, Bill!) to forward slashes. Yes, that's a simple change-and-replace that can be done with any text editor. But once the Valet went to the trouble of adding a path case tool, ignoring backslashes just felt so dirty. And not in a good way.

Examples

--------------   --------------
Before           After
--------------   --------------
no\fish\today    no/fish/today
No fish today    no/fish/today
NO_FISH_TODAY    no/fish/today
NoFishToday      no/fish/today
no.fish.today    no/fish/today

Return to 'Word Case Tools'



Word: snake_case

Converts words to snake case format.

Examples

--------------   --------------
Before           After
--------------   --------------
No fish today    no_fish_today
NO_FISH_TODAY    no_fish_today
NoFishToday      no_fish_today
no/fish/today    no_fish_today

Return to 'Word Case Tools'



Miscellany


Buttons on status bar

When the Valet is installed as an extension, at start-up VS Code will add the following buttons to the status bar at the bottom of the VS Code window.

ButtonShortcutAction
Valetalt+v h or
alt+v alt+v
Displays a menu listing all Valet tools. Selecting a list entry launches that tool.
Repeatalt+v rAllows you to re-run the last tool using the same options. This button only becomes visible after you've used a Valet tool, and isn't actually labeled "Repeat"; instead, the label will show the most recently used tool.

Although the Valet enjoys the limelight, if you would rather have it skulk in the shadows the status bar buttons can be removed via the control.button.valet and control.button.repeat properties in the Valet's extension settings.

The Valet's tools menu is also available via the VS Code context menu that is displayed when right-clicking on text selected in the editor. If you don't want the Valet to appear in the context menu, use the extension setting's control.contextMenu property to remove it from the menu.

If all else fails, you can find the Valet tools in the VS Code command palette using the standard VS Code [ctrl+shift p] shortcut. The list can be very long, so to find the Valet's tools filter on (what else?) "Valet".

Finally, you may be asking why there are two shortcuts for the Valet's tools menu. The [alt-v h] shortcut is a no-brainer -- legions of coders are trained to find help via shortcuts that use the "h" key. The [alt-v v] "v" double-tap simply gets you there quicker.

Return to TOC


Extension settings

The Valet is a bit fussy about its appearance, but you can control some aspects of that via VS Code's Settings page. However, please note that the bowtie is NOT negotiable.

The last time the Valet checked, you could get to its extension settings as follows:

  • Click on the Extensions icon (that 3-squares-plus-1 thing) in the VS Code sidebar.
  • Find the Valet's stylish red vest in the installed Extensions list.
  • Click on the gear icon.
  • Select "Extension Settings".

However, options move, menus change -- you just never know what Redmond's jolly jokesters will do next to make your life better, whether you like it or not. So, if the Valet's directions lead you down a rabbit hole, see VS Code's own user settings page for the latest on where to find extension settings.

Return to TOC


JSON languageIds property

Several configuration properties used by the Valet are defined using a JSON array of objects containing languageIds properties. The languageIds property is used to define an array of target language IDs for a configuration setting.

Each language ID in the array is a string, usually all lowercase, that represents the VS Code ID for the language. In many cases, the ID for a given language is obvious; for example, the language IDs for Java and Python are "java" and "python". In other cases, the language ID might not be so obvious; for example, the ID for C# is "csharp", not "c#".

To determine the language ID for a given language, open the "Select Language Mode" menu on VS Code's status bar. That menu shows a list of all languages supported by VS Code, and in each menu entry the language ID is the text in parenthesis.

If you set the languageIds property in the JSON to an empty array, the Valet will assume that the associated property applies to all languages. That's often the simplest approach if you don't want to be bothered with finding the VS Code language IDs for the languages you code in.

The following JSON examples show various ways of setting the languageIds for the Valet's tool.comment.wrap.prefixes property.

Example 1:
* and /// will be treated as a line comment prefix in Java and C#.

[
	{ 
		"languageIds": ["java", "csharp"], 
		"prefixes": ["*", "///"]
	}
] 

Example 2:
/// will be treated as a line comment prefix in all languages.

[
	{ 
		"languageIds": [], 
		"prefixes": ["///"]
	}
] 

In JSON, linefeeds and whitespace are ignored. So, for example, the JSON in example 2 could be converted to a single line of text using the Valet's Line: Join tool and be added to the Valet's config settings as this:

[ { "languageIds": [], "prefixes": ["///"] } ]

Return to TOC


Disabling shortcuts

The Valet's extension settings include a control.shortcuts property that can be used to enable/disable alt-v shortcuts. Disable shortcuts if they would interfere with your own custom shortcuts, or if you simply don't like the idea of a parvenu like the Valet mingling with VS Code's regular shortcuts.

Return to TOC


Modifying the tools menu

By default, all tools in Tools List are shown in the Valet's tools menu. However, the Valet understands you may not share the same unconditional love it has for all its children, so you can select which tool categories are shown in the menu via the following properties in the Valet's extension settings.

Tool categoryDisplay property
Aligncontrol.menu.align
Commentcontrol.menu.comment
Encodecontrol.menu.encode
Escapecontrol.menu.escape
Filtercontrol.menu.filter
Generatecontrol.menu.generate
Hashcontrol.menu.hash
Linecontrol.menu.line
Morphcontrol.menu.morph
Textcontrol.menu.text
Wordcontrol.menu.word

If you disable display of a category of tools, those tools can still be accessed via VS Code's tool palette.

The top of the tools menu contains a history of the last tools used to make it easier to access frequently used tools. The default maximum number of entries in the history list is 5, but this can be modified via the control.history.count property in the extension settings. If you live in the moment and despise nostalgia, set this property to 0.

By default, the tool history is saved between sessions. If you'd rather not save tool history, set the extension settings' history.persist property to false.

Return to TOC


Internationalization (i18n)

The Valet attempts to be a good citizen of the world and accommodate languages other than English. For example, the sorting and case conversion tools all use the locale-aware versions of the appropriate JavaScript functions for comparing text.

However, the Valet's text alignment features may disappoint coders who use languages that contain glyphs different from those found in Latin or related alphabets. For example, the glyphs for Chinese, Japanese, and Korean are often wider than Latin alphabet character glyphs, even when using monospaced fonts. As a result, text in these languages may not align correctly using the alignment tools when mixed with text in Latin alphabets.

Return to TOC


Localization (l10n)

The Valet was written in English, but it is ready for localization. If you would like to volunteer to translate the Valet from English into another language, please contact us at valet@sophodoros.com.

But please, only apply for the Valet translation gig if you are reasonably fluent in both English and the target language. The Valet understands that tools like Google Translate have their uses. However, using them to translate a relatively large, cohesive (if not necessarily coherent) body of work into a language you don't already know might result in too many examples of "my hovercraft is full of eels."

We can't actually pay you for translation work. However, anyone providing a translation will be eligible for inclusion in the "Friends of the Valet" gallery in the Acknowledgments, and that, of course, is a reward priceless beyond compare.

Return to TOC


Output target

Most of the Valet's tools replace the selected text with the output of the tool. However, some tools (including most of the escape and hash tools) will ask you to select an output target and provide the following options:

OptionDescription
Replace textReplace the selected text with the output of the tool.
To clipboardWrite the output of the tool to the system clipboard.
BothReplace the text and write the output to the clipboard.

These options exist because the Valet couldn't decide what users would want to do with the output of these tools. Even the Valet's omniscience has its limits. The default option is to write to the clipboard because that seemed like the most likely outcome.

Return to TOC


Escaping non-ASCII Unicode

Many of the Valet's escape tools ask you if you want to escape non-ASCII Unicode characters. If you answer yes, all Unicode characters above codepoint 0x007F will be escaped. Most text files you encounter when using VS Code will be encoded using UTF-8, so typically escaping non-ASCII characters won't be necessary.

However, except for making it less readable by humans, it's usually OK to escape non-ASCII characters in UTF-8 files. So, go ahead and escape them if you are an English-speaking monoglot with an atavistic need to escape those outlandish foreign characters.

Return to TOC


Text field history

Some tools display a pick list of the history of previous values when you are prompted to enter data. Those tools are listed in the table below. The table also lists the extension settings option that you can use to set the maximum number of history entries for that tool and the default values used by the Valet.

ToolDisplay propertyDefault
Align: Texttool.align.text.history.count10
Filter: Keeptool.filter.keep.history.count10
Filter: Removetool.filter.remove.history.count10
Filter: Templatetool.template.history.count10
Hash: HMACtool.hmac.userkeys.history.count0
Hash: UUIDtool.uuid.namespace.history.count0

Set a tool's history count property to 0 to disable history for that tool. The default counts for the Hash tools are set to 0 because that data may be sensitive and the Valet prefers to hide it from prying eyes unless you say otherwise.

Clicking on a history entry in a tool's pick list will immediately use that value. However, if you use the up- and down-arrow keys to navigate the history list, you can edit the selected string in the text field before hitting Enter to use the value.

If your history becomes filled with cruft from bygone eras, use the "Clear history" option at the bottom of the Valet's tools menu to hide any embarrassing faux pas from posterity.

By default, tool text history will be persisted between sessions of VS Code. Should your privacy concerns outweigh the convenience of retaining history, go to the extension settings and disable the history.persist property. When this property is disabled, history will be discarded when you exit VS Code. Tool menu history persistence is also controlled by the history.persist property.

Return to TOC


Smart select

Most Valet tools that change text only operate on the text explicitly selected by the user. However, for some tools users will almost always want the tool to operate on the entire line containing the selected text, even if only a portion of the text is selected.

For example, consider the following comment line with whitespace at the start of the line:

    // Lorem ipsum dolor sit amet consectetur

If the code wrap tool is set to 40 chars and you only select the text starting with the "//" in the above line (i.e., the leading spaces are not selected), the text will be wrapped as follows:

    // Lorem ipsum dolor sit amet 
// consectetur

Although that perhaps is correct from the perspective of what text was selected, that's probably not what you wanted. Instead, the wrap tool should act as if the entire line was selected so it preserves the starting indentation on the wrapped lines, like this:

    // Lorem ipsum dolor sit amet 
    // consectetur

To ensure that this works as expected, the Valet implements a "smart select" feature. With smart select, the Valet assumes the full line of text is selected even if only a portion is selected. Smart select is used by the following tools that are designed to operate on entire lines of text:

Tools that use smart select
Align: Columns
Align: Text
Comment: Toggle
Comment: Wrap
Line: Join

Smart select is the default behavior for the tools in this table starting with Valet v2.3.0. You can disable this feature via the smart.select property in the Valet's extension settings.

Return to TOC


Tab manifesto

If you're at all serious about code aesthetics, you've probably already chosen sides in the great tabs-vs-spaces debate. The Valet strongly believes that source code should always use tabs for indentation, but nowhere else. Code that uses this approach can be viewed in any text editor with the coder's preferred tab size without distorting the format.

This tabs-are-for-indenting-only philosophy is what led to the creation of the tab cleanup tool, one of the original members of the Valet tool pantheon. The tab cleanup tool serves as a pre-filter for many of the other tools to ensure that any alignment goodness done by those tools is consistent regardless of the tab size setting.

However, while the Valet strongly favors the use of tabs for indentation, if you've enabled VS Code's insertSpaces option the Valet will respect your wishes and dutifully remove even leading tabs from the text. But it sure won't like it.

In a gesture perhaps intended as a way of bridging the great divide between anti-spacers and anti-tabbers, v1.52 of VS Code introduced a feature called sticky tabs. This feature makes the Valet's hateful grudge against leading spaces a little harder to justify if your files never leave the cozy confines of VS Code.

The Valet's tabbing philosophy only makes sense if you edit code using a monospaced font. If you don't, you are clearly wise in ways beyond the ken of mortal men, and the Valet can only wish you well in your journey beyond the stars.

Return to TOC


Logging and Privacy

The Valet writes log data to a VS Code output channel named (surprise!) "Code Valet". You can view the contents of this channel in VS Code as follows:

  1. Click "View" > "Output" in VS Code's toolbar.
  2. Click on the dropdown menu in the Output tab's header and select "Code Valet".

The privacy of all data written to VS Code output channels is governed by Microsoft's privacy policies for VS Code. The Valet itself NEVER transmits log data to Sophodoros or any other outside entities. If you contact Sophodoros to report an issue with the Valet, we MAY ask you to send us a copy of the Valet's log data that's shown in the log channel output.

The Valet's log may include configuration data and data entered as Valet tool parameters. Depending on how you use the Valet, this might include personally identifiable information (PII). Thus, you should carefully review the log data before sharing this data with anyone, including Sophodoros. If you have any concerns whatsoever about the possibility of there being PII or any other sensitive data in your Valet logs, do not share your logs.

If despite the Valet's assurances about the relative safety of your logs you still would rather not have your activity logged, you can turn the Valet's logging off by setting the log.level property to "Off" in the Valet's extension settings. If you change the log level, you must restart VS Code for the change to take effect.

Return to TOC


Acknowledgments

The Word Case tools use Blake Embrey's npm change-case package for converting between variable name formats. (PascalCase, camel-case, etc.)

Crypto-related hashing in the Hash tools is done using the npm crypto-js package. CRC hashes are generated courtesy of the npm crc-32 package. UUIDs (both hashed and random) are generated using the npm uuid package.

Base64 encoding, HTML escaping, and XML escaping are implemented using the npm html-entities package. Most of the other escape tools rely on the Valet's port of portions of the Apache Commons StringEscapeUtils library from Java to Typescript.

The following users have suggested useful features or fixes and are thus accorded "Friend of the Valet" status, with all the honors and privileges that pertain to the title:

  • Jessie W.
  • Michal K.

The Valet would be remiss if it didn't send sloppy wet kisses to StackOverflow, which has become so ubiquitous that it's easy to forget what an invaluable resource it is.

And finally, as a VS Code extension the Valet is forever indebted to the minions of Redmond for their efforts in making VS Code free, open source, and (most importantly) extensible via its extensions API.

However, the Valet only wishes the founding mothers and fathers had shown a little more imagination when it came time to name their new editor. While the Valet gladly evangelizes for VS Code, heathens are both skeptical and confused when told, "VS Code is NOT Visual Studio." And, it really yanks the Valet's bowtie when online searches targeting VS Code return links that are mostly about Visual Studio.

Return to TOC


Support

If you have questions, comments, or bug reports related to this extension, please submit them to valet@sophodoros.com.

Please rate the Valet in the Microsoft Marketplace if you find it at all useful. For all its showy arrogance, the Valet really does care what you think.

Finally, to answer what is probably the single most important question burning foremost in your mind, the Valet pronounces its name "val-LAY", never "VAL-it".

Return to TOC


License

Copyright Sophodoros LLC

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Return to TOC



Last update: 2024-03-23


  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2025 Microsoft