Many times when I'm debugging I like to log out a line like this:
console.log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
console.log(dataThatImTryingToSee);
console.log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
However, it gets annoying having to type in the console.log line's contents all the time. Is there a way to add hotkeys in Sublime that would insert a line such as the console.log one?
Sublime can do this with something called Snippets, which allow you to re-use bits of text in a variety of ways to make your coding life easier.
To get started, select Tools > Developer > New Snippet... from the menu, and replace what you see there with the following, and then save it in the location that Sublime will select by default, which is your User package. The name doesn't matter as long as it ends in sublime-snippet, but remember what name you used because you're going to need it in a minute.
<snippet>
<content><![CDATA[
console.log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
console.log(${1:$SELECTION});
console.log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");${0}
]]></content>
<description>Debug log an item to the console</description>
<!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
<tabTrigger>dlog</tabTrigger>
<!-- Optional: Set a scope to limit where the snippet will trigger -->
<scope>source.js</scope>
</snippet>
If you're not familiar with snippets, the text inside of the CDATA part of the XML is the body of the snippet, which will get inserted into the document.
${0} and ${1} are "fields", which you will be able to tab through entering text as you go. Fields are traversed in numerical order, but the special field ${0} indicates the location where the cursor should ultimately end up, which in this case is at the end of the last line so you can continue coding.
Fields can have the form ${#:default}, where the text initially displayed for the field is default. This will appear automatically in the snippet when it triggers, but it will be selected for you to type over it if you want.
The special field $SELECTION will be replaced with any text that happens to be selected when the snippet triggers (more on that in a second).
With the snippet saved you already have a couple of options open to you to trigger it, as long as you're in a JavaScript file (the syntax has to be set to JavaScript, so be sure to save any new files first).
First, if you open the command palette and enter the text Snippet to filter the list of commands to those which contain that text, you will see all snippets that apply to your current file, and in that list is an entry that says Snippet: Debug log an item to the console, which will trigger the snippet when you select it.
In this case, if you have any text selected, it will automatically be placed into the second console.log, so you can select a variable or what have you and trigger the snippet to log it directly.
Secondly, you can just enter the text dlog and press Tab to expand the snippet as well. The command palette entry mentioned above has text to the right that says dlog,tab to remind you. Depending on your settings, you may also get offered an auto completion popup as well.
Your question specifically talks about adding a hotkey, which is also possible. In that case you want to add a binding something similar to this to your custom key bindings:
{
"keys": ["alt+shift+d"],
"command": "insert_snippet",
"args": {
"name": "Packages/User/data_log.sublime-snippet"
},
"context":
[
{ "key": "selector", "operator": "equal", "operand": "source.js" },
]
},
You can change the key to whatever you would like, naturally. Note also that the name of the snippet you provide has to match what you saved the file as. If you followed the directions above it will have been saved in Packages\User already.
Now when you press the key, the snippet triggers. As above, if you have any text selected, it will automatically be inserted into the second console.log.
Note that in all cases when the snippet triggers, you will first have your cursor set inside the second console.log (possibly with some selected text already there), and Sublime is waiting for you to finish typing text for that field, so press Tab again to skip to the end of the snippet.
As a reminder of this, you'll notice that the status line (if you have it turned on) tells you Field 1 of 2 to let you know that you're inside a snippet.
This example assumes that you're working with JavaScript, so the snippet above and the key bindings will both only trigger when the current file is JavaScript. If you're using some other language, you can remove the scope from the snippet and/or the context part of the key binding to make them apply in all files, or modify the scope there to match the language you want to target.
This just scratches the surface of what you can pull off with a snippet. You can also do things like use the same field more than once to have the same text appear in multiple places, do regular expression substitutions, and much more. Check out the link above for more information.
Related
I am typesetting a latex file in VIM using the Vimtex plugin.
Every time I close a bracket, this text shows up automatically in the <++>.
For example:
\section{This is one}<++>
\section{The variable $V_L$<++> explains things}<++>
\begin{equation}
<+content+>
\label{<+label+>}
\end{equation}<++>
LaTeX compiles my text with those printed out in the pdf so I have to manually remove the every time. This behavior goes from $$ to {} to others also and even inside certain areas when using autocompletion features wit F5.
I did look add this question but it did not provide much help as to how to solve my issue.
How can I prevent the from being added to my tex files?
If they are a feature meant for something I do not understand, how do I prevent them from compiling in my pdf's?
This part of the documentation on the vim-latex (not Vimtex) repo on github
explains how the macro system works, how it's useful and solely meant for editing
NOTE: Place Holders
-------------
Almost all macros provided in Latex-Suite implement Stephen Riem's
bracketing system and Gergely Kontra's JumpFunc() for handling
place-holders. This consists of using "place-holders" to mark off
locations where the next relevant editing has to be done. As an example,
when you type EFI in |insert-mode|, you will get the following: >
\begin{figure}[<+htpb+>]
\centering
\includegraphics{<+file+>}
\caption{<+caption text+>}
\label{fig:<+label+>}
\end{figure}<++>
The text <+htpb+> will be selected and you will be left in |select-mode|
so that you can continue typing straight away. After having typed in the
placement specifier, you can press <Ctrl-J> (while still in insert-mode).
This will take you directly to the next "place-holder". i.e, <+file+> will
be visually selected with Vim in select mode again for typing in the file
aaaa. This saves on a lot of key presses.
Note: Upon testing I realized that the placeholder only appears when the bracketing is empty.
I'm struggling to find out how to create a new syntax highlighting in Sublime Text 3 using the new .sublime-syntax style definition (most previous answers relate to old ways of doing it).
As of Sublime Text Build 3084, a new syntax definition format has been added, with the .sublime-syntax extension.
I can find the:
syntax rules
scope naming rules
colour scheme rules
But I can't find the most basic piece of information detailing how these tie together!
I'm not trying to create a theme, or tweaking an existing syntax definition. I just want to create syntax highlighting to files with an extension I plan on using for my own purposes.
In the syntax definition I have to specify a scope (e.g. scope: source.c) but where does that scope file live? Or rather, where do I create my scope file, and how do I name it, so that it loads?
How do I know that my syntax file, and the scope file it uses, are loaded and applied successfully?
Are there any compile or refresh steps, or does everything automatically reload?
Thanks.
A full discussion of how to create a custom syntax is well outside the bounds of something as simple as a Stack Overflow answer. Also I think you're making your problem more complicated than it actually is (although creating a syntax is pretty complicated in general).
In order to walk you through the steps that you would take to create a custom syntax, here's an example.
To start with, create a file with the following contents and save it somewhere as sample.ec, and leave the file open:
// This is a line comment
if (x == 2)
y = 1
else
z = 1
You'll notice that the syntax for this file is set to Plain Text (see the status line in the lower right), which is the default syntax for files that are unknown to Sublime.
Now, select Tools > Developer > New Syntax... from the menu. A buffer with the following will appear. Use File > Save to save the file; the location will default to your User package. The name you give it is not important, but make sure that the extension is sublime-syntax. In my example I'm calling my file Sample.sublime-syntax.
%YAML 1.2
---
# See http://www.sublimetext.com/docs/3/syntax.html
file_extensions:
- ec
scope: source.example-c
contexts:
main:
# Strings begin and end with quotes, and use backslashes as an escape
# character
- match: '"'
scope: punctuation.definition.string.begin.example-c
push: double_quoted_string
# Comments begin with a '//' and finish at the end of the line
- match: '//'
scope: punctuation.definition.comment.example-c
push: line_comment
# Keywords are if, else for and while.
# Note that blackslashes don't need to be escaped within single quoted
# strings in YAML. When using single quoted strings, only single quotes
# need to be escaped: this is done by using two single quotes next to each
# other.
- match: '\b(if|else|for|while)\b'
scope: keyword.control.example-c
# Numbers
- match: '\b(-)?[0-9.]+\b'
scope: constant.numeric.example-c
double_quoted_string:
- meta_scope: string.quoted.double.example-c
- match: '\\.'
scope: constant.character.escape.example-c
- match: '"'
scope: punctuation.definition.string.end.example-c
pop: true
line_comment:
- meta_scope: comment.line.example-c
- match: $
pop: true
Now open the Sublime Console with View > Show Console or press the associated key binding. You'll see that the last line in the console is this:
generating syntax summary
Leaving the console open, click in the syntax file and perform another save operation again without changing anything. The same line appears in the console again.
Are there any compile or refresh steps, or does everything automatically reload?
As seen here, every time you modify the syntax definition, the file is recompiled and the results are cached. So there are no compile steps (other than saving) and nothing you need to do in order to refresh anything.
Now lets turn our attention back to the sample file. It's still open, and the syntax still says that it's Plain Text.
Now close the file and re-open it again; a shortcut for this is to use File > Open Recent > Reopen Closed File or it's associated key binding.
Notice that now that the file is re-opened, there are several changes. Firstly, the syntax name in the bottom right side of the window says Sample (or whatever you named your sublime-syntax file above). For another, the contents of the file are now syntax highlighted.
The colors you see are dependent on the color scheme you use, but an example might look like this:
// This is a line comment
if (x == 2)
y = 1
else
z = 1
How do I know that my syntax file, and the scope file it uses, are loaded and applied successfully?
You can see that the syntax file was compiled by the lack of an error message when you save your changes, and you can tell that it's applied by trying to use the syntax.
Here the syntax is being used automatically, but you'll find that if you check View > Syntax in the menu or click the current syntax name in the bottom right of the window, your syntax will appear there. Similarly there is now an entry in the command palette named Set Syntax: Sample (or whatever).
That leads us into your last question. If you go back to your sublime-syntax file, you'll see this at the top:
# See http://www.sublimetext.com/docs/3/syntax.html
file_extensions:
- ec
scope: source.example-c
The first thing to note is that file_extensions includes ec, and our sample file is called sample.ec; thus this syntax applies to it automatically due to it's name.
Now switch into the sample.ec file, place the cursor somewhere in the buffer and use Tools > Developer > Show Scope Name or press the associated key.
The content of the popup that appears will vary depending on where in the file the cursor is located, but the common point is that the scope that appears always starts with source.example-c.
In the syntax definition I have to specify a scope (e.g. scope: source.c) but where does that scope file live? Or rather, where do I create my scope file, and how do I name it, so that it loads?
As seen here, there is no such thing as a "scope file"; the sublime-syntax file directly specifies the scope as part of the syntax rules, so it's the only file that you need to create in order to create a syntax. It may look like a filename, but it is not one.
The scopes that are applied in the syntax matching rules in the syntax need to coincide with the scopes in your color scheme in order to be syntax highlighted; that's why you should use the scope naming rules to use the common set of scopes that all syntaxes share unless you're also planning to make a color scheme to go along with your syntax, but unless you use the recommended scopes, your syntax won't work well with other color schemes and your color scheme won't work well for other syntaxes.
From this starting point you can modify the sublime-syntax file here in order to make it highlight files the way you want. That would include changing the base scope at the top, applying an appropriate extension, and then including all of the rules that match your language.
As mentioned above, creating the actual rules to match your file is the most complicated part of creating a syntax unless your file format is very simplistic. It's outside the scope of something that could be conveyed in a Stack Overflow answer, but the official documentation linked above gives you some information on it.
Apart from looking at existing syntax files to see how they're doing what they do, you can also ask more directed questions on the Sublime forum.
I will shortly answer your questions, someone else can feel free to write a longer guide:
You put your syntax definitions inside a package: Select Preferences > Browse Packages... this should open your file explorer. There you can either create a new folder for a new package or use the User folder, which is the default user package. Inside that create a file YourSyntax.sublime-syntax.
You can open the ST console ctrl+` and it will output that the syntax is loaded and potential errors. You can also press ctrl+shift+p and write Set Syntax: YourSyntax in a buffer to directly see it.
You just need to save the file and it will reload the syntax definition.
Sublime Text is so damn advanced and this seems like such a stupid question, but...
I started writing a for loop in PHP (using SFTP), loved that it gave me a choice to auto-generate the loop. However, it enters this weird multi-cursor mode, which
1)I am not really sure how to use/exit without using the mouse;
2) it seems useless, seeing as all 3 type the same thing, even though I need to change, for example, the $i > x or $i = x.
Although Sublime does indeed support the idea of multiple cursors (which is an incredible time saver and useful as all get out, as we're about to see), what you're actually asking about here is a snippet which in this case happens to also include multiple cursors.
The general idea is that for code that you're likely to type many times (e.g. a for loop), you can create a snippet that will generate the bulk of the text for you in one shot, and then allow you to easily customize it as needed. In this case, the snippet in question is part of the default functionality of Sublime and is provided by the shipped PHP package.
To answer point #2 in your question first, this is far from useless. As seen here, I enter the text for and then press Tab to expand the snippet out. The first thing to notice here is that the status line says Field 1 of 4 to tell me that I'm in a snippet and that it contains four fields.
The first field is the name of the control variable for the loop, and all of them are selected so that as I change the name, all of them change at the same time because when there are multiple cursors, the text you type appears at all of them at the same time.
Once I'm done changing the name of the variable, I press Tab again to go to the next field, which allows me to easily change the point at which the loop starts. Another press of Tab takes me to the third field, where I can specify where the loop ends.
One last press of Tab exits the snippet and selects the text in the loop, so I can start writing my code (caveat: I am not a PHP developer).
At this point you can see Sublime offering another snippet for echo, which would expand out to an echo statement complete with quotes, then allow me to edit the text in the echo and skip to the end.
Circling back around to the first point in your question, you can use Esc at any point to jump out of a snippet and go back to regular editing. You can also use Tab or Shift+Tab to move through the fields in the snippet, and pressing Tab at the last field in the snippet exits it as well.
In this particular case, the first field in the snippet sets up multiple cursors, and so exiting the snippet while this field is active leaves multiple cursors in effect. You can jump back to a single cursor by pressing Esc one more time (this is true regardless of how you ended up with multiple cursors).
When I write HTML in Sublime Text 3, I like having autocompletion of attributes and element names and so on, but Sublime Text is always over-predicting things and turning my text content into elements (inappropriately), when the vast majority of the document body I am writing is text, not elements. What gets really annoying is if I press Enter at the end of a line where it believes the word I am typing is a typo of a different element, I get some really frustrating behavior:
The workaround I see is to press EscEnter at the end of every line but that isn't particularly ergonomic (and I have severe RSI so I'd rather have things be ergonomic).
Here are the relevant portions of my Preferences.sublime-settings:
{
"auto_complete": false,
"auto_complete_selector": "source - (comment, string.quoted)",
"tab_completion": false,
"tab_size": 4,
"translate_tabs_to_spaces": true,
"trim_trailing_white_space_on_save": true,
"word_wrap": true
}
I have looked at the Sublime Text documentation regarding completions and snippets but it isn't obvious to me how to suppress completions entirely during a text context. I don't currently have any HTML-mode-specific options configured.
Sublime's HTML autocompletions are implemented in a Python script.
It is possible to edit it, such that HTML tags will only be offered when you type < and a letter - instead of offering them while typing "plain" text content inside HTML.
To do this:
Install PackageResourceViewer using Package Control (if it isn't already installed)
From the Command Palette, type PRV: O and select PackageResourceViewer: Open Resource
Select HTML
Select html_completions.py
Find the line # if the opening < is not here insert that (https://github.com/sublimehq/Packages/blob/77867ed8000601962fec21a012f42b789c42195b/HTML/html_completions.py#L243)
Change completion_list = [(pair[0], '<' + pair[1]) for pair in completion_list] to completion_list = []
Save the file
Note that this creates a file that will override the version that comes with ST, so when a new build of ST3 is released, your version will still be used. In case this file is ever updated, it might be a good idea to delete your version to ensure you have the latest changes, and then to re-apply the above steps (if necessary - maybe it will be "fixed" in a future update to not suggest anything when auto_complete is set to false). To do this:
Tools -> Browse Packages
HTML
Delete html_completions.py
The tabnames plugin keeps a tab local variable t:tab_name for the tab label. Unfortunately, mksession does not appear to save tab specific variables. What options do I have for saving this data, as I will need it to later (manually) load the tab names. Here's what I have so far:
Update sessionoptions to save tab data (is this possible?)
Find some SessionSavePre event to traverse all tabs and make a global list of tab names g:tab_names (does such an event exist?)
Update a global tab names list g:tab_names every time tabs are added or removed (I would rather not do this as it involves shifting previous entries around)
I found a way around this here. What I did was set up a helper Python script which went through the file and looked for tabedit commands. Once found, it would append all necessary tab data after that command. The caveat is that you can't write/load complex objects like lists, and that the first tab is actually loaded as a window (via edit) and not as a tab.
I then made a mapping like so to make sure I always used my helper script when saving sessions.
nnoremap <leader>mks :call MakeFullSession()<CR>