andrewradev / switch.vim Goto Github PK
View Code? Open in Web Editor NEWA simple Vim plugin to switch segments of text with predefined replacements
Home Page: http://www.vim.org/scripts/script.php?script_id=4172
License: MIT License
A simple Vim plugin to switch segments of text with predefined replacements
Home Page: http://www.vim.org/scripts/script.php?script_id=4172
License: MIT License
I'm using neovim 0.4.3.
After updating switch.vim, I started getting the following error on startup when opening a Ruby file:
Error detected while processing /Users/rav/.vim/bundle/switch.vim/ftplugin/ruby/switch.vim:
line 21:
E121: Undefined variable: g:switch_builtins
E15: Invalid expression: [ g:switch_builtins.ruby_hash_style, g:switch_builtins.ruby_oneline_hash, g:switch_buil
tins.ruby_lambda, g:switch_builtins.ruby_if_clause, g:switch_builtins.rspec_should, g:switch_builtins.rspec_expe
ct, g:switch_builtins.rspec_to, g:switch_builtins.rspec_be_truthy_falsey, g:switch_builtins.ruby_string, g:swi
tch_builtins.ruby_short_blocks, g:switch_builtins.ruby_array_shorthand, g:switch_builtins.ruby_fetch, g:switch_b
uiltins.ruby_assert_nil ]
I tried commenting out all plugins, removing them from the bundle directory, but the error was still there.
I created an empty vimrc which only sourced switch.vim and the error was gone. After I removed NeoBundle code from my vimrc and directly sourced only switch.vim, the error was also gone.
So I went to do a git bisect, because the plugin worked without problems before updating it to recent master. I found that the commit 2bf6516 is the problematic one.
However, I have no idea how to further debug this. Any pointers will be appreciated!
I have the following in ftplugin/notes.vim:
let g:switch_custom_definitions = ['•', '✔', '✗']
but when my cursor is on •
and I try to execute :Switch
I get the following error:
Error detected while processing function <SNR>60_Switch..switch#Switch:
line 8:
E706: Variable type mismatch for: mapping
Press ENTER or type command to continue
Hi,
When editing tests one quite often needs to flip between .to
and .not_to
(or .to_not
) in RSpec tests (ft=ruby
).
Also be_truthy
and be_falsey
similar to true
and false
.
Can this be added? Thanks.
I've tried to implement LaTeX font size commands switching which contains \large
, \Large
, \LARGE
sequence. It seems that switch.vim
can not correctly handle them.
Here is MWE:
let g:switch_custom_definitions =
\ [
\ [ 'test', 'Test', 'TEST' ],
\ ]
Not depending on the initial word, it switches to Test
and stops there.
Every once in a while I add a few custom switches for this myself. I am guessing that some of them are re-inventing the wheel, others might be useful to other people.
Adding to the built-ins is probably problematic, I am not sure - people might have very specific ideas on how to do switches themselves.
But what would be nice is to have something like a collaborative wiki, where everyone can share their custom switches. People could copy/paste them then - or take them as inspiration.
What do you think?
Hello,
I'd like to suggest the following change:
function! s:SwitchReverse()
silent call switch#Switch({'reverse': 1})
silent! call repeat#set(":Switch\<cr>")
endfunction
to
function! s:SwitchReverse()
silent call switch#Switch({'reverse': 1})
silent! call repeat#set(":SwitchReverse\<cr>") " <- Change here
endfunction
I can create a pull request if favored.
Hi there, this occured to me when using the ruby_array_shorthand
builtin:
['foo']
['bar']
['far']
something
['boo']
becomes
['foo']
%w(bar)
[far)
something
[boo)
when executing :Switch
while the cursor is in column 1 of line 2.
Only the second and third rule are being applied everywhere, apparently.
This seems like a pretty damn cool plugin - I think it could possibly be useful enough to add a default mapping like you did for splitjoin. I nominate gs
, because it literally does nothing (for [n] seconds, actually).
Any way to combine with tpope/vim-speeddating
to reuse <C-a>/<C-x>
?
Likewise to execute original mapping if no definition match current word ?
Reverse ability stopped working after #bb71ada.
Did I miss something since last update? 😕
let g:switchQuotes = [
\ {
\ '''\(.\{-}\)''': '"\1"',
\ '"\(.\{-}\)"': '''\1''',
\ '`\(.\{-}\)`': '''\1'''
\ }
\]
" old
nnoremap <silent> ! :<C-u>silent! call switch#Switch(g:switchQuotes, {'reverse': 1})<CR>
" new (?)
nnoremap <silent> ! :<C-u>silent! call switch#Switch({'definitions': g:switchQuotes}, {'reverse': 1})<CR>
Quotes are changed once and the pattern/mapping completely stops working.
PS. Please, add silent
to switch#Switch
by default. Thank you for such a useful plugin!
I am programming in Python, and I am trying to use switch on a line with a boolean flag on it.
Nothing happens if I try switch on this line:
train_layers_1to3 = True
It will works fine on these:
train_layers_1to3 = (True) -> train_layers_1to3 = (False), or
train_layers_1to3 = True -> train_layers_1to3 = False
Is this a bug, or is it just me?
Hi,
Is it possible to add switch between {}
and do end
in ruby files? I am actively refactoring code all the time and cleaning up using rubocop advise. Changing block syntax is not very fun.
Thanks.
Hey Andrew, i really like your plugin! Thx for the awesome work! I use it many times daily.
Now i wanted to ask you, if you can help me with a bash switch.
I want to switch between the following variable declarations:
"${test_var}"
${test_var}
$test_var
The declarations could be placed everywhere.
Is that one easy for you?
Thx again for the plugin!
Hey,
I wanted to add a few switches for res <=> req and request <=> response and did so via appending them to g:switch_custom_definitions
:
let switch_custom_definitions =
\ [
\ ["request", "response"],
\ ["req", "res"]
\ ]
However, it turns out the shortest match wins, so request turns to resuest.
I was of course able to rewrite it via the dict mechanism and added a few \>
in there for good measure, but how about respecting the order of those custom definitions so such common subset cases could be handled without more verbose regexps? Especially when each individual switch list does respect order. :)
I just wanted to switch the string '/path'
to "/path"
but I learned that switch.vim doesn't work when the string starts with a /
.
In short I propose to add a possibility to choose the longest match.
I have some common definitions for switching yes
<->no
.
For the latex there is a series of font size commands, which also include \normalsize
. The latex configuration is added to the buffer configuration.
The problem is that when font size is switched to \normalsize
, then the line is matched by no
which is transformed to yes
.
I would actually expect matching algorithm to choose the largest matching string for substitution. In this case it's guaranteed that the short match is not a substring of some longer match. Therefore I propose to add an option to check for the largest match. It may be also a string option, allowing to choose between several options: longest, shortest, sequential (or something like this).
Is there a possibility to iterate the list in reverse so it could be mapped to a key?
Btw, thank you for the plugin and wiki, I will upload my latex configuration after some cleaning.
Hey,
I've got quite a list of antonyms set up. Occasionally, those words occur in camel case inside other words. E.g. findFirst
<=> findLast
with first
and last
being set up as Switch.vim definitions. It'd be great if the casing be preserved when switching. Same when switch constants: FIRST
and LAST
.
Thanks!
It would be neat if adding
let g:switch_custom_definitions =
\ [
\ ['foo', 'bar', 'baz']
\ ]
would also handle
Foo -> Bar
FOO -> BAR
etc. without having to specify all cases for each entry.
This is implemented in Toggle.vim
Hi Andrew,
First of all, many thanks for your effort building and maintaining this project.
I've played a bit a few months ago and just came back to it and realized that is not working if I open a file from vim.
:e /path/to/file
vim /path/to/file
I tried with this minimal 4 lines .vimrc
call plug#begin('~/.vim/plugged')
Plug 'AndrewRadev/switch.vim'
call plug#end()
let b:switch_custom_definitions = [ ['foo', 'bar', 'baz'] ]
Thanks,
Szilveszter
vim: 8.0.494 compiled from source using ./configure --enable-python3interp=dynamic --enable-cscope --enable-rubyinterp --without-x --disable-gui && make && sudo make install
Switch: latest version ddc0697
The pattern used in keys of dictionaries doesn't seem to support verymagic expressions.
I get the following error Pattern not found: \%>13c\v<MyRegexp>\%<41c
Hi,
Not sure if it goes to SplitJoin or Switch or both. Maybe first transformation can be done in Switch and the second one in SplitJoin.
It would be great if I could get rid of the old Ruby lambda syntax lambda { |x| }
and convert:
lambda { |x| whatever(x) }
->(x) { whatever(x) }
This is one-way transformation. But the next one should be reversible:
->(x) { whatever(x) }
lambda do |x|
whatever(x)
end
Please let me know what you think as this might be hard to make.
There's something wrong as I heard the bell every time executing the command.
I'v tested with gvim -Nu NORC --cmd 'se rtp+=~/.vim/bundle/switch.vim'
switch#NormalizedCase
doesn't seem to let me prevent it from matching internally in a word. Specifically, if I have switch#NormalizedCase(['or', 'and']), then switch will turn sorry
into sandry
, but if I try switch#NormalizedCase(['\<or\>', '\<and\>'])
, then 2 or 3
turns into 2 <and> 3
with the angle brackets carried along for the ride.
(Apologies if I've just missed it, and don't think I've ever said so but splitjoin and switch are 2 of the 3 best kept vim secrets in my opinion so super thanks for having written them!)
This is strictly speaking not an issue but just and idea. Currently the cursor needs to be on the word, but often times there is only one relevant word in a line that needs to be toggled, at least in my use cases. It would be nice if it worked like vim's <C-A>
and <C-X>
(add and subtract) feature and just find the first relevant match on the line and operates on that.
If I get time and there is general interest and no one wants to work on it, I will do it.
I wish to switch between 3 strings: '', ' Y' and '* N'
I tried the following settings:
let g:switch_find_smallest_match = 0
let g:switch_custom_definitions = [['* Y', '* N', '*']]
but this doesn't seem to work. What am I missing here?
When you switch the output statement =
in slim and probably haml it turns it into -
.
Okay but could you not do it from the middle of the line? I was bitten by it many times when I was replacing =>
with new ruby hash syntax, so I press /=><cr>
then n-n-n-n-n-
until I replace them all but it's been a few times when the next -
turns current line from =
to -
and that disables the output.
The solution would be to do the replacement only if the cursor is either on or before the =
in the line.
Hope my explanation makes any sense, I accidentally commented important parts like this a few times.
Hey,
There are a couple of useful switches built in that I'd like to use, but occasionally I have a need to add a more specific override. For example, with the latest addition to switch between a JavaScript function declaration (
Line 105 in b4116f2
switch_find_smallest_match = 0
), my simpler ["function*", "function"]
fails to match.
Have you thought about first looking in the custom definitions and only then falling back to builtins? With a smallest match search it didn't matter, but with a linear search it makes more sense to me to first try possible overrides.
Cheers
I mainly work with React. Lately, I find myself often needing to do this transform:
<Thing foo={data} />
<Thing foo={`${data}`} />
It's very tedious even with vim-surround, and it's an ideal use-case for this plugin, but the special meanings of the characters involved have given me a headache.
I've been slowly grinding my way up the Vim ladder since I started college in 2012. Plenty of times I've figured out how to do a regular expression that saved me hours upon hours of labor time over the course of the next months, and those are the times I'm really glad I'm obstinate enough to have stuck with it for this long, because it was a whim to begin with.
Sometimes, though, you've just gotta ask for help.
Can anyone write this transform? It might be a good one to add to the wiki.
I'm trying to make a matcher to switch the different ruby block styles.
In other words, switch between:
do_something do |x|
x.now!
end
do_something { |x| x.now! }
do_something(&:now!)
It looks like switch only looks for matches on the current line though. Am I right? If so, what do you think about multiline matching?
If we have a situation in which two switch operations could happen based on where the cursor is, it is ambiguous which switch is performed. I'm currently using this magical gist https://gist.github.com/othree/5655583 and currently (as an example...) I want to introduce a switch that toggles between a type T
and its const T&
counterpart for C++ but what happens is that if my cursor is on top of the type name it will of course run the fancy change-variable-case-style switch. I'd like to make it so that the change-variable-case-style switch is the lowest priority, rather than as it is now where I would basically be experiencing more pressure to delete it as I begin to use switch more heavily.
Although it works just fine to move the cursor to a suitable place it picks up the other switch and does the right thing. But it's not exactly ideal.
What do you think? This should not introduce much of a performance hit.
Actually, I'm going to go and play around with reordering the g:switch_custom_definitions
list order, it may be possible to control priority inherently by ordering the definition.
Hi,
Could you please treat slim
as ruby
? I usually do set ft=ruby
and then set ft=slim
after changing things. Or maybe there is a setting for that?
I want to write a switch for transforming base64 text, but to do this I need to call out to the !
command, obviously, to call a shell function. How would you do something like that with this plugin?
It would be nice if I could transform an Boolean expression using De Morgan's Theorems. It's useful when you want to convert an 'if' expression into an 'else', or simply switch the form of your expression.
Examples:
Selecting first OR term (!(A && B)
) in the next expression and switching:
!(A && B) || C
wold give:
(A && B) || C
Anywhere in the expression:
A || B && (C || D)
transforms the whole expression into:
!(A || B) || !(C || D)
Simplifying further:
(!A && !B) || (!C && !D)
I think you get the idea...
Maybe the language servers have some functions that could help with the tokenization.
When toggling true
to false
in C++, I get
\%>33c\Ctrue\m\%<39c
in my search history, while .
to ->
results in
\%>4c\(\k\+\)->\m\%<17c
I think the solution is to use call search("pattern")
, instead of using /
but I couldn't find the slash in the source to change, so this is probably something different
Hello,
Thank you for sharing the nice library.
I'm wondering if I could switch all the flags in a file at once.
Suppose I have a bash script like
#!/usr/bin/env bash
if true; then
./script1.sh
fi
if true; then
./script2.sh
fi
if true; then
./script13sh
fi
if true; then
./script4.sh
fi
I sometimes need to stop running all the scripts.
It would be nice to accomplish this by typing like gas
I would be happy if you could consider this.
Thank you.
In Erlang it's useful to switch betweeh the forms "..."
and <<"...">>
so I've attempted to define:
au FileType erlang let b:switch_custom_definitions =
\ [
\ 'string_binaries' : {
\ '<<"\([^"]*\)">>': '"\1"',
\ '"\([^"]*\)"': '<<"\1">>',
\ }
\ ]
But this doesn't work so well when I'm inside the angled bracketed quotes as it keeps adding more angle brackets. Is it possible to do this right?
Hey,
Please format the first line of the help file in doc/switch.txt
like :help write-local-help
says. This way it shows up properly on :help
-s listing.
In python I've found that sometimes I need to change dictionary to a list of key, value pairs. So from that
{'key1: 'value1', 'key2': 'value2'}
(('key1', 'value1), ('key2', 'value2'))
I don't think it's possible with current implementation because of lack of ability to use g modifier.
Example:
foo = :bar?
baz = :qux!
Performing :Switch
on bar
and qux
, I'd expect to get
foo = "bar?"
baz = "qux!"
but instead I get
foo = "bar"?
baz = "qux"!
let g:switch_definitions += [['是', '否']]
Error detected while processing function <SNR>83_Switch..switch#Switch..<SNR>318_Replace:
line 4:
E486: Pattern not found: \%>48c\V否\m\%<51c
increase: 1 -> 2 -> 3
decrease: 3 <- 2 <- 1
i've just installed your plugin (master branch) and tried with my php file.
after :Switch true becomes False and then every time in capitals. I think it should not behave like this.
Meanwhile my workaround is to add ["const", "let"] to g:switch_custom_definitions.
Great plugin! 👍
It would be awesome to be able to switch (bools) anywhere on the line and then have the cursor return to the original position. Possibly related to #49 and #14.
I implemented a function to do this for Python. I dunno if it can be used to upgrade the plugin, but it could be useful for someone else, so maybe include it as an example in the documentation?
function! MySwitch()
let save_pos = getpos(".")
call search('true\|false', '', line('.'))
execute 'Switch'
call setpos(".", save_pos)
endfunction
nmap <Leader>s :call MySwitch()<CR>
I've used this function as a bool only toggle plug-in vim-toggle-bool
Hi,
Since Rspec prefers be_falsey
and be_truthy
instead of be_false
and be_true
, current behaviour doesn't really work with specs. It converts be_falsey
to be_truey
.
Maybe it's time to add another matcher.
On this line:
expect(page).|not_to have_link 'Refund'
With the cursor at |
, gs
will toggle between not_to
and to
, as expected. If I subsequently u
ndo, however, the cursor moves to the beginning of the line. Is it possible for the cursor to remain where it was before the undo?
Hi,
It would be great if it could switch
function whatever() {
}
to
var whatever = function() {
}
Thanks.
It isn't a bug, but it would be nice to add an "alert" in the README telling that this plugin only work with VIM 7.3 or higher, since it uses the strwidth
function.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.