On Sublime Text 3 (but I guess it's the same with ST2), I know that when you copy ( CTRL + C ) when there is nothing selected, the entire line is copied but I need to know how to paste it below my cursor.
It currently paste it above it and it doesn't seem logical to me, is there a way to modify this behaviour ?
Following Dan Lowe's answer, I made this file :
http://pastebin.com/7nPWZCPh
and added this line
{ "keys": ["ctrl+shift+v"], "command": "run_macro_file", "args": {"file": "res://Packages/User/paste_no_line.sublime-macro"}},
to my user's keybindings.
Works as intended but I have two differente "paste command" now.
It's not that it pastes "above" or "below", it's that it is operating on the current line. When you copy without first making a selection, it copies the current line. When you paste that, it also operates on the current line -- it pastes the buffer into that line, and as a side effect, whatever was on that line is bumped out of the way to the next line. It can't be bumped upward instead - the file can only grow or add new lines downward, you can't grow upward beyond line 1.
As to how to modify the behavior, I would suggest trying to make a macro.
http://docs.sublimetext.info/en/latest/extensibility/macros.html
As you pointed out in the comments, a macro works but it leaves you with two different ways to do a paste, one for normal use and the other for this "entire line" behavior. That is unfortunate, though there is another (harder) solution. You could try to write a Sublime plugin to detect how to behave and do what you want in each case. This is a bit beyond my ability to do for you... but in thinking about this, I realized that the Vintage package already has a command for this, because its p and P keys paste before and after the cursor, respectively. I looked inside the Vintage package to find where they did it. Here is their code, though I couldn't explain to you exactly how it works. You would want to try to emulate ViPasteRight.
class ViPrefixableCommand(sublime_plugin.TextCommand):
# Ensure register and repeat are picked up from g_input_state, and that
# it'll be recorded on the undo stack
def run_(self, edit_token, args):
if not args:
args = {}
if g_input_state.register:
args['register'] = g_input_state.register
g_input_state.register = None
if g_input_state.prefix_repeat_digits:
args['repeat'] = digits_to_number(g_input_state.prefix_repeat_digits)
g_input_state.prefix_repeat_digits = []
if 'event' in args:
del args['event']
edit = self.view.begin_edit(edit_token, self.name(), args)
try:
return self.run(edit, **args)
finally:
self.view.end_edit(edit)
class ViPasteRight(ViPrefixableCommand):
def advance(self, pt):
if self.view.substr(pt) == '\n' or pt >= self.view.size():
return pt
else:
return pt + 1
def run(self, edit, register = '"', repeat = 1):
visual_mode = self.view.has_non_empty_selection_region()
if not visual_mode:
transform_selection(self.view, lambda pt: self.advance(pt))
self.view.run_command('paste_from_register', {'forward': not visual_mode,
'repeat': repeat,
'register': register})
class ViPasteLeft(ViPrefixableCommand):
def run(self, edit, register = '"', repeat = 1):
self.view.run_command('paste_from_register', {'forward': False,
'repeat': repeat,
'register': register})
And here is how they bind them to keys. If you wanted to try to adapt this you probably would not need the context, that is something they need due to Vintage mode's modal nature.
{ "keys": ["P"], "command": "vi_paste_left",
"context": [{"key": "setting.command_mode"}]
},
{ "keys": ["p"], "command": "vi_paste_right",
"context": [{"key": "setting.command_mode"}]
},
Here is the docs section about plugins, if you want to try to tackle it that way.
http://docs.sublimetext.info/en/latest/extensibility/plugins.html
Related
Making the *.sublime-completions file, I found the "bug" which occurs when typing a long function like:
one.two.three.four.five(One := One_var, Two := Two_Var);
So if you type the whole function:
"one.two.three.four.five" and then press tab - it will paste another part of functions without issues.
But, if you type "one.two.thr" - and then in pop-up hint see that function and hit "Enter" it will replaces like:
one.two.one.two.three.four.five(One := One_var, Two := Two_Var);
How can I configure trigger to replace "one.two.thr" to correct function format?
This is my trigger.
{ "trigger": "one.two.three.four.five", "contents": "${TM_CURRENT_LINE/(.*)/(one.two.three.four.five)/}(One := One_var, Two := Two_Var);" },
This is not a bug, but a default setting of Sublime Text. By default, dots are treated as word_separators. Hence every time you type ., the completion trigger will be reset.
Example:
Let's assume we have only the following completions available:
{
"trigger": "one.two.three",
"contents": "one.two.three.four.five"
},
{
"trigger": "two",
"contents": "it_takes_two"
}
Now, let's type them in Sublime Text (the | marks the cursor position!)
one| -> will trigger "one.two.three.four.five"
one.| -> new word, forgot about "one.two.three.four.five"
one.two| -> will trigger "it_takes_two"
In the last case, both completions will be listed in the completion popup does to the fuzzy match for ”two”. However, the closer match ”two” will have a higher priority.
To fix this, you can edit the word_separators setting in a package setting or your global user settings. By default the setting treats the following characters as word separators:
./\\()\"'-:,.;<>~!##$%^&*|+=[]{}`~?
Alternatively, you ommit the dots from your completion triggers, e.g. use one-two-three instead of one.two.three.
Hi i have a program that when a button is pressed it should move to the next stacked widget replace some text in some labels and then execute some functions but this is not working and moves to the next page when the functions completes
The code is :
QtCore.QObject.connect(self.StartBtn, QtCore.SIGNAL(_fromUtf8("clicked()")), self.start) #Start
def nextPage(self):
current_page = self.stackedWidget.currentIndex()
i = int(current_page) + 1
self.stackedWidget.setCurrentIndex(i)
def start(self):
self.nextPage()
self.animation()
self.runFunctions()
def runFunctions(self):
try:
self.DbLabel.setText(_translate("MainWindow", "Checking Database", None))
if checkDb == True:
self.DbLabel.setText(_translate("MainWindow", "Checking Database ", None))
self.checkDbFun()
self.DbLabel.setText(_translate("MainWindow", "Database checked", None))
else:
self.checkedDbImg.setPixmap(QtGui.QPixmap(_fromUtf8("Files\\x.png")))
self.DbLabel.setText(_translate("MainWindow", "Database not checked", None))
except Exception as e:
self.AlertMessage(e)
def animation(self):
self.LoadingGif = QtGui.QLabel(MainWindow)
movie = QtGui.QMovie("Files\\loading.png")
self.LoadingGif.setMovie(movie)
self.LoadingGif.setAlignment(QtCore.Qt.AlignCenter)
self.gridLayout_2.addWidget(self.LoadingGif, 4, 1, 1, 1)
movie.start()
So what i want is to press StartBtn then move to next stacked widget page load the animation image and then run the functions
You probably need to let Qt process events in order for the tab change to take effect. You could do that two ways:
insert a qApp.processEvents() between the animation() and runFunctions() (qApp is in PyQt5.QtWidgets)
call runFunctions() via a single-shot timer: QTimer.singleShot(0, runFunctions), which will schuedule runFunctions via the event loop, so any pending events will first be processed (because runFunctions() is the latest added), then runFunctions() will get called. If you actually have params for runFunctions(), use a lambda.
I favor the first approach because I find it more clearly indicates what is happening (events need to be processed), but I recommend also adding a comment on that line that "so stack tab can change".
BTW you should be use the new-style notation for signals-slot connections, much cleaner, of the form "signal.connect(slot)":
self.StartBtn.clicked.connect(self.start)
So for approach #1 your code would look like this:
from PyQt5.QtWidgets import qApp
...
self.StartBtn.clicked.connect(self.start)
...
def start(self):
self.nextPage()
self.animation()
qApp.processEvents()
self.runFunctions()
...
I see no option to sort the sidebar in Sublime, how can I do it? I'd like to sort it alphabetically.
There is a Sublime plugin for that, called SortTabs. It works both with Sublime Text 2 and 3.
You can install it using Sublime Package Manger and then sort tabs using any of the following methods:
Sort Tabs by file name
Sort Tabs by file type
Sort Tabs by file path
Sort Tabs by modification date
Sort Tabs by last activation
I have found this answer
If you sort the tabs, it sorts the sidebar, and this sorts the tabs
I amended the classname though not to anything better. the classname was probably better before.
{ "keys": ["ctrl+alt+b"], "command": "sorttsortsidebar" }
http://www.sublimetext.com/forum/viewtopic.php?f=4&t=3876&start=20
import sublime_plugin
from os import path
from operator import itemgetter
# A simple command to sort current tabs alphabetically (returning focus to the
# original tab).
# Does not work with different groups or windows. Not catered for unsaved views
# (although it seems to work okay if there are any). It could be modified to
# work in these circumstances.
# { "keys": ["ctrl+alt+b"], "command": "sort_tabs" },
class SorttsortsidebarCommand(sublime_plugin.WindowCommand):
def run(self):
print("ddffd_sorttabs")
file_views = []
win = self.window
curr_view = win.active_view()
for vw in win.views():
_, tail = path.split(vw.file_name() or path.sep)
group, _ = win.get_view_index(vw)
file_views.append((tail.lower(), vw, group))
file_views.sort(key = itemgetter(2, 0))
moving_index = 0
for index, (_, vw, group) in enumerate(file_views):
if index == 0 or group > prev_group:
moving_index = 0
prev_group = group
else:
moving_index += 1
win.set_view_index(vw, group, moving_index)
win.focus_view(curr_view)
The quest
Turn this (with currHour being the current selection):
var currHour = now.getHours();
into this:
var currHour = now.getHours();
console.log('currHour=' + currHour);
Should work also for these cases:
currHour = now.getHours();
-->
currHour = now.getHours();
console.log('currHour=' + currHour);
and (where b is selected):
a = b;
-->
a = b;
console.log('b=' + b);
etc.
The Situation
Now, by following this answer I was able to produce the second line, with this:
<snippet>
<content>
<![CDATA[console.log('$SELECTION=' + $SELECTION);]]> </content>
<description>Print selection to console.log</description>
</snippet>
NB: my snippet code ommits <scope> because the scope is implied by the location of the snippet file (under language-specific dir -- JavaScript).
NB2: the <tabTrigger> setting in the snippet was ommited intentionally, because I will use a keyboard shortcut:
{ "keys": ["ctrl+shift+o"], "command": "insert_snippet", "args": { "name": "Packages/User/JavaScript/console-log-selection.sublime-snippet" } },
OK, that brings me half way there...
The problem
The current "solution" requires of me to manually duplicate the selection before I can invoke the snippet. That is an inconvenient step I'd like to skip if I can.
So, are there ways to make snippet duplicate the selection into new line?
I'm not great with snippets, so there may be another way. Anyways, you can do it with a plugin.
import re
import sublime
import sublime_plugin
class ConsoleLog(sublime_plugin.TextCommand):
def run(self, edit):
view = self.view
cursor = view.sel()[0]
line_region = view.line(cursor)
string = view.substr(line_region)
match = re.search(r"(\s*)(var\s+)?(\w+)\s*=", string)
if match:
if cursor.empty():
var_text = match.group(3)
else:
var_text = view.substr(cursor)
view.insert(edit, line_region.end(), "\n%sconsole.log('%s = ' + %s);" % (match.group(1), var_text, var_text))
end = view.line(line_region.end() + 1).end()
view.sel().clear()
view.sel().add(sublime.Region(end, end))
You just need to place the cursor on the line with your assignment operation. Bind your key binding to console_log. You can change the name as you see fit. Just be sure you change the name of the text command as well.
You could also modify your snippet so you don't have to type the text first. It seems unintuitive to type the variable name, select it, then hit your snippet key. Something like this may work better.
<snippet>
<content>
<![CDATA[console.log('$1 =' + $1);$2]]> </content>
<description>Print selection to console.log</description>
</snippet>
Edit:
I used the plugin to generate the console.logs with the cursor on the lines containing var foo = bar and foo = bar. That is, it's two invocations of the plugin command. Though you could modify it to handle multiple cursors also.
var foo = bar
console.log('foo = ' + foo)
foo = bar
console.log('foo = ' + foo)
I also modified the plugin so it should use a variable assignment automatically if nothing is selected. If something is selected, it will use the selected text in the console log. If you don't want the empty selection stuff, just remove the if statement under if match: and replace it with var_text = view.substr(cursor)
You can accomplish essentially what you want by combining a similar snippet with a macro.
The snippet:
<snippet>
<content><![CDATA[
${TM_CURRENT_LINE/var *(.+?) *=.+/\nconsole.log\('$1=' + $1\);/}
]]>
</content>
<description>Print selection to console.log</description>
</snippet>
The snippet figures out the variable name based on the current line and formats the console.log line using that variable.
The macro:
[
{"command": "move_to", "args": {"to": "hardeol", "extend": false}},
{"command": "insert_snippet", "args": {"name": "Packages/User/console-log-selection.sublime-snippet"}}
]
The macro uses an existing command - move_to - to get to the end of the line before inserting the snippet. This allows you to run the command from anywhere on the line.
Finally, the shortcut:
{ "keys": ["ctrl+shift+o"],
"command": "run_macro_file",
"args": { "file": "Packages/User/console-log-selection.sublime-macro" }
},
This seems like the best approach for inserting the log line if the variable assignment line already exists.
A macro will do what you want in both cases:
Save this in
~/Library/Application Support/Sublime Text 2/Packages/User/saran_macro.sublime-macro
[
{"command": "copy"},
{"command": "move_to", "args": {"to": "hardeol", "extend": false}},
{"command": "insert", "args": {"characters": "\nconsole.log('"}},
{"command": "paste"},
{"command": "insert", "args": {"characters": "=' + "}},
{"command": "paste"},
{"command": "insert", "args": {"characters":");"}}
]
Add this to your keybindings:
{ "keys": ["ctrl+shift+i"], "command": "run_macro_file", "args": { "file": "Packages/User/saran_macro.sublime-macro" } }
Whatever you highlight will be the variable in the macro.
Hello I Used the code in the selected answer to create this.
It supports multiple selections and put the correct identation. Also it dosen't have to be a "var foo =" line
Say if I have the following code in Sublime:
if (condition) {
// code
}
When my cursor is at the end of // code, I would like to set a key bind (e.g. Tab) that will exit the if-statement block and move it to the end of }. Thanks.
The BracketHighlighter plugin can provide this functionality natively... sort of. In its example shortcuts file, Example.sublime-keymap, there is a "Go to Right Bracket" example key binding:
// Go to right bracket
{
"keys": ["ctrl+alt+super+down"],
"command": "bh_key",
"args":
{
"lines" : true,
"plugin":
{
"type": ["__all__"],
"command": "bh_modules.bracketselect",
"args": {"select": "right"}
}
}
},
The only problem is that the called bracketselect command moves the cursor to the left side of the right bracket, requiring another keypress to fully escape from the block. I don't think that's what you want.
Worry not! Thankfully, BracketHighlighter provides a very intuitive plugin API, and I found that I could modify the bracketselect plugin to create a command that would escape from a bracket-enclosed block—basically the same as bracketselect, but it moves the cursor to the right side of the closing bracket rather than the left, and doesn't need any extra arguments.
You'll first need to install BracketHighlighter if you haven't yet.
Next, save blockescape.py (see below if the link ever dies) to
Preferences -> Browse Packages... -> BracketHighlighter/bh_modules/blockescape.py
Then, add this entry to the top of your user key bindings (Preferences -> Key Bindings — User):
{
"keys": ["tab"],
"command": "bh_key",
"args":
{
"lines" : true,
"plugin":
{
"type": ["__all__"],
"command": "bh_modules.blockescape"
}
}
},
I wouldn't recommend using tab as your trigger key, because tab has an important role already with expansions. Of course, you could define a special context in which to use tab, but that is up to you.
In case Github is ever down, here's the plugin code:
import bh_plugin
import sublime
DEFAULT_TAGS = ["cfml", "html", "angle"]
class BlockEscape(bh_plugin.BracketPluginCommand):
def run(self, edit, name, tags=DEFAULT_TAGS):
current_left, current_right = self.selection[0].begin(), self.selection[0].end()
left, right = self.left, self.right
first, last = left.end, right.begin
if left.end != right.end:
if name in tags and left.size() > 1:
first, last = right.begin + 1, right.begin + 1
if first == current_left and last == current_right:
first, last = right.end, right.end
else:
first, last = right.begin, right.begin
if first == current_left and last == current_right:
first, last = right.end, right.end
else:
# There is no second bracket, so just select the first
if name in tags and left.size() > 1:
first, last = left.begin + 1, left.begin + 1
else:
first, last = right.end, right.end
if first == current_left and last == current_right:
first, last = right.end, right.end
self.selection = [sublime.Region(first+1, last+1)]
def plugin():
return BlockEscape
Since I more or less hacked the plugin together, it might not work properly. In that case, feel free to edit it yourself or leave a comment on the Gist page.
You can add the $0 in a snippet to tab to that location:
<snippet>
<description>If Condition</description>
<content><![CDATA[if (${1:/* condition */}){
${2:/* code */}
}${0}]]></content>
<tabTrigger>if</tabTrigger>
<scope>source.c</scope>
</snippet>