TL DR
Is there some extension, or other functionality, to select code above and below the cursor that is surrounded by some characters, e.g. %% or % ===== or anything else?
Why
I am coding Matlab in VSCode, since the builtin Matlab editor lacks a lot of useful functionalities. However, One thing that I miss is the ability to run 'sections':
%% section 1
x = 0:0.01:pi;
y = sin(y);
plot(x,y);
%% section 2
x = 0:0.01:pi;
y = cos(y);
plot(x,y);
%% section 3
x = 0:0.01:pi;
y = tan(y);
plot(x,y);
A section can be run using Ctrl+Enter. Since I use Matlab on Windows, there is no support for running the Matlab interpreter from the terminal/cmd.
So I created some AutoHotKey scripts that will copy selected code, open the Matlab window, paste it, and run. This works fine, however, when I want to run a very large section, this means that I have to select this manually, and press my defined shortcut to call the AutoHotkey script. Hence above question.
So say I have the cursor at some line insection 2, how can I select only the code in this section (including or excluding section 'headers', these are comments so does not matter).
I have made an extension Select By that allows the selection based on regular expressions relative to the cursor position. You can specify different expressions for forward and backward search and if you want to include the searched text in the selection.
You can set up to 5 regex searches.
The extension defines 5 commands that can be used in keyboard shortcuts
This can (of course) be done by writing a custom extension.
Since this seems like useful functionality in general and an interesting exercise, I've added the required capability to my personal vscode-smcpeak extension.
To use it:
Install vscode-smcpeak. This has to be installed manually for now. At time of writing, 0.0.7 is latest.
Install macros by ctf0. This one can be installed from within VSCode. Restart VSCode after installing it. (See below regarding the choice of "macros" extension.)
Add to your settings.json (File → Preferences → Settings, then click the "Open Settings (JSON)" icon in the upper right):
// Custom macros for ctf0.macros extension
"macros.list": {
// https://stackoverflow.com/questions/57749780/is-there-a-way-to-select-code-between-certain-characters
"selectPercentRegion": [
{
"command": "smcpeak.goToLineMatching",
"args": {
"regex": "^%%",
"moveUp": true,
"select": false,
"allowZeroMove": true
}
},
{
"command": "smcpeak.goToLineMatching",
"args": {
"regex": "^%%",
"moveUp": false,
"select": true,
"allowZeroMove": false
}
},
"smcpeak.revealCurrentSelection"
]
},
Add to keybindings.json (File → Preferences → Keyboard Shortcuts, then click the "Open Keyboard Shortcuts (JSON)" icon in the upper right):
{
"key": "ctrl+alt+m", // or whatever
"command": "macros.selectPercentRegion"
},
(Note: VSCode will always complain that macros.selectPercentRegion is not a valid command. That's a limitation of the "macros" extension.)
Then, with the cursor within a region delimited by the specified regexes, press the keybinding to activate the macro:
Why use two extensions?
The accepted answer, by rioV8 uses a single extension to answer the OP's question. This looks like a good solution to me, and is simpler to use than mine, so I approve of that being the accepted answer.
However, there is an advantage to my approach: it allows the behavior to be modified in settings.json. For example, the OP asked in a follow-up question about having the command additionally copy the text to the clipboard after selecting. Using the macro-based solution, this is an easy modification to settings.json; simply add:
"editor.action.clipboardCopyAction"
to the end of the selectPercentRegion macro. (That is the command normally bound to Ctrl+C.)
Thus, while my suggestion has more moving parts, I personally prefer this approach.
Which macros extension to use?
As Mark noted in a comment, the most popular macros extension, geddski.macros, is unmaintained. It furthermore has a rather serious bug in that the commands are not properly sequenced, leading to race conditions. (I actually saw this once during my testing.)
There are two forks of geddski.macros on the marketplace, l7ssha.macrosRe and ctf0.macros. l7ssha.macrosRe only adds the "delay" ability, which is an awkward way to resolve the race conditions. ctf0.macros, on the other hand, fully fixes the race condition (via a complete rewrite).
Therefore, I recommend ctf0.macros, and in fact have edited my answer to use it rather than the original geddski.macros extension.
However, be aware:
ctf0.macros uses macros.list rather than macros in settings.json
ctf0.macros requires a restart of VSCode after installation to activate
How it works
The additions are in vscode-smcpeak commit 6d5f5d4689.
My extension registers a new command, smcpeak.goToLineMatching, that searches up or down for a line containing a regex. The logic is very simple, just a loop and regex test.
It also registers smcpeak.revealCurrentSelection, needed because otherwise the selected text might be offscreen and nothing scrolls to it by default.
The macro selectPercentRegion uses goToLineMatching to look upwards for one regex, setting the anchor (selection start) there, then uses it again to look down for another regex (although they are the same here), extending the selection to that point. Then it scrolls to ensure the selection is visible.
It should be straightforward to transplant this code to your own extension if you don't want the rest of the stuff that mine provides. (But mine does not bind any keys, so there should be no downside to having the extra stuff.)
Here is another way to do this, with an extension I wrote Find and Transform.
Make this keybinding in your keybindings.json (or it could be a setting too):
{
"key": "alt+m", // whatever keybinding you want
"command": "findInCurrentFile",
"args": {
"find": "^(%%[\\s\\S]+?)(?=^$)|(^%%[\\s\\S]+)",
"run": [
"$${",
"const sections = vscode.window.activeTextEditor.selections;",
"await vscode.commands.executeCommand('cursorUndo');",
"const mySection = sections.find(section => section.contains(vscode.window.activeTextEditor.selection));",
"if (mySection) {",
"vscode.window.activeTextEditor.selections = [mySection];"
"}",
"}$$",
],
"isRegex": true,
"postCommands": "editor.action.clipboardCopyAction"
}
}
The find regex finds and selects all %% .... sections. But since you only want the section where your cursor started, some code is run to restore that original cursor and then find that section that contains the one current cursor. Then that section is selected. And in the postCommand that selection is saved to the clipboard.
That is using javascript and the vscode extension api within a keybinding or setting.
Related
I know the topic of multi cursors-editing in visual studio code is duplicate but what I want is the way (by keyboard) to select word occurrences in just one line in visual studio code, because the other option: ctrl + F2 it selects all the occurrences in all the file, and not the mouse way by holding alt and click.
let say I have this:
const FETCH_USERS_REQUEST = "FETCH_USERS_REQUEST";
const FETCH_USERS_REQUEST = "FETCH_USERS_REQUEST";
when the cursor is on REQUEST word for the second line I want to do two cursors in the second line after the two occurrences of REQUEST.
You have 2 alternatives:
Enable the Find in Selection option in the Find Widget after entering your find query.
An extension that I wrote does this fairly well, see Find and Transform.
With this simple keybinding:
{
"key": "alt+y", // whatever keybinding you want
"command": "findInCurrentFile",
"args": {
"restrictFind": "line" // find all on current line only
// with multiple cursors you can have as many current lines as you wish
}
}
It does a find in the current file. Since there is no actual find query, like REQUEST, designated in the args. It will find the current word at the cursor on the line. Different languages define what a "word" is differently. For javascript, for example, FETCH_USERS_REQUEST is the current word even if the cursor is on Request only.
You can manage this by actually selecting, double-clicking on Request or Ctrl+D, and then trigger the above keybinding. Then the extesnion will search for whatever is selected, if there is a non-empty selection.
The extension is designed to select those find matches, not put the cursor after them, but you can simply right-arrow to dismiss the selection and the cursor will be where you want.
[I have to update the extension, the current version v0.9.7 in the Marketplace won't do this - but here is a demo of it already working. It should be updated tomorrow at the latest, look for v0.9.8.]
I'm using Visual Studio Code 1.14 on MacOS and have tried creating my own keybinding that re-indents only the lines of code that I've highlighted.
I have this in keybindings.json:
[
{
"key": "alt+cmd+[", "command": "editor.action.reindentlines",
"when": "editorHasSelection && editorTextFocus"
}
]
I chose the commands for the "when": clause based on this article.
The Problem: When I use my custom keyboard shortcut, it re-indents the entire page instead of only the text I've selected.
It's petty, perhaps, but this can cause a formatting nightmare, such as when writing a ReactJS app where VSC's regex pattern for detecting how to indent lines seems to get confused when looking at a mix of javascript and html within a .jsx file. In such cases I only want to re-indent/auto-indent the text I choose - not the entire page.
How can I get the keybinding to function with the behavior I'm looking for?
The when-clause can only change when the command is active - not how it behaves. The issue is that the implementation of the command operates on the whole file, rather than the current selection.
I don't think reindentation of a selection is supported yet, but it seems to be on the roadmap. For instance, it was mentioned in #19847 (emphasis mine):
The reason that right now we don't support Reindent in ranges is that we have some issues with boundaries in embedded-language files. Some of them are just TextMate Grammar issues but I'm sure if that can fix all. Once that issue is addressed, I think it's easy to support reindent in ranges/selection. And then Reindent when paste/moveLines/etc.
Thanks to #Gama11 for pointing me to this github issue.
The solution that accomplishes what I was trying to do is to use the command editor.action.formatSelection instead of editor.action.redindentlines.
As shown by Gama11, reindent in ranges isn't currently supported, however Format Selection is a very similar command that uses different logic to accomplish indentation within a certain range.
How can I automatically hard wrap lines in VSCode? By that I mean if a line reaches a specified column, automatically insert a newline at the word boundary closest to that column without going over. Vim has a setting called textwidth that does this that I like to use when editing Markdown. It doesn't seem like VSCode does, as far as I can tell. It just has ways to control softwrapping.
VSCode doesn't support this out of the box. But you can install the Rewrap extension, which allows you to format the block that your cursor is currently in by pressing Alt + Q.
Rewrap requires no further settings, since it reads VSCode's settings to obtain the column at which to break.
Rewrap also supports automatic wrapping (off by default): https://github.com/stkb/Rewrap/wiki/Auto-wrap
Unfortunately, VSCode doesn't have this feature yet. But, we still can make it to be as close as vim automatic word wrapping beautiful feature.
First Step
We need to setup soft word wrap feature in VSCode.
Open VSCode Settings via Code => Preferences => Settings.
Add these 3 lines of editor settings.
"editor.wordWrap": "wordWrapColumn",
"editor.wrappingIndent": "same",
"editor.wordWrapColumn": n
Don't forget to change (n) with your preferred length of columns line. For me, I feel more comfortable to set it to 60.
Save this setting.
The main purpose of this first step is to make us feel more comfortable when we're typing because we don't need to manually type Enter and see a long line of text.
Second Step
We need to install Vim emulation for VSCode and set vim textwidth.
Install Vim emulation via VSCode extensions.
Open VSCode Settings via Code => Preferences => Settings.
Add this line of vim setting.
"vim.textwidth": n,
Don't forget to change (n) with your preferred length of columns line. For me, I will set this to be the same with (n) in the first step.
Save this setting.
Actual Use
When you finish to write your whole document, you can format it to be hard wrap lines using this way.
Block all text using visual line mode (Shift + v)
Type 'gq'
Now VSCode support auto "soft" wrapping out of the box.
Settings --> Text Editor --> Last 3 options (as on today) is for autowrapping.
Word Wrap (Controls how lines should wrap)
Word Wrap Column (Controls the wrapping column of the editor)
Wrapping indent (Controls the indentation of wrapped lines)
By default Word Wrap is off.
As of 2020 and if you're using the Prettier - Code formatter plugin:
Go to Plugins -> Find Prettier -> Cog -> Extension Settings -> Prettier: Print Width Fit code within this line limit and set to whatever you want. By default it's 80.
When you save the file, Prettier will format automatically.
Hard Wrap Comments
Use the Rewrap extension.
Soft Wrap Code
Add the following setting (replace column width with your preference): "editor.wordWrapColumn": 100
Then add either "editor.wordWrap": "wordWrapColumn" (wraps at the column) or "editor.wordWrap": "bounded" (wraps at either the column or the viewport).
Hard Wrap Comments and Soft Wrap Code
Unfortunately the extension and VSCode settings do not play nicely.
Feel free to upvote this feature request.
There is currently an Open request for this in the VS Code Issue tracker on GitHub, You Can Find It Here
Most of these didn’t work for me, but I found the extension Vsctoix, which does.
We start out with line breaks at column 80:
Mechanisms such as a “windfall clause” help distribute riches within particular
futures. But for a windfall clause to be useful, many conjunctive assumptions
have to be true. We present a new method to borrow against potential future
windfalls today, when they have greater marginal use. The method also increases
the probability and thus the expected value of the windfalls.
Then we execute “IX: Join Lines” (no parameter):
Mechanisms such as a “windfall clause” help distribute riches within particular futures. But for a windfall clause to be useful, many conjunctive assumptions have to be true. We present a new method to borrow against potential future windfalls today, when they have greater marginal use. The method also increases the probability and thus the expected value of the windfalls.
And then “IX: Break Line At” with parameter 100:
Mechanisms such as a “windfall clause” help distribute riches within particular futures. But for a
windfall clause to be useful, many conjunctive assumptions have to be true. We present a new method
to borrow against potential future windfalls today, when they have greater marginal use. The method
also increases the probability and thus the expected value of the windfalls.
It would be neat if it respected paragraph breaks and did both steps at once, but so far it’s the only extension that works for me – except I haven’t tried the vim emulation yet.
You can do this without any extension. You just use two regex search-and-replace.
Isolate the lines you want to rewrap by moving them to a separate file.
Join all the lines into one line. For example, ctrl+h, "\n" ==> " ". Note: make sure regex is enabled (the dot star icon)
Split the line into multiple lines. For example, ctrl+h, "(.{100}) " ==> "$1\n". Notice the space after the paren.
Copy the lines back to the original file.
There are many variations on this technique. For example, you could using comma instead of space "(.{100})," ==> "$1,\n". You could use Find in Selection alt+L instead of using a temp file.
Edit: (below answer might be for a soft wrap, see here for difference between soft and hard wrap: https://stackoverflow.com/a/319932/9481613)
In my version it is Preferences -> Settings then scroll down to "Editor: Word Wrap" where a dropdown box is available from which I selected wordWrapColumn. After choosing this and closing, when I click on View now at the bottom it says Word Wrap Alt+Z.
If anyone is running having issues, accessibility support/screen reader may need to be disabled. Go to preferences >> text editor >> accessibility support and toggle it off.
You can easily set the column limit using ColumnLimit member in C_Cpp.clang_format_fallbackStyle in settings.json (You have to install Microsoft C/C++ extension)
"C_Cpp.clang_format_fallbackStyle": "{ BasedOnStyle: WebKit, IndentWidth: 4, ColumnLimit: 80 }",
Then you can format the file using Shift + Alt + F
There are many options you can change in this format feature
"C_Cpp.clang_format_fallbackStyle": "{ BasedOnStyle: WebKit, UseTab: Never, IndentWidth: 4, TabWidth: 4, BreakBeforeBraces: Attach, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: false, ColumnLimit: 80, AccessModifierOffset: -4 }",
Name of the predefined style used as a fallback in case clang-format
is invoked with style file but the .clang-format file is not found.
Possible values are Visual Studio, LLVM, Google, Chromium, Mozilla,
WebKit, Microsoft, GNU, none, or use {key: value, ...} to set specific
parameters. For example, the Visual Studio style is similar to: {
BasedOnStyle: LLVM, UseTab: Never, IndentWidth: 4, TabWidth: 4,
BreakBeforeBraces: Allman, AllowShortIfStatementsOnASingleLine: false,
IndentCaseLabels: false, ColumnLimit: 0, AccessModifierOffset: -4,
NamespaceIndentation: All, FixNamespaceComments: false }
Before
void Proc::Memory::getSramOff(const char* mem_name, uint dataSize, uint addrBits, uint& noOfBytes, uint& sram_off)
After
void Proc::Memory::getSramOff(const char* mem_name, uint dataSize,
uint addrBits, uint& noOfBytes, uint& sram_off)
Is it possible to customize the way code folding works in Visual Studio Code?
I use a common pattern of defining regions of code across a variety of different document types.
So, for XML I wrap sections of text with <!-- #region --> and <!-- #endregion -->
For c#, I use #region to #endregion,
For TypeScript/Javascript, I use /* #region */ and /* #endregion */.
In full Visual Studio (not VS Code), I have a custom extension which snoops for the pattern across document types, and creates folds based on that, allowing me to create neat, custom document outlines. I'd like to use the same pattern in Visual Studio Code. Is it possible to create a custom VS Code extension which detects these comment patterns, and somehow tags folds based on the patterns?
FoldingRangeProvider can be used if you are looking to contribute custom folding logic in an extension.
Be sure to set your VS Code version in engines in package.json to 1.23, the version that introduced this.
Here's how you'd use one.
export function activate(context: ExtensionContext) {
languages.registerFoldingRangeProvider({ scheme: 'file', language: 'markdown' }, new MyFoldingRangeProvider());
}
class MyFoldingRangeProvider implements FoldingRangeProvider {
provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken): FoldingRange[] {
return detectRanges().map(({ lineStart, lineEnd }) => new FoldingRange(lineStart, lineEnd));
}
}
On August 6th 2022 the feature "Fold Selection" was added to "V.S. Code" as part of the sem-minor v1.70.0 release. This new feature gives users complete control over line folds, by total I mean, when & where. Fold Selection allows you to fold whatever code you want, wherever you want.
Below is a GIF image that was appended to the official v1.70.0 release notes
I copy & pasted this image because..,
A. The image shows how the new feature works, and...
B. because it shows that the feature works much like line folding does in IDEs — i.e. VS-22, Intelli-J, CLion, etc...
V.S. Code is actually the first editor I ever used, and I stuck with it for the last 5 years, but one thing I noticed on day 1 of test driving V.S. Code was that it did not have this feature.
Using the new Fold Selection Feature
You can use the feature via the quick input, just type "Fold Selection" until the option pops up for you to select, however, I perfer customizing a keybinding for it.
Here is the default configuration for fold selection in the default keyboard shortcuts JSON document:
{
"key": "ctrl+k ctrl+,",
"command": "editor.createFoldingRangeFromSelection",
"when": "editorTextFocus && foldingEnabled"
}
How to configure the above snippet is beyond the scope of this post, but I suggest keeping the when statement as it is configured above (which is the default).
You can use the keybinding shown in the JSON snippet w/o any configuration, which would be:
CTRL + K CTRL+,
...however, vscode has to attach most all commands to some keyboard shortcut. Most people cannot remember all of the commands and shortcuts, so for features you use often, it makes since to attach it to more practicle option, I like to use something like
CTRL + SHIFT + SPACE SPACE
Its almost like quickly pressing space twice.
Anyways, this is a far better option than what was available before, cheers!
CLICK HERE TO READ THE OFFICIAL RELEASE NOTES
There are three ways to achieve customized folding in a VSCode extension.
You can define regex as folding markers in a [language-name].configuration.json file. (However, we don't have much customization with this approach)
{
"folding": {
"markers": {
"start": "starting regex",
"end": "ending regex"
}
}
}
You can define a FoldingRangeProvider from within the extension as described in this answer. FoldingRange in vscode package supports folding customization with startLine, endLine, and foldingKind.
You can use Language Server support with textDocument/foldingRange. FoldingRange in the vscode-languageserver-protocol supports folding customization with startLine, endLine, startCharacter, endCharacter, and foldingKind.
Check this for more details.
Unfortunately, not at the moment. There is a an open issue in github for this very topic.
I have defined some keywords for a proprietary language I use at work:
{ "match": "\\b(util.tickettimelimit|util.user_ip|util.server_name|util.today)\\b",
"name": "keyword.source.GTX2",
"comment": "Tags"
}
I also have a completion file:
{
"scope": "source.GTX2",
"completions":
[
"util.server_name",
"util.tickettimelimit",
"util.today",
"util.user_ip"
]
}
When I start typing "util" I see the correct autocomplete options:
But as soon as I enter the "."(dot) autocomplete options go away:
Is there a way to change this behavior? I just want the keywords to be trated as a whole thing and ignore the dots.
Thanks!
I've looked everywhere I can, and it seems the auto-complete code is embedded within the executable itself (at least on Windows, I haven't checked my Mac yet), and not in one of the numerous external .py files scattered around, so I can't even see the parameters for how auto-completion is performed. I looked through the default Packages/Default/Preferences.sublime-settings file and while there are several options relating to auto-complete, there are none relating to what we're looking for. While looking through the Default (Windows).sublime-keymap file in the same directory, I tried adding the following:
{ "keys": ["."], "command": "hide_auto_complete", "context":
[
{ "key": "auto_complete_visible", "operator": "equal", "operand": false }
]
},
but alas it didn't work. There are a number of auto_complete commands there, and while this looked the most promising I haven't tried the rest.
I haven't exhaustively looked through the source and config files for the nifty SublimeCodeIntel plugin (also available through Package Control), so it's possible you might be able to find an option there. You'd probably have to completely disable the built-in auto-complete functionality first, so it doesn't override SCI.
So, I guess for now there's not much you can do. You can always leave a feature request and see if it makes it into Sublime Text 3, or search/open a thread on the Sublime Text Forum and see if anyone else has any suggestions. Good luck!
What I think #Ashish is alluding to is the word_separators setting. You will want to create a syntax specific preference (Preferences -> Settings - More -> Syntax Specific - User). Create a word_separators entry with the dot removed (Copy from the default preferences as the base). This will give you the behavior you want but there are some things to note. The dot, obviously, will not be treated as a word separator, which will change some behavior.
I'll use java as an example. If I had a variable foo, with some method bar, I could enter foo.b and bar would be shown as a completion. Without the dot as a separator, you will not see this.
Another example, perhaps easier to understand is when selecting words. If you use ctrl/cmd + d to select the word, it selects words, bound by word separators. So if I had foo.ba|r, where the | represents the cursor position and used ctrl/cmd+d it would select bar. With the dot removed as a word separator, foo.bar would be selected.
Let me know if I can clarify anything.
It's a little late but I hope this can help, create a new plugin and add this code:
import re
myObjects = {"util": ["server", "tickettimelimit", "today", "user_ip"]}
class CustomAutocomplete(sublime_plugin.EventListener):
def on_query_completions(self, view, prefix, locations):
if not view.match_selector(0, "source.GTX2"):
return
if prefix == "":
# get the last word in the current line
currentposition = view.sel()[0].begin()
currentline = view.full_line(currentposition)
text = view.substr(currentline)
words = re.findall("\w+", text)
lastword = words[-1]
if lastword in myObjects.keys():
# return a list of tuples, it represents snippets
# the first element is the trigger and the second one
# is the content
return [(x, x) for x in myObjects[lastword]]
return []
And add the next key in the user settings:
"auto_complete_triggers":
[
{
"characters": ".",
"selector": "source.GTX2"
}
]
Don't press . (dot) else you will need to type at least one character after dot so list can appear again. Using Brackets or Dot tells Sublime Text 2 that user has completed typing.
example: if I type for then sublime will show dropdown list but if I type for( list will disappear.
Click on Preferences > Settings - User, then copy and paste the following
// Characters that are considered to separate words – does not include periods.
// Place comma at the end of the line if there are multiple keybindings.
"word_separators": "/\\()\"‘-:,;~!##$%^&*|+=[]{}`~?"
From this webpage:
http://tomschenkjr.net/using-sublime-text-2-for-r/