mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-01-23 07:10:06 +08:00
chore(bundle): use bundle splitjoin
This commit is contained in:
parent
332214f846
commit
de0760cef7
@ -112,7 +112,7 @@ function! SpaceVim#layers#edit#plugins() abort
|
|||||||
\ [g:_spacevim_root_dir . 'bundle/editorconfig-vim', { 'merged' : 0, 'if' : has('python') || has('python3')}],
|
\ [g:_spacevim_root_dir . 'bundle/editorconfig-vim', { 'merged' : 0, 'if' : has('python') || has('python3')}],
|
||||||
\ [g:_spacevim_root_dir . 'bundle/vim-jplus', { 'on_map' : '<Plug>(jplus' }],
|
\ [g:_spacevim_root_dir . 'bundle/vim-jplus', { 'on_map' : '<Plug>(jplus' }],
|
||||||
\ [g:_spacevim_root_dir . 'bundle/tabular', { 'merged' : 0, 'on_cmd' : ['Tabularize']}],
|
\ [g:_spacevim_root_dir . 'bundle/tabular', { 'merged' : 0, 'on_cmd' : ['Tabularize']}],
|
||||||
\ ['andrewradev/splitjoin.vim',{ 'on_cmd':['SplitjoinJoin', 'SplitjoinSplit'],'merged' : 0, 'loadconf' : 1}],
|
\ [g:_spacevim_root_dir . 'bundle/splitjoin.vim',{ 'on_cmd':['SplitjoinJoin', 'SplitjoinSplit'],'merged' : 0, 'loadconf' : 1}],
|
||||||
\ ]
|
\ ]
|
||||||
if has('nvim-0.8.0')
|
if has('nvim-0.8.0')
|
||||||
call add(plugins,[g:_spacevim_root_dir . 'bundle/nvim-surround', { 'merged' : 0, 'loadconf' : 1, 'on_event' : ['BufReadPost']}])
|
call add(plugins,[g:_spacevim_root_dir . 'bundle/nvim-surround', { 'merged' : 0, 'loadconf' : 1, 'on_event' : ['BufReadPost']}])
|
||||||
|
38
bundle/splitjoin.vim/.circleci/config.yml
Normal file
38
bundle/splitjoin.vim/.circleci/config.yml
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
version: 2.1
|
||||||
|
|
||||||
|
orbs:
|
||||||
|
ruby: circleci/ruby@2.0.0
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
docker:
|
||||||
|
- image: cimg/ruby:3.2.1
|
||||||
|
executor: ruby/default
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run:
|
||||||
|
name: Install submodules
|
||||||
|
command: |
|
||||||
|
git submodule init
|
||||||
|
git submodule update
|
||||||
|
- run:
|
||||||
|
name: Install bundler
|
||||||
|
command: gem install bundler:2.1.4
|
||||||
|
- ruby/install-deps
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Install dependencies
|
||||||
|
command: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get -y install xvfb vim-gtk3
|
||||||
|
- run:
|
||||||
|
name: Which (g)vim?
|
||||||
|
command: xvfb-run gvim --version
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Run tests
|
||||||
|
command: xvfb-run bundle exec rspec -fd spec
|
||||||
|
|
||||||
|
workflows:
|
||||||
|
test:
|
||||||
|
jobs: [test]
|
20
bundle/splitjoin.vim/.github/workflows/mirror.yml
vendored
Normal file
20
bundle/splitjoin.vim/.github/workflows/mirror.yml
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Originally forked from: https://github.com/google/mirror-branch-action
|
||||||
|
# Current repo: https://github.com/AndrewRadev/mirror-branch-action
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
mirror_job:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Mirror main branch to master branch
|
||||||
|
steps:
|
||||||
|
- name: Mirror action step
|
||||||
|
id: mirror
|
||||||
|
uses: AndrewRadev/mirror-branch-action@main
|
||||||
|
with:
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
source: 'main'
|
||||||
|
dest: 'master'
|
4
bundle/splitjoin.vim/.gitignore
vendored
Normal file
4
bundle/splitjoin.vim/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
_project.vim
|
||||||
|
tags
|
||||||
|
doc/tags
|
||||||
|
tmp/
|
18
bundle/splitjoin.vim/.gitmodules
vendored
Normal file
18
bundle/splitjoin.vim/.gitmodules
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
[submodule "spec/support/rust.vim"]
|
||||||
|
path = spec/support/rust.vim
|
||||||
|
url = https://github.com/rust-lang/rust.vim
|
||||||
|
[submodule "spec/support/vim-javascript"]
|
||||||
|
path = spec/support/vim-javascript
|
||||||
|
url = https://github.com/pangloss/vim-javascript
|
||||||
|
[submodule "spec/support/tabular"]
|
||||||
|
path = spec/support/tabular
|
||||||
|
url = https://github.com/godlygeek/tabular
|
||||||
|
[submodule "spec/support/vim-elm-syntax"]
|
||||||
|
path = spec/support/vim-elm-syntax
|
||||||
|
url = https://github.com/andys8/vim-elm-syntax
|
||||||
|
[submodule "spec/support/vim-elixir"]
|
||||||
|
path = spec/support/vim-elixir
|
||||||
|
url = https://github.com/elixir-editors/vim-elixir
|
||||||
|
[submodule "spec/support/R-Vim-runtime"]
|
||||||
|
path = spec/support/R-Vim-runtime
|
||||||
|
url = https://github.com/jalvesaq/R-Vim-runtime
|
2
bundle/splitjoin.vim/.rspec
Normal file
2
bundle/splitjoin.vim/.rspec
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
--color
|
||||||
|
--exclude-pattern="./spec/support/**/*"
|
74
bundle/splitjoin.vim/CODE_OF_CONDUCT.md
Normal file
74
bundle/splitjoin.vim/CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
In the interest of fostering an open and welcoming environment, we as
|
||||||
|
contributors and maintainers pledge to making participation in our project and
|
||||||
|
our community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||||
|
nationality, personal appearance, race, religion, or sexual identity and
|
||||||
|
orientation.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to creating a positive environment
|
||||||
|
include:
|
||||||
|
|
||||||
|
* Using welcoming and inclusive language
|
||||||
|
* Being respectful of differing viewpoints and experiences
|
||||||
|
* Gracefully accepting constructive criticism
|
||||||
|
* Focusing on what is best for the community
|
||||||
|
* Showing empathy towards other community members
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||||
|
advances
|
||||||
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or electronic
|
||||||
|
address, without explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Our Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying the standards of acceptable
|
||||||
|
behavior and are expected to take appropriate and fair corrective action in
|
||||||
|
response to any instances of unacceptable behavior.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or
|
||||||
|
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||||
|
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||||
|
permanently any contributor for other behaviors that they deem inappropriate,
|
||||||
|
threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces
|
||||||
|
when an individual is representing the project or its community. Examples of
|
||||||
|
representing a project or community include using an official project e-mail
|
||||||
|
address, posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event. Representation of a project may be
|
||||||
|
further defined and clarified by project maintainers.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported by contacting the project team at andrey.radev@gmail.com. All
|
||||||
|
complaints will be reviewed and investigated and will result in a response that
|
||||||
|
is deemed necessary and appropriate to the circumstances. The project team is
|
||||||
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||||
|
Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
|
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||||
|
faith may face temporary or permanent repercussions as determined by other
|
||||||
|
members of the project's leadership.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||||
|
available at [http://contributor-covenant.org/version/1/4][version]
|
||||||
|
|
||||||
|
[homepage]: http://contributor-covenant.org
|
||||||
|
[version]: http://contributor-covenant.org/version/1/4/
|
44
bundle/splitjoin.vim/CONTRIBUTING.md
Normal file
44
bundle/splitjoin.vim/CONTRIBUTING.md
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# Contributing
|
||||||
|
|
||||||
|
If you'd like to contribute to the project, you can use the usual github pull-request flow:
|
||||||
|
|
||||||
|
1. Fork the project
|
||||||
|
2. Make your change/addition, preferably in a separate branch.
|
||||||
|
3. Test the new behaviour and make sure all existing tests pass (optional, see below for more information).
|
||||||
|
4. Issue a pull request with a description of your feature/bugfix.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
This project uses [rspec](http://rspec.info/) and [vimrunner](https://github.com/AndrewRadev/vimrunner) to test its behaviour. Testing vimscript this way does a great job of catching regressions, since it launches a real Vim instance and drives it (almost) as if it's a real user. Tests are written in the ruby programming language, so if you're familiar with it, you should (I hope) find the tests fairly understandable and easy to get into.
|
||||||
|
|
||||||
|
If you're not familiar with ruby, it's okay to skip them. I'd definitely appreciate it if you could take a look at the tests and attempt to write something that describes your change. Even if you don't, TravisCI should run the tests on every pull request, so we'll know right away if there's a regression. In that case, I'll work on the tests myself and see what I can do.
|
||||||
|
|
||||||
|
To run the test suite, you need to first make sure you've got git submodules checked out:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git submodule init
|
||||||
|
$ git submodule update
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, provided you have ruby installed, you need bundler:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ gem install bundler
|
||||||
|
```
|
||||||
|
|
||||||
|
If you already have the `bundle` command (check it out with `which bundle`), you don't need this step. Afterwards, it should be as simple as:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ bundle install
|
||||||
|
$ bundle exec rspec spec
|
||||||
|
```
|
||||||
|
|
||||||
|
Instead of running `rspec` by hand you can also use:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ bundle exec guard
|
||||||
|
```
|
||||||
|
|
||||||
|
This will trigger `rspec` automatically every time you make a change either to a spec file like `spec/plugin/coffee_spec.rb` or one of sj's autoload files like `autoload/sj/coffee.vim`. This has the additional benefit of only running the specs for the file you are currently working one, which shortens your feedback loop considerably. E.g. when you work on `autoload/sj/sh.vim` only shell specs will be run.
|
||||||
|
|
||||||
|
Depending on what kind of Vim you have installed, this may spawn a GUI Vim instance, or even several. You can read up on [vimrunner's README](https://github.com/AndrewRadev/vimrunner/blob/master/README.md) to understand how that works.
|
9
bundle/splitjoin.vim/Gemfile
Normal file
9
bundle/splitjoin.vim/Gemfile
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
source 'http://rubygems.org'
|
||||||
|
|
||||||
|
gem 'rake'
|
||||||
|
gem 'rspec'
|
||||||
|
gem 'vimrunner'
|
||||||
|
gem 'pry'
|
||||||
|
|
||||||
|
gem 'guard'
|
||||||
|
gem 'guard-rspec'
|
67
bundle/splitjoin.vim/Gemfile.lock
Normal file
67
bundle/splitjoin.vim/Gemfile.lock
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
GEM
|
||||||
|
remote: http://rubygems.org/
|
||||||
|
specs:
|
||||||
|
coderay (1.1.3)
|
||||||
|
diff-lcs (1.5.0)
|
||||||
|
ffi (1.16.3)
|
||||||
|
formatador (1.1.0)
|
||||||
|
guard (2.18.1)
|
||||||
|
formatador (>= 0.2.4)
|
||||||
|
listen (>= 2.7, < 4.0)
|
||||||
|
lumberjack (>= 1.0.12, < 2.0)
|
||||||
|
nenv (~> 0.1)
|
||||||
|
notiffany (~> 0.0)
|
||||||
|
pry (>= 0.13.0)
|
||||||
|
shellany (~> 0.0)
|
||||||
|
thor (>= 0.18.1)
|
||||||
|
guard-compat (1.2.1)
|
||||||
|
guard-rspec (4.7.3)
|
||||||
|
guard (~> 2.1)
|
||||||
|
guard-compat (~> 1.1)
|
||||||
|
rspec (>= 2.99.0, < 4.0)
|
||||||
|
listen (3.8.0)
|
||||||
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||||
|
rb-inotify (~> 0.9, >= 0.9.10)
|
||||||
|
lumberjack (1.2.10)
|
||||||
|
method_source (1.0.0)
|
||||||
|
nenv (0.3.0)
|
||||||
|
notiffany (0.1.3)
|
||||||
|
nenv (~> 0.1)
|
||||||
|
shellany (~> 0.0)
|
||||||
|
pry (0.14.2)
|
||||||
|
coderay (~> 1.1)
|
||||||
|
method_source (~> 1.0)
|
||||||
|
rake (13.1.0)
|
||||||
|
rb-fsevent (0.11.2)
|
||||||
|
rb-inotify (0.10.1)
|
||||||
|
ffi (~> 1.0)
|
||||||
|
rspec (3.12.0)
|
||||||
|
rspec-core (~> 3.12.0)
|
||||||
|
rspec-expectations (~> 3.12.0)
|
||||||
|
rspec-mocks (~> 3.12.0)
|
||||||
|
rspec-core (3.12.2)
|
||||||
|
rspec-support (~> 3.12.0)
|
||||||
|
rspec-expectations (3.12.3)
|
||||||
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
|
rspec-support (~> 3.12.0)
|
||||||
|
rspec-mocks (3.12.6)
|
||||||
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
|
rspec-support (~> 3.12.0)
|
||||||
|
rspec-support (3.12.1)
|
||||||
|
shellany (0.0.1)
|
||||||
|
thor (1.3.0)
|
||||||
|
vimrunner (0.3.5)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
ruby
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
guard
|
||||||
|
guard-rspec
|
||||||
|
pry
|
||||||
|
rake
|
||||||
|
rspec
|
||||||
|
vimrunner
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.1.4
|
4
bundle/splitjoin.vim/Guardfile
Normal file
4
bundle/splitjoin.vim/Guardfile
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
guard 'rspec', cmd: 'bundle exec rspec' do
|
||||||
|
watch(%r{autoload/sj/(.*)\.vim}) { |m| "spec/plugin/#{m[1]}_spec.rb"}
|
||||||
|
watch(%r{spec/plugin/(.*)_spec.rb})
|
||||||
|
end
|
17
bundle/splitjoin.vim/LICENSE
Normal file
17
bundle/splitjoin.vim/LICENSE
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
108
bundle/splitjoin.vim/README.md
Normal file
108
bundle/splitjoin.vim/README.md
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
[![GitHub version](https://badge.fury.io/gh/andrewradev%2Fsplitjoin.vim.svg)](https://badge.fury.io/gh/andrewradev%2Fsplitjoin.vim)
|
||||||
|
[![Build Status](https://circleci.com/gh/AndrewRadev/splitjoin.vim/tree/main.svg?style=shield)](https://circleci.com/gh/AndrewRadev/splitjoin.vim?branch=main)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
This plugin is meant to simplify a task I've found too common in my workflow: switching between a single-line statement and a multi-line one. It offers the following default keybindings, which can be customized:
|
||||||
|
|
||||||
|
* `gS` to split a one-liner into multiple lines
|
||||||
|
* `gJ` (with the cursor on the first line of a block) to join a block into a single-line statement.
|
||||||
|
|
||||||
|
![Demo](http://i.andrewradev.com/2fcc9f013816ec744c54e57476afac32.gif)
|
||||||
|
|
||||||
|
I usually work with ruby and a lot of expressions can be written very concisely on a single line. A good example is the "if" statement:
|
||||||
|
|
||||||
|
``` ruby
|
||||||
|
puts "foo" if bar?
|
||||||
|
```
|
||||||
|
|
||||||
|
This is a great feature of the language, but when you need to add more statements to the body of the "if", you need to rewrite it:
|
||||||
|
|
||||||
|
``` ruby
|
||||||
|
if bar?
|
||||||
|
puts "foo"
|
||||||
|
puts "baz"
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
The idea of this plugin is to introduce a single key binding (default: `gS`) for transforming a line like this:
|
||||||
|
|
||||||
|
``` html
|
||||||
|
<div id="foo">bar</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
Into this:
|
||||||
|
|
||||||
|
``` html
|
||||||
|
<div id="foo">
|
||||||
|
bar
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
And another binding (default: `gJ`) for the opposite transformation.
|
||||||
|
|
||||||
|
This currently works for various constructs in the following languages:
|
||||||
|
|
||||||
|
- C
|
||||||
|
- CSS
|
||||||
|
- Clojure
|
||||||
|
- Coffeescript
|
||||||
|
- Elixir
|
||||||
|
- Elm
|
||||||
|
- Eruby
|
||||||
|
- Go
|
||||||
|
- HAML
|
||||||
|
- HTML (and HTML-like markup)
|
||||||
|
- Handlebars
|
||||||
|
- JSON
|
||||||
|
- Java
|
||||||
|
- Javascript (within JSX, TSX, Vue.js templates as well)
|
||||||
|
- Lua
|
||||||
|
- PHP
|
||||||
|
- Perl
|
||||||
|
- Python
|
||||||
|
- R
|
||||||
|
- Ruby
|
||||||
|
- Rust
|
||||||
|
- SCSS and Less
|
||||||
|
- Shell (sh, bash, zsh)
|
||||||
|
- Tex
|
||||||
|
- Vimscript
|
||||||
|
- YAML
|
||||||
|
|
||||||
|
For more information, including examples for all of those languages, try `:help
|
||||||
|
splitjoin`, or take a look at the full help file online at
|
||||||
|
[doc/splitjoin.txt](https://github.com/AndrewRadev/splitjoin.vim/blob/master/doc/splitjoin.txt)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
The easiest way to install the plugin is with a plugin manager:
|
||||||
|
|
||||||
|
- vim-plug: https://github.com/junegunn/vim-plug
|
||||||
|
- Vundle: https://github.com/VundleVim/Vundle.vim
|
||||||
|
|
||||||
|
If you use one, just follow the instructions in its documentation.
|
||||||
|
|
||||||
|
You can install the plugin yourself using Vim's "packages" functionality by cloning the project (or adding it as a submodule) under `~/.vim/pack/<any-name>/start/`. For example:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/AndrewRadev/splitjoin.vim ~/.vim/pack/_/start/splitjoin
|
||||||
|
```
|
||||||
|
|
||||||
|
This should automatically load the plugin for you on Vim start. Alternatively, you can add it to `~/.vim/pack/<any-name>/opt/` instead and load it in your .vimrc manually with:
|
||||||
|
|
||||||
|
``` vim
|
||||||
|
packadd splitjoin
|
||||||
|
```
|
||||||
|
|
||||||
|
If you'd rather not use git, you can download the files from the "releases" tab and unzip them in the relevant directory: https://github.com/AndrewRadev/splitjoin.vim/releases.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
If you'd like to hack on the plugin, please see
|
||||||
|
[CONTRIBUTING.md](https://github.com/AndrewRadev/splitjoin.vim/blob/master/CONTRIBUTING.md) first.
|
||||||
|
|
||||||
|
## Issues
|
||||||
|
|
||||||
|
Any issues and suggestions are very welcome on the
|
||||||
|
[github bugtracker](https://github.com/AndrewRadev/splitjoin.vim/issues).
|
8
bundle/splitjoin.vim/Rakefile
Normal file
8
bundle/splitjoin.vim/Rakefile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
task :default do
|
||||||
|
sh 'rspec spec'
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Prepare archive for deployment"
|
||||||
|
task :archive do
|
||||||
|
sh 'zip -r ~/splitjoin.zip autoload/ doc/splitjoin.txt ftplugin/ plugin/'
|
||||||
|
end
|
881
bundle/splitjoin.vim/autoload/sj.vim
Normal file
881
bundle/splitjoin.vim/autoload/sj.vim
Normal file
@ -0,0 +1,881 @@
|
|||||||
|
" vim: foldmethod=marker
|
||||||
|
|
||||||
|
" Main entry points {{{1
|
||||||
|
"
|
||||||
|
" The two main functions that loop through callbacks and execute them.
|
||||||
|
"
|
||||||
|
" function! sj#Split() {{{2
|
||||||
|
"
|
||||||
|
function! sj#Split()
|
||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
" expand any folds under the cursor, or we might replace the wrong area
|
||||||
|
silent! foldopen
|
||||||
|
|
||||||
|
let disabled_callbacks = sj#settings#Read('disabled_split_callbacks')
|
||||||
|
|
||||||
|
let saved_view = winsaveview()
|
||||||
|
let saved_whichwrap = &whichwrap
|
||||||
|
set whichwrap-=l
|
||||||
|
|
||||||
|
if !sj#settings#Read('quiet') | echo "Splitjoin: Working..." | endif
|
||||||
|
for callback in b:splitjoin_split_callbacks
|
||||||
|
if index(disabled_callbacks, callback) >= 0
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
call sj#PushCursor()
|
||||||
|
|
||||||
|
if call(callback, [])
|
||||||
|
silent! call repeat#set("\<plug>SplitjoinSplit")
|
||||||
|
let &whichwrap = saved_whichwrap
|
||||||
|
if !sj#settings#Read('quiet')
|
||||||
|
" clear progress message
|
||||||
|
redraw | echo ""
|
||||||
|
endif
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
finally
|
||||||
|
call sj#PopCursor()
|
||||||
|
endtry
|
||||||
|
endfor
|
||||||
|
|
||||||
|
call winrestview(saved_view)
|
||||||
|
let &whichwrap = saved_whichwrap
|
||||||
|
if !sj#settings#Read('quiet')
|
||||||
|
" clear progress message
|
||||||
|
redraw | echo ""
|
||||||
|
endif
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! sj#Join() {{{2
|
||||||
|
"
|
||||||
|
function! sj#Join()
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
" expand any folds under the cursor, or we might replace the wrong area
|
||||||
|
silent! foldopen
|
||||||
|
|
||||||
|
let disabled_callbacks = sj#settings#Read('disabled_join_callbacks')
|
||||||
|
|
||||||
|
let saved_view = winsaveview()
|
||||||
|
let saved_whichwrap = &whichwrap
|
||||||
|
set whichwrap-=l
|
||||||
|
|
||||||
|
if !sj#settings#Read('quiet') | echo "Splitjoin: Working..." | endif
|
||||||
|
for callback in b:splitjoin_join_callbacks
|
||||||
|
if index(disabled_callbacks, callback) >= 0
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
call sj#PushCursor()
|
||||||
|
|
||||||
|
if call(callback, [])
|
||||||
|
silent! call repeat#set("\<plug>SplitjoinJoin")
|
||||||
|
let &whichwrap = saved_whichwrap
|
||||||
|
if !sj#settings#Read('quiet')
|
||||||
|
" clear progress message
|
||||||
|
redraw | echo ""
|
||||||
|
endif
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
finally
|
||||||
|
call sj#PopCursor()
|
||||||
|
endtry
|
||||||
|
endfor
|
||||||
|
|
||||||
|
call winrestview(saved_view)
|
||||||
|
let &whichwrap = saved_whichwrap
|
||||||
|
if !sj#settings#Read('quiet')
|
||||||
|
" clear progress message
|
||||||
|
redraw | echo ""
|
||||||
|
endif
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Cursor stack manipulation {{{1
|
||||||
|
"
|
||||||
|
" In order to make the pattern of saving the cursor and restoring it
|
||||||
|
" afterwards easier, these functions implement a simple cursor stack. The
|
||||||
|
" basic usage is:
|
||||||
|
"
|
||||||
|
" call sj#PushCursor()
|
||||||
|
" " Do stuff that move the cursor around
|
||||||
|
" call sj#PopCursor()
|
||||||
|
"
|
||||||
|
" function! sj#PushCursor() {{{2
|
||||||
|
"
|
||||||
|
" Adds the current cursor position to the cursor stack.
|
||||||
|
function! sj#PushCursor()
|
||||||
|
if !exists('b:cursor_position_stack')
|
||||||
|
let b:cursor_position_stack = []
|
||||||
|
endif
|
||||||
|
|
||||||
|
call add(b:cursor_position_stack, winsaveview())
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! sj#PopCursor() {{{2
|
||||||
|
"
|
||||||
|
" Restores the cursor to the latest position in the cursor stack, as added
|
||||||
|
" from the sj#PushCursor function. Removes the position from the stack.
|
||||||
|
function! sj#PopCursor()
|
||||||
|
call winrestview(remove(b:cursor_position_stack, -1))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! sj#DropCursor() {{{2
|
||||||
|
"
|
||||||
|
" Discards the last saved cursor position from the cursor stack.
|
||||||
|
" Note that if the cursor hasn't been saved at all, this will raise an error.
|
||||||
|
function! sj#DropCursor()
|
||||||
|
call remove(b:cursor_position_stack, -1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Indenting {{{1
|
||||||
|
"
|
||||||
|
" Some languages don't have built-in support, and some languages have semantic
|
||||||
|
" indentation. In such cases, code blocks might need to be reindented
|
||||||
|
" manually.
|
||||||
|
"
|
||||||
|
|
||||||
|
" function! sj#SetIndent(start_lineno, end_lineno, indent) {{{2
|
||||||
|
" function! sj#SetIndent(lineno, indent)
|
||||||
|
"
|
||||||
|
" Sets the indent of the given line numbers to "indent" amount of whitespace.
|
||||||
|
"
|
||||||
|
function! sj#SetIndent(...)
|
||||||
|
if a:0 == 3
|
||||||
|
let start_lineno = a:1
|
||||||
|
let end_lineno = a:2
|
||||||
|
let indent = a:3
|
||||||
|
elseif a:0 == 2
|
||||||
|
let start_lineno = a:1
|
||||||
|
let end_lineno = a:1
|
||||||
|
let indent = a:2
|
||||||
|
endif
|
||||||
|
|
||||||
|
let is_tabs = &l:expandtab
|
||||||
|
let shift = shiftwidth()
|
||||||
|
|
||||||
|
if is_tabs == 0
|
||||||
|
if shift > 0
|
||||||
|
let indent = indent / shift
|
||||||
|
endif
|
||||||
|
|
||||||
|
let whitespace = repeat('\t', indent)
|
||||||
|
else
|
||||||
|
let whitespace = repeat(' ', indent)
|
||||||
|
endif
|
||||||
|
|
||||||
|
exe start_lineno.','.end_lineno.'s/^\s*/'.whitespace
|
||||||
|
|
||||||
|
" Don't leave a history entry
|
||||||
|
call histdel('search', -1)
|
||||||
|
let @/ = histget('search', -1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! sj#PeekCursor() {{{2
|
||||||
|
"
|
||||||
|
" Returns the last saved cursor position from the cursor stack.
|
||||||
|
" Note that if the cursor hasn't been saved at all, this will raise an error.
|
||||||
|
function! sj#PeekCursor()
|
||||||
|
return b:cursor_position_stack[-1]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Text replacement {{{1
|
||||||
|
"
|
||||||
|
" Vim doesn't seem to have a whole lot of functions to aid in text replacement
|
||||||
|
" within a buffer. The ":normal!" command usually works just fine, but it
|
||||||
|
" could be difficult to maintain sometimes. These functions encapsulate a few
|
||||||
|
" common patterns for this.
|
||||||
|
|
||||||
|
" function! sj#ReplaceMotion(motion, text) {{{2
|
||||||
|
"
|
||||||
|
" Replace the normal mode "motion" with "text". This is mostly just a wrapper
|
||||||
|
" for a normal! command with a paste, but doesn't pollute any registers.
|
||||||
|
"
|
||||||
|
" Examples:
|
||||||
|
" call sj#ReplaceMotion('Va{', 'some text')
|
||||||
|
" call sj#ReplaceMotion('V', 'replacement line')
|
||||||
|
"
|
||||||
|
" Note that the motion needs to include a visual mode key, like "V", "v" or
|
||||||
|
" "gv"
|
||||||
|
function! sj#ReplaceMotion(motion, text)
|
||||||
|
" reset clipboard to avoid problems with 'unnamed' and 'autoselect'
|
||||||
|
let saved_clipboard = &clipboard
|
||||||
|
set clipboard=
|
||||||
|
let saved_selection = &selection
|
||||||
|
let &selection = "inclusive"
|
||||||
|
|
||||||
|
let saved_register_text = getreg('"', 1)
|
||||||
|
let saved_register_type = getregtype('"')
|
||||||
|
let saved_opening_visual = getpos("'<")
|
||||||
|
let saved_closing_visual = getpos("'>")
|
||||||
|
|
||||||
|
call setreg('"', a:text, 'v')
|
||||||
|
exec 'silent noautocmd normal! '.a:motion.'p'
|
||||||
|
|
||||||
|
" TODO (2021-02-22) Not a good idea to rely on reindent here
|
||||||
|
silent normal! gv=
|
||||||
|
|
||||||
|
call setreg('"', saved_register_text, saved_register_type)
|
||||||
|
call setpos("'<", saved_opening_visual)
|
||||||
|
call setpos("'>", saved_closing_visual)
|
||||||
|
|
||||||
|
let &clipboard = saved_clipboard
|
||||||
|
let &selection = saved_selection
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! sj#ReplaceLines(start, end, text) {{{2
|
||||||
|
"
|
||||||
|
" Replace the area defined by the 'start' and 'end' lines with 'text'.
|
||||||
|
function! sj#ReplaceLines(start, end, text)
|
||||||
|
let interval = a:end - a:start
|
||||||
|
|
||||||
|
if interval == 0
|
||||||
|
return sj#ReplaceMotion(a:start.'GV', a:text)
|
||||||
|
else
|
||||||
|
return sj#ReplaceMotion(a:start.'GV'.interval.'j', a:text)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! sj#ReplaceCols(start, end, text) {{{2
|
||||||
|
"
|
||||||
|
" Replace the area defined by the 'start' and 'end' columns on the current
|
||||||
|
" line with 'text'
|
||||||
|
function! sj#ReplaceCols(start, end, text)
|
||||||
|
let start_position = getpos('.')
|
||||||
|
let end_position = getpos('.')
|
||||||
|
|
||||||
|
let start_position[2] = a:start
|
||||||
|
let end_position[2] = a:end
|
||||||
|
|
||||||
|
return sj#ReplaceByPosition(start_position, end_position, a:text)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! sj#ReplaceByPosition(start, end, text) {{{2
|
||||||
|
"
|
||||||
|
" Replace the area defined by the 'start' and 'end' positions with 'text'. The
|
||||||
|
" positions should be compatible with the results of getpos():
|
||||||
|
"
|
||||||
|
" [bufnum, lnum, col, off]
|
||||||
|
"
|
||||||
|
function! sj#ReplaceByPosition(start, end, text)
|
||||||
|
let saved_z_pos = getpos("'z")
|
||||||
|
|
||||||
|
try
|
||||||
|
call setpos('.', a:start)
|
||||||
|
call setpos("'z", a:end)
|
||||||
|
|
||||||
|
return sj#ReplaceMotion('v`z', a:text)
|
||||||
|
finally
|
||||||
|
call setpos("'z", saved_z_pos)
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Text retrieval {{{1
|
||||||
|
"
|
||||||
|
" These functions are similar to the text replacement functions, only retrieve
|
||||||
|
" the text instead.
|
||||||
|
"
|
||||||
|
" function! sj#GetMotion(motion) {{{2
|
||||||
|
"
|
||||||
|
" Execute the normal mode motion "motion" and return the text it marks.
|
||||||
|
"
|
||||||
|
" Note that the motion needs to include a visual mode key, like "V", "v" or
|
||||||
|
" "gv"
|
||||||
|
function! sj#GetMotion(motion)
|
||||||
|
call sj#PushCursor()
|
||||||
|
|
||||||
|
let saved_selection = &selection
|
||||||
|
let &selection = "inclusive"
|
||||||
|
let saved_register_text = getreg('z', 1)
|
||||||
|
let saved_register_type = getregtype('z')
|
||||||
|
let saved_opening_visual = getpos("'<")
|
||||||
|
let saved_closing_visual = getpos("'>")
|
||||||
|
|
||||||
|
let @z = ''
|
||||||
|
exec 'silent noautocmd normal! '.a:motion.'"zy'
|
||||||
|
let text = @z
|
||||||
|
|
||||||
|
if text == ''
|
||||||
|
" nothing got selected, so we might still be in visual mode
|
||||||
|
exe "normal! \<esc>"
|
||||||
|
endif
|
||||||
|
|
||||||
|
call setreg('z', saved_register_text, saved_register_type)
|
||||||
|
call setpos("'<", saved_opening_visual)
|
||||||
|
call setpos("'>", saved_closing_visual)
|
||||||
|
let &selection = saved_selection
|
||||||
|
|
||||||
|
call sj#PopCursor()
|
||||||
|
|
||||||
|
return text
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! sj#GetLines(start, end) {{{2
|
||||||
|
"
|
||||||
|
" Retrieve the lines from "start" to "end" and return them as a list. This is
|
||||||
|
" simply a wrapper for getbufline for the moment.
|
||||||
|
function! sj#GetLines(start, end)
|
||||||
|
return getbufline('%', a:start, a:end)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! sj#GetCols(start, end) {{{2
|
||||||
|
"
|
||||||
|
" Retrieve the text from columns "start" to "end" on the current line.
|
||||||
|
function! sj#GetCols(start, end)
|
||||||
|
return strpart(getline('.'), a:start - 1, a:end - a:start + 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! sj#GetByPosition(start, end) {{{2
|
||||||
|
"
|
||||||
|
" Fetch the area defined by the 'start' and 'end' positions. The positions
|
||||||
|
" should be compatible with the results of getpos():
|
||||||
|
"
|
||||||
|
" [bufnum, lnum, col, off]
|
||||||
|
"
|
||||||
|
function! sj#GetByPosition(start, end)
|
||||||
|
let saved_z_pos = getpos("'z")
|
||||||
|
|
||||||
|
try
|
||||||
|
call setpos('.', a:start)
|
||||||
|
call setpos("'z", a:end)
|
||||||
|
|
||||||
|
return sj#GetMotion('v`z')
|
||||||
|
finally
|
||||||
|
call setpos("'z", saved_z_pos)
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" String functions {{{1
|
||||||
|
" Various string manipulation utility functions
|
||||||
|
function! sj#BlankString(s)
|
||||||
|
return (a:s =~ '^\s*$')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Surprisingly, Vim doesn't seem to have a "trim" function. In any case, these
|
||||||
|
" should be fairly obvious.
|
||||||
|
function! sj#Ltrim(s)
|
||||||
|
return substitute(a:s, '^\_s\+', '', '')
|
||||||
|
endfunction
|
||||||
|
function! sj#Rtrim(s)
|
||||||
|
return substitute(a:s, '\_s\+$', '', '')
|
||||||
|
endfunction
|
||||||
|
function! sj#Trim(s)
|
||||||
|
return sj#Rtrim(sj#Ltrim(a:s))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Execute sj#Trim on each item of a List
|
||||||
|
function! sj#TrimList(list)
|
||||||
|
return map(a:list, 'sj#Trim(v:val)')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Remove blank strings from the List
|
||||||
|
function! sj#RemoveBlanks(list)
|
||||||
|
return filter(a:list, 'v:val !~ "^\\s*$"')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Searching for patterns {{{1
|
||||||
|
"
|
||||||
|
" function! sj#SearchUnderCursor(pattern, flags, skip) {{{2
|
||||||
|
"
|
||||||
|
" Searches for a match for the given pattern under the cursor. Returns the
|
||||||
|
" result of the |search()| call if a match was found, 0 otherwise.
|
||||||
|
"
|
||||||
|
" Moves the cursor unless the 'n' flag is given.
|
||||||
|
"
|
||||||
|
" The a:flags parameter can include one of "e", "p", "s", "n", which work the
|
||||||
|
" same way as the built-in |search()| call. Any other flags will be ignored.
|
||||||
|
"
|
||||||
|
function! sj#SearchUnderCursor(pattern, ...)
|
||||||
|
let [match_start, match_end] = call('sj#SearchColsUnderCursor', [a:pattern] + a:000)
|
||||||
|
if match_start > 0
|
||||||
|
return match_start
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! sj#SearchColsUnderCursor(pattern, flags, skip) {{{2
|
||||||
|
"
|
||||||
|
" Searches for a match for the given pattern under the cursor. Returns the
|
||||||
|
" start and (end + 1) column positions of the match. If nothing was found,
|
||||||
|
" returns [0, 0].
|
||||||
|
"
|
||||||
|
" Moves the cursor unless the 'n' flag is given.
|
||||||
|
"
|
||||||
|
" Respects the skip expression if it's given.
|
||||||
|
"
|
||||||
|
" See sj#SearchUnderCursor for the behaviour of a:flags
|
||||||
|
"
|
||||||
|
function! sj#SearchColsUnderCursor(pattern, ...)
|
||||||
|
if a:0 >= 1
|
||||||
|
let given_flags = a:1
|
||||||
|
else
|
||||||
|
let given_flags = ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:0 >= 2
|
||||||
|
let skip = a:2
|
||||||
|
else
|
||||||
|
let skip = ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
let lnum = line('.')
|
||||||
|
let col = col('.')
|
||||||
|
let pattern = a:pattern
|
||||||
|
let extra_flags = ''
|
||||||
|
|
||||||
|
" handle any extra flags provided by the user
|
||||||
|
for char in ['e', 'p', 's']
|
||||||
|
if stridx(given_flags, char) >= 0
|
||||||
|
let extra_flags .= char
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
call sj#PushCursor()
|
||||||
|
|
||||||
|
" find the start of the pattern
|
||||||
|
call search(pattern, 'bcW', lnum)
|
||||||
|
let search_result = sj#SearchSkip(pattern, skip, 'cW'.extra_flags, lnum)
|
||||||
|
if search_result <= 0
|
||||||
|
call sj#PopCursor()
|
||||||
|
return [0, 0]
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PushCursor()
|
||||||
|
|
||||||
|
" find the end of the pattern
|
||||||
|
if stridx(extra_flags, 'e') >= 0
|
||||||
|
let match_end = col('.')
|
||||||
|
|
||||||
|
call sj#PushCursor()
|
||||||
|
call sj#SearchSkip(pattern, skip, 'cWb', lnum)
|
||||||
|
let match_start = col('.')
|
||||||
|
call sj#PopCursor()
|
||||||
|
else
|
||||||
|
let match_start = col('.')
|
||||||
|
call sj#SearchSkip(pattern, skip, 'cWe', lnum)
|
||||||
|
let match_end = col('.')
|
||||||
|
end
|
||||||
|
|
||||||
|
" set the end of the pattern to the next character, or EOL. Extra logic
|
||||||
|
" is for multibyte characters.
|
||||||
|
normal! l
|
||||||
|
if col('.') == match_end
|
||||||
|
" no movement, we must be at the end
|
||||||
|
let match_end = col('$')
|
||||||
|
else
|
||||||
|
let match_end = col('.')
|
||||||
|
endif
|
||||||
|
call sj#PopCursor()
|
||||||
|
|
||||||
|
if !sj#ColBetween(col, match_start, match_end)
|
||||||
|
" then the cursor is not in the pattern
|
||||||
|
call sj#PopCursor()
|
||||||
|
return [0, 0]
|
||||||
|
else
|
||||||
|
" a match has been found
|
||||||
|
if stridx(given_flags, 'n') >= 0
|
||||||
|
call sj#PopCursor()
|
||||||
|
else
|
||||||
|
call sj#DropCursor()
|
||||||
|
endif
|
||||||
|
|
||||||
|
return [match_start, match_end]
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! sj#SearchSkip(pattern, skip, ...) {{{2
|
||||||
|
" A partial replacement to search() that consults a skip pattern when
|
||||||
|
" performing a search, just like searchpair().
|
||||||
|
"
|
||||||
|
" Note that it doesn't accept the "n" and "c" flags due to implementation
|
||||||
|
" difficulties.
|
||||||
|
function! sj#SearchSkip(pattern, skip, ...)
|
||||||
|
" collect all of our arguments
|
||||||
|
let pattern = a:pattern
|
||||||
|
let skip = a:skip
|
||||||
|
|
||||||
|
if a:0 >= 1
|
||||||
|
let flags = a:1
|
||||||
|
else
|
||||||
|
let flags = ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
if stridx(flags, 'n') > -1
|
||||||
|
echoerr "Doesn't work with 'n' flag, was given: ".flags
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let stopline = (a:0 >= 2) ? a:2 : 0
|
||||||
|
let timeout = (a:0 >= 3) ? a:3 : 0
|
||||||
|
|
||||||
|
" Note: Native search() seems to hit a bug with one of the HTML tests
|
||||||
|
" (because of \zs?)
|
||||||
|
if skip == ''
|
||||||
|
" no skip, can delegate to native search()
|
||||||
|
return search(pattern, flags, stopline, timeout)
|
||||||
|
" elseif has('patch-8.2.915')
|
||||||
|
" " the native search() function can do this now:
|
||||||
|
" return search(pattern, flags, stopline, timeout, skip)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" search for the pattern, skipping a match if necessary
|
||||||
|
let skip_match = 1
|
||||||
|
while skip_match
|
||||||
|
let match = search(pattern, flags, stopline, timeout)
|
||||||
|
|
||||||
|
" remove 'c' flag for any run after the first
|
||||||
|
let flags = substitute(flags, 'c', '', 'g')
|
||||||
|
|
||||||
|
if match && eval(skip)
|
||||||
|
let skip_match = 1
|
||||||
|
else
|
||||||
|
let skip_match = 0
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
return match
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#SkipSyntax(syntax_groups)
|
||||||
|
let syntax_groups = a:syntax_groups
|
||||||
|
let skip_pattern = '\%('.join(syntax_groups, '\|').'\)'
|
||||||
|
|
||||||
|
return "synIDattr(synID(line('.'),col('.'),1),'name') =~ '".skip_pattern."'"
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#IncludeSyntax(syntax_groups)
|
||||||
|
let syntax_groups = a:syntax_groups
|
||||||
|
let include_pattern = '\%('.join(syntax_groups, '\|').'\)'
|
||||||
|
|
||||||
|
return "synIDattr(synID(line('.'),col('.'),1),'name') !~ '".include_pattern."'"
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Checks if the current position of the cursor is within the given limits.
|
||||||
|
"
|
||||||
|
function! sj#CursorBetween(start, end)
|
||||||
|
return sj#ColBetween(col('.'), a:start, a:end)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Checks if the given column is within the given limits.
|
||||||
|
"
|
||||||
|
function! sj#ColBetween(col, start, end)
|
||||||
|
return a:start <= a:col && a:end > a:col
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Regex helpers {{{1
|
||||||
|
"
|
||||||
|
" function! sj#ExtractRx(expr, pat, sub) {{{2
|
||||||
|
"
|
||||||
|
" Extract a regex match from a string. Ordinarily, substitute() would be used
|
||||||
|
" for this, but it's a bit too cumbersome for extracting a particular grouped
|
||||||
|
" match. Example usage:
|
||||||
|
"
|
||||||
|
" sj#ExtractRx('foo:bar:baz', ':\(.*\):', '\1') == 'bar'
|
||||||
|
"
|
||||||
|
function! sj#ExtractRx(expr, pat, sub)
|
||||||
|
let rx = a:pat
|
||||||
|
|
||||||
|
if stridx(a:pat, '^') != 0
|
||||||
|
let rx = '^.*'.rx
|
||||||
|
endif
|
||||||
|
|
||||||
|
if strridx(a:pat, '$') + 1 != strlen(a:pat)
|
||||||
|
let rx = rx.'.*$'
|
||||||
|
endif
|
||||||
|
|
||||||
|
return substitute(a:expr, rx, a:sub, '')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Compatibility {{{1
|
||||||
|
"
|
||||||
|
" Functionality that is present in newer versions of Vim, but needs a
|
||||||
|
" compatibility layer for older ones.
|
||||||
|
"
|
||||||
|
" function! sj#Keeppatterns(command) {{{2
|
||||||
|
"
|
||||||
|
" Executes the given command, but attempts to keep search patterns as they
|
||||||
|
" were.
|
||||||
|
"
|
||||||
|
function! sj#Keeppatterns(command)
|
||||||
|
if exists(':keeppatterns')
|
||||||
|
exe 'keeppatterns '.a:command
|
||||||
|
else
|
||||||
|
let histnr = histnr('search')
|
||||||
|
|
||||||
|
exe a:command
|
||||||
|
|
||||||
|
if histnr != histnr('search')
|
||||||
|
call histdel('search', -1)
|
||||||
|
let @/ = histget('search', -1)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Splitjoin-specific helpers {{{1
|
||||||
|
|
||||||
|
" These functions are not general-purpose, but can be used all around the
|
||||||
|
" plugin disregarding filetype, so they have no place in the specific autoload
|
||||||
|
" files.
|
||||||
|
|
||||||
|
function! sj#Align(from, to, type)
|
||||||
|
if a:from >= a:to
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if exists('g:tabular_loaded')
|
||||||
|
call s:Tabularize(a:from, a:to, a:type)
|
||||||
|
elseif exists('g:loaded_AlignPlugin')
|
||||||
|
call s:Align(a:from, a:to, a:type)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:Tabularize(from, to, type)
|
||||||
|
if a:type == 'hashrocket'
|
||||||
|
let pattern = '^[^=>]*\zs=>'
|
||||||
|
elseif a:type == 'css_declaration' || a:type == 'json_object'
|
||||||
|
let pattern = '^[^:]*:\s*\zs\s/l0'
|
||||||
|
elseif a:type == 'lua_table'
|
||||||
|
let pattern = '^[^=]*\zs='
|
||||||
|
elseif a:type == 'when_then'
|
||||||
|
let pattern = 'then'
|
||||||
|
elseif a:type == 'equals'
|
||||||
|
let pattern = '='
|
||||||
|
else
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
exe a:from.",".a:to."Tabularize/".pattern
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:Align(from, to, type)
|
||||||
|
if a:type == 'hashrocket'
|
||||||
|
let pattern = 'l: =>'
|
||||||
|
elseif a:type == 'css_declaration' || a:type == 'json_object'
|
||||||
|
let pattern = 'lp0W0 :\s*\zs'
|
||||||
|
elseif a:type == 'when_then'
|
||||||
|
let pattern = 'l: then'
|
||||||
|
elseif a:type == 'equals'
|
||||||
|
let pattern = '='
|
||||||
|
else
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
exe a:from.",".a:to."Align! ".pattern
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Returns a pair with the column positions of the closest opening and closing
|
||||||
|
" braces on the current line. The a:open and a:close parameters are the
|
||||||
|
" opening and closing brace characters to look for.
|
||||||
|
"
|
||||||
|
" The optional parameter is the list of syntax groups to skip while searching.
|
||||||
|
"
|
||||||
|
" If a pair is not found on the line, returns [-1, -1]
|
||||||
|
"
|
||||||
|
" Examples:
|
||||||
|
"
|
||||||
|
" let [start, end] = sj#LocateBracesOnLine('{', '}')
|
||||||
|
" let [start, end] = sj#LocateBracesOnLine('{', '}', ['rubyString'])
|
||||||
|
" let [start, end] = sj#LocateBracesOnLine('[', ']')
|
||||||
|
"
|
||||||
|
function! sj#LocateBracesOnLine(open, close, ...)
|
||||||
|
let [_bufnum, line, col, _off] = getpos('.')
|
||||||
|
let search_pattern = '\V'.a:open.'\m.*\V'.a:close
|
||||||
|
let current_line = line('.')
|
||||||
|
|
||||||
|
" bail early if there's obviously no match
|
||||||
|
if getline('.') !~ search_pattern
|
||||||
|
return [-1, -1]
|
||||||
|
endif
|
||||||
|
|
||||||
|
" optional skip parameter
|
||||||
|
if a:0 > 0
|
||||||
|
let skip = sj#SkipSyntax(a:1)
|
||||||
|
else
|
||||||
|
let skip = ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
" try looking backwards, then forwards
|
||||||
|
let found = searchpair('\V'.a:open, '', '\V'.a:close, 'cb', skip, line('.'))
|
||||||
|
if found <= 0
|
||||||
|
let found = sj#SearchSkip(search_pattern, skip, '', line('.'))
|
||||||
|
endif
|
||||||
|
|
||||||
|
if found > 0
|
||||||
|
let from = col('.')
|
||||||
|
|
||||||
|
normal! %
|
||||||
|
if line('.') != current_line
|
||||||
|
return [-1, -1]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let to = col('.')
|
||||||
|
|
||||||
|
return [from, to]
|
||||||
|
else
|
||||||
|
return [-1, -1]
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Returns a pair with the column positions of the closest opening and closing
|
||||||
|
" braces on the current line, but only if the cursor is between them.
|
||||||
|
"
|
||||||
|
" The optional parameter is the list of syntax groups to skip while searching.
|
||||||
|
"
|
||||||
|
" If a pair is not found around the cursor, returns [-1, -1]
|
||||||
|
"
|
||||||
|
" Examples:
|
||||||
|
"
|
||||||
|
" let [start, end] = sj#LocateBracesAroundCursor('{', '}')
|
||||||
|
" let [start, end] = sj#LocateBracesAroundCursor('{', '}', ['rubyString'])
|
||||||
|
" let [start, end] = sj#LocateBracesAroundCursor('[', ']')
|
||||||
|
"
|
||||||
|
function! sj#LocateBracesAroundCursor(open, close, ...)
|
||||||
|
let args = [a:open, a:close]
|
||||||
|
if a:0 > 0
|
||||||
|
call extend(args, a:000)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PushCursor()
|
||||||
|
let [start, end] = call('sj#LocateBracesOnLine', args)
|
||||||
|
call sj#PopCursor()
|
||||||
|
|
||||||
|
if sj#CursorBetween(start, end)
|
||||||
|
return [start, end]
|
||||||
|
else
|
||||||
|
return [-1, -1]
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Removes all extra whitespace on the current line. Such is often left when
|
||||||
|
" joining lines that have been aligned.
|
||||||
|
"
|
||||||
|
" Example:
|
||||||
|
"
|
||||||
|
" var one = { one: "two", three: "four" };
|
||||||
|
" " turns into:
|
||||||
|
" var one = { one: "two", three: "four" };
|
||||||
|
"
|
||||||
|
function! sj#CompressWhitespaceOnLine()
|
||||||
|
call sj#PushCursor()
|
||||||
|
call sj#Keeppatterns('s/\S\zs \+/ /g')
|
||||||
|
call sj#PopCursor()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Parses a JSON-like object and returns a list of its components
|
||||||
|
" (comma-separated parts).
|
||||||
|
"
|
||||||
|
" Note that a:from and a:to are the start and end of the body, not the curly
|
||||||
|
" braces that usually define a JSON object. This makes it possible to use the
|
||||||
|
" function for parsing an argument list into separate arguments, knowing their
|
||||||
|
" start and end.
|
||||||
|
"
|
||||||
|
" Different languages have different rules for delimiters, so it might be a
|
||||||
|
" better idea to write a specific parser. See autoload/sj/argparser/json.vim
|
||||||
|
" for inspiration.
|
||||||
|
"
|
||||||
|
function! sj#ParseJsonObjectBody(from, to)
|
||||||
|
" Just use js object parser
|
||||||
|
let parser = sj#argparser#json#Construct(a:from, a:to, getline('.'))
|
||||||
|
call parser.Process()
|
||||||
|
return parser.args
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Jumps over nested brackets until it reaches the given pattern.
|
||||||
|
"
|
||||||
|
" Special handling for "<" for Rust (for now), but this only matters if it's
|
||||||
|
" provided in the `a:opening_brackets`
|
||||||
|
"
|
||||||
|
function! sj#JumpBracketsTill(end_pattern, brackets)
|
||||||
|
let opening_brackets = a:brackets['opening']
|
||||||
|
let closing_brackets = a:brackets['closing']
|
||||||
|
|
||||||
|
try
|
||||||
|
" ensure we can't go to the next line:
|
||||||
|
let saved_whichwrap = &whichwrap
|
||||||
|
set whichwrap-=l
|
||||||
|
" ensure we can go to the very end of the line
|
||||||
|
let saved_virtualedit = &virtualedit
|
||||||
|
set virtualedit=onemore
|
||||||
|
|
||||||
|
let remainder_of_line = s:RemainderOfLine()
|
||||||
|
while remainder_of_line !~ '^'.a:end_pattern
|
||||||
|
\ && remainder_of_line !~ '^\s*$'
|
||||||
|
let [opening_bracket_match, offset] = s:BracketMatch(remainder_of_line, opening_brackets)
|
||||||
|
let [closing_bracket_match, _] = s:BracketMatch(remainder_of_line, closing_brackets)
|
||||||
|
|
||||||
|
if opening_bracket_match < 0 && closing_bracket_match >= 0
|
||||||
|
let closing_bracket = closing_brackets[closing_bracket_match]
|
||||||
|
|
||||||
|
if closing_bracket == '>'
|
||||||
|
" an unmatched > in this context means comparison, so do nothing
|
||||||
|
else
|
||||||
|
" there's an extra closing bracket from outside the list, bail out
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif opening_bracket_match >= 0
|
||||||
|
" then try to jump to the closing bracket
|
||||||
|
let opening_bracket = opening_brackets[opening_bracket_match]
|
||||||
|
let closing_bracket = closing_brackets[opening_bracket_match]
|
||||||
|
|
||||||
|
" first, go to the opening bracket
|
||||||
|
if offset > 0
|
||||||
|
exe "normal! ".offset."l"
|
||||||
|
end
|
||||||
|
|
||||||
|
if opening_bracket == closing_bracket
|
||||||
|
" same bracket (quote), search for it, unless it's escaped
|
||||||
|
call search('\\\@<!\V'.closing_bracket, 'W', line('.'))
|
||||||
|
else
|
||||||
|
" different closing, use searchpair
|
||||||
|
call searchpair('\V'.opening_bracket, '', '\V'.closing_bracket, 'W', '', line('.'))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! l
|
||||||
|
let remainder_of_line = s:RemainderOfLine()
|
||||||
|
if remainder_of_line =~ '^$'
|
||||||
|
" we have no more content, the current column is the end of the expression
|
||||||
|
return col('.')
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" we're past the final column of the expression, so return the previous
|
||||||
|
" one:
|
||||||
|
return col('.') - 1
|
||||||
|
finally
|
||||||
|
let &whichwrap = saved_whichwrap
|
||||||
|
let &virtualedit = saved_virtualedit
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:RemainderOfLine()
|
||||||
|
return strpart(getline('.'), col('.') - 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:BracketMatch(text, brackets)
|
||||||
|
let index = 0
|
||||||
|
let offset = match(a:text, '^\s*\zs')
|
||||||
|
let text = strpart(a:text, offset)
|
||||||
|
|
||||||
|
for char in split(a:brackets, '\zs')
|
||||||
|
if text[0] ==# char
|
||||||
|
return [index, offset]
|
||||||
|
else
|
||||||
|
let index += 1
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return [-1, 0]
|
||||||
|
endfunction
|
27
bundle/splitjoin.vim/autoload/sj/argparser/clojure.vim
Normal file
27
bundle/splitjoin.vim/autoload/sj/argparser/clojure.vim
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
function! sj#argparser#clojure#Construct(start_index, end_index, line)
|
||||||
|
let parser = sj#argparser#common#Construct(a:start_index, a:end_index, a:line)
|
||||||
|
|
||||||
|
call extend(parser, {
|
||||||
|
\ 'Process': function('sj#argparser#clojure#Process'),
|
||||||
|
\ })
|
||||||
|
|
||||||
|
return parser
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#argparser#clojure#Process() dict
|
||||||
|
while !self.Finished()
|
||||||
|
if self.body[0] =~ '\s'
|
||||||
|
call self.PushArg()
|
||||||
|
call self.Next()
|
||||||
|
continue
|
||||||
|
elseif self.body[0] =~ '["{\[(|]'
|
||||||
|
call self.JumpPair('"{[(|', '"}])|')
|
||||||
|
endif
|
||||||
|
|
||||||
|
call self.PushChar()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if len(sj#Trim(self.current_arg)) > 0
|
||||||
|
call self.PushArg()
|
||||||
|
endif
|
||||||
|
endfunction
|
206
bundle/splitjoin.vim/autoload/sj/argparser/common.vim
Normal file
206
bundle/splitjoin.vim/autoload/sj/argparser/common.vim
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
" Constructor:
|
||||||
|
" ============
|
||||||
|
|
||||||
|
function! sj#argparser#common#Construct(start_column, end_column, line)
|
||||||
|
let parser = {
|
||||||
|
\ 'args': [],
|
||||||
|
\ 'opts': [],
|
||||||
|
\ 'body': a:line,
|
||||||
|
\ 'index': a:start_column - 1,
|
||||||
|
\ 'current_arg': '',
|
||||||
|
\ 'current_arg_type': 'normal',
|
||||||
|
\
|
||||||
|
\ 'Process': function('sj#argparser#common#Process'),
|
||||||
|
\ 'PushArg': function('sj#argparser#common#PushArg'),
|
||||||
|
\ 'PushChar': function('sj#argparser#common#PushChar'),
|
||||||
|
\ 'Next': function('sj#argparser#common#Next'),
|
||||||
|
\ 'JumpPair': function('sj#argparser#common#JumpPair'),
|
||||||
|
\ 'AtFunctionEnd': function('sj#argparser#common#AtFunctionEnd'),
|
||||||
|
\ 'Finished': function('sj#argparser#common#Finished'),
|
||||||
|
\ }
|
||||||
|
|
||||||
|
if a:start_column > 1
|
||||||
|
let parser.body = strpart(parser.body, a:start_column - 1)
|
||||||
|
endif
|
||||||
|
if a:end_column > 1
|
||||||
|
let parser.body = strpart(parser.body, 0, (a:end_column - a:start_column) + 1)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return parser
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Methods:
|
||||||
|
" ========
|
||||||
|
|
||||||
|
function! sj#argparser#common#Process() dict
|
||||||
|
throw "Not implemented"
|
||||||
|
|
||||||
|
" " Implementation might go something like this:
|
||||||
|
"
|
||||||
|
" while !self.Finished()
|
||||||
|
" if self.body[0] == ','
|
||||||
|
" call self.PushArg()
|
||||||
|
" call self.Next()
|
||||||
|
" continue
|
||||||
|
" elseif self.AtFunctionEnd()
|
||||||
|
" break
|
||||||
|
" else
|
||||||
|
" " ...
|
||||||
|
" endif
|
||||||
|
|
||||||
|
" call self.PushChar()
|
||||||
|
" endwhile
|
||||||
|
|
||||||
|
" if len(self.current_arg) > 0
|
||||||
|
" call self.PushArg()
|
||||||
|
" endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Pushes the current argument to the args and initializes a new one.
|
||||||
|
function! sj#argparser#common#PushArg() dict
|
||||||
|
call add(self.args, sj#Trim(self.current_arg))
|
||||||
|
|
||||||
|
let self.current_arg = ''
|
||||||
|
let self.current_arg_type = 'normal'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Moves the parser to the next char and consumes the current
|
||||||
|
function! sj#argparser#common#PushChar() dict
|
||||||
|
let self.current_arg .= self.body[0]
|
||||||
|
call self.Next()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Moves the parser to the next char without consuming it.
|
||||||
|
function! sj#argparser#common#Next() dict
|
||||||
|
let self.body = strpart(self.body, 1)
|
||||||
|
let self.index = self.index + 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Finds the current char in a:start_chars and jumps to its match in a:end_chars.
|
||||||
|
"
|
||||||
|
" Example:
|
||||||
|
" call parser.JumpPair("([", ")]")
|
||||||
|
"
|
||||||
|
" This will parse matching round and square brackets.
|
||||||
|
"
|
||||||
|
" Note: nesting doesn't work properly if there's a string containing unmatched
|
||||||
|
" braces within the pair.
|
||||||
|
function! sj#argparser#common#JumpPair(start_chars, end_chars) dict
|
||||||
|
let char_index = stridx(a:start_chars, self.body[0])
|
||||||
|
let start_char = a:start_chars[char_index]
|
||||||
|
let target_char = a:end_chars[char_index]
|
||||||
|
|
||||||
|
" prepare a stack for nested braces and the like
|
||||||
|
let stack = 1
|
||||||
|
let n = 0
|
||||||
|
let limit = len(self.body)
|
||||||
|
|
||||||
|
" Note: if the start and end chars are the same (quotes, for example), this
|
||||||
|
" will still work, because we're checking for the target_char before the
|
||||||
|
" start_char
|
||||||
|
while stack > 0 && n < limit
|
||||||
|
let n = n + 1
|
||||||
|
|
||||||
|
if self.body[n] == target_char
|
||||||
|
let stack = stack - 1
|
||||||
|
elseif self.body[n] == start_char
|
||||||
|
let stack = stack + 1
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
let self.current_arg .= strpart(self.body, 0, n)
|
||||||
|
|
||||||
|
let self.body = strpart(self.body, n)
|
||||||
|
let self.index = self.index + n
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Returns true if the parser has finished parsing the arguments.
|
||||||
|
function! sj#argparser#common#Finished() dict
|
||||||
|
return len(self.body) <= 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Returns true if the parser is at the function's end
|
||||||
|
function! sj#argparser#common#AtFunctionEnd() dict
|
||||||
|
return (self.body[0] == ')')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Public functions:
|
||||||
|
" =================
|
||||||
|
|
||||||
|
" This code was originally created for ruby functions, but seems to be useful
|
||||||
|
" for elixir as well, with some modifications.
|
||||||
|
"
|
||||||
|
function! sj#argparser#common#LocateRubylikeFunction(keyword_pattern, syntax_groups)
|
||||||
|
call sj#PushCursor()
|
||||||
|
let start_col = col('.')
|
||||||
|
let skip = sj#SkipSyntax(a:syntax_groups)
|
||||||
|
|
||||||
|
" The first pattern matches functions with brackets and consists of the
|
||||||
|
" following:
|
||||||
|
"
|
||||||
|
" - a keyword
|
||||||
|
" - an opening round bracket
|
||||||
|
" - something that's not a comma and doesn't look like an operator
|
||||||
|
" (to avoid a few edge cases)
|
||||||
|
"
|
||||||
|
let pattern = '\v(^|\s|\.|::)\m' . a:keyword_pattern . '\v\(\s*[^,=<>+-/*^%})\]]'
|
||||||
|
let found = sj#SearchSkip(pattern, skip, 'bcW', line('.'))
|
||||||
|
if found <= 0
|
||||||
|
" try searching forward
|
||||||
|
let found = sj#SearchSkip(pattern, skip, 'cW', line('.'))
|
||||||
|
endif
|
||||||
|
if found > 0
|
||||||
|
" first, figure out the function name
|
||||||
|
call search('\k\+', 'cW', line('.'))
|
||||||
|
let function_name = expand('<cword>')
|
||||||
|
|
||||||
|
" go to the end of the matching pattern
|
||||||
|
call search(pattern, 'cWe', line('.'))
|
||||||
|
" look for the starting bracket
|
||||||
|
if sj#SearchSkip(a:keyword_pattern . '\s*\zs(\s*\%#', skip, 'bcW', line('.'))
|
||||||
|
let function_type = 'with_round_braces'
|
||||||
|
let from = col('.') + 1
|
||||||
|
normal! h%h
|
||||||
|
let to = col('.')
|
||||||
|
|
||||||
|
if sj#ColBetween(start_col, from - 1, to + 1)
|
||||||
|
return [function_name, from, to, function_type]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PopCursor()
|
||||||
|
|
||||||
|
" The second pattern matches functions without brackets:
|
||||||
|
"
|
||||||
|
" - a keyword
|
||||||
|
" - at least one space
|
||||||
|
" - something that's not a comma and doesn't look like an operator
|
||||||
|
" (to avoid a few edge cases)
|
||||||
|
"
|
||||||
|
let pattern = '\v(^|\s|\.|::)\m' . a:keyword_pattern . '\v\s+[^ ,=<>+-/*^%})\]]'
|
||||||
|
let found = sj#SearchSkip(pattern, skip, 'bcW', line('.'))
|
||||||
|
if found <= 0
|
||||||
|
" try searching forward
|
||||||
|
let found = sj#SearchSkip(pattern, skip, 'cW', line('.'))
|
||||||
|
endif
|
||||||
|
if found > 0
|
||||||
|
" first, figure out the function name
|
||||||
|
call search('\k\+', 'cW', line('.'))
|
||||||
|
let function_name = expand('<cword>')
|
||||||
|
let function_start_col = col('.')
|
||||||
|
|
||||||
|
" go to the end of the matching pattern
|
||||||
|
call search(pattern, 'cWe', line('.'))
|
||||||
|
|
||||||
|
let function_type = 'with_spaces'
|
||||||
|
let from = col('.')
|
||||||
|
let to = -1 " we're not sure about the end
|
||||||
|
|
||||||
|
if sj#ColBetween(start_col, function_start_col - 1, col('$'))
|
||||||
|
return [function_name, from, to, function_type]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
return ['', -1, -1, 'none']
|
||||||
|
endfunction
|
34
bundle/splitjoin.vim/autoload/sj/argparser/elixir.vim
Normal file
34
bundle/splitjoin.vim/autoload/sj/argparser/elixir.vim
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
function! sj#argparser#elixir#LocateFunction()
|
||||||
|
return sj#argparser#common#LocateRubylikeFunction(
|
||||||
|
\ '\k\+[?!]\=',
|
||||||
|
\ ['elixirString', 'elixirAtom']
|
||||||
|
\ )
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#argparser#elixir#Construct(start_index, end_index, line)
|
||||||
|
let parser = sj#argparser#common#Construct(a:start_index, a:end_index, a:line)
|
||||||
|
|
||||||
|
call extend(parser, {
|
||||||
|
\ 'Process': function('sj#argparser#elixir#Process'),
|
||||||
|
\ })
|
||||||
|
|
||||||
|
return parser
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#argparser#elixir#Process() dict
|
||||||
|
while !self.Finished()
|
||||||
|
if self.body[0] == ','
|
||||||
|
call self.PushArg()
|
||||||
|
call self.Next()
|
||||||
|
continue
|
||||||
|
elseif self.body[0] =~ "[\"'{\[(/]"
|
||||||
|
call self.JumpPair("\"'{[(/", "\"'}])/")
|
||||||
|
endif
|
||||||
|
|
||||||
|
call self.PushChar()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if len(sj#Trim(self.current_arg)) > 0
|
||||||
|
call self.PushArg()
|
||||||
|
endif
|
||||||
|
endfunction
|
33
bundle/splitjoin.vim/autoload/sj/argparser/go_vars.vim
Normal file
33
bundle/splitjoin.vim/autoload/sj/argparser/go_vars.vim
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
function! sj#argparser#go_vars#Construct(line)
|
||||||
|
" 0, 0 for start, end, since we're giving it the full body
|
||||||
|
let parser = sj#argparser#common#Construct(0, 0, a:line)
|
||||||
|
|
||||||
|
call extend(parser, {
|
||||||
|
\ 'comment': '',
|
||||||
|
\
|
||||||
|
\ 'Process': function('sj#argparser#go_vars#Process'),
|
||||||
|
\ })
|
||||||
|
|
||||||
|
return parser
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#argparser#go_vars#Process() dict
|
||||||
|
while !self.Finished()
|
||||||
|
if self.body[0] == ','
|
||||||
|
call self.PushArg()
|
||||||
|
call self.Next()
|
||||||
|
continue
|
||||||
|
elseif self.body[0] =~ "[\"'{\[(]"
|
||||||
|
call self.JumpPair("\"'{[(<", "\"'}])>")
|
||||||
|
elseif self.body =~ '^\s*\/\/'
|
||||||
|
let self.comment = sj#Trim(self.body)
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
|
||||||
|
call self.PushChar()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if len(sj#Trim(self.current_arg)) > 0
|
||||||
|
call self.PushArg()
|
||||||
|
endif
|
||||||
|
endfunction
|
33
bundle/splitjoin.vim/autoload/sj/argparser/html_args.vim
Normal file
33
bundle/splitjoin.vim/autoload/sj/argparser/html_args.vim
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
function! sj#argparser#html_args#Construct(start_index, end_index, line)
|
||||||
|
let parser = sj#argparser#common#Construct(a:start_index, a:end_index, a:line)
|
||||||
|
|
||||||
|
call extend(parser, {
|
||||||
|
\ 'Process': function('sj#argparser#html_args#Process'),
|
||||||
|
\ })
|
||||||
|
|
||||||
|
return parser
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#argparser#html_args#Process() dict
|
||||||
|
while !self.Finished()
|
||||||
|
if self.body =~ '^\s*/\=>'
|
||||||
|
" end of the tag, push it onto the last argument
|
||||||
|
let self.current_arg .= self.body
|
||||||
|
break
|
||||||
|
elseif self.body[0] == ' '
|
||||||
|
if self.current_arg != ''
|
||||||
|
call self.PushArg()
|
||||||
|
endif
|
||||||
|
call self.Next()
|
||||||
|
continue
|
||||||
|
elseif self.body[0] =~ '["''{]'
|
||||||
|
call self.JumpPair('"''{', '"''}')
|
||||||
|
endif
|
||||||
|
|
||||||
|
call self.PushChar()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if len(self.current_arg) > 0
|
||||||
|
call self.PushArg()
|
||||||
|
endif
|
||||||
|
endfunction
|
27
bundle/splitjoin.vim/autoload/sj/argparser/js.vim
Normal file
27
bundle/splitjoin.vim/autoload/sj/argparser/js.vim
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
function! sj#argparser#js#Construct(start_index, end_index, line)
|
||||||
|
let parser = sj#argparser#common#Construct(a:start_index, a:end_index, a:line)
|
||||||
|
|
||||||
|
call extend(parser, {
|
||||||
|
\ 'Process': function('sj#argparser#js#Process'),
|
||||||
|
\ })
|
||||||
|
|
||||||
|
return parser
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#argparser#js#Process() dict
|
||||||
|
while !self.Finished()
|
||||||
|
if self.body[0] == ','
|
||||||
|
call self.PushArg()
|
||||||
|
call self.Next()
|
||||||
|
continue
|
||||||
|
elseif self.body[0] =~ "[\"'{\[(/]"
|
||||||
|
call self.JumpPair("\"'{[(/", "\"'}])/")
|
||||||
|
endif
|
||||||
|
|
||||||
|
call self.PushChar()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if len(sj#Trim(self.current_arg)) > 0
|
||||||
|
call self.PushArg()
|
||||||
|
endif
|
||||||
|
endfunction
|
29
bundle/splitjoin.vim/autoload/sj/argparser/json.vim
Normal file
29
bundle/splitjoin.vim/autoload/sj/argparser/json.vim
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
function! sj#argparser#json#Construct(start_index, end_index, line)
|
||||||
|
let parser = sj#argparser#common#Construct(a:start_index, a:end_index, a:line)
|
||||||
|
|
||||||
|
call extend(parser, {
|
||||||
|
\ 'Process': function('sj#argparser#json#Process'),
|
||||||
|
\ })
|
||||||
|
|
||||||
|
return parser
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Note: Differs from "js" parser by the fact that JSON doesn't have /regexes/
|
||||||
|
" to skip through.
|
||||||
|
function! sj#argparser#json#Process() dict
|
||||||
|
while !self.Finished()
|
||||||
|
if self.body[0] == ','
|
||||||
|
call self.PushArg()
|
||||||
|
call self.Next()
|
||||||
|
continue
|
||||||
|
elseif self.body[0] =~ "[\"'{\[(]"
|
||||||
|
call self.JumpPair("\"'{[(", "\"'}])")
|
||||||
|
endif
|
||||||
|
|
||||||
|
call self.PushChar()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if len(sj#Trim(self.current_arg)) > 0
|
||||||
|
call self.PushArg()
|
||||||
|
endif
|
||||||
|
endfunction
|
156
bundle/splitjoin.vim/autoload/sj/argparser/ruby.vim
Normal file
156
bundle/splitjoin.vim/autoload/sj/argparser/ruby.vim
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
" Constructor:
|
||||||
|
" ============
|
||||||
|
|
||||||
|
function! sj#argparser#ruby#Construct(start_index, end_index, line)
|
||||||
|
let parser = sj#argparser#common#Construct(a:start_index, a:end_index, a:line)
|
||||||
|
|
||||||
|
call extend(parser, {
|
||||||
|
\ 'hash_type': '',
|
||||||
|
\ 'cursor_arg': 0,
|
||||||
|
\ 'cursor_col': col('.'),
|
||||||
|
\
|
||||||
|
\ 'Process': function('sj#argparser#ruby#Process'),
|
||||||
|
\ 'PushArg': function('sj#argparser#ruby#PushArg'),
|
||||||
|
\ 'AtFunctionEnd': function('sj#argparser#ruby#AtFunctionEnd'),
|
||||||
|
\ 'ExpandOptionHash': function('sj#argparser#ruby#ExpandOptionHash'),
|
||||||
|
\ 'MarkOptionArg': function('sj#argparser#ruby#MarkOptionArg'),
|
||||||
|
\ })
|
||||||
|
|
||||||
|
return parser
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Methods:
|
||||||
|
" ========
|
||||||
|
|
||||||
|
function! sj#argparser#ruby#Process() dict
|
||||||
|
while !self.Finished()
|
||||||
|
if self.body[0] == ','
|
||||||
|
call self.PushArg()
|
||||||
|
call self.Next()
|
||||||
|
continue
|
||||||
|
elseif self.AtFunctionEnd()
|
||||||
|
break
|
||||||
|
elseif self.body[0] =~ '[''"]'
|
||||||
|
call self.JumpPair("'\"", "'\"")
|
||||||
|
|
||||||
|
" Example: 'some key': value
|
||||||
|
if len(self.body) > 1 && self.body[1] == ':'
|
||||||
|
call self.MarkOptionArg('new')
|
||||||
|
endif
|
||||||
|
elseif self.body[0] =~ "[{\[`(/]"
|
||||||
|
call self.JumpPair("{[`(/", "}]`)/")
|
||||||
|
elseif self.body[0] == '%'
|
||||||
|
call self.PushChar()
|
||||||
|
if self.body[0] =~ '[qQrswWx]'
|
||||||
|
call self.PushChar()
|
||||||
|
endif
|
||||||
|
let delimiter = self.body[0]
|
||||||
|
if delimiter =~ '[[({<]'
|
||||||
|
call self.JumpPair('[({<', '])}>')
|
||||||
|
else
|
||||||
|
call self.JumpPair(delimiter, delimiter)
|
||||||
|
endif
|
||||||
|
elseif self.body =~ '^=>'
|
||||||
|
" Example: 'some key' => value
|
||||||
|
call self.MarkOptionArg('classic')
|
||||||
|
elseif self.body =~ '^\(\k\|[?!]\):[^:]'
|
||||||
|
" Example: some_key: value
|
||||||
|
call self.MarkOptionArg('new')
|
||||||
|
endif
|
||||||
|
|
||||||
|
call self.PushChar()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if len(self.current_arg) > 0
|
||||||
|
call self.PushArg()
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Pushes the current argument either to the args or opts stack and initializes
|
||||||
|
" a new one.
|
||||||
|
function! sj#argparser#ruby#PushArg() dict
|
||||||
|
if self.current_arg_type == 'option'
|
||||||
|
call add(self.opts, sj#Trim(self.current_arg))
|
||||||
|
else
|
||||||
|
call add(self.args, sj#Trim(self.current_arg))
|
||||||
|
endif
|
||||||
|
|
||||||
|
let self.current_arg = ''
|
||||||
|
let self.current_arg_type = 'normal'
|
||||||
|
|
||||||
|
if self.cursor_col > self.index + 1
|
||||||
|
" cursor is after the current argument
|
||||||
|
let self.cursor_arg += 1
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" If the last argument is a hash and no options have been parsed, splits the
|
||||||
|
" last argument and fills the options with it.
|
||||||
|
function! sj#argparser#ruby#ExpandOptionHash() dict
|
||||||
|
if len(self.opts) <= 0 && len(self.args) > 0
|
||||||
|
" then try parsing the last parameter
|
||||||
|
let last = self.args[-1]
|
||||||
|
let hash_pattern = '^{\(.*\(=>\|\k:\|[''"]:\).*\)}$'
|
||||||
|
|
||||||
|
if last =~ hash_pattern
|
||||||
|
" then it seems to be a hash, expand it
|
||||||
|
call remove(self.args, -1)
|
||||||
|
|
||||||
|
let hash = sj#ExtractRx(last, hash_pattern, '\1')
|
||||||
|
|
||||||
|
let [_from, _to, _args, opts, hash_type, _cursor_arg] =
|
||||||
|
\ sj#argparser#ruby#ParseArguments(0, -1, hash, { 'expand_options': 1 })
|
||||||
|
call extend(self.opts, opts)
|
||||||
|
let self.hash_type = hash_type
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Returns true if the parser is at the function's end, either because of a
|
||||||
|
" closing brace, a "do" clause or a "%>".
|
||||||
|
function! sj#argparser#ruby#AtFunctionEnd() dict
|
||||||
|
if self.body[0] == ')'
|
||||||
|
return 1
|
||||||
|
elseif self.body =~ '\v^\s*do(\s*\|.*\|)?(\s*-?\%\>\s*)?$'
|
||||||
|
return 1
|
||||||
|
elseif self.body =~ '^\s*-\?%>'
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Public functions:
|
||||||
|
" =================
|
||||||
|
|
||||||
|
function! sj#argparser#ruby#LocateFunction()
|
||||||
|
return sj#argparser#common#LocateRubylikeFunction(
|
||||||
|
\ '\k\+[?!]\=',
|
||||||
|
\ ['rubyInterpolationDelimiter', 'rubyString']
|
||||||
|
\ )
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#argparser#ruby#MarkOptionArg(type) dict
|
||||||
|
let self.current_arg_type = 'option'
|
||||||
|
|
||||||
|
if a:type == 'new' && sj#BlankString(self.hash_type)
|
||||||
|
let self.hash_type = 'new'
|
||||||
|
elseif a:type == 'classic' && sj#BlankString(self.hash_type)
|
||||||
|
let self.hash_type = 'classic'
|
||||||
|
elseif a:type != self.hash_type
|
||||||
|
let self.hash_type = 'mixed'
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#argparser#ruby#LocateHash()
|
||||||
|
return sj#LocateBracesOnLine('{', '}', ['rubyInterpolationDelimiter', 'rubyString'])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#argparser#ruby#ParseArguments(start_index, end_index, line, options)
|
||||||
|
let parser = sj#argparser#ruby#Construct(a:start_index, a:end_index, a:line)
|
||||||
|
call parser.Process()
|
||||||
|
if a:options.expand_options
|
||||||
|
call parser.ExpandOptionHash()
|
||||||
|
endif
|
||||||
|
return [ a:start_index, parser.index, parser.args, parser.opts, parser.hash_type, parser.cursor_arg ]
|
||||||
|
endfunction
|
42
bundle/splitjoin.vim/autoload/sj/argparser/rust_list.vim
Normal file
42
bundle/splitjoin.vim/autoload/sj/argparser/rust_list.vim
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
function! sj#argparser#rust_list#Construct(type, start_index, end_index, line)
|
||||||
|
let parser = sj#argparser#common#Construct(a:start_index, a:end_index, a:line)
|
||||||
|
|
||||||
|
call extend(parser, {
|
||||||
|
\ 'type': a:type,
|
||||||
|
\
|
||||||
|
\ 'Process': function('sj#argparser#rust_list#Process'),
|
||||||
|
\ })
|
||||||
|
|
||||||
|
return parser
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Note: Differs from "json" parser by <generics> and 'lifetimes
|
||||||
|
function! sj#argparser#rust_list#Process() dict
|
||||||
|
if self.type == 'list'
|
||||||
|
let bracket_regex = "[\"'{\[(<]"
|
||||||
|
let opening_brackets = "\"'{[(<"
|
||||||
|
let closing_brackets = "\"'}])>"
|
||||||
|
elseif self.type == 'fn'
|
||||||
|
let bracket_regex = "[\"{\[(<]"
|
||||||
|
let opening_brackets = "\"{[(<"
|
||||||
|
let closing_brackets = "\"}])>"
|
||||||
|
else
|
||||||
|
throw "Unknown rust_list parse type: " . self.type
|
||||||
|
endif
|
||||||
|
|
||||||
|
while !self.Finished()
|
||||||
|
if self.body[0] == ','
|
||||||
|
call self.PushArg()
|
||||||
|
call self.Next()
|
||||||
|
continue
|
||||||
|
elseif self.body[0] =~ bracket_regex
|
||||||
|
call self.JumpPair(opening_brackets, closing_brackets)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call self.PushChar()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if len(sj#Trim(self.current_arg)) > 0
|
||||||
|
call self.PushArg()
|
||||||
|
endif
|
||||||
|
endfunction
|
105
bundle/splitjoin.vim/autoload/sj/argparser/rust_struct.vim
Normal file
105
bundle/splitjoin.vim/autoload/sj/argparser/rust_struct.vim
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
function! sj#argparser#rust_struct#Construct(start_index, end_index, line)
|
||||||
|
let parser = sj#argparser#common#Construct(a:start_index, a:end_index, a:line)
|
||||||
|
|
||||||
|
call extend(parser, {
|
||||||
|
\ 'current_arg_attributes': [],
|
||||||
|
\
|
||||||
|
\ 'PushArg': function('sj#argparser#rust_struct#PushArg'),
|
||||||
|
\ 'Process': function('sj#argparser#rust_struct#Process'),
|
||||||
|
\
|
||||||
|
\ 'IsValidStruct': function('sj#argparser#rust_struct#IsValidStruct'),
|
||||||
|
\ 'IsOnlyStructPairs': function('sj#argparser#rust_struct#IsOnlyStructPairs'),
|
||||||
|
\ })
|
||||||
|
|
||||||
|
return parser
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#argparser#rust_struct#Process() dict
|
||||||
|
while !self.Finished()
|
||||||
|
if self.body[0] == ','
|
||||||
|
call self.PushArg()
|
||||||
|
call self.Next()
|
||||||
|
continue
|
||||||
|
elseif self.body =~ '^#['
|
||||||
|
" It's an #[attribute], so the "current arg" is going to be temporarily
|
||||||
|
" reset so we can parse it
|
||||||
|
let real_current_arg = self.current_arg
|
||||||
|
let self.current_arg = ''
|
||||||
|
|
||||||
|
call self.PushChar()
|
||||||
|
call self.JumpPair('[', ']')
|
||||||
|
call self.PushChar()
|
||||||
|
call add(self.current_arg_attributes, self.current_arg)
|
||||||
|
|
||||||
|
let self.current_arg = real_current_arg
|
||||||
|
elseif self.body =~ '^''\\\=.'''
|
||||||
|
" then it's a char, not a lifetime, we can jump it
|
||||||
|
call self.JumpPair("'", "'")
|
||||||
|
elseif self.body[0] =~ '["{\[(|]'
|
||||||
|
call self.JumpPair('"{[(|', '"}])|')
|
||||||
|
endif
|
||||||
|
|
||||||
|
call self.PushChar()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if len(sj#Trim(self.current_arg)) > 0
|
||||||
|
call self.PushArg()
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Pushes the current argument to the args and initializes a new one. Special
|
||||||
|
" handling for attributes
|
||||||
|
function! sj#argparser#rust_struct#PushArg() dict
|
||||||
|
call add(self.args, {
|
||||||
|
\ "attributes": self.current_arg_attributes,
|
||||||
|
\ "argument": sj#Trim(self.current_arg)
|
||||||
|
\ })
|
||||||
|
|
||||||
|
let self.current_arg = ''
|
||||||
|
let self.current_arg_type = 'normal'
|
||||||
|
let self.current_arg_attributes = []
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Expects self.Process() to have been run
|
||||||
|
"
|
||||||
|
" Possibilities:
|
||||||
|
" StructName { key: value }, or
|
||||||
|
" StructName { prop1, prop2 }, or
|
||||||
|
" StructName { prop1, ..Foo }, or
|
||||||
|
" StructName { #[cfg] prop1, ..Foo }
|
||||||
|
"
|
||||||
|
function! sj#argparser#rust_struct#IsValidStruct() dict
|
||||||
|
let visibility = '\%(pub\%((crate)\)\=\s*\)\='
|
||||||
|
|
||||||
|
for entry in self.args
|
||||||
|
if entry.argument !~ '^'.visibility.'\k\+$' &&
|
||||||
|
\ entry.argument !~ '^'.visibility.'\k\+:' &&
|
||||||
|
\ entry.argument !~ '^'.visibility.'\.\.\k'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Expects self.Process() to have been run
|
||||||
|
"
|
||||||
|
" Possibilities:
|
||||||
|
" StructName { key: value, other_key: expression() }
|
||||||
|
"
|
||||||
|
function! sj#argparser#rust_struct#IsOnlyStructPairs() dict
|
||||||
|
let visibility = '\%(pub\%((crate)\)\=\s*\)\='
|
||||||
|
|
||||||
|
for entry in self.args
|
||||||
|
if len(entry.attributes) > 0
|
||||||
|
" then it's not just pairs, there's also an attribute
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if entry.argument !~ '^'.visibility.'\k\+:'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
27
bundle/splitjoin.vim/autoload/sj/argparser/sh.vim
Normal file
27
bundle/splitjoin.vim/autoload/sj/argparser/sh.vim
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
function! sj#argparser#sh#Construct(start_index, end_index, line)
|
||||||
|
let parser = sj#argparser#common#Construct(a:start_index, a:end_index, a:line)
|
||||||
|
|
||||||
|
call extend(parser, {
|
||||||
|
\ 'Process': function('sj#argparser#sh#Process'),
|
||||||
|
\ })
|
||||||
|
|
||||||
|
return parser
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#argparser#sh#Process() dict
|
||||||
|
while !self.Finished()
|
||||||
|
if self.body[0] == ';'
|
||||||
|
call self.PushArg()
|
||||||
|
call self.Next()
|
||||||
|
continue
|
||||||
|
elseif self.body[0] =~ "[\"'\[(/]"
|
||||||
|
call self.JumpPair("\"'[(/", "\"'])/")
|
||||||
|
endif
|
||||||
|
|
||||||
|
call self.PushChar()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if len(self.current_arg) > 0
|
||||||
|
call self.PushArg()
|
||||||
|
endif
|
||||||
|
endfunction
|
68
bundle/splitjoin.vim/autoload/sj/c.vim
Normal file
68
bundle/splitjoin.vim/autoload/sj/c.vim
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
" Only real syntax that's interesting is cParen and cConditional
|
||||||
|
let s:skip = sj#SkipSyntax(['cComment', 'cCommentL', 'cString', 'cCppString', 'cBlock'])
|
||||||
|
|
||||||
|
function! sj#c#SplitFuncall()
|
||||||
|
if sj#SearchUnderCursor('(.\{-})', '', s:skip) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PushCursor()
|
||||||
|
|
||||||
|
normal! l
|
||||||
|
let start = col('.')
|
||||||
|
normal! h%h
|
||||||
|
let end = col('.')
|
||||||
|
|
||||||
|
let items = sj#ParseJsonObjectBody(start, end)
|
||||||
|
|
||||||
|
let body = "("
|
||||||
|
if sj#settings#Read('c_argument_split_first_newline')
|
||||||
|
let body = "(\n"
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body .= join(items, ",\n")
|
||||||
|
|
||||||
|
if sj#settings#Read('c_argument_split_last_newline')
|
||||||
|
let body .= "\n)"
|
||||||
|
else
|
||||||
|
let body .= ")"
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PopCursor()
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('va(', body)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#c#SplitIfClause()
|
||||||
|
if sj#SearchUnderCursor('if\s*(.\{-})', '', s:skip) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let items = sj#TrimList(split(getline('.'), '\ze\(&&\|||\)'))
|
||||||
|
let body = join(items, "\n")
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('V', body)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#c#JoinFuncall()
|
||||||
|
if sj#SearchUnderCursor('([^)]*\s*$', '', s:skip) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! va(J
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#c#JoinIfClause()
|
||||||
|
if sj#SearchUnderCursor('if\s*([^)]*\s*$', '', s:skip) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PushCursor()
|
||||||
|
normal! f(
|
||||||
|
normal! va(J
|
||||||
|
call sj#PopCursor()
|
||||||
|
return 1
|
||||||
|
endfunction
|
49
bundle/splitjoin.vim/autoload/sj/clojure.vim
Normal file
49
bundle/splitjoin.vim/autoload/sj/clojure.vim
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
let s:skip_syntax = sj#SkipSyntax(['String', 'Comment'])
|
||||||
|
|
||||||
|
function! sj#clojure#SplitList()
|
||||||
|
if sj#SearchSkip('[([{]', s:skip_syntax, 'bW', line('.'), ) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PushCursor()
|
||||||
|
let start_col = col('.')
|
||||||
|
let bracket = getline('.')[start_col - 1]
|
||||||
|
|
||||||
|
if bracket == '('
|
||||||
|
let closing_bracket = ')'
|
||||||
|
elseif bracket == '['
|
||||||
|
let closing_bracket = '\]'
|
||||||
|
elseif bracket == '{'
|
||||||
|
let closing_bracket = '}'
|
||||||
|
else
|
||||||
|
throw "Unknown bracket: " . bracket
|
||||||
|
endif
|
||||||
|
|
||||||
|
if searchpair(bracket, '', closing_bracket, 'W', s:skip_syntax, line('.')) <= 0
|
||||||
|
call sj#PopCursor()
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let end_col = col('.')
|
||||||
|
|
||||||
|
let parser = sj#argparser#clojure#Construct(start_col + 1, end_col - 1, getline('.'))
|
||||||
|
call parser.Process()
|
||||||
|
if len(parser.args) <= 0
|
||||||
|
call sj#PopCursor()
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PopCursor()
|
||||||
|
call sj#ReplaceMotion('vi' . bracket, join(parser.args, "\n"))
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#clojure#JoinList()
|
||||||
|
if sj#SearchSkip('[([{]', s:skip_syntax, 'bW') <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let bracket = getline('.')[col('.') - 1]
|
||||||
|
exe 'normal! va'.bracket.'J'
|
||||||
|
return 1
|
||||||
|
endfunction
|
298
bundle/splitjoin.vim/autoload/sj/coffee.vim
Normal file
298
bundle/splitjoin.vim/autoload/sj/coffee.vim
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
function! sj#coffee#SplitFunction()
|
||||||
|
let lineno = line('.')
|
||||||
|
let line = getline('.')
|
||||||
|
let indent = indent(lineno)
|
||||||
|
|
||||||
|
if line !~ '[-=]>'
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
call sj#Keeppatterns('s/\([-=]\)>\s*/\1>\r/')
|
||||||
|
call sj#SetIndent(lineno, indent)
|
||||||
|
call sj#SetIndent(lineno + 1, indent + &sw)
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#coffee#JoinFunction()
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if line !~ '[-=]>'
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
call sj#Keeppatterns('s/\([-=]\)>\_s\+/\1> /')
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#coffee#SplitIfClause()
|
||||||
|
let line = getline('.')
|
||||||
|
let base_indent = indent('.')
|
||||||
|
let suffix_pattern = '\v(.*\S.*) (if|unless|while|until|for) (.*)'
|
||||||
|
let postfix_pattern = '\v(if|unless|while|until) (.*) then (.*)'
|
||||||
|
|
||||||
|
if line =~ suffix_pattern
|
||||||
|
call sj#ReplaceMotion('V', substitute(line, suffix_pattern, '\2 \3\n\1', ''))
|
||||||
|
call sj#SetIndent(line('.'), base_indent)
|
||||||
|
call sj#SetIndent(line('.') + 1, base_indent + &sw)
|
||||||
|
return 1
|
||||||
|
elseif line =~ postfix_pattern
|
||||||
|
call sj#ReplaceMotion('V', substitute(line, postfix_pattern, '\1 \2\n\3', ''))
|
||||||
|
call sj#SetIndent(line('.'), base_indent)
|
||||||
|
call sj#SetIndent(line('.') + 1, base_indent + &sw)
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#coffee#JoinIfElseClause()
|
||||||
|
let if_lineno = line('.')
|
||||||
|
let else_lineno = line('.') + 2
|
||||||
|
let if_line = getline(if_lineno)
|
||||||
|
let else_line = getline(else_lineno)
|
||||||
|
let base_indent = indent('.')
|
||||||
|
let if_pattern = '\v^\s*(if|unless|while|until|for)\s'
|
||||||
|
let else_pattern = '\v^\s*else$'
|
||||||
|
|
||||||
|
if if_line !~ if_pattern || else_line !~ else_pattern
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if indent(if_lineno) != indent(else_lineno)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let if_clause = sj#Trim(if_line)
|
||||||
|
let true_body = sj#Trim(getline(line('.') + 1))
|
||||||
|
let else_clause = sj#Trim(else_line)
|
||||||
|
let false_body = sj#Trim(getline(line('.') + 3))
|
||||||
|
|
||||||
|
let assignment_pattern = '^\(\w\+\)\s*=\s*'
|
||||||
|
if true_body =~ assignment_pattern && false_body =~ assignment_pattern
|
||||||
|
" it might start with the assignment of a single variable, let's see
|
||||||
|
let match_index = matchend(true_body, assignment_pattern)
|
||||||
|
if strpart(true_body, 0, match_index) == strpart(false_body, 0, match_index)
|
||||||
|
" assignment, change the components a bit
|
||||||
|
let if_clause = strpart(true_body, 0, match_index).if_clause
|
||||||
|
let true_body = strpart(true_body, match_index)
|
||||||
|
let false_body = strpart(false_body, match_index)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Vjjj', if_clause.' then '.true_body.' else '.false_body)
|
||||||
|
call sj#SetIndent(line('.'), base_indent)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#coffee#JoinIfClause()
|
||||||
|
let line = getline('.')
|
||||||
|
let base_indent = indent('.')
|
||||||
|
let pattern = '\v^\s*(if|unless|while|until|for)\ze\s'
|
||||||
|
|
||||||
|
if line !~ pattern
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let if_clause = sj#Trim(getline('.'))
|
||||||
|
let body = sj#Trim(getline(line('.') + 1))
|
||||||
|
|
||||||
|
if sj#settings#Read('coffee_suffix_if_clause')
|
||||||
|
call sj#ReplaceMotion('Vj', body.' '.if_clause)
|
||||||
|
else
|
||||||
|
call sj#ReplaceMotion('Vj', if_clause.' then '.body)
|
||||||
|
endif
|
||||||
|
call sj#SetIndent(line('.'), base_indent)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#coffee#SplitTernaryClause()
|
||||||
|
let lineno = line('.')
|
||||||
|
let indent = indent('.')
|
||||||
|
let line = getline('.')
|
||||||
|
let pattern = '\v^(\s*)(.*)if (.*) then (.*) else ([^)]*)(.*)$'
|
||||||
|
|
||||||
|
if line =~ pattern
|
||||||
|
let body_when_true = sj#ExtractRx(line, pattern, '\4')
|
||||||
|
let body_when_false = sj#ExtractRx(line, pattern, '\5')
|
||||||
|
let replacement = "if \\3\r\\2".body_when_true."\\6\relse\r\\2".body_when_false."\\6"
|
||||||
|
exe 's/'.pattern.'/'.escape(replacement, '/')
|
||||||
|
|
||||||
|
call sj#SetIndent(lineno, lineno + 3, indent)
|
||||||
|
normal! >>kk>>
|
||||||
|
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#coffee#SplitObjectLiteral()
|
||||||
|
let [from, to] = sj#LocateBracesOnLine('{', '}')
|
||||||
|
let bracket = '{'
|
||||||
|
|
||||||
|
if from < 0 && to < 0
|
||||||
|
let [from, to] = sj#LocateBracesOnLine('(', ')')
|
||||||
|
let bracket = '('
|
||||||
|
endif
|
||||||
|
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let lineno = line('.')
|
||||||
|
let indent = indent(lineno)
|
||||||
|
let pairs = sj#ParseJsonObjectBody(from + 1, to - 1)
|
||||||
|
|
||||||
|
" Some are arguments, some are real pairs
|
||||||
|
let arguments = []
|
||||||
|
while len(pairs) > 0
|
||||||
|
let item = pairs[0]
|
||||||
|
|
||||||
|
if item =~ '^\k\+:'
|
||||||
|
" we've reached the pairs, stop here
|
||||||
|
break
|
||||||
|
else
|
||||||
|
call add(arguments, remove(pairs, 0))
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if len(pairs) == 0
|
||||||
|
" nothing to split
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if len(arguments) > 0
|
||||||
|
let argument_list = ' '.join(arguments, ', ').', '
|
||||||
|
else
|
||||||
|
let argument_list = ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = argument_list."\n".join(pairs, "\n")
|
||||||
|
call sj#ReplaceMotion('Va'.bracket, body)
|
||||||
|
|
||||||
|
" clean the remaining whitespace
|
||||||
|
call sj#Keeppatterns('s/\s\+$//e')
|
||||||
|
|
||||||
|
call sj#SetIndent(lineno + 1, lineno + len(pairs), indent + &sw)
|
||||||
|
|
||||||
|
if sj#settings#Read('align')
|
||||||
|
let body_start = lineno + 1
|
||||||
|
let body_end = body_start + len(pairs) - 1
|
||||||
|
call sj#Align(body_start, body_end, 'json_object')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#coffee#JoinObjectLiteral()
|
||||||
|
if line('.') == line('$')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [start_line, end_line] = s:IndentedLinesBelow('.')
|
||||||
|
|
||||||
|
if start_line == -1
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let lines = sj#GetLines(start_line, end_line)
|
||||||
|
let lines = sj#TrimList(lines)
|
||||||
|
let lines = map(lines, 'sj#Trim(v:val)')
|
||||||
|
if sj#settings#Read('normalize_whitespace')
|
||||||
|
let lines = map(lines, 'substitute(v:val, ":\\s\\+", ": ", "")')
|
||||||
|
endif
|
||||||
|
let body = getline('.').' { '.join(lines, ', ').' }'
|
||||||
|
call sj#ReplaceLines(start_line - 1, end_line, body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#coffee#SplitTripleString()
|
||||||
|
if search('["'']\{3}.\{-}["'']\{3}\s*$', 'Wbc', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let start_col = col('.')
|
||||||
|
let quote = getline('.')[col('.') - 1]
|
||||||
|
let double_quote = repeat(quote, 2)
|
||||||
|
let triple_quote = repeat(quote, 3)
|
||||||
|
|
||||||
|
normal! lll
|
||||||
|
if search(double_quote.'\zs'.quote, 'W', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let end_col = col('.')
|
||||||
|
|
||||||
|
let body = sj#GetCols(start_col, end_col)
|
||||||
|
let new_body = substitute(body, '^'.triple_quote.'\(.*\)'.triple_quote.'$', '\1', '')
|
||||||
|
let new_body = triple_quote."\n".new_body."\n".triple_quote
|
||||||
|
|
||||||
|
call sj#ReplaceCols(start_col, end_col, new_body)
|
||||||
|
normal! j>>j<<
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#coffee#SplitString()
|
||||||
|
if search('["''].\{-}["'']\s*$', 'Wbc', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let quote = getline('.')[col('.') - 1]
|
||||||
|
let multi_quote = repeat(quote, 2) " Note: only two quotes
|
||||||
|
|
||||||
|
let body = sj#GetMotion('vi'.quote)
|
||||||
|
let new_body = substitute(body, '\\'.quote, quote, 'g')
|
||||||
|
let new_body = multi_quote."\n".new_body."\n".multi_quote
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('vi'.quote, new_body)
|
||||||
|
normal! j>>
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#coffee#JoinString()
|
||||||
|
if search('\%("""\|''''''\)\s*$', 'Wbc') <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let start = getpos('.')
|
||||||
|
let multi_quote = expand('<cword>')
|
||||||
|
let quote = multi_quote[0]
|
||||||
|
|
||||||
|
normal! j
|
||||||
|
|
||||||
|
if search(multi_quote, 'Wce') <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let end = getpos('.')
|
||||||
|
|
||||||
|
let body = sj#GetByPosition(start, end)
|
||||||
|
let new_body = substitute(body, '^'.multi_quote.'\_s*\(.*\)\_s*'.multi_quote.'$', '\1', 'g')
|
||||||
|
let new_body = substitute(new_body, quote, '\\'.quote, 'g')
|
||||||
|
let new_body = sj#Trim(new_body)
|
||||||
|
let new_body = quote.new_body.quote
|
||||||
|
|
||||||
|
call sj#ReplaceByPosition(start, end, new_body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:IndentedLinesBelow(line)
|
||||||
|
let current_line = line(a:line)
|
||||||
|
let first_line = nextnonblank(current_line + 1)
|
||||||
|
let next_line = first_line
|
||||||
|
let base_indent = indent(current_line)
|
||||||
|
|
||||||
|
if indent(first_line) <= base_indent
|
||||||
|
return [-1, -1]
|
||||||
|
endif
|
||||||
|
|
||||||
|
while next_line <= line('$') && indent(next_line) > base_indent
|
||||||
|
let current_line = next_line
|
||||||
|
let next_line = nextnonblank(current_line + 1)
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
return [first_line, current_line]
|
||||||
|
endfunction
|
122
bundle/splitjoin.vim/autoload/sj/css.vim
Normal file
122
bundle/splitjoin.vim/autoload/sj/css.vim
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
function! sj#css#SplitDefinition()
|
||||||
|
if !s:LocateDefinition()
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if getline('.') !~ '{.*}' " then there's nothing to split
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if getline('.')[col('.') - 1 : col('.')] == '{}'
|
||||||
|
" nothing in the body
|
||||||
|
let body = ''
|
||||||
|
else
|
||||||
|
let body = sj#GetMotion('vi{')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let lines = split(body, ";\s*")
|
||||||
|
let lines = sj#TrimList(lines)
|
||||||
|
let lines = filter(lines, '!sj#BlankString(v:val)')
|
||||||
|
|
||||||
|
let body = join(lines, ";\n")
|
||||||
|
if !sj#BlankString(body)
|
||||||
|
let body .= ";"
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('va{', "{\n".body."\n}")
|
||||||
|
|
||||||
|
if sj#settings#Read('align')
|
||||||
|
let alignment_start = line('.') + 1
|
||||||
|
let alignment_end = alignment_start + len(lines) - 1
|
||||||
|
call sj#Align(alignment_start, alignment_end, 'css_declaration')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#css#JoinDefinition()
|
||||||
|
if !s:LocateDefinition()
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if getline('.') =~ '{.*}' " then there's nothing to join
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! 0
|
||||||
|
call search('{', 'Wc', line('.'))
|
||||||
|
|
||||||
|
if getline(line('.') + 1) =~ '^}'
|
||||||
|
" nothing in the body
|
||||||
|
let body = ''
|
||||||
|
else
|
||||||
|
let body = sj#GetMotion('Vi{')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let lines = split(body, ";\\?\s*\n")
|
||||||
|
let lines = sj#TrimList(lines)
|
||||||
|
let lines = filter(lines, 'v:val !~ "^\s*$"')
|
||||||
|
if sj#settings#Read('normalize_whitespace')
|
||||||
|
let lines = map(lines, "substitute(v:val, '\\s*:\\s\\+', ': ', '')")
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = join(lines, "; ")
|
||||||
|
let body = substitute(body, '\S.*\zs;\?$', ';', '')
|
||||||
|
let body = substitute(body, '{;', '{', '') " for SCSS
|
||||||
|
|
||||||
|
if body == ''
|
||||||
|
call sj#ReplaceMotion('va{', '{}')
|
||||||
|
else
|
||||||
|
call sj#ReplaceMotion('va{', '{ '.body.' }')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#css#JoinMultilineSelector()
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
let start_line = line('.')
|
||||||
|
let end_line = start_line
|
||||||
|
let col = col('.')
|
||||||
|
let limit_line = line('$')
|
||||||
|
|
||||||
|
while !sj#BlankString(line) && line !~ '{\s*$' && end_line < limit_line
|
||||||
|
call cursor(end_line + 1, col)
|
||||||
|
let end_line = line('.')
|
||||||
|
let line = getline('.')
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if start_line == end_line
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
if line =~ '^\s*{\s*$'
|
||||||
|
let end_line = end_line - 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
exe start_line.','.end_line.'join'
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#css#SplitMultilineSelector()
|
||||||
|
if getline('.') !~ '.*,.*{\s*$'
|
||||||
|
" then there is nothing to split
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let definition = getline('.')
|
||||||
|
let replacement = substitute(definition, ',\s*', ",\n", 'g')
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('V', replacement)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:LocateDefinition()
|
||||||
|
if search('{', 'bcW', line('.')) <= 0 && search('{', 'cW', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
endfunction
|
143
bundle/splitjoin.vim/autoload/sj/cue.vim
Normal file
143
bundle/splitjoin.vim/autoload/sj/cue.vim
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
function! sj#cue#SplitImports()
|
||||||
|
let pattern = '^import\s\+\(\%(\k\+\s\+\)\=\%(".*"\)\)$'
|
||||||
|
|
||||||
|
if getline('.') =~ pattern
|
||||||
|
call sj#Keeppatterns('s/' . pattern . '/import (\r\1\r)/')
|
||||||
|
normal! k==
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#cue#SplitStructLiteral()
|
||||||
|
let [from, to] = sj#LocateBracesOnLine('{', '}')
|
||||||
|
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let pairs = sj#ParseJsonObjectBody(from + 1, to - 1)
|
||||||
|
let body = join(pairs, "\n")
|
||||||
|
let body = "{\n".body."\n}"
|
||||||
|
call sj#ReplaceMotion('Va{', body)
|
||||||
|
|
||||||
|
if sj#settings#Read('align')
|
||||||
|
let body_start = line('.') + 1
|
||||||
|
let body_end = body_start + len(pairs) - 1
|
||||||
|
call sj#Align(body_start, body_end, 'json_object')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#cue#JoinStructLiteral()
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if line =~ '{\s*$'
|
||||||
|
call search('{', 'c', line('.'))
|
||||||
|
let body = sj#GetMotion('Vi{')
|
||||||
|
|
||||||
|
let lines = split(body, "\n")
|
||||||
|
let lines = sj#TrimList(lines)
|
||||||
|
if sj#settings#Read('normalize_whitespace')
|
||||||
|
let lines = map(lines, 'substitute(v:val, ":\\s\\+", ": ", "")')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = join(lines, ', ')
|
||||||
|
let body = substitute(body, ',$', '', '')
|
||||||
|
|
||||||
|
if sj#settings#Read('curly_brace_padding')
|
||||||
|
let body = '{ '.body.' }'
|
||||||
|
else
|
||||||
|
let body = '{'.body.'}'
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va{', body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#cue#SplitArray()
|
||||||
|
return s:SplitList(['[', ']'], 'cursor_on_line')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#cue#JoinArray()
|
||||||
|
return s:JoinList(['[', ']'], 'padding')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#cue#SplitArgs()
|
||||||
|
return s:SplitList(['(', ')'], 'cursor_inside')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#cue#JoinArgs()
|
||||||
|
return s:JoinList(['(', ')'], 'no_padding')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:SplitList(delimiter, cursor_position)
|
||||||
|
let start = a:delimiter[0]
|
||||||
|
let end = a:delimiter[1]
|
||||||
|
|
||||||
|
let lineno = line('.')
|
||||||
|
let indent = indent('.')
|
||||||
|
|
||||||
|
if a:cursor_position == 'cursor_inside'
|
||||||
|
let [from, to] = sj#LocateBracesAroundCursor(start, end)
|
||||||
|
elseif a:cursor_position == 'cursor_on_line'
|
||||||
|
let [from, to] = sj#LocateBracesOnLine(start, end)
|
||||||
|
else
|
||||||
|
echoerr "Invalid value for a:cursor_position: ".a:cursor_position
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let items = sj#ParseJsonObjectBody(from + 1, to - 1)
|
||||||
|
if empty(items)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = start."\n".join(items, ",\n")."\n".end
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va'.start, body)
|
||||||
|
|
||||||
|
let end_line = lineno + len(items) + 1
|
||||||
|
call sj#SetIndent(end_line, indent)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:JoinList(delimiter, delimiter_padding)
|
||||||
|
let start = a:delimiter[0]
|
||||||
|
let end = a:delimiter[1]
|
||||||
|
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if line !~ start . '\s*$'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call search(start, 'c', line('.'))
|
||||||
|
let body = sj#GetMotion('Vi'.start)
|
||||||
|
|
||||||
|
let lines = split(body, "\n")
|
||||||
|
let lines = sj#TrimList(lines)
|
||||||
|
let body = sj#Trim(join(lines, ' '))
|
||||||
|
let body = substitute(body, ',\s*$', '', '')
|
||||||
|
|
||||||
|
if a:delimiter_padding == 'padding'
|
||||||
|
let body = start.' '.body.' '.end
|
||||||
|
else
|
||||||
|
let body = start.body.end
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va'.start, body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
288
bundle/splitjoin.vim/autoload/sj/elixir.vim
Normal file
288
bundle/splitjoin.vim/autoload/sj/elixir.vim
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
function! sj#elixir#SplitDoBlock()
|
||||||
|
let [function_name, function_start, function_end, function_type] =
|
||||||
|
\ sj#argparser#elixir#LocateFunction()
|
||||||
|
if function_start < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let is_if = function_name == 'if' || function_name == 'unless'
|
||||||
|
|
||||||
|
let parser = sj#argparser#elixir#Construct(function_start, function_end, getline('.'))
|
||||||
|
call parser.Process()
|
||||||
|
|
||||||
|
let do_body = ''
|
||||||
|
let else_body = ''
|
||||||
|
let args = []
|
||||||
|
|
||||||
|
for arg in parser.args
|
||||||
|
if arg =~ '^do:' && do_body == ''
|
||||||
|
let do_body = substitute(arg, '^do:\s*', '', '')
|
||||||
|
elseif arg =~ '^else:' && is_if && else_body == ''
|
||||||
|
let else_body = substitute(arg, '^else:\s*', '', '')
|
||||||
|
else
|
||||||
|
call add(args, arg)
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if do_body == ''
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if is_if && function_type == 'with_round_braces'
|
||||||
|
" skip the round brackets before the if-clause
|
||||||
|
let new_line = strpart(line, 0, function_start - 2) . ' ' . join(args, ', ')
|
||||||
|
else
|
||||||
|
let new_line = strpart(line, 0, function_start - 1) . join(args, ', ')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if function_end > 0
|
||||||
|
if is_if && function_type == 'with_round_braces'
|
||||||
|
" skip the round brackets after the if-clause
|
||||||
|
let new_line .= strpart(line, function_end + 1)
|
||||||
|
else
|
||||||
|
let new_line .= strpart(line, function_end)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
" we didn't detect an end, so it goes on to the end of the line
|
||||||
|
endif
|
||||||
|
|
||||||
|
if else_body != ''
|
||||||
|
let do_block = " do\n" . do_body . "\nelse\n" . else_body . "\nend"
|
||||||
|
else
|
||||||
|
let do_block = " do\n" . do_body . "\nend"
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceLines(line('.'), line('.'), new_line . do_block)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#elixir#JoinDoBlock()
|
||||||
|
let do_pattern = '\s*do\s*\%(#.*\)\=$'
|
||||||
|
let def_lineno = line('.')
|
||||||
|
let def_line = getline(def_lineno)
|
||||||
|
|
||||||
|
if def_line !~ do_pattern
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [function_name, function_start, function_end, function_type] =
|
||||||
|
\ sj#argparser#elixir#LocateFunction()
|
||||||
|
if function_start < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let is_if = function_name == 'if' || function_name == 'unless'
|
||||||
|
let body_lineno = line('.') + 1
|
||||||
|
let body_line = getline(body_lineno)
|
||||||
|
|
||||||
|
if is_if && getline(line('.') + 2) =~ '^\s*else\>'
|
||||||
|
let else_lineno = line('.') + 2
|
||||||
|
let else_line = getline(else_lineno)
|
||||||
|
|
||||||
|
let else_body_lineno = line('.') + 3
|
||||||
|
let else_body_line = getline(else_body_lineno)
|
||||||
|
|
||||||
|
let end_lineno = line('.') + 4
|
||||||
|
let end_line = getline(end_lineno)
|
||||||
|
else
|
||||||
|
let else_line = ''
|
||||||
|
|
||||||
|
let end_lineno = line('.') + 2
|
||||||
|
let end_line = getline(end_lineno)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if end_line !~ '^\s*end$'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
exe 'keeppatterns s/'.do_pattern.'//'
|
||||||
|
if function_end < 0
|
||||||
|
let function_end = col('$') - 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let args = sj#GetCols(function_start, function_end)
|
||||||
|
let joined_args = ', do: '.sj#Trim(body_line)
|
||||||
|
if else_line != ''
|
||||||
|
let joined_args .= ', else: '.sj#Trim(else_body_line)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceCols(function_start, function_end, args . joined_args)
|
||||||
|
exe body_lineno.','.end_lineno.'delete _'
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#elixir#JoinCommaDelimitedItems()
|
||||||
|
if getline('.') !~ ',\s*$'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let start_lineno = line('.')
|
||||||
|
let end_lineno = start_lineno
|
||||||
|
let lineno = nextnonblank(start_lineno + 1)
|
||||||
|
let line = getline(lineno)
|
||||||
|
|
||||||
|
while lineno <= line('$') && line =~ ',\s*$'
|
||||||
|
let end_lineno = lineno
|
||||||
|
let lineno = nextnonblank(lineno + 1)
|
||||||
|
let line = getline(lineno)
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
let end_lineno = lineno
|
||||||
|
|
||||||
|
call cursor(start_lineno, 0)
|
||||||
|
exe "normal! V".(end_lineno - start_lineno)."jJ"
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#elixir#SplitArray()
|
||||||
|
let [from, to] = sj#LocateBracesAroundCursor('[', ']', [
|
||||||
|
\ 'elixirInterpolationDelimiter',
|
||||||
|
\ 'elixirString',
|
||||||
|
\ 'elixirStringDelimiter',
|
||||||
|
\ 'elixirSigilDelimiter',
|
||||||
|
\ ])
|
||||||
|
|
||||||
|
if from < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let items = sj#ParseJsonObjectBody(from + 1, to - 1)
|
||||||
|
|
||||||
|
if len(items) == 0 || to - from < 2
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
" substitute [1, 2, | tail]
|
||||||
|
let items[-1] = substitute(items[-1], "\\(|[^>].*\\)", "\n\\1", "")
|
||||||
|
let body = "[\n" . join(items, ",\n") . "\n]"
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va[', body)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#elixir#JoinArray()
|
||||||
|
normal! $
|
||||||
|
|
||||||
|
if getline('.')[col('.') - 1] != '['
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = sj#Trim(sj#GetMotion('Vi['))
|
||||||
|
" remove trailing comma
|
||||||
|
let body = substitute(body, ',\ze\_s*$', '', '')
|
||||||
|
|
||||||
|
let items = split(body, ",\s*\n")
|
||||||
|
if len(items) == 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" join isolated | tail on the last line
|
||||||
|
let items[-1] = substitute(items[-1], "[[:space:]]*\\(|[^>].*\\)", " \\1", "")
|
||||||
|
|
||||||
|
let body = join(sj#TrimList(items), ', ')
|
||||||
|
call sj#ReplaceMotion('Va[', '['.body.']')
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
let s:pipe_pattern = '^\s*|>\s\+'
|
||||||
|
let s:atom_pattern = ':\k\+'
|
||||||
|
let s:module_pattern = '\k\%(\k\|\.\)*'
|
||||||
|
let s:function_pattern = '\k\+[?!]\='
|
||||||
|
let s:atom_or_module_pattern = '\%(' . s:atom_pattern . '\.\|' . s:module_pattern . '\.\)\='
|
||||||
|
|
||||||
|
function! sj#elixir#SplitPipe()
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
call sj#PushCursor()
|
||||||
|
normal! 0f(
|
||||||
|
let [function_name, function_start, function_end, function_type] =
|
||||||
|
\ sj#argparser#elixir#LocateFunction()
|
||||||
|
call sj#PopCursor()
|
||||||
|
|
||||||
|
" We only support function calls that start at the beginning of the line
|
||||||
|
" (accounting for whitespace)
|
||||||
|
let prefix = strpart(line, 0, function_start - 1)
|
||||||
|
let prefix_pattern = '^\s*' . s:atom_or_module_pattern . function_name . '\((\|\s\+\)$'
|
||||||
|
|
||||||
|
if function_start < 0 || prefix !~ prefix_pattern
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let comment_pattern = '\s*\(#.*\)\=$'
|
||||||
|
|
||||||
|
if function_end < 0
|
||||||
|
let comment_start = match(line, comment_pattern)
|
||||||
|
|
||||||
|
if comment_start < 0
|
||||||
|
let rest = 'none'
|
||||||
|
else
|
||||||
|
let rest = strpart(line, comment_start)
|
||||||
|
let function_end = comment_start
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
let rest = strpart(line, function_end + 1)
|
||||||
|
|
||||||
|
if rest !~ '^' . comment_pattern
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
end
|
||||||
|
|
||||||
|
let parser = sj#argparser#elixir#Construct(function_start, function_end, line)
|
||||||
|
call parser.Process()
|
||||||
|
|
||||||
|
let args = parser.args
|
||||||
|
|
||||||
|
let function_call = sj#Trim(strpart(line, 0, function_start - 2))
|
||||||
|
let result = args[0] . "\n|> " . function_call . '(' . join(args[1:], ', ') . ')' . rest
|
||||||
|
|
||||||
|
call sj#ReplaceLines(line('.'), line('.'), result)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#elixir#JoinPipe()
|
||||||
|
call sj#PushCursor()
|
||||||
|
|
||||||
|
let line = getline('.')
|
||||||
|
if line !~ s:pipe_pattern
|
||||||
|
normal! j
|
||||||
|
let line = getline('.')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let line_num = line('.')
|
||||||
|
let prev_line = sj#Trim(getline(line_num - 1))
|
||||||
|
|
||||||
|
if line !~ s:pipe_pattern || prev_line =~ s:pipe_pattern
|
||||||
|
call sj#PopCursor()
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let empty_args_pattern = s:pipe_pattern . '\(' . s:atom_or_module_pattern . s:function_pattern . '\)()'
|
||||||
|
|
||||||
|
if line =~ empty_args_pattern
|
||||||
|
let function_name = substitute(line, empty_args_pattern, '\1', '')
|
||||||
|
let result = function_name . '(' . prev_line . ')'
|
||||||
|
call sj#PopCursor()
|
||||||
|
else
|
||||||
|
normal! f(l
|
||||||
|
let [function_name, function_start, function_end, function_type] =
|
||||||
|
\ sj#argparser#elixir#LocateFunction()
|
||||||
|
call sj#PopCursor()
|
||||||
|
|
||||||
|
if function_start < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let parser = sj#argparser#elixir#Construct(function_start, function_end, line)
|
||||||
|
call parser.Process()
|
||||||
|
|
||||||
|
let args = parser.args
|
||||||
|
let function_call = substitute(strpart(line, 0, function_start - 2), '|>\s\+', '', '')
|
||||||
|
let result = function_call . '(' . prev_line . ', ' . join(args, ', ') . ')'
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceLines(line_num - 1, line_num, result)
|
||||||
|
return 1
|
||||||
|
endfunction
|
249
bundle/splitjoin.vim/autoload/sj/elm.vim
Normal file
249
bundle/splitjoin.vim/autoload/sj/elm.vim
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
" vim: foldmethod=marker
|
||||||
|
|
||||||
|
" Split / Join {{{1
|
||||||
|
"
|
||||||
|
" function! sj#elm#JoinBraces() {{{2
|
||||||
|
"
|
||||||
|
" Attempts to join the multiline tuple, record or list closest
|
||||||
|
" to current cursor position.
|
||||||
|
function! sj#elm#JoinBraces()
|
||||||
|
let [from, to] = s:ClosestMultilineBraces()
|
||||||
|
|
||||||
|
if from[0] < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let original = sj#GetByPosition([0, from[0], from[1]], [0, to[0], to[1]])
|
||||||
|
let joined = s:JoinOuterBraces(s:JoinLines(original))
|
||||||
|
call sj#ReplaceByPosition([0, from[0], from[1]], [0, to[0], to[1]], joined)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! sj#elm#SplitBraces() {{{2
|
||||||
|
"
|
||||||
|
" Attempts to split the tuple, record or list furthest to current
|
||||||
|
" cursor position on the same line.
|
||||||
|
function! sj#elm#SplitBraces()
|
||||||
|
try
|
||||||
|
call sj#PushCursor()
|
||||||
|
|
||||||
|
let [from, to] = s:CurrentLineOutermostBraces(col('.'))
|
||||||
|
|
||||||
|
if from < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let parts = s:SplitParts(from, to)
|
||||||
|
|
||||||
|
if len(parts) <= 2
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let replacement = join(parts, "\n")
|
||||||
|
|
||||||
|
call cursor(line('.'), from)
|
||||||
|
let [previousLine, previousCol] = searchpos('\S', 'bn')
|
||||||
|
if previousLine == line('.') && previousCol > 0 && s:CharAt(previousCol) =~ '[=:]'
|
||||||
|
let replacement = "\n".replacement
|
||||||
|
let from = previousCol + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
call sj#ReplaceCols(from, to, replacement)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
finally
|
||||||
|
call sj#PopCursor()
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
" Helper functions {{{1
|
||||||
|
|
||||||
|
" function! s:SkipSyntax() {{{2
|
||||||
|
"
|
||||||
|
" Returns Elm's typical skippable syntax (strings and comments)
|
||||||
|
function! s:SkipSyntax()
|
||||||
|
return sj#SkipSyntax(['elmString', 'elmTripleString', 'elmComment'])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! s:CurrentLineClosestBraces(column) {{{2
|
||||||
|
"
|
||||||
|
" Returns the columns corresponding to the bracing pair closest
|
||||||
|
" to and surrounding given column as a list ([opening, closing]).
|
||||||
|
" Returns [-1, -1] when there is none on the same line.
|
||||||
|
function! s:CurrentLineClosestBraces(column)
|
||||||
|
try
|
||||||
|
call sj#PushCursor()
|
||||||
|
|
||||||
|
let skip = s:SkipSyntax()
|
||||||
|
let currentLine = line('.')
|
||||||
|
|
||||||
|
call cursor(currentLine, a:column)
|
||||||
|
let from = searchpairpos('[{(\[]', '', '[})\]]', 'bcn', skip, currentLine)
|
||||||
|
|
||||||
|
if from[0] == 0
|
||||||
|
return [-1, -1]
|
||||||
|
end
|
||||||
|
|
||||||
|
call cursor(from[0], from[1])
|
||||||
|
normal! %
|
||||||
|
|
||||||
|
if line('.') != currentLine
|
||||||
|
return [-1, -1]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let to = col('.')
|
||||||
|
|
||||||
|
return [from[1], to]
|
||||||
|
finally
|
||||||
|
call sj#PopCursor()
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! s:CurrentLineOutermostBraces(column) {{{2
|
||||||
|
"
|
||||||
|
" Returns the colums corresponding to the bracing pair furthest
|
||||||
|
" to and surrounding given column as a list ([opening, closing]).
|
||||||
|
" Returns [-1, -1] when there is none on the same line.
|
||||||
|
function! s:CurrentLineOutermostBraces(column)
|
||||||
|
if a:column < 1
|
||||||
|
return [-1, -1]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let currentMatch = s:CurrentLineClosestBraces(a:column)
|
||||||
|
|
||||||
|
if currentMatch[0] < 1
|
||||||
|
return [-1, -1]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let betterMatch = s:CurrentLineOutermostBraces(currentMatch[0] - 1)
|
||||||
|
|
||||||
|
if betterMatch[0] < 1
|
||||||
|
return currentMatch
|
||||||
|
endif
|
||||||
|
|
||||||
|
return betterMatch
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! s:ClosestMultilineBraces() {{{2
|
||||||
|
"
|
||||||
|
" Returns the position of the closest pair of multiline braces
|
||||||
|
" around the cursor.
|
||||||
|
"
|
||||||
|
" The positions are given as a couple of arrays:
|
||||||
|
"
|
||||||
|
" [[startLine, startCol], [endLine, endCol]]
|
||||||
|
"
|
||||||
|
" When no position is found, returns:
|
||||||
|
"
|
||||||
|
" [[-1, -1], [-1, -1]]
|
||||||
|
function! s:ClosestMultilineBraces()
|
||||||
|
try
|
||||||
|
call sj#PushCursor()
|
||||||
|
|
||||||
|
let skip = s:SkipSyntax()
|
||||||
|
|
||||||
|
let currentLine = line('.')
|
||||||
|
|
||||||
|
normal! $
|
||||||
|
|
||||||
|
let [toLine, toCol] = searchpairpos('[{(\[]', '', '[})\]]', '', skip, line('$'))
|
||||||
|
|
||||||
|
if toLine < currentLine
|
||||||
|
return [[-1, -1], [-1, -1]]
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! %
|
||||||
|
|
||||||
|
let fromLine = line('.')
|
||||||
|
let fromCol = col('.')
|
||||||
|
|
||||||
|
if fromLine >= toLine
|
||||||
|
return [[-1, -1], [-1, -1]]
|
||||||
|
endif
|
||||||
|
|
||||||
|
return [[fromLine, fromCol], [toLine, toCol]]
|
||||||
|
finally
|
||||||
|
call sj#PopCursor()
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! s:JoinOuterBraces(text)
|
||||||
|
"
|
||||||
|
" Removes spaces separating the first and last char of a string
|
||||||
|
" with the closest non-space char found.
|
||||||
|
"
|
||||||
|
" ex:
|
||||||
|
"
|
||||||
|
" [ 1, 2, 3 ] => [1, 2, 3]
|
||||||
|
function! s:JoinOuterBraces(text)
|
||||||
|
return substitute(substitute(a:text, '\s*\(.\)$', '\1', ''), '^\(.\)\s*', '\1', '')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! s:JoinLines(text)
|
||||||
|
"
|
||||||
|
" Joins lines in text, removing complementary spaces around
|
||||||
|
" newline chars when the last line starts with a ',' and keeping
|
||||||
|
" one whitespace for other cases.
|
||||||
|
function! s:JoinLines(text)
|
||||||
|
return substitute(substitute(a:text, '\s*\n\s*,', ',', 'g'), '\s*\n\s*', ' ', 'g')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! s:SplitParts(from, to)
|
||||||
|
"
|
||||||
|
" Splits a section of a line according to bracing characters
|
||||||
|
" rules.
|
||||||
|
"
|
||||||
|
" ex:
|
||||||
|
" "[1,2,3]"
|
||||||
|
" v
|
||||||
|
" [ "[ 1", ", 2", ", 3", "]" ]
|
||||||
|
"
|
||||||
|
" "{a | foo = bar, baz = buzz}"
|
||||||
|
" v
|
||||||
|
" [ "{ a", "| foo = bar", ", baz = buzz", "}" ]
|
||||||
|
function! s:SplitParts(from, to)
|
||||||
|
try
|
||||||
|
call sj#PushCursor()
|
||||||
|
let skip = s:SkipSyntax()
|
||||||
|
let currentLine = line('.')
|
||||||
|
|
||||||
|
call cursor(currentLine, a:from)
|
||||||
|
|
||||||
|
let openingCol = a:from
|
||||||
|
let openingChar = s:CurrentChar()
|
||||||
|
let parts = []
|
||||||
|
|
||||||
|
while col('.') < a:to
|
||||||
|
call searchpair('[{(\[]', ',\|\(\(<\)\@<!|\(>\)\@!\)', '[})\]]', '', skip, currentLine)
|
||||||
|
let closingCol = col('.')
|
||||||
|
let closingChar = s:CurrentChar()
|
||||||
|
let part = openingChar.' '.sj#Trim(sj#GetByPosition([0, currentLine, openingCol + 1, 0], [0, currentLine, closingCol - 1, 0]))
|
||||||
|
call add(parts, part)
|
||||||
|
let openingCol = closingCol
|
||||||
|
let openingChar = closingChar
|
||||||
|
call cursor(currentLine, openingCol)
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call add(parts, s:CharAt(a:to))
|
||||||
|
|
||||||
|
return parts
|
||||||
|
finally
|
||||||
|
call sj#PopCursor()
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! s:CharAt(column)
|
||||||
|
"
|
||||||
|
" Returns the char sitting at given column of current line.
|
||||||
|
function! s:CharAt(column)
|
||||||
|
return getline('.')[a:column - 1]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! s:CurrentChar()
|
||||||
|
"
|
||||||
|
" Returns the character at current cursor's position
|
||||||
|
function! s:CurrentChar()
|
||||||
|
return s:CharAt(col('.'))
|
||||||
|
endfunction
|
55
bundle/splitjoin.vim/autoload/sj/eruby.vim
Normal file
55
bundle/splitjoin.vim/autoload/sj/eruby.vim
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
function! sj#eruby#SplitIfClause()
|
||||||
|
let line = getline('.')
|
||||||
|
let pattern = '\v\<\%(.*\S.*) (if|unless) (.*)\s*\%\>'
|
||||||
|
|
||||||
|
if line =~ pattern
|
||||||
|
let body = substitute(line, pattern, '<% \2 \3%>\n<%\1 %>\n<% end %>', '')
|
||||||
|
call sj#ReplaceMotion('V', body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#eruby#JoinIfClause()
|
||||||
|
let line = getline('.')
|
||||||
|
let pattern = '\v^\s*\<\%\s*(if|unless)'
|
||||||
|
|
||||||
|
if line =~ pattern
|
||||||
|
normal! jj
|
||||||
|
|
||||||
|
if getline('.') =~ 'end'
|
||||||
|
let body = sj#GetMotion('Vkk')
|
||||||
|
|
||||||
|
let [if_line, body, end_line] = split(body, '\n')
|
||||||
|
|
||||||
|
let if_line = sj#ExtractRx(if_line, '<%\s*\(.\{-}\)\s*%>', '\1')
|
||||||
|
let body = sj#ExtractRx(body, '\(<%=\?\s*.\{-}\)\s*%>', '\1')
|
||||||
|
|
||||||
|
let replacement = body.' '.if_line.' %>'
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('gv', replacement)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#eruby#SplitHtmlTags()
|
||||||
|
if eval(sj#SkipSyntax(['erubyDelimiter', 'erubyExpression']))
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
return sj#html#SplitTags()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#eruby#SplitHtmlAttributes()
|
||||||
|
if eval(sj#SkipSyntax(['erubyDelimiter', 'erubyExpression']))
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
return sj#html#SplitAttributes()
|
||||||
|
endfunction
|
405
bundle/splitjoin.vim/autoload/sj/go.vim
Normal file
405
bundle/splitjoin.vim/autoload/sj/go.vim
Normal file
@ -0,0 +1,405 @@
|
|||||||
|
function! sj#go#SplitImports()
|
||||||
|
let pattern = '^import\s\+\(\%(\k\+\s\+\)\=\%(".*"\)\)$'
|
||||||
|
|
||||||
|
if getline('.') =~ pattern
|
||||||
|
call sj#Keeppatterns('s/' . pattern . '/import (\r\1\r)/')
|
||||||
|
normal! k==
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#go#JoinImports()
|
||||||
|
if getline('.') =~ '^import\s*($' &&
|
||||||
|
\ getline(line('.') + 1) =~ '^\s*\%(\k\+\s\+\)\=".*"$' &&
|
||||||
|
\ getline(line('.') + 2) =~ '^)$'
|
||||||
|
call sj#Keeppatterns('s/^import (\_s\+\(\%(\k\+\s\+\)\=\(".*"\)\)\_s\+)$/import \1/')
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#go#SplitVars() abort
|
||||||
|
let pattern = '^\s*\(var\|type\|const\)\s\+[[:keyword:], ]\+=\='
|
||||||
|
if sj#SearchUnderCursor(pattern) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call search(pattern, 'Wce', line('.'))
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if line[col('.') - 1] == '='
|
||||||
|
" before and after =
|
||||||
|
let lhs = sj#Trim(strpart(line, 0, col('.') - 1))
|
||||||
|
let rhs = sj#Ltrim(strpart(line, col('.')))
|
||||||
|
|
||||||
|
let values_parser = sj#argparser#go_vars#Construct(rhs)
|
||||||
|
call values_parser.Process()
|
||||||
|
|
||||||
|
let values = values_parser.args
|
||||||
|
let comment = values_parser.comment
|
||||||
|
else
|
||||||
|
let [comment, comment_start, _] = matchstrpos(line, '\s*\%(\/\/.*\)\=$')
|
||||||
|
if comment == ""
|
||||||
|
let lhs = sj#Trim(line)
|
||||||
|
else
|
||||||
|
let lhs = sj#Trim(strpart(line, 0, comment_start))
|
||||||
|
endif
|
||||||
|
|
||||||
|
let values = []
|
||||||
|
endif
|
||||||
|
|
||||||
|
if len(values) > 0 && values[-1] =~ '[{([]\s*$'
|
||||||
|
" the value is incomplete, so let's not attempt to split it
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [prefix, _, prefix_end] = matchstrpos(lhs, '^\s*\(var\|type\|const\)\s\+')
|
||||||
|
let lhs = strpart(lhs, prefix_end)
|
||||||
|
|
||||||
|
let variables = []
|
||||||
|
let last_type = ''
|
||||||
|
for variable in reverse(split(lhs, ',\s*'))
|
||||||
|
let variable = sj#Trim(variable)
|
||||||
|
let type = matchstr(variable, '^\k\+\s\+\zs\S.*$')
|
||||||
|
|
||||||
|
if empty(type) && !empty(last_type)
|
||||||
|
" No type, take the last one that we saw going backwards
|
||||||
|
call add(variables, variable . ' ' . last_type)
|
||||||
|
else
|
||||||
|
let last_type = type
|
||||||
|
call add(variables, variable)
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
call reverse(variables)
|
||||||
|
|
||||||
|
let declarations = []
|
||||||
|
for i in range(0, len(variables) - 1)
|
||||||
|
if i < len(values)
|
||||||
|
call add(declarations, variables[i] . ' = ' . values[i])
|
||||||
|
else
|
||||||
|
call add(declarations, variables[i])
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let replacement = prefix . "(\n"
|
||||||
|
let replacement .= join(declarations, "\n")
|
||||||
|
let replacement .= "\n)"
|
||||||
|
if comment != ''
|
||||||
|
let replacement .= ' ' . sj#Ltrim(comment)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('_vg_', replacement)
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#go#JoinVars() abort
|
||||||
|
let pattern = '^\s*\(var\|type\|const\)\s\+('
|
||||||
|
if sj#SearchUnderCursor(pattern) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call search(pattern, 'Wce', line('.'))
|
||||||
|
|
||||||
|
let declarations = sj#TrimList(split(sj#GetMotion('vi('), "\n"))
|
||||||
|
if len(declarations) == 1
|
||||||
|
" Only one line, so just join it as-is
|
||||||
|
call sj#ReplaceMotion('va(', declarations[0])
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let variables = []
|
||||||
|
let values = []
|
||||||
|
let types = []
|
||||||
|
|
||||||
|
for line in declarations
|
||||||
|
let [lhs, _, match_end] = matchstrpos(line, '.\{-}\s*=\s*')
|
||||||
|
|
||||||
|
if match_end > -1
|
||||||
|
let variable_description = matchstr(lhs, '.\{-}\ze\s*=\s*')
|
||||||
|
let line = substitute(line, ',$', '', '')
|
||||||
|
call add(values, strpart(line, match_end))
|
||||||
|
else
|
||||||
|
let line = substitute(line, ',$', '', '')
|
||||||
|
let variable_description = line
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [variable, _, match_end] = matchstrpos(variable_description, '^\k\+\s*')
|
||||||
|
let type = strpart(variable_description, match_end)
|
||||||
|
call add(variables, { 'variable': sj#Rtrim(variable), 'type': type })
|
||||||
|
call add(types, type)
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if len(variables) == 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if len(uniq(types)) > 1
|
||||||
|
" We have assignment to values, but we also have different types, so it
|
||||||
|
" can't be on one line
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Handle var one, two string -> one should also get "string"
|
||||||
|
let declarations = []
|
||||||
|
let index = 0
|
||||||
|
for entry in variables
|
||||||
|
if empty(entry.type) || (len(variables) > index + 1 && entry.type ==# variables[index + 1].type)
|
||||||
|
" This variable's type is the same as the next one's, so skip it
|
||||||
|
call add(declarations, entry.variable)
|
||||||
|
elseif empty(entry.type)
|
||||||
|
call add(declarations, entry.variable)
|
||||||
|
else
|
||||||
|
call add(declarations, entry.variable . ' ' . entry.type)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let index += 1
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let combined_declaration = join(declarations, ', ')
|
||||||
|
if len(values) > 0
|
||||||
|
let combined_declaration .= ' = ' . join(values, ', ')
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('va(', combined_declaration)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#go#SplitStruct()
|
||||||
|
let [start, end] = sj#LocateBracesAroundCursor('{', '}', ['goString', 'goComment'])
|
||||||
|
if start < 0 && end < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let args = sj#ParseJsonObjectBody(start + 1, end - 1)
|
||||||
|
if len(args) == 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
for arg in args
|
||||||
|
if arg !~ '^\k\+\s*:'
|
||||||
|
" this is not really a struct instantiation
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
endfor
|
||||||
|
|
||||||
|
call sj#ReplaceCols(start + 1, end - 1, "\n".join(args, ",\n").",\n")
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#go#JoinStructDeclaration()
|
||||||
|
let start_lineno = line('.')
|
||||||
|
let pattern = '^\s*type\s\+.*\s*\zsstruct\s*{$'
|
||||||
|
|
||||||
|
if search(pattern, 'Wc', line('.')) <= 0 &&
|
||||||
|
\ search(pattern, 'Wcb', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PushCursor()
|
||||||
|
normal! f{%
|
||||||
|
let end_lineno = line('.')
|
||||||
|
|
||||||
|
if start_lineno == end_lineno
|
||||||
|
" we haven't moved, brackets not found
|
||||||
|
call sj#PopCursor()
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let arguments = []
|
||||||
|
for line in getbufline('%', start_lineno + 1, end_lineno - 1)
|
||||||
|
let argument = substitute(line, ',$', '', '')
|
||||||
|
let argument = sj#Trim(argument)
|
||||||
|
|
||||||
|
if argument != ''
|
||||||
|
call add(arguments, argument)
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if len(arguments) == 0
|
||||||
|
let replacement = 'struct{}'
|
||||||
|
else
|
||||||
|
let replacement = 'struct{ ' . join(arguments, ', ') . ' }'
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PopCursor()
|
||||||
|
call sj#ReplaceMotion('vf{%', replacement)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#go#JoinStruct()
|
||||||
|
let start_lineno = line('.')
|
||||||
|
let pattern = '\k\+\s*{$'
|
||||||
|
|
||||||
|
if search(pattern, 'Wc', line('.')) <= 0 &&
|
||||||
|
\ search(pattern, 'Wcb', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call search(pattern, 'Wce', line('.'))
|
||||||
|
|
||||||
|
normal! %
|
||||||
|
let end_lineno = line('.')
|
||||||
|
|
||||||
|
if start_lineno == end_lineno
|
||||||
|
" we haven't moved, brackets not found
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let arguments = []
|
||||||
|
for line in getbufline('%', start_lineno + 1, end_lineno - 1)
|
||||||
|
let argument = substitute(line, ',$', '', '')
|
||||||
|
let argument = sj#Trim(argument)
|
||||||
|
|
||||||
|
if argument !~ '^\k\+\s*:'
|
||||||
|
" this is not really a struct instantiation
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
if sj#settings#Read('normalize_whitespace')
|
||||||
|
let argument = substitute(argument, '^\k\+\zs:\s\+', ': ', 'g')
|
||||||
|
endif
|
||||||
|
|
||||||
|
call add(arguments, argument)
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let replacement = '{' . join(arguments, ', ') . '}'
|
||||||
|
call sj#ReplaceMotion('va{', replacement)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#go#SplitSingleLineCurlyBracketBlock()
|
||||||
|
let [start, end] = sj#LocateBracesAroundCursor('{', '}', ['goString', 'goComment'])
|
||||||
|
if start < 0 && end < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = sj#GetMotion('vi{')
|
||||||
|
|
||||||
|
if getline('.')[0:start - 1] =~# '\<struct\s*{$'
|
||||||
|
" struct { is enforced by gofmt
|
||||||
|
let padding = ' '
|
||||||
|
else
|
||||||
|
let padding = ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('va{', padding."{\n".sj#Trim(body)."\n}")
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#go#JoinSingleLineFunctionBody()
|
||||||
|
let start_lineno = line('.')
|
||||||
|
|
||||||
|
if search('{$', 'Wc', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! %
|
||||||
|
let end_lineno = line('.')
|
||||||
|
|
||||||
|
if start_lineno == end_lineno
|
||||||
|
" we haven't moved, brackets not found
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if end_lineno - start_lineno > 2
|
||||||
|
" more than one line between them, can't join
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! va{J
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#go#SplitFunc()
|
||||||
|
let pattern = '^func\%(\s*(.\{-})\s*\)\=\s\+\k\+\zs('
|
||||||
|
if search(pattern, 'Wcn', line('.')) <= 0 &&
|
||||||
|
\ search(pattern, 'Wbcn', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let split_type = ''
|
||||||
|
|
||||||
|
let [start, end] = sj#LocateBracesAroundCursor('(', ')', ['goString', 'goComment'])
|
||||||
|
if start > 0
|
||||||
|
let split_type = 'definition_list'
|
||||||
|
else
|
||||||
|
let [start, end] = sj#LocateBracesAroundCursor('{', '}', ['goString', 'goComment'])
|
||||||
|
|
||||||
|
if start > 0
|
||||||
|
let split_type = 'function_body'
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if split_type == 'function_body'
|
||||||
|
let contents = sj#Trim(sj#GetCols(start + 1, end - 1))
|
||||||
|
call sj#ReplaceCols(start + 1, end - 1, "\n".contents."\n")
|
||||||
|
return 1
|
||||||
|
elseif split_type == 'definition_list'
|
||||||
|
let parsed = sj#ParseJsonObjectBody(start + 1, end - 1)
|
||||||
|
|
||||||
|
" Keep `a, b int` variable groups on the same line
|
||||||
|
let arg_groups = []
|
||||||
|
let typed_arg_group = ''
|
||||||
|
for elem in parsed
|
||||||
|
if match(elem, '\s\+') != -1
|
||||||
|
let typed_arg_group .= elem
|
||||||
|
call add(arg_groups, typed_arg_group)
|
||||||
|
let typed_arg_group = ''
|
||||||
|
else
|
||||||
|
" not typed here, group it with later vars
|
||||||
|
let typed_arg_group .= elem . ', '
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
call sj#ReplaceCols(start + 1, end - 1, "\n".join(arg_groups, ",\n").",\n")
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#go#SplitFuncCall()
|
||||||
|
let [start, end] = sj#LocateBracesAroundCursor('(', ')', ['goString', 'goComment'])
|
||||||
|
if start < 0 && end < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let args = sj#ParseJsonObjectBody(start + 1, end - 1)
|
||||||
|
call sj#ReplaceCols(start + 1, end - 1, "\n".join(args, ",\n").",\n")
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#go#JoinFuncCallOrDefinition()
|
||||||
|
let start_lineno = line('.')
|
||||||
|
|
||||||
|
if search('($', 'Wc', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if strpart(getline('.'), 0, col('.')) =~ '\(var\|type\|const\|import\)\s\+($'
|
||||||
|
" This isn't a function call, it's a multiline var/const/type declaration
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! %
|
||||||
|
let end_lineno = line('.')
|
||||||
|
|
||||||
|
if start_lineno == end_lineno
|
||||||
|
" we haven't moved, brackets not found
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let arguments = []
|
||||||
|
for line in getbufline('%', start_lineno + 1, end_lineno - 1)
|
||||||
|
let argument = substitute(line, ',$', '', '')
|
||||||
|
let argument = sj#Trim(argument)
|
||||||
|
call add(arguments, argument)
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let replacement = '(' . join(arguments, ', ') . ')'
|
||||||
|
call sj#ReplaceMotion('va(', replacement)
|
||||||
|
return 1
|
||||||
|
endfunction
|
78
bundle/splitjoin.vim/autoload/sj/haml.vim
Normal file
78
bundle/splitjoin.vim/autoload/sj/haml.vim
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
" TODO (2013-05-09) Only works for very simple things, needs work
|
||||||
|
function! sj#haml#SplitInterpolation()
|
||||||
|
let lineno = line('.')
|
||||||
|
let line = getline('.')
|
||||||
|
let indent = indent('.')
|
||||||
|
let pattern = '^\s*%.\{-}\zs='
|
||||||
|
|
||||||
|
if line !~ pattern
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#Keeppatterns('s/'.pattern.'/\r=/')
|
||||||
|
call s:SetIndent(lineno + 1, lineno + 1, indent + &sw)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#haml#JoinInterpolation()
|
||||||
|
if line('.') == line('$')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let line = getline('.')
|
||||||
|
let next_line = getline(line('.') + 1)
|
||||||
|
|
||||||
|
if !(line =~ '^\s*%\k\+\s*$' && next_line =~ '^\s*=')
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
call sj#Keeppatterns('s/\n\s*//')
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Sets the absolute indent of the given range of lines to the given indent
|
||||||
|
function! s:SetIndent(from, to, indent)
|
||||||
|
let new_whitespace = repeat(' ', a:indent)
|
||||||
|
exe a:from.','.a:to.'s/^\s*/'.new_whitespace
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#haml#SplitInlineInterpolation()
|
||||||
|
let lineno = line('.')
|
||||||
|
let indent = indent(lineno)
|
||||||
|
let line = getline(lineno)
|
||||||
|
let pattern = '^\(.*\)\s*#{\(.\{-}\)}\s*$'
|
||||||
|
|
||||||
|
if line !~ pattern
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let new_line = sj#ExtractRx(line, pattern, '\1')
|
||||||
|
let code = sj#ExtractRx(line, pattern, '\2')
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('V', new_line."\n= ".code)
|
||||||
|
call sj#SetIndent(lineno + 1, lineno + 1, indent)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#haml#JoinToInlineInterpolation()
|
||||||
|
if line('.') == line('$')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let lineno = line('.')
|
||||||
|
let line = getline(lineno)
|
||||||
|
let indent = indent(lineno)
|
||||||
|
let next_indent = indent(lineno + 1)
|
||||||
|
let next_line = getline(lineno + 1)
|
||||||
|
|
||||||
|
if indent == next_indent && next_line =~ '^\s*='
|
||||||
|
let code = substitute(sj#Trim(next_line), '^=\s*', '', '')
|
||||||
|
let line = sj#Rtrim(line).' #{'.code.'}'
|
||||||
|
call sj#ReplaceLines(lineno, lineno, line)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
105
bundle/splitjoin.vim/autoload/sj/handlebars.vim
Normal file
105
bundle/splitjoin.vim/autoload/sj/handlebars.vim
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
function! sj#handlebars#SplitComponent()
|
||||||
|
if !sj#SearchUnderCursor('{{#\=\%(\k\|-\|\/\)\+ .\{-}}}')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = sj#GetMotion('vi{')
|
||||||
|
let body = substitute(body, '\s\+\(\k\+=\)', '\n\1', 'g')
|
||||||
|
if !sj#settings#Read('handlebars_closing_bracket_on_same_line')
|
||||||
|
let body = substitute(body, '}$', "\n}", '')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if sj#settings#Read('handlebars_hanging_arguments')
|
||||||
|
" substitute just the first newline with a space
|
||||||
|
let body = substitute(body, '\n', ' ', '')
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('vi{', body)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#handlebars#JoinComponent()
|
||||||
|
if !(sj#SearchUnderCursor('{{#\=\%(\k\|-\|\/\)\+.*$') && getline('.') !~ '}}')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! vi{J
|
||||||
|
call sj#Keeppatterns('s/\s\+}}/}}/ge')
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#handlebars#SplitBlockComponent()
|
||||||
|
let saved_iskeyword = &iskeyword
|
||||||
|
|
||||||
|
try
|
||||||
|
set iskeyword+=-,/
|
||||||
|
let start_pattern = '{{#\k\+\%( .\{-}\)\=}}'
|
||||||
|
|
||||||
|
if !search(start_pattern, 'bWc', line('.'))
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call search('\k', 'W', line('.'))
|
||||||
|
let component_name = expand('<cword>')
|
||||||
|
call search(start_pattern, 'eW', line('.'))
|
||||||
|
let start_col = col('.') + 1
|
||||||
|
|
||||||
|
if !search('{{/'.component_name.'}}', 'W', line('.'))
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let end_col = col('.') - 1
|
||||||
|
|
||||||
|
if end_col - start_col > 0
|
||||||
|
let body = sj#GetCols(start_col, end_col)
|
||||||
|
call sj#ReplaceCols(start_col, end_col, "\n".sj#Trim(body)."\n")
|
||||||
|
else
|
||||||
|
" empty block component
|
||||||
|
call sj#ReplaceCols(start_col, start_col, "\n{")
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
finally
|
||||||
|
let &iskeyword = saved_iskeyword
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#handlebars#JoinBlockComponent()
|
||||||
|
let saved_iskeyword = &iskeyword
|
||||||
|
|
||||||
|
try
|
||||||
|
set iskeyword+=-,/
|
||||||
|
let start_pattern = '{{#\k\+\%( .\{-}\)\=}}\s*$'
|
||||||
|
|
||||||
|
if !search(start_pattern, 'bWc', line('.'))
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call search('\k', 'W', line('.'))
|
||||||
|
let component_name = expand('<cword>')
|
||||||
|
let start_line = line('.')
|
||||||
|
|
||||||
|
if !search('{{/'.component_name.'}}', 'W')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let end_line = line('.')
|
||||||
|
|
||||||
|
if end_line - start_line <= 0
|
||||||
|
" not right, there needs to be at least one line of a difference
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if end_line - start_line > 1
|
||||||
|
let body = join(sj#TrimList(getbufline('%', start_line + 1, end_line -1)), ' ')
|
||||||
|
else
|
||||||
|
let body = ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
let start_tag = sj#Rtrim(getline(start_line))
|
||||||
|
let end_tag = sj#Ltrim(getline(end_line))
|
||||||
|
|
||||||
|
call sj#ReplaceLines(start_line, end_line, start_tag.body.end_tag)
|
||||||
|
return 1
|
||||||
|
finally
|
||||||
|
let &iskeyword = saved_iskeyword
|
||||||
|
endtry
|
||||||
|
endfunction
|
144
bundle/splitjoin.vim/autoload/sj/html.vim
Normal file
144
bundle/splitjoin.vim/autoload/sj/html.vim
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
function! sj#html#SplitTags()
|
||||||
|
let line = getline('.')
|
||||||
|
let tag_regex = '\(<.\{-}>\)\(.*\)\(<\/.\{-}>\)'
|
||||||
|
let tag_with_content_regex = '\(<.\{-}>\)\(.\+\)\(<\/.\{-}>\)'
|
||||||
|
|
||||||
|
if line =~ tag_regex
|
||||||
|
let body = sj#GetMotion('Vat')
|
||||||
|
if line =~ tag_with_content_regex
|
||||||
|
call sj#ReplaceMotion('Vat', substitute(body, tag_regex, '\1\n\2\n\3', ''))
|
||||||
|
else
|
||||||
|
call sj#ReplaceMotion('Vat', substitute(body, tag_regex, '\1\n\3', ''))
|
||||||
|
endif
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Needs to be called with the cursor on a starting or ending tag to work.
|
||||||
|
function! sj#html#JoinTags()
|
||||||
|
if s:noTagUnderCursor()
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let tag = sj#GetMotion('vat')
|
||||||
|
let body = sj#GetMotion('vit')
|
||||||
|
|
||||||
|
if len(split(tag, "\n")) == 1
|
||||||
|
" then it's just one line, ignore
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = sj#Trim(body)
|
||||||
|
let body = join(sj#TrimList(split(body, "\n")), ' ')
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('vit', body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#html#SplitAttributes()
|
||||||
|
let lineno = line('.')
|
||||||
|
let line = getline('.')
|
||||||
|
let skip = sj#SkipSyntax(['htmlString'])
|
||||||
|
|
||||||
|
" Check if we are really on a single tag line
|
||||||
|
if sj#SearchSkip('<', skip, 'bcWe', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let start = col('.')
|
||||||
|
|
||||||
|
" Avoid matching =>
|
||||||
|
if sj#SearchSkip('\%(^\|[^=]\)\zs>', skip, 'W', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let end = col('.')
|
||||||
|
|
||||||
|
let result = []
|
||||||
|
let indent = indent('.')
|
||||||
|
|
||||||
|
let argparser = sj#argparser#html_args#Construct(start, end, getline('.'))
|
||||||
|
call argparser.Process()
|
||||||
|
let args = argparser.args
|
||||||
|
|
||||||
|
if len(args) <= 1
|
||||||
|
" only one argument would only the tag opener, no attributes
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" The first item contains the tag and needs slightly different handling
|
||||||
|
let args[0] = s:withIndentation(args[0], indent)
|
||||||
|
|
||||||
|
if sj#settings#Read('html_attributes_bracket_on_new_line')
|
||||||
|
let args[-1] = substitute(args[-1], '\s*/\=>$', "\n\\0", '')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if sj#settings#Read('html_attributes_hanging')
|
||||||
|
if len(args) <= 2
|
||||||
|
" in the hanging case, nothing to split if there's at least one
|
||||||
|
" non-opening attribute
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let body = args[0].' '.join(args[1:-1], "\n")
|
||||||
|
else
|
||||||
|
let body = join(args, "\n")
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceCols(start, end, sj#Trim(body))
|
||||||
|
|
||||||
|
if sj#settings#Read('html_attributes_hanging')
|
||||||
|
" For some strange reason, built-in HTML indenting fails here.
|
||||||
|
let attr_indent = indent + len(args[0]) + 1
|
||||||
|
let start_line = lineno + 1
|
||||||
|
let end_line = lineno + len(args[1:-1]) -1
|
||||||
|
|
||||||
|
for l in range(start_line, end_line)
|
||||||
|
call setline(l, repeat(' ', attr_indent).sj#Trim(getline(l)))
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#html#JoinAttributes()
|
||||||
|
let line = getline('.')
|
||||||
|
let indent = repeat(' ', indent('.'))
|
||||||
|
|
||||||
|
if s:noTagUnderCursor()
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let skip = sj#SkipSyntax(['htmlString'])
|
||||||
|
|
||||||
|
if sj#SearchSkip('<', skip, 'bcW') <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let start_pos = getpos('.')
|
||||||
|
|
||||||
|
if sj#SearchSkip('\%(^\|[^=]\)\zs>', skip, 'Wc') <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let end_pos = getpos('.')
|
||||||
|
|
||||||
|
if start_pos[1] == end_pos[1]
|
||||||
|
" tag is single-line, nothing to join
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let lines = split(sj#GetByPosition(start_pos, end_pos), "\n")
|
||||||
|
let joined = join(sj#TrimList(lines), ' ')
|
||||||
|
let joined = substitute(joined, '\s*>$', '>', '')
|
||||||
|
|
||||||
|
call sj#ReplaceByPosition(start_pos, end_pos, joined)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:noTagUnderCursor()
|
||||||
|
return searchpair('<', '', '>', 'cb', '', line('.')) <= 0
|
||||||
|
\ && searchpair('<', '', '>', 'c', '', line('.')) <= 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:withIndentation(str, indent)
|
||||||
|
return repeat(' ', a:indent) . a:str
|
||||||
|
endfunction
|
183
bundle/splitjoin.vim/autoload/sj/java.vim
Normal file
183
bundle/splitjoin.vim/autoload/sj/java.vim
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
let s:skip = sj#SkipSyntax(['javaComment', 'javaString'])
|
||||||
|
|
||||||
|
function! sj#java#SplitIfClauseBody()
|
||||||
|
if sj#SearchSkip('^\s*if (.\+) .\+;\?', s:skip, 'bc', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" skip nested () brackets
|
||||||
|
normal! ^w%l
|
||||||
|
let body = sj#Trim(sj#GetMotion('vg_'))
|
||||||
|
|
||||||
|
if body == '{'
|
||||||
|
" nothing to split
|
||||||
|
return 0
|
||||||
|
endi
|
||||||
|
|
||||||
|
if body[0] == '{'
|
||||||
|
let with_curly_brackets = 1
|
||||||
|
normal! f{
|
||||||
|
let body = sj#Trim(sj#GetMotion('vi{'))
|
||||||
|
else
|
||||||
|
let with_curly_brackets = 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if body[0] == ')'
|
||||||
|
" normal! l didn't work, body must be on another line, nothing to do here
|
||||||
|
return 0
|
||||||
|
" elseif body =~ '//\|/*'
|
||||||
|
elseif body =~ '\n'
|
||||||
|
" it's more than one line, nevermind
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if with_curly_brackets
|
||||||
|
call sj#ReplaceMotion('va{', "{\n".body."\n}")
|
||||||
|
else
|
||||||
|
call sj#ReplaceMotion('vg_', "\n".body)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#java#JoinIfClauseBody()
|
||||||
|
if sj#SearchSkip('^\s*if\s*(.\+)\s*{$', s:skip, 'e', line('.')) > 0
|
||||||
|
normal! va{J
|
||||||
|
return 1
|
||||||
|
elseif sj#SearchSkip('^\s*if\s*(.\+)\s*$', s:skip, 'bc', line('.')) > 0 &&
|
||||||
|
\ indent(nextnonblank(line('.') + 1)) > indent(line('.'))
|
||||||
|
normal! J
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#java#SplitIfClauseCondition()
|
||||||
|
normal! ^
|
||||||
|
if sj#SearchSkip('^\s*if\s\+(', s:skip, 'ce', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let start_pos = getpos('.')
|
||||||
|
normal! %
|
||||||
|
let end_pos = getpos('.')
|
||||||
|
|
||||||
|
if start_pos[1] != end_pos[1]
|
||||||
|
" closing ) was on a different line, don't split
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if start_pos[2] == end_pos[2]
|
||||||
|
" same column, we didn't move
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let items = sj#TrimList(split(sj#GetByPosition(start_pos, end_pos), '\ze\(&&\|||\)'))
|
||||||
|
let body = join(items, "\n")
|
||||||
|
|
||||||
|
call sj#ReplaceByPosition(start_pos, end_pos, body)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#java#JoinIfClauseCondition()
|
||||||
|
normal! ^
|
||||||
|
if sj#SearchSkip('^\s*if\s*(', s:skip, 'ce', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let start_line = line('.')
|
||||||
|
normal! %
|
||||||
|
let end_line = line('.')
|
||||||
|
|
||||||
|
if start_line == end_line
|
||||||
|
" closing ) was on the same line, nothing to do
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! va)J
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#java#SplitFuncall()
|
||||||
|
if sj#SearchUnderCursor('(.\{-})', '', s:skip) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PushCursor()
|
||||||
|
|
||||||
|
normal! l
|
||||||
|
let start = col('.')
|
||||||
|
normal! h%h
|
||||||
|
let end = col('.')
|
||||||
|
|
||||||
|
let items = sj#ParseJsonObjectBody(start, end)
|
||||||
|
|
||||||
|
if sj#settings#Read('java_argument_split_first_newline')
|
||||||
|
let body = "(\n"
|
||||||
|
else
|
||||||
|
let body = "("
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body .= join(items, ",\n")
|
||||||
|
|
||||||
|
if sj#settings#Read('java_argument_split_last_newline')
|
||||||
|
let body .= "\n)"
|
||||||
|
else
|
||||||
|
let body .= ")"
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PopCursor()
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('va(', body)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#java#JoinFuncall()
|
||||||
|
if sj#SearchUnderCursor('([^)]*\s*$', '', s:skip) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let lines = sj#TrimList(split(sj#GetMotion('vi('), "\n"))
|
||||||
|
call sj#ReplaceMotion('va(', '('.join(lines, ' ').')')
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#java#SplitLambda()
|
||||||
|
if !sj#SearchUnderCursor('\%((.\{})\|\k\+\)\s*->\s*.*$')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call search('\%((.\{})\|\k\+\)\s*->\s*\zs.*$', 'W', line('.'))
|
||||||
|
|
||||||
|
if strpart(getline('.'), col('.') - 1) =~ '^\s*{'
|
||||||
|
" then we have a curly bracket group, easy split:
|
||||||
|
let body = sj#GetMotion('vi{')
|
||||||
|
call sj#ReplaceMotion('vi{', "\nreturn ".sj#Trim(body).";\n")
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let start_col = col('.')
|
||||||
|
let end_col = sj#JumpBracketsTill('[\])};,]', {'opening': '([{"''', 'closing': ')]}"'''})
|
||||||
|
|
||||||
|
let body = sj#GetCols(start_col, end_col)
|
||||||
|
let replacement = "{\nreturn ".body.";\n}"
|
||||||
|
|
||||||
|
call sj#ReplaceCols(start_col, end_col, replacement)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#java#JoinLambda()
|
||||||
|
if !sj#SearchUnderCursor('\%((.\{})\|\k\+\)\s*->\s*{\s*$')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! $
|
||||||
|
|
||||||
|
let body = sj#Trim(sj#GetMotion('vi{'))
|
||||||
|
let body = substitute(body, '^return\s*', '', '')
|
||||||
|
let body = substitute(body, ';$', '', '')
|
||||||
|
call sj#ReplaceMotion('va{', body)
|
||||||
|
return 1
|
||||||
|
endfunction
|
267
bundle/splitjoin.vim/autoload/sj/js.vim
Normal file
267
bundle/splitjoin.vim/autoload/sj/js.vim
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
function! sj#js#SplitObjectLiteral()
|
||||||
|
let [from, to] = sj#LocateBracesAroundCursor('{', '}')
|
||||||
|
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if synIDattr(synID(line('.'), from, 1), "name") == 'jsxBraces'
|
||||||
|
" from jsx-pretty
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let pairs = sj#ParseJsonObjectBody(from + 1, to - 1)
|
||||||
|
let body = join(pairs, ",\n")
|
||||||
|
if sj#settings#Read('trailing_comma')
|
||||||
|
let body .= ','
|
||||||
|
endif
|
||||||
|
let body = "{\n".body."\n}"
|
||||||
|
call sj#ReplaceMotion('Va{', body)
|
||||||
|
|
||||||
|
if sj#settings#Read('align')
|
||||||
|
let body_start = line('.') + 1
|
||||||
|
let body_end = body_start + len(pairs) - 1
|
||||||
|
call sj#Align(body_start, body_end, 'json_object')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#js#SplitFunction()
|
||||||
|
if !sj#SearchUnderCursor('\<function\>.*(.*)\s*{.*}')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! f{
|
||||||
|
let [from, to] = sj#LocateBracesAroundCursor('{', '}')
|
||||||
|
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = sj#Trim(sj#GetMotion('vi{'))
|
||||||
|
call sj#ReplaceMotion('va{', "{\n".body."\n}")
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#js#JoinObjectLiteral()
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if line =~ '{\s*$'
|
||||||
|
call search('{', 'c', line('.'))
|
||||||
|
let body = sj#GetMotion('Vi{')
|
||||||
|
|
||||||
|
let lines = split(body, "\n")
|
||||||
|
let lines = sj#TrimList(lines)
|
||||||
|
if sj#settings#Read('normalize_whitespace')
|
||||||
|
let lines = map(lines, 'substitute(v:val, ":\\s\\+", ": ", "")')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = join(lines, ' ')
|
||||||
|
let body = substitute(body, ',$', '', '')
|
||||||
|
|
||||||
|
if sj#settings#Read('curly_brace_padding')
|
||||||
|
let body = '{ '.body.' }'
|
||||||
|
else
|
||||||
|
let body = '{'.body.'}'
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va{', body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#js#JoinFunction()
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if line =~ 'function\%(\s\+\k\+\)\=(.*) {\s*$'
|
||||||
|
call search('{', 'c', line('.'))
|
||||||
|
let body = sj#GetMotion('Vi{')
|
||||||
|
|
||||||
|
let lines = split(body, ';\=\s*\n')
|
||||||
|
let lines = sj#TrimList(lines)
|
||||||
|
let body = join(lines, '; ').';'
|
||||||
|
let body = '{ '.body.' }'
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va{', body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#js#SplitArray()
|
||||||
|
return s:SplitList(['[', ']'], 'cursor_inside')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#js#SplitArgs()
|
||||||
|
return s:SplitList(['(', ')'], 'cursor_on_line')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#js#JoinArray()
|
||||||
|
return s:JoinList(['[', ']'])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#js#JoinArgs()
|
||||||
|
return s:JoinList(['(', ')'])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#js#SplitOneLineIf()
|
||||||
|
let line = getline('.')
|
||||||
|
if line =~ '^\s*if (.\+) .\+;\?'
|
||||||
|
let lines = []
|
||||||
|
" use regular vim movements to know where we have to split
|
||||||
|
normal! ^w%
|
||||||
|
let end_if = getpos('.')[2]
|
||||||
|
call add(lines, line[0:end_if] . '{')
|
||||||
|
call add(lines, sj#Trim(line[end_if :]))
|
||||||
|
call add(lines, '}')
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('V', join(lines, "\n"))
|
||||||
|
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#js#JoinOneLineIf()
|
||||||
|
let if_line_no = line('.')
|
||||||
|
let if_line = getline('.')
|
||||||
|
let end_line_no = if_line_no + 2
|
||||||
|
let end_line = getline(end_line_no)
|
||||||
|
|
||||||
|
if if_line !~ '^\s*if (.\+) {' || end_line !~ '^\s*}\s*$'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = sj#Trim(getline(if_line_no + 1))
|
||||||
|
let new = if_line[:-2] . body
|
||||||
|
|
||||||
|
call sj#ReplaceLines(if_line_no, end_line_no, new)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:SplitList(delimiter, cursor_position)
|
||||||
|
let start = a:delimiter[0]
|
||||||
|
let end = a:delimiter[1]
|
||||||
|
|
||||||
|
let lineno = line('.')
|
||||||
|
let indent = indent('.')
|
||||||
|
|
||||||
|
if a:cursor_position == 'cursor_inside'
|
||||||
|
let [from, to] = sj#LocateBracesAroundCursor(start, end)
|
||||||
|
elseif a:cursor_position == 'cursor_on_line'
|
||||||
|
let [from, to] = sj#LocateBracesOnLine(start, end)
|
||||||
|
else
|
||||||
|
echoerr "Invalid value for a:cursor_position: ".a:cursor_position
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let items = sj#ParseJsonObjectBody(from + 1, to - 1)
|
||||||
|
if empty(items)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if sj#settings#Read('trailing_comma')
|
||||||
|
let body = start."\n".join(items, ",\n").",\n".end
|
||||||
|
else
|
||||||
|
let body = start."\n".join(items, ",\n")."\n".end
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va'.start, body)
|
||||||
|
|
||||||
|
" built-in js indenting doesn't indent this properly
|
||||||
|
for l in range(lineno + 1, lineno + len(items))
|
||||||
|
call sj#SetIndent(l, indent + &sw)
|
||||||
|
endfor
|
||||||
|
" closing bracket
|
||||||
|
let end_line = lineno + len(items) + 1
|
||||||
|
call sj#SetIndent(end_line, indent)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:JoinList(delimiter)
|
||||||
|
let start = a:delimiter[0]
|
||||||
|
let end = a:delimiter[1]
|
||||||
|
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if line !~ start . '\s*$'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call search(start, 'c', line('.'))
|
||||||
|
let body = sj#GetMotion('Vi'.start)
|
||||||
|
|
||||||
|
let lines = split(body, "\n")
|
||||||
|
let lines = sj#TrimList(lines)
|
||||||
|
let body = sj#Trim(join(lines, ' '))
|
||||||
|
let body = substitute(body, ',\s*$', '', '')
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va'.start, start.body.end)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#js#SplitFatArrowFunction()
|
||||||
|
if !sj#SearchUnderCursor('\%((.\{})\|\k\+\)\s*=>\s*.*$')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call search('\%((.\{})\|\k\+\)\s*=>\s*\zs.*$', 'W', line('.'))
|
||||||
|
|
||||||
|
if strpart(getline('.'), col('.') - 1) =~ '^\s*{'
|
||||||
|
" then we have a curly bracket group, easy split:
|
||||||
|
let body = sj#GetMotion('vi{')
|
||||||
|
call sj#ReplaceMotion('vi{', "\n".sj#Trim(body)."\n")
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let start_col = col('.')
|
||||||
|
let end_col = sj#JumpBracketsTill('[\])};,]', {'opening': '([{"''', 'closing': ')]}"'''})
|
||||||
|
|
||||||
|
let body = sj#Trim(sj#GetCols(start_col, end_col))
|
||||||
|
if body =~ '^({.*})$'
|
||||||
|
" then we have ({ <object> }) to avoid ambiguity, not needed anymore:
|
||||||
|
let body = substitute(body, '^(\({.*}\))$', '\1', '')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if getline('.') =~ ';\s*\%(//.*\)\=$'
|
||||||
|
let replacement = "{\nreturn ".body.";\n}"
|
||||||
|
else
|
||||||
|
let replacement = "{\nreturn ".body."\n}"
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceCols(start_col, end_col, replacement)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#js#JoinFatArrowFunction()
|
||||||
|
if !sj#SearchUnderCursor('\%((.\{})\|\k\+\)\s*=>\s*{\s*$')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! $
|
||||||
|
|
||||||
|
let body = sj#Trim(sj#GetMotion('vi{'))
|
||||||
|
let body = substitute(body, '^return\s*', '', '')
|
||||||
|
let body = substitute(body, '\s*;$', '', '')
|
||||||
|
|
||||||
|
if body =~ '^{.*}$'
|
||||||
|
" ({ <object> }), because otherwise it's ambiguous
|
||||||
|
let body = '('.body.')'
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('va{', body)
|
||||||
|
return 1
|
||||||
|
endfunction
|
133
bundle/splitjoin.vim/autoload/sj/jsx.vim
Normal file
133
bundle/splitjoin.vim/autoload/sj/jsx.vim
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
function! sj#jsx#SplitJsxExpression()
|
||||||
|
" Examples:
|
||||||
|
"
|
||||||
|
" let x = <tag>
|
||||||
|
" () => <tag>
|
||||||
|
" return <tag>
|
||||||
|
"
|
||||||
|
let pattern = '\%(\%(let\|const\|var\)\s\+\k\+\s*=\s*\|)\s*=>\|return\s\+\)\s*' .
|
||||||
|
\ '\zs<\k[^>/[:space:]]*'
|
||||||
|
|
||||||
|
if sj#SearchUnderCursor(pattern) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" is it a fully-closed jsx tag?
|
||||||
|
let body = sj#GetMotion('vat')
|
||||||
|
if body =~ '^<\(\k\+\).*</\1>$'
|
||||||
|
if body =~ "\n"
|
||||||
|
" multiple lines, not splitting
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('vat', "(\n".sj#Trim(body)."\n)")
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
" is it a self-closing tag?
|
||||||
|
let body = sj#GetMotion('va>')
|
||||||
|
if body =~ '^<\k\+.*/>$'
|
||||||
|
if body =~ "\n"
|
||||||
|
" multiple lines, not splitting
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('va>', "(\n".sj#Trim(body)."\n)")
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#jsx#JoinJsxExpression()
|
||||||
|
" Examples:
|
||||||
|
"
|
||||||
|
" let x = (
|
||||||
|
" () => (
|
||||||
|
" return (
|
||||||
|
"
|
||||||
|
let pattern = '\%(\%(let\|const\|var\)\s\+\k\+\s*=\s*\|)\s*=>\|return\s\+\)\s*($'
|
||||||
|
if sj#SearchUnderCursor(pattern) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! $
|
||||||
|
let body = sj#Trim(sj#GetMotion('vi('))
|
||||||
|
if body =~ "\n"
|
||||||
|
" multiline tag, no point in handling
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if body !~ '^<\k\+.*/>$' && body !~ '^<\(\k\+\).*</\1>$'
|
||||||
|
" doesn't look like a tag
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('va(', body)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#jsx#SplitSelfClosingTag()
|
||||||
|
if s:noTagUnderCursor()
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let tag = sj#GetMotion('va<')
|
||||||
|
if tag == '' || tag !~ '^<\k'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" is it self-closing?
|
||||||
|
if tag !~ '/>$'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let tag_name = matchstr(tag, '^<\zs\k[^>/[:space:]]*')
|
||||||
|
let replacement = substitute(tag, '\s*/>$', '>\n</'.tag_name.'>', '')
|
||||||
|
call sj#ReplaceMotion('va<', replacement)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Needs to be called with the cursor on a starting or ending tag to work.
|
||||||
|
function! sj#jsx#JoinHtmlTag()
|
||||||
|
if s:noTagUnderCursor()
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let tag = sj#GetMotion('vat')
|
||||||
|
if tag =~ '^\s*$'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let tag_name = matchstr(tag, '^<\zs\k[^>/[:space:]]*')
|
||||||
|
let empty_tag_pattern = '>\_s*</\s*'.tag_name.'\s*>$'
|
||||||
|
|
||||||
|
if tag =~ empty_tag_pattern
|
||||||
|
" then there's no contents, let's turn it into a self-closing tag
|
||||||
|
let self_closing_tag = substitute(tag, empty_tag_pattern, ' />', '')
|
||||||
|
if self_closing_tag == tag
|
||||||
|
" then the substitution failed for some reason
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('vat', self_closing_tag)
|
||||||
|
else
|
||||||
|
" There's contents in the tag, let's try to single-line it
|
||||||
|
if len(split(tag, "\n")) == 1
|
||||||
|
" already single-line, nothing to do
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = sj#GetMotion('vit')
|
||||||
|
let body = join(sj#TrimList(split(body, "\n")), ' ')
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('vit', body)
|
||||||
|
end
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:noTagUnderCursor()
|
||||||
|
return searchpair('<', '', '>', 'cb', '', line('.')) <= 0
|
||||||
|
\ && searchpair('<', '', '>', 'c', '', line('.')) <= 0
|
||||||
|
endfunction
|
131
bundle/splitjoin.vim/autoload/sj/lua.vim
Normal file
131
bundle/splitjoin.vim/autoload/sj/lua.vim
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
let s:function_pattern = '\(\<function\>.\{-}(.\{-})\)\(.*\)\<end\>'
|
||||||
|
|
||||||
|
function! sj#lua#SplitFunctionString(str)
|
||||||
|
let head = sj#ExtractRx(a:str, s:function_pattern, '\1')
|
||||||
|
let body = sj#Trim(sj#ExtractRx(a:str, s:function_pattern, '\2'))
|
||||||
|
|
||||||
|
if sj#BlankString(body)
|
||||||
|
let body = ''
|
||||||
|
else
|
||||||
|
let body = substitute(body, "; ", "\n", "").'\n'
|
||||||
|
endif
|
||||||
|
|
||||||
|
let replacement = head."\n".body."end"
|
||||||
|
let new_line = substitute(a:str, s:function_pattern, replacement, '')
|
||||||
|
|
||||||
|
return new_line
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#lua#SplitFunction()
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if line !~ s:function_pattern
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
call sj#ReplaceMotion('V', sj#lua#SplitFunctionString(line))
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#lua#JoinFunction()
|
||||||
|
normal! 0
|
||||||
|
if search('\<function\>', 'cW', line('.')) < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let function_lineno = line('.')
|
||||||
|
if searchpair('\<function\>', '', '^\s*\<end\>', 'W') <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let end_lineno = line('.')
|
||||||
|
|
||||||
|
let function_line = getline(function_lineno)
|
||||||
|
let end_line = sj#Trim(getline(end_lineno))
|
||||||
|
|
||||||
|
if end_lineno - function_lineno > 1
|
||||||
|
let body_lines = sj#GetLines(function_lineno + 1, end_lineno - 1)
|
||||||
|
let body_lines = sj#TrimList(body_lines)
|
||||||
|
let body = join(body_lines, '; ')
|
||||||
|
let body = ' '.body.' '
|
||||||
|
else
|
||||||
|
let body = ' '
|
||||||
|
endif
|
||||||
|
|
||||||
|
let replacement = function_line.body.end_line
|
||||||
|
call sj#ReplaceLines(function_lineno, end_lineno, replacement)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#lua#SplitTable()
|
||||||
|
let [from, to] = sj#LocateBracesOnLine('{', '}')
|
||||||
|
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
let parser = sj#argparser#js#Construct(from + 1, to -1, getline('.'))
|
||||||
|
call parser.Process()
|
||||||
|
let pairs = filter(parser.args, 'v:val !~ "^\s*$"')
|
||||||
|
|
||||||
|
let idx = 0
|
||||||
|
while idx < len(pairs)
|
||||||
|
let item = pairs[idx]
|
||||||
|
if item =~ s:function_pattern
|
||||||
|
let pairs[idx] = sj#lua#SplitFunctionString(item)
|
||||||
|
endif
|
||||||
|
let idx = idx + 1
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
let body = "{\n".join(pairs, ",\n").",\n}"
|
||||||
|
call sj#ReplaceMotion('Va{', body)
|
||||||
|
|
||||||
|
if sj#settings#Read('align')
|
||||||
|
let body_start = line('.') + 1
|
||||||
|
let body_end = body_start + len(pairs) - 1
|
||||||
|
call sj#Align(body_start, body_end, 'lua_table')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
endf
|
||||||
|
|
||||||
|
function! sj#lua#JoinTable()
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if line =~ '{\s*$'
|
||||||
|
call search('{', 'c', line('.'))
|
||||||
|
let body = sj#GetMotion('Vi{')
|
||||||
|
|
||||||
|
let parser = sj#argparser#js#Construct(0, strlen(body), body)
|
||||||
|
call parser.Process()
|
||||||
|
|
||||||
|
let lines = sj#TrimList(parser.args)
|
||||||
|
|
||||||
|
let idx = 0
|
||||||
|
while idx < len(lines)
|
||||||
|
let item = lines[idx]
|
||||||
|
if item =~ s:function_pattern
|
||||||
|
let head = sj#Trim(sj#ExtractRx(item, s:function_pattern, '\1'))
|
||||||
|
let body = sj#Trim(sj#ExtractRx(item, s:function_pattern, '\2'))
|
||||||
|
let body_lines = sj#TrimList(split(body, "\n"))
|
||||||
|
let replacement = head . ' ' . join(body_lines, '; '). ' end'
|
||||||
|
|
||||||
|
let lines[idx] = substitute(item, s:function_pattern, replacement, '')
|
||||||
|
endif
|
||||||
|
let idx = idx + 1
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if sj#settings#Read('normalize_whitespace')
|
||||||
|
let lines = map(lines, "substitute(v:val, '\\s\\+=\\s\\+', ' = ', '')")
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = substitute(join(lines, ', '), ',\s*$', '', '')
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va{', '{ '.body.' }')
|
||||||
|
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
endf
|
241
bundle/splitjoin.vim/autoload/sj/perl.vim
Normal file
241
bundle/splitjoin.vim/autoload/sj/perl.vim
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
function! sj#perl#SplitSuffixIfClause()
|
||||||
|
let pattern = '\(.*\) \(if\|unless\|while\|until\) \(.*\);\s*$'
|
||||||
|
|
||||||
|
if sj#settings#Read('perl_brace_on_same_line')
|
||||||
|
let replacement = "\\2 (\\3) {\n\\1;\n}"
|
||||||
|
else
|
||||||
|
let replacement = "\\2 (\\3) \n{\n\\1;\n}"
|
||||||
|
endif
|
||||||
|
|
||||||
|
return s:Split(pattern, replacement)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#perl#SplitPrefixIfClause()
|
||||||
|
let pattern = '\<if\s*(.\{-})\s*{.*}'
|
||||||
|
|
||||||
|
if search(pattern, 'Wbc') <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! f(
|
||||||
|
normal %
|
||||||
|
normal! f{
|
||||||
|
|
||||||
|
let body = sj#GetMotion('Va{')
|
||||||
|
let body = substitute(body, '^{\s*\(.\{-}\)\s*}$', "{\n\\1\n}", '')
|
||||||
|
call sj#ReplaceMotion('Va{', body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#perl#JoinIfClause()
|
||||||
|
let current_line = getline('.')
|
||||||
|
let if_clause_pattern = '^\s*\(if\|unless\|while\|until\)\s*(\(.*\))\s*{\=\s*$'
|
||||||
|
|
||||||
|
if current_line !~ if_clause_pattern
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let condition = substitute(current_line, if_clause_pattern, '\2', '')
|
||||||
|
let operation = substitute(current_line, if_clause_pattern, '\1', '')
|
||||||
|
let start_line = line('.')
|
||||||
|
|
||||||
|
call search('{', 'W')
|
||||||
|
if searchpair('{', '', '}', 'W') <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let end_line = line('.')
|
||||||
|
let body = sj#GetMotion('Vi{')
|
||||||
|
let body = join(split(body, ";\\s*\n"), '; ')
|
||||||
|
let body = substitute(body, ';\s\+', '; ', 'g')
|
||||||
|
let body = sj#Trim(body)
|
||||||
|
|
||||||
|
let replacement = body.' '.operation.' '.condition.';'
|
||||||
|
call sj#ReplaceLines(start_line, end_line, replacement)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#perl#SplitAndClause()
|
||||||
|
let pattern = '\(.*\) and \(.*\);\s*$'
|
||||||
|
|
||||||
|
if sj#settings#Read('perl_brace_on_same_line')
|
||||||
|
let replacement = "if (\\1) {\n\\2;\n}"
|
||||||
|
else
|
||||||
|
let replacement = "if (\\1) \n{\n\\2;\n}"
|
||||||
|
endif
|
||||||
|
|
||||||
|
return s:Split(pattern, replacement)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#perl#SplitOrClause()
|
||||||
|
let pattern = '\(.*\) or \(.*\);\s*$'
|
||||||
|
|
||||||
|
if sj#settings#Read('perl_brace_on_same_line')
|
||||||
|
let replacement = "unless (\\1) {\n\\2;\n}"
|
||||||
|
else
|
||||||
|
let replacement = "unless (\\1) \n{\n\\2;\n}"
|
||||||
|
endif
|
||||||
|
|
||||||
|
return s:Split(pattern, replacement)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#perl#SplitHash()
|
||||||
|
let [from, to] = sj#LocateBracesOnLine('{', '}')
|
||||||
|
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let pairs = sj#ParseJsonObjectBody(from + 1, to - 1)
|
||||||
|
let body = "{\n".join(pairs, ",\n").",\n}"
|
||||||
|
call sj#ReplaceMotion('Va{', body)
|
||||||
|
|
||||||
|
if sj#settings#Read('align')
|
||||||
|
let body_start = line('.') + 1
|
||||||
|
let body_end = body_start + len(pairs) - 1
|
||||||
|
call sj#Align(body_start, body_end, 'hashrocket')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#perl#JoinHash()
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if search('{\s*$', 'c', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = sj#GetMotion('Vi{')
|
||||||
|
|
||||||
|
let lines = split(body, ",\n")
|
||||||
|
let lines = sj#TrimList(lines)
|
||||||
|
if sj#settings#Read('normalize_whitespace')
|
||||||
|
let lines = map(lines, 'substitute(v:val, "=>\\s\\+", "=> ", "")')
|
||||||
|
let lines = map(lines, 'substitute(v:val, "\\s\\+=>", " =>", "")')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = join(lines, ', ')
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va{', '{'.body.'}')
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#perl#SplitSquareBracketedList()
|
||||||
|
let [from, to] = sj#LocateBracesOnLine('[', ']')
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let items = sj#ParseJsonObjectBody(from + 1, to - 1)
|
||||||
|
let body = "[\n".join(items, ",\n")
|
||||||
|
if sj#settings#Read('trailing_comma')
|
||||||
|
let body .= ","
|
||||||
|
endif
|
||||||
|
let body .= "\n]"
|
||||||
|
call sj#ReplaceMotion('Va[', body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#perl#SplitRoundBracketedList()
|
||||||
|
let [from, to] = sj#LocateBracesOnLine('(', ')')
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let items = sj#ParseJsonObjectBody(from + 1, to - 1)
|
||||||
|
let body = "(\n".join(items, ",\n")
|
||||||
|
if sj#settings#Read('trailing_comma')
|
||||||
|
let body .= ","
|
||||||
|
endif
|
||||||
|
let body .= "\n)"
|
||||||
|
call sj#ReplaceMotion('Va(', body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#perl#SplitWordList()
|
||||||
|
let [from, to] = sj#LocateBracesOnLine('qw(', ')')
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call search('qw\zs(', 'b', line('.'))
|
||||||
|
let remainder_of_line = getline('.')[col('.') - 1 : -1]
|
||||||
|
|
||||||
|
if remainder_of_line !~ '\%(\w\|\s\)\+)'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let items = split(matchstr(remainder_of_line, '\%(\k\|\s\)\+'), '\s\+')
|
||||||
|
let body = "(\n".join(items, "\n")."\n)"
|
||||||
|
call sj#ReplaceMotion('Va(', body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#perl#JoinSquareBracketedList()
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if search('[\s*$', 'c', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = sj#GetMotion('Vi[')
|
||||||
|
|
||||||
|
let lines = split(body, ",\n")
|
||||||
|
let lines = sj#TrimList(lines)
|
||||||
|
let body = join(lines, ', ')
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va[', '['.body.']')
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#perl#JoinRoundBracketedList()
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if search('(\s*$', 'c', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = sj#GetMotion('Vi(')
|
||||||
|
|
||||||
|
let lines = split(body, ",\n")
|
||||||
|
let lines = sj#TrimList(lines)
|
||||||
|
let body = join(lines, ', ')
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va(', '('.body.')')
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#perl#JoinWordList()
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if search('qw\zs(\s*$', 'c', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = sj#GetMotion('Vi(')
|
||||||
|
|
||||||
|
let lines = split(body, "\n")
|
||||||
|
let lines = sj#TrimList(lines)
|
||||||
|
let body = join(lines, ' ')
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va(', '('.body.')')
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:Split(pattern, replacement_pattern)
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if line !~ a:pattern
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('V', substitute(line, a:pattern, a:replacement_pattern, ''))
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
254
bundle/splitjoin.vim/autoload/sj/php.vim
Normal file
254
bundle/splitjoin.vim/autoload/sj/php.vim
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
function! sj#php#SplitBraces()
|
||||||
|
return s:SplitList('(', ')')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#php#SplitArray()
|
||||||
|
return s:SplitList('[', ']')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#php#JoinBraces()
|
||||||
|
return s:JoinList('(', ')')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#php#JoinArray()
|
||||||
|
return s:JoinList('[', ']')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#php#JoinHtmlTags()
|
||||||
|
if synIDattr(synID(line("."), col("."), 1), "name") =~ '^php'
|
||||||
|
" then we're in php, don't try to join tags
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return sj#html#JoinTags()
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#php#SplitIfClause()
|
||||||
|
let pattern = '\<if\s*(.\{-})\s*{.*}'
|
||||||
|
|
||||||
|
if search(pattern, 'Wbc', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! f(
|
||||||
|
normal %
|
||||||
|
normal! f{
|
||||||
|
|
||||||
|
let body = sj#GetMotion('Va{')
|
||||||
|
let body = substitute(body, '^{\s*\(.\{-}\)\s*}$', "{\n\\1\n}", '')
|
||||||
|
call sj#ReplaceMotion('Va{', body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#php#SplitElseClause()
|
||||||
|
let pattern = '\<else\s*{.*}'
|
||||||
|
|
||||||
|
if search(pattern, 'Wbc', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! f{
|
||||||
|
|
||||||
|
let body = sj#GetMotion('Va{')
|
||||||
|
let body = substitute(body, '^{\s*\(.\{-}\)\s*}$', "{\n\\1\n}", '')
|
||||||
|
call sj#ReplaceMotion('Va{', body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#php#JoinIfClause()
|
||||||
|
let pattern = '\<if\s*(.\{-})\s*{\s*$'
|
||||||
|
|
||||||
|
if search(pattern, 'Wbc', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! f(
|
||||||
|
normal %
|
||||||
|
normal! f{
|
||||||
|
|
||||||
|
let body = sj#GetMotion('Va{')
|
||||||
|
let body = substitute(body, "\\s*\n\\s*", ' ', 'g')
|
||||||
|
call sj#ReplaceMotion('Va{', body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#php#JoinElseClause()
|
||||||
|
let pattern = '\<else\s*{\s*$'
|
||||||
|
|
||||||
|
if search(pattern, 'Wbc', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! f{
|
||||||
|
|
||||||
|
let body = sj#GetMotion('Va{')
|
||||||
|
let body = substitute(body, "\\s*\n\\s*", ' ', 'g')
|
||||||
|
call sj#ReplaceMotion('Va{', body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#php#SplitPhpMarker()
|
||||||
|
if sj#SearchUnderCursor('<?=\=\%(php\)\=.\{-}?>') <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let start_col = col('.')
|
||||||
|
let skip = sj#SkipSyntax(['phpStringSingle', 'phpStringDouble', 'phpComment'])
|
||||||
|
if sj#SearchSkip('?>', skip, 'We', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let end_col = col('.')
|
||||||
|
|
||||||
|
let body = sj#GetCols(start_col, end_col)
|
||||||
|
let body = substitute(body, '^<?\(=\=\%(php\)\=\)\s*', "<?\\1\n", '')
|
||||||
|
let body = substitute(body, '\s*?>$', "\n?>", '')
|
||||||
|
|
||||||
|
call sj#ReplaceCols(start_col, end_col, body)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#php#JoinPhpMarker()
|
||||||
|
if sj#SearchUnderCursor('<?=\=\%(php\)\=\s*$') <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let start_lineno = line('.')
|
||||||
|
let skip = sj#SkipSyntax(['phpStringSingle', 'phpStringDouble', 'phpComment'])
|
||||||
|
if sj#SearchSkip('?>', skip, 'We') <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let end_lineno = line('.')
|
||||||
|
|
||||||
|
let saved_joinspaces = &joinspaces
|
||||||
|
set nojoinspaces
|
||||||
|
exe start_lineno.','.end_lineno.'join'
|
||||||
|
let &joinspaces = saved_joinspaces
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:SplitList(start_char, end_char)
|
||||||
|
let [from, to] = sj#LocateBracesOnLine(a:start_char, a:end_char)
|
||||||
|
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let pairs = sj#ParseJsonObjectBody(from + 1, to - 1)
|
||||||
|
|
||||||
|
if len(pairs) < 1
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = a:start_char."\n".join(pairs, ",\n")
|
||||||
|
if sj#settings#Read('trailing_comma')
|
||||||
|
let body = body.','
|
||||||
|
endif
|
||||||
|
let body = body."\n".a:end_char
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va'.a:start_char, body)
|
||||||
|
|
||||||
|
let body_start = line('.') + 1
|
||||||
|
let body_end = body_start + len(pairs)
|
||||||
|
|
||||||
|
call sj#PushCursor()
|
||||||
|
exe "normal! jV".(body_end - body_start)."j2="
|
||||||
|
call sj#PopCursor()
|
||||||
|
|
||||||
|
if sj#settings#Read('align')
|
||||||
|
call sj#Align(body_start, body_end, 'hashrocket')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:JoinList(start_char, end_char)
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if line !~ a:start_char.'\s*$'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call search(a:start_char.'\s*$', 'ce', line('.'))
|
||||||
|
|
||||||
|
let body = sj#Trim(sj#GetMotion('Vi'.a:start_char))
|
||||||
|
let body = substitute(body, ',$', '', '')
|
||||||
|
|
||||||
|
if sj#settings#Read('normalize_whitespace')
|
||||||
|
let body = substitute(body, '\s*=>\s*', ' => ', 'g')
|
||||||
|
endif
|
||||||
|
let body = join(sj#TrimList(split(body, "\n")), ' ')
|
||||||
|
call sj#ReplaceMotion('Va'.a:start_char, a:start_char.body.a:end_char)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:SplitNextArrow()
|
||||||
|
let l:arrow_or_paren = search('\v(\(|\S\zs-\>\ze)', '', line('.'))
|
||||||
|
|
||||||
|
if ! arrow_or_paren
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if matchstr(getline('.'), '\%' . col('.') . 'c.') == '('
|
||||||
|
normal! %
|
||||||
|
else
|
||||||
|
exe "normal! i\<cr>"
|
||||||
|
endif
|
||||||
|
|
||||||
|
call s:SplitNextArrow()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#php#SplitMethodChain()
|
||||||
|
let pattern = '->[^-);]*'
|
||||||
|
|
||||||
|
if sj#SearchUnderCursor('\S'.pattern) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call search(pattern, 'W', line('.'))
|
||||||
|
let start_col = col('.')
|
||||||
|
call search(pattern, 'We', line('.'))
|
||||||
|
let end_col = col('.')
|
||||||
|
|
||||||
|
" try to find a (...) after the keyword
|
||||||
|
let current_line = line('.')
|
||||||
|
normal! l
|
||||||
|
if getline('.')[col('.') - 1] == '('
|
||||||
|
normal! %
|
||||||
|
if line('.') == current_line
|
||||||
|
" the closing ) is on the same line, grab that one as well
|
||||||
|
let end_col = col('.')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = sj#GetCols(start_col, end_col)
|
||||||
|
call sj#ReplaceCols(start_col, end_col, "\n".body)
|
||||||
|
|
||||||
|
if sj#settings#Read('php_method_chain_full')
|
||||||
|
normal! j
|
||||||
|
call s:SplitNextArrow()
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#php#JoinMethodChain()
|
||||||
|
let next_line = nextnonblank(line('.') + 1)
|
||||||
|
|
||||||
|
if getline(next_line) !~ '->'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#Keeppatterns('s/\n\_s*//g')
|
||||||
|
|
||||||
|
if sj#settings#Read('php_method_chain_full')
|
||||||
|
call sj#php#JoinMethodChain()
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
422
bundle/splitjoin.vim/autoload/sj/python.vim
Normal file
422
bundle/splitjoin.vim/autoload/sj/python.vim
Normal file
@ -0,0 +1,422 @@
|
|||||||
|
let s:skip = sj#SkipSyntax(['pythonString', 'pythonComment', 'pythonStrInterpRegion'])
|
||||||
|
|
||||||
|
function! sj#python#SplitStatement()
|
||||||
|
if sj#SearchSkip('^[^:]*\zs:\s*\S', s:skip, 'c', line('.'))
|
||||||
|
call sj#Keeppatterns('s/\%#:\s*/:\r/')
|
||||||
|
normal! ==
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#python#JoinStatement()
|
||||||
|
if sj#SearchSkip(':\s*$', s:skip, 'c', line('.')) > 0
|
||||||
|
join
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#python#SplitDict()
|
||||||
|
let [from, to] = sj#LocateBracesAroundCursor('{', '}', ['pythonString'])
|
||||||
|
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
let pairs = sj#ParseJsonObjectBody(from + 1, to - 1)
|
||||||
|
let body = "{\n".join(pairs, ",\n")."\n}"
|
||||||
|
if sj#settings#Read('trailing_comma')
|
||||||
|
let body = substitute(body, ',\?\n}', ',\n}', '')
|
||||||
|
endif
|
||||||
|
call sj#ReplaceMotion('Va{', body)
|
||||||
|
|
||||||
|
let body_start = line('.') + 1
|
||||||
|
let body_end = body_start + len(pairs)
|
||||||
|
|
||||||
|
let base_indent = indent('.')
|
||||||
|
for line in range(body_start, body_end)
|
||||||
|
if base_indent == indent(line)
|
||||||
|
" then indentation didn't work quite right, let's just indent it
|
||||||
|
" ourselves
|
||||||
|
exe line.'normal! >>>>'
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
exe body_start.','.body_end.'normal! =='
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#python#JoinDict()
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if line =~ '{\s*$'
|
||||||
|
call search('{', 'c', line('.'))
|
||||||
|
let body = sj#GetMotion('Vi{')
|
||||||
|
|
||||||
|
let lines = sj#TrimList(split(body, "\n"))
|
||||||
|
if sj#settings#Read('normalize_whitespace')
|
||||||
|
let lines = map(lines, 'substitute(v:val, ":\\s\\+", ": ", "")')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = join(lines, ' ')
|
||||||
|
if sj#settings#Read('trailing_comma')
|
||||||
|
let body = substitute(body, ',\?$', '', '')
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va{', '{'.body.'}')
|
||||||
|
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#python#SplitArray()
|
||||||
|
return s:SplitList('\[.*]', '[', ']')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#python#JoinArray()
|
||||||
|
return s:JoinList('\[[^]]*\s*$', '[', ']')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#python#SplitTuple()
|
||||||
|
return s:SplitList('(.\{-})', '(', ')')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#python#JoinTuple()
|
||||||
|
return s:JoinList('([^)]*\s*$', '(', ')')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#python#SplitImport()
|
||||||
|
let import_pattern = '^from \%(.*\) import \zs.*$'
|
||||||
|
|
||||||
|
normal! 0
|
||||||
|
if search(import_pattern, 'Wc', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let import_list = sj#GetMotion('vg_')
|
||||||
|
|
||||||
|
if stridx(import_list, ',') < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let imports = split(import_list, ',\s*')
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('vg_', join(imports, ",\\\n"))
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#python#JoinImport()
|
||||||
|
let import_pattern = '^from \%(.*\) import .*\\\s*$'
|
||||||
|
|
||||||
|
if getline('.') !~ import_pattern
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let start_lineno = line('.')
|
||||||
|
let current_lineno = nextnonblank(start_lineno + 1)
|
||||||
|
|
||||||
|
while getline(current_lineno) =~ '\\\s*$' && current_lineno < line('$')
|
||||||
|
let current_lineno = nextnonblank(current_lineno + 1)
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
let end_lineno = current_lineno
|
||||||
|
|
||||||
|
exe start_lineno.','.end_lineno.'s/,\\\n\s*/, /e'
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#python#SplitAssignment()
|
||||||
|
if sj#SearchUnderCursor('^\s*\%(\%(\k\|\.\)\+,\s*\)\+\%(\k\|\.\)\+\s*=\s*\S') <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let variables = split(sj#Trim(sj#GetMotion('vt=')), ',\s*')
|
||||||
|
normal! f=
|
||||||
|
call search('\S', 'W', line('.'))
|
||||||
|
let values = sj#ParseJsonObjectBody(col('.'), col('$'))
|
||||||
|
let indent = substitute(getline('.'), '^\(\s*\).*', '\1', '')
|
||||||
|
|
||||||
|
let lines = []
|
||||||
|
|
||||||
|
if len(variables) == len(values)
|
||||||
|
let index = 0
|
||||||
|
for variable in variables
|
||||||
|
call add(lines, indent.variable.' = '.values[index])
|
||||||
|
let index += 1
|
||||||
|
endfor
|
||||||
|
elseif len(values) == 1
|
||||||
|
" consider it an array, and index it
|
||||||
|
let index = 0
|
||||||
|
let array = values[0]
|
||||||
|
for variable in variables
|
||||||
|
call add(lines, indent.variable.' = '.array.'['.index.']')
|
||||||
|
let index += 1
|
||||||
|
endfor
|
||||||
|
else
|
||||||
|
" the sides don't match, let's give up
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('V', join(lines, "\n"))
|
||||||
|
if sj#settings#Read('align')
|
||||||
|
call sj#Align(line('.'), line('.') + len(lines) - 1, 'equals')
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#python#JoinAssignment()
|
||||||
|
let assignment_pattern = '^\s*\%(\k\|\.\)\+\zs\s*=\s*\ze\S'
|
||||||
|
|
||||||
|
if search(assignment_pattern, 'W', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let start_line = line('.')
|
||||||
|
let [first_variable, first_value] = split(getline('.'), assignment_pattern)
|
||||||
|
let variables = [ first_variable ]
|
||||||
|
let values = [ first_value ]
|
||||||
|
|
||||||
|
let end_line = start_line
|
||||||
|
let next_line = line('.') + 1
|
||||||
|
while next_line > 0 && next_line <= line('$')
|
||||||
|
exe next_line
|
||||||
|
|
||||||
|
if search(assignment_pattern, 'W', line('.')) <= 0
|
||||||
|
break
|
||||||
|
else
|
||||||
|
let [variable, value] = split(getline(next_line), assignment_pattern)
|
||||||
|
call add(variables, sj#Trim(variable))
|
||||||
|
call add(values, sj#Trim(value))
|
||||||
|
let end_line = next_line
|
||||||
|
let next_line += 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if v:count > 0 && v:count == (end_line - start_line + 1)
|
||||||
|
" stop at the user-provided count
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if len(variables) <= 1
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if len(values) > 1 && values[0] =~ '\[0\]$'
|
||||||
|
" it might be an array, so we could simplify it
|
||||||
|
let is_array = 1
|
||||||
|
let index = 1
|
||||||
|
let array_name = substitute(values[0], '\[0\]$', '', '')
|
||||||
|
for value in values[1:]
|
||||||
|
if value !~ '^'.array_name.'\s*\['.index.'\]'
|
||||||
|
let is_array = 0
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
let index += 1
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if is_array
|
||||||
|
" the entire right-hand side can be just one item
|
||||||
|
let values = [ array_name ]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = join(variables, ', ').' = '.join(values, ', ')
|
||||||
|
call sj#ReplaceLines(start_line, end_line, body)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#python#SplitTernaryAssignment()
|
||||||
|
if getline('.') !~ '^\s*\%(\k\|\.\)\+\s*=\s*\S'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! 0
|
||||||
|
let include_syntax = sj#IncludeSyntax(['pythonConditional'])
|
||||||
|
|
||||||
|
if sj#SearchSkip('\<if\>', include_syntax, 'W', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let if_col = col('.')
|
||||||
|
|
||||||
|
if sj#SearchSkip('\<else\>', include_syntax, 'W', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let else_col = col('.')
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
let assignment_if_true = trim(strpart(line, 0, if_col - 1))
|
||||||
|
let if_clause = trim(strpart(line, if_col - 1, else_col - if_col))
|
||||||
|
let body_if_false = trim(strpart(line, else_col + len('else')))
|
||||||
|
|
||||||
|
let assignment_prefix = matchstr(assignment_if_true, '\%(\k\|\.\)\+\s*=')
|
||||||
|
let assignment_if_false = assignment_prefix . ' ' . body_if_false
|
||||||
|
|
||||||
|
let indent = repeat(' ', shiftwidth())
|
||||||
|
let base_indent = repeat(' ', indent(line('.')))
|
||||||
|
|
||||||
|
let body = join([
|
||||||
|
\ base_indent . if_clause . ':',
|
||||||
|
\ base_indent . indent . assignment_if_true,
|
||||||
|
\ base_indent . 'else:',
|
||||||
|
\ base_indent . indent . assignment_if_false,
|
||||||
|
\ ], "\n")
|
||||||
|
call sj#ReplaceMotion('V', body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#python#JoinTernaryAssignment()
|
||||||
|
let include_syntax = sj#IncludeSyntax(['pythonConditional'])
|
||||||
|
let start_lineno = line('.')
|
||||||
|
normal! 0
|
||||||
|
|
||||||
|
if sj#SearchSkip('^\s*\zsif\>', include_syntax, 'Wc', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let if_line = trim(getline('.'))
|
||||||
|
if if_line !~ ':$'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let if_clause = strpart(if_line, 0, len(if_line) - 1)
|
||||||
|
|
||||||
|
if search('^\s*\zs\%(\k\|\.\)\+\s*=\s*\S', 'Wc', line('.') + 1) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let assignment_if_true = trim(getline('.'))
|
||||||
|
let lhs_if_true = matchstr(assignment_if_true, '^\s*\zs\%(\k\|\.\)\+\s*=')
|
||||||
|
let body_if_true = trim(strpart(assignment_if_true, len(lhs_if_true)))
|
||||||
|
|
||||||
|
if sj#SearchSkip('^\s*\zselse:', include_syntax, 'Wc', line('.') + 2) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let else_line = trim(getline('.'))
|
||||||
|
if else_line !~ ':$'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if search('^\s*\zs\%(\k\|\.\)\+\s*=\s*\S', 'Wc', line('.') + 3) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let assignment_if_false = trim(getline('.'))
|
||||||
|
let lhs_if_false = matchstr(assignment_if_false, '^\s*\zs\%(\k\|\.\)\+\s*=')
|
||||||
|
let body_if_false = trim(strpart(assignment_if_false, len(lhs_if_false)))
|
||||||
|
|
||||||
|
if lhs_if_true != lhs_if_false
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = lhs_if_true . ' ' . body_if_true . ' ' . if_clause . ' else ' . body_if_false
|
||||||
|
call sj#ReplaceLines(start_lineno, start_lineno + 3, body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:SplitList(regex, opening_char, closing_char)
|
||||||
|
let [from, to] = sj#LocateBracesAroundCursor(a:opening_char, a:closing_char, ['pythonString'])
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PushCursor()
|
||||||
|
|
||||||
|
let items = sj#ParseJsonObjectBody(from + 1, to - 1)
|
||||||
|
if len(items) <= 1
|
||||||
|
call sj#PopCursor()
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if sj#settings#Read('python_brackets_on_separate_lines')
|
||||||
|
if sj#settings#Read('trailing_comma')
|
||||||
|
let body = a:opening_char."\n".join(items, ",\n").",\n".a:closing_char
|
||||||
|
else
|
||||||
|
let body = a:opening_char."\n".join(items, ",\n")."\n".a:closing_char
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
let body = a:opening_char.join(items, ",\n").a:closing_char
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PopCursor()
|
||||||
|
call sj#ReplaceMotion('va'.a:opening_char, body)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:JoinList(regex, opening_char, closing_char)
|
||||||
|
if sj#SearchUnderCursor(a:regex) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = sj#GetMotion('va'.a:opening_char)
|
||||||
|
let body = substitute(body, '\_s\+', ' ', 'g')
|
||||||
|
let body = substitute(body, '^'.a:opening_char.'\s\+', a:opening_char, '')
|
||||||
|
if sj#settings#Read('trailing_comma')
|
||||||
|
let body = substitute(body, ',\?\s\+'.a:closing_char.'$', a:closing_char, '')
|
||||||
|
else
|
||||||
|
let body = substitute(body, '\s\+'.a:closing_char.'$', a:closing_char, '')
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('va'.a:opening_char, body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#python#SplitListComprehension()
|
||||||
|
for [opening_char, closing_char] in [['(', ')'], ['[', ']'], ['{', '}']]
|
||||||
|
let [from, to] = sj#LocateBracesAroundCursor(opening_char, closing_char, ['pythonString'])
|
||||||
|
if from > 0 && to > 0
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if to - from < 2
|
||||||
|
" empty list
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Start after the opening bracket
|
||||||
|
let pos = getpos('.')
|
||||||
|
let pos[2] = from + 1
|
||||||
|
call setpos('.', pos)
|
||||||
|
|
||||||
|
let break_columns = []
|
||||||
|
let include_syntax = sj#IncludeSyntax(['pythonRepeat', 'pythonConditional'])
|
||||||
|
|
||||||
|
while sj#SearchSkip('\<\%(for\|if\)\>', include_syntax, 'W', line('.')) > 0
|
||||||
|
call add(break_columns, col('.') - from)
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if len(break_columns) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = sj#GetMotion('vi' .. opening_char)
|
||||||
|
let parts = []
|
||||||
|
let last_break = 0
|
||||||
|
|
||||||
|
for break_column in break_columns
|
||||||
|
let part = strpart(body, last_break, break_column - last_break - 1)
|
||||||
|
call add(parts, sj#Trim(part))
|
||||||
|
let last_break = break_column - 1
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let part = strpart(body, last_break, to - last_break - 1)
|
||||||
|
call add(parts, sj#Trim(part))
|
||||||
|
|
||||||
|
if sj#settings#Read('python_brackets_on_separate_lines')
|
||||||
|
let body = opening_char .. "\n" .. join(parts, "\n") .. "\n" .. closing_char
|
||||||
|
else
|
||||||
|
let body = opening_char .. join(parts, "\n") .. closing_char
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('va' .. opening_char, body)
|
||||||
|
return 1
|
||||||
|
endfunction
|
196
bundle/splitjoin.vim/autoload/sj/r.vim
Normal file
196
bundle/splitjoin.vim/autoload/sj/r.vim
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
" Only real syntax that's interesting is cParen and cConditional
|
||||||
|
let s:skip = sj#SkipSyntax(['rComment'])
|
||||||
|
|
||||||
|
" function! sj#r#SplitFuncall()
|
||||||
|
"
|
||||||
|
" Split the R function call if the cursor lies within the arguments of a
|
||||||
|
" function call
|
||||||
|
"
|
||||||
|
function! sj#r#SplitFuncall()
|
||||||
|
if !s:IsValidSelection("va(")
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PushCursor()
|
||||||
|
let items = s:ParseJsonFromMotion("va(\<esc>vi(")
|
||||||
|
let items = map(items, {k, v -> v . (k+1 < len(items) ? "," : "")})
|
||||||
|
|
||||||
|
let r_indent_align_args = get(g:, 'r_indent_align_args', 1)
|
||||||
|
if r_indent_align_args && len(items)
|
||||||
|
let items[0] = "(" . items[0]
|
||||||
|
let items[-1] = items[-1] . ")"
|
||||||
|
let lines = items
|
||||||
|
else
|
||||||
|
let lines = ["("] + items + [")"]
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PopCursor()
|
||||||
|
call s:ReplaceMotionPreserveCursor('va(', lines)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! sj#r#JoinFuncall()
|
||||||
|
"
|
||||||
|
" Join an R function call if the cursor lies within the arguments of a
|
||||||
|
" function call
|
||||||
|
"
|
||||||
|
function! sj#r#JoinFuncall()
|
||||||
|
if !s:IsValidSelection("va(")
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PushCursor()
|
||||||
|
|
||||||
|
let existing_text = sj#GetMotion("va(\<esc>vi(")
|
||||||
|
let items = s:ParseJsonObject(existing_text)
|
||||||
|
let text = join(items, ", ")
|
||||||
|
|
||||||
|
" if replacement wouldn't have any effect, fail to attempt a latter callback
|
||||||
|
if text == existing_text
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PopCursor()
|
||||||
|
call s:ReplaceMotionPreserveCursor("va(", ["(" . text . ")"])
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! sj#r#JoinSmart()
|
||||||
|
"
|
||||||
|
" Reexecute :SplitjoinJoin at the end of the line, where it is more likely
|
||||||
|
" to find a code block relevant to being joined.
|
||||||
|
"
|
||||||
|
function! sj#r#JoinSmart()
|
||||||
|
try
|
||||||
|
call sj#PushCursor()
|
||||||
|
|
||||||
|
let cur_pos = getpos(".")
|
||||||
|
silent normal! $
|
||||||
|
let end_pos = getpos(".")
|
||||||
|
|
||||||
|
if cur_pos[1:2] != end_pos[1:2]
|
||||||
|
execute ":SplitjoinJoin"
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
finally
|
||||||
|
call sj#PopCursor()
|
||||||
|
endtr
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! s:DoMotion(motion)
|
||||||
|
"
|
||||||
|
" Perform a normal-mode motion command
|
||||||
|
"
|
||||||
|
function s:DoMotion(motion)
|
||||||
|
call sj#PushCursor()
|
||||||
|
execute "silent normal! " . a:motion . "\<esc>"
|
||||||
|
execute "silent normal! \<esc>"
|
||||||
|
call sj#PopCursor()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! s:MoveCursor(lines, cols)
|
||||||
|
"
|
||||||
|
" Reposition cursor given relative lines offset and columns from the start of
|
||||||
|
" the line
|
||||||
|
"
|
||||||
|
function! s:MoveCursor(lines, cols)
|
||||||
|
let y = a:lines > 0 ? a:lines . 'j^' : a:lines < 0 ? a:lines . 'k^' : ''
|
||||||
|
let x = a:cols > 0 ? a:cols . 'l' : a:cols < 0 ? a:cols . 'h' : ''
|
||||||
|
let motion = y . x
|
||||||
|
if len(motion)
|
||||||
|
execute 'silent normal! ' . motion
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! s:ParseJsonObject(text)
|
||||||
|
"
|
||||||
|
" Wrapper around sj#argparser#js#Construct to simply parse a given string
|
||||||
|
"
|
||||||
|
function! s:ParseJsonObject(text)
|
||||||
|
let parser = sj#argparser#js#Construct(0, len(a:text), a:text)
|
||||||
|
call parser.Process()
|
||||||
|
return parser.args
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! s:ParseJsonFromMotion(motion)
|
||||||
|
"
|
||||||
|
" Parse a json object from the visual selection of a given normal-mode motion
|
||||||
|
" string
|
||||||
|
"
|
||||||
|
function! s:ParseJsonFromMotion(motion)
|
||||||
|
let text = sj#GetMotion(a:motion)
|
||||||
|
return s:ParseJsonObject(text)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! s:IsValidSelection(motion)
|
||||||
|
"
|
||||||
|
" Test whether a visual selection contains more than a single character after
|
||||||
|
" performing the given normal-mode motion string
|
||||||
|
"
|
||||||
|
function! s:IsValidSelection(motion)
|
||||||
|
call s:DoMotion(a:motion)
|
||||||
|
return getpos("'<") != getpos("'>")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! s:ReplaceMotionPreserveCursor(motion, rep) {{{2
|
||||||
|
"
|
||||||
|
" Replace the normal mode "motion" selection with a list of replacement lines,
|
||||||
|
" "rep", separated by line breaks, Assuming the non-whitespace content of
|
||||||
|
" "motion" is identical to the non-whitespace content of the joined lines of
|
||||||
|
" "rep", the cursor will be repositioned to the resulting location of the
|
||||||
|
" current character under the cursor.
|
||||||
|
"
|
||||||
|
function! s:ReplaceMotionPreserveCursor(motion, rep)
|
||||||
|
" default to interpretting all lines of text as originally from text to replace
|
||||||
|
let rep = a:rep
|
||||||
|
|
||||||
|
" do motion and get bounds & text
|
||||||
|
call s:DoMotion(a:motion)
|
||||||
|
let ini = split(sj#GetByPosition(getpos("'<"), getpos(".")), "\n")
|
||||||
|
let ini = map(ini, {k, v -> sj#Ltrim(v)})
|
||||||
|
|
||||||
|
" do replacement
|
||||||
|
let body = join(a:rep, "\n")
|
||||||
|
call sj#ReplaceMotion(a:motion, body)
|
||||||
|
|
||||||
|
" go back to start of selection
|
||||||
|
silent normal! `<
|
||||||
|
|
||||||
|
" try to reconcile initial selection against replacement lines
|
||||||
|
let [cursory, cursorx, leading_ws] = [0, 0, 0]
|
||||||
|
while len(ini) && len(rep)
|
||||||
|
let i = stridx(ini[0], rep[0])
|
||||||
|
let j = stridx(rep[0], ini[0])
|
||||||
|
if i >= 0
|
||||||
|
" if an entire line of the replacement text found in initial then we'll
|
||||||
|
" need our cursor to move to the next line if more lines are insered
|
||||||
|
let ini[0] = sj#Ltrim(ini[0][i+len(rep[0]):])
|
||||||
|
let cursorx += i + len(rep[0])
|
||||||
|
let ini = len(ini[0]) ? ini : ini[1:]
|
||||||
|
let rep = rep[1:]
|
||||||
|
if len(ini)
|
||||||
|
let cursory += 1
|
||||||
|
let cursorx = 0
|
||||||
|
endif
|
||||||
|
elseif j >= 0
|
||||||
|
" if an entire line of the initial is found in the replacement then
|
||||||
|
" we'll need our cursor to move rightward through length of the initial
|
||||||
|
let rep[0] = rep[0][j+len(ini[0]):]
|
||||||
|
let leading_ws = len(rep[0])
|
||||||
|
let rep[0] = sj#Ltrim(rep[0])
|
||||||
|
let leading_ws = leading_ws - len(rep[0])
|
||||||
|
let cursorx += j + len(ini[0])
|
||||||
|
let ini = ini[1:]
|
||||||
|
let cursorx += (len(ini) && len(ini[0]) ? leading_ws : 0)
|
||||||
|
else
|
||||||
|
let ini = []
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call s:MoveCursor(cursory, max([cursorx-1, 0]))
|
||||||
|
call sj#PushCursor()
|
||||||
|
endfunction
|
1314
bundle/splitjoin.vim/autoload/sj/ruby.vim
Normal file
1314
bundle/splitjoin.vim/autoload/sj/ruby.vim
Normal file
File diff suppressed because it is too large
Load Diff
935
bundle/splitjoin.vim/autoload/sj/rust.vim
Normal file
935
bundle/splitjoin.vim/autoload/sj/rust.vim
Normal file
@ -0,0 +1,935 @@
|
|||||||
|
let s:skip_syntax = sj#SkipSyntax(['String', 'Comment'])
|
||||||
|
let s:eol_pattern = '\s*\%(//.*\)\=$'
|
||||||
|
|
||||||
|
" TODO (2023-02-25) running substitute() on semicolons won't work well for
|
||||||
|
" strings. Need a generic solution, sj#DelimiterOffsets(
|
||||||
|
|
||||||
|
function! sj#rust#SplitMatchExpression()
|
||||||
|
if !sj#SearchUnderCursor('\<match .* {')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#JumpBracketsTill('{', {'opening': '([<"''', 'closing': ')]>"'''})
|
||||||
|
let [from, to] = sj#LocateBracesAroundCursor('{', '}')
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let parser = sj#argparser#rust_struct#Construct(from + 1, to - 1, getline('.'))
|
||||||
|
call parser.Process()
|
||||||
|
let args = parser.args
|
||||||
|
if len(args) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let items = map(args, 'v:val.argument')
|
||||||
|
let body = join(items, ",\n")
|
||||||
|
if sj#settings#Read('trailing_comma')
|
||||||
|
let body .= ','
|
||||||
|
endif
|
||||||
|
let body = "{\n" . body . "\n}"
|
||||||
|
|
||||||
|
call sj#ReplaceCols(from, to, body)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#SplitMatchClause()
|
||||||
|
if !sj#SearchUnderCursor('^.*\s*=>\s*.*$')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !search('=>\s*\zs.', 'W', line('.'))
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let start_col = col('.')
|
||||||
|
if !search(',\='.s:eol_pattern, 'W', line('.'))
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" handle trailing comma if there is one
|
||||||
|
if getline('.')[col('.') - 1] == ','
|
||||||
|
let content_end_col = col('.')
|
||||||
|
let body_end_col = content_end_col - 1
|
||||||
|
else
|
||||||
|
let content_end_col = col('.')
|
||||||
|
let body_end_col = content_end_col
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = sj#Trim(sj#GetCols(start_col, body_end_col))
|
||||||
|
if body =~ '[({[.,*/%+-]$'
|
||||||
|
" ends in an opening bracket or operator of some sorts, so it's
|
||||||
|
" incomplete, don't touch it
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = substitute(body, '^{\s*\(.\{-}\)\s*}$', '\1', '')
|
||||||
|
call sj#ReplaceCols(start_col, content_end_col, "{\n".body."\n},")
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#JoinMatchClause()
|
||||||
|
if !sj#SearchUnderCursor('^.*\s*=>\s*{\s*$')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call search('=>\s*\zs{', 'W', line('.'))
|
||||||
|
|
||||||
|
let body = sj#Trim(sj#GetMotion('Vi{'))
|
||||||
|
if stridx(body, "\n") >= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if len(body) == 0
|
||||||
|
call sj#ReplaceMotion('va{', '{}')
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Remove semicolons when joining, they don't work in non-block form
|
||||||
|
if body[len(body) - 1] == ';'
|
||||||
|
let body = body[0 : len(body) - 2]
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va{', body)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#SplitQuestionMark()
|
||||||
|
if sj#SearchSkip('.?', s:skip_syntax, 'Wc', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let current_line = line('.')
|
||||||
|
let end_col = col('.')
|
||||||
|
let question_mark_col = col('.') + 1
|
||||||
|
let char = getline('.')[end_col - 1]
|
||||||
|
|
||||||
|
let previous_start_col = -2
|
||||||
|
let start_col = -1
|
||||||
|
|
||||||
|
while previous_start_col != start_col
|
||||||
|
let previous_start_col = start_col
|
||||||
|
|
||||||
|
if char =~ '\k'
|
||||||
|
call search('\k\+?;', 'bWc', line('.'))
|
||||||
|
let start_col = col('.')
|
||||||
|
elseif char == '}'
|
||||||
|
" go to opening bracket
|
||||||
|
normal! %
|
||||||
|
let start_col = col('.')
|
||||||
|
elseif char == ')'
|
||||||
|
" go to opening bracket
|
||||||
|
normal! %
|
||||||
|
" find first method-call char
|
||||||
|
call search('\%(\k\|\.\|::\)\+!\?(', 'bWc')
|
||||||
|
|
||||||
|
if line('.') != current_line
|
||||||
|
" multiline expression, let's just ignore it
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let start_col = col('.')
|
||||||
|
else
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
|
||||||
|
if start_col <= 1
|
||||||
|
" first character, no previous one
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
|
||||||
|
" move backwards one step from the start
|
||||||
|
let pos = getpos('.')
|
||||||
|
let pos[2] = start_col - 1
|
||||||
|
call setpos('.', pos)
|
||||||
|
let char = getline('.')[col('.') - 1]
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" is it a Result, or an Option?
|
||||||
|
let expr_type = s:FunctionReturnType()
|
||||||
|
" default to a Result, if we can't find anything
|
||||||
|
if expr_type == ''
|
||||||
|
let expr_type = 'Result'
|
||||||
|
endif
|
||||||
|
let expr = sj#GetCols(start_col, end_col)
|
||||||
|
|
||||||
|
if expr_type == 'Result'
|
||||||
|
let replacement = join([
|
||||||
|
\ "match ".expr." {",
|
||||||
|
\ " Ok(value) => value,",
|
||||||
|
\ " Err(e) => return Err(e.into()),",
|
||||||
|
\ "}"
|
||||||
|
\ ], "\n")
|
||||||
|
elseif expr_type == 'Option'
|
||||||
|
let replacement = join([
|
||||||
|
\ "match ".expr." {",
|
||||||
|
\ " None => return None,",
|
||||||
|
\ " Some(value) => value,",
|
||||||
|
\ "}"
|
||||||
|
\ ], "\n")
|
||||||
|
else
|
||||||
|
echoerr "Unknown expr_type: ".expr_type
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceCols(start_col, question_mark_col, replacement)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#JoinMatchStatement()
|
||||||
|
let match_pattern = '\<match .* {$'
|
||||||
|
|
||||||
|
if sj#SearchSkip(match_pattern, s:skip_syntax, 'Wc', line('.')) <= 0
|
||||||
|
\ && sj#SearchSkip(match_pattern, s:skip_syntax, 'Wbc', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" is it a Result, or an Option?
|
||||||
|
let return_type = s:FunctionReturnType()
|
||||||
|
|
||||||
|
let match_position = getpos('.')
|
||||||
|
let match_line = match_position[1]
|
||||||
|
let match_col = match_position[2]
|
||||||
|
|
||||||
|
let remainder_of_line = strpart(getline('.'), match_col - 1)
|
||||||
|
let expr = substitute(remainder_of_line, '^match \(.*\) {$', '\1', '')
|
||||||
|
|
||||||
|
let first_line = match_line + 1
|
||||||
|
let second_line = match_line + 2
|
||||||
|
let closing_line = match_line + 3
|
||||||
|
|
||||||
|
let ok_pattern = '^\s*Ok(\(\k\+\))\s*=>\s*\1'
|
||||||
|
let err_pattern = '^\s*Err(\k\+)\s*=>\s*return\s\+Err('
|
||||||
|
let some_pattern = '^\s*Some(\(\k\+\))\s*=>\s*\1'
|
||||||
|
let none_pattern = '^\s*None\s*=>\s*return\s\+None\>'
|
||||||
|
|
||||||
|
if getline(first_line) =~# ok_pattern || getline(second_line) =~# ok_pattern
|
||||||
|
let expr_type = 'Result'
|
||||||
|
elseif getline(first_line) =~# none_pattern || getline(second_line) =~# none_pattern
|
||||||
|
let expr_type = 'Option'
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if getline(second_line) =~# err_pattern || getline(first_line) =~# err_pattern
|
||||||
|
let expr_type = 'Result'
|
||||||
|
elseif getline(second_line) =~# some_pattern || getline(first_line) =~# some_pattern
|
||||||
|
let expr_type = 'Option'
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if search('^\s*}\ze', 'We', closing_line) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let end_position = getpos('.')
|
||||||
|
|
||||||
|
if expr_type == return_type
|
||||||
|
call sj#ReplaceByPosition(match_position, end_position, expr.'?')
|
||||||
|
else
|
||||||
|
call sj#ReplaceByPosition(match_position, end_position, expr.'.unwrap()')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#SplitBlockClosure()
|
||||||
|
if sj#SearchUnderCursor('|.\{-}|\s*\zs{', 'Wc', s:skip_syntax, line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let closure_contents = sj#GetMotion('vi{')
|
||||||
|
let closure_contents = substitute(closure_contents, ';\ze.', ";\n", 'g')
|
||||||
|
call sj#ReplaceMotion('va{', "{\n".sj#Trim(closure_contents)."\n}")
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#SplitExprClosure()
|
||||||
|
if !sj#SearchUnderCursor('|.\{-}| [^{]')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
if search('|.\{-}| \zs.', 'W', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let start_col = col('.')
|
||||||
|
let end_col = sj#JumpBracketsTill('\%([,;]\|$\)', {'opening': '([<{"''', 'closing': ')]>}"'''})
|
||||||
|
if end_col == col('$')
|
||||||
|
" found end-of-line, one character past the actual end
|
||||||
|
let end_col -= 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let closure_contents = sj#GetCols(start_col, end_col)
|
||||||
|
if closure_contents =~ '[({[.,*/%+-]$'
|
||||||
|
" ends in an opening bracket or operator of some sorts, so it's
|
||||||
|
" incomplete, don't touch it
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceCols(start_col, end_col, "{\n".closure_contents."\n}")
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#JoinClosure()
|
||||||
|
if !sj#SearchUnderCursor('|.\{-}| {\s*$')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
if search('|.\{-}| \zs{\s*$', 'W', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" check if we've got an empty block:
|
||||||
|
if sj#GetMotion('va{') =~ '^{\_s*}$'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let closure_contents = sj#Trim(sj#GetMotion('vi{'))
|
||||||
|
let lines = sj#TrimList(split(closure_contents, "\n"))
|
||||||
|
|
||||||
|
if len(lines) > 1
|
||||||
|
let replacement = '{ '.join(lines, ' ').' }'
|
||||||
|
elseif len(lines) == 1
|
||||||
|
let replacement = lines[0]
|
||||||
|
else
|
||||||
|
" No contents, leave nothing inside
|
||||||
|
let replacement = ' '
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('va{', replacement)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#SplitCurlyBrackets()
|
||||||
|
" in case we're on a struct name, go to the bracket:
|
||||||
|
call sj#SearchUnderCursor('\k\+\s*{', 'e')
|
||||||
|
" in case we're in an if-clause, go to the bracket:
|
||||||
|
call sj#SearchUnderCursor('\<if .\{-}{', 'e')
|
||||||
|
|
||||||
|
let [from, to] = sj#LocateBracesAroundCursor('{', '}')
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (to - from) < 2
|
||||||
|
call sj#ReplaceMotion('va{', "{\n\n}")
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = sj#Trim(sj#GetCols(from + 1, to - 1))
|
||||||
|
if len(body) == 0
|
||||||
|
call sj#ReplaceMotion('va{', "{\n\n}")
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let prefix = sj#GetCols(0, from - 1)
|
||||||
|
let indent = indent(line('.')) + (exists('*shiftwidth') ? shiftwidth() : &sw)
|
||||||
|
|
||||||
|
let parser = sj#argparser#rust_struct#Construct(from + 1, to - 1, getline('.'))
|
||||||
|
call parser.Process()
|
||||||
|
let args = parser.args
|
||||||
|
if len(args) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if prefix =~ '^\s*use\s\+\%(\k\+::\)\+\s*$'
|
||||||
|
" then it's a module import:
|
||||||
|
" use my_mod::{Alpha, Beta as _, Gamma};
|
||||||
|
let imports = map(args, 'v:val.argument')
|
||||||
|
let body = join(imports, ",\n")
|
||||||
|
if sj#settings#Read('trailing_comma')
|
||||||
|
let body .= ','
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceCols(from, to, "{\n".body."\n}")
|
||||||
|
elseif parser.IsValidStruct()
|
||||||
|
let is_only_pairs = parser.IsOnlyStructPairs()
|
||||||
|
|
||||||
|
let items = []
|
||||||
|
let last_arg = ''
|
||||||
|
for arg in args
|
||||||
|
let last_arg = arg.argument
|
||||||
|
|
||||||
|
" attributes are not indented, so let's give them appropriate whitespace
|
||||||
|
let whitespace = repeat(' ', indent)
|
||||||
|
let components = map(copy(arg.attributes), 'whitespace.v:val')
|
||||||
|
|
||||||
|
call add(components, arg.argument)
|
||||||
|
call add(items, join(components, "\n"))
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let body = join(items, ",\n")
|
||||||
|
if sj#settings#Read('trailing_comma')
|
||||||
|
if last_arg =~ '^\.\.'
|
||||||
|
" interpolated struct, a trailing comma would be invalid
|
||||||
|
else
|
||||||
|
let body .= ','
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceCols(from, to, "{\n".body."\n}")
|
||||||
|
|
||||||
|
if is_only_pairs && sj#settings#Read('align')
|
||||||
|
let body_start = line('.') + 1
|
||||||
|
let body_end = body_start + len(items) - 1
|
||||||
|
|
||||||
|
if items[-1] =~ '^\.\.'
|
||||||
|
" interpolated struct, don't align that one
|
||||||
|
let body_end -= 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if body_end - body_start > 0
|
||||||
|
call sj#Align(body_start, body_end, 'json_object')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
" it's just a normal block, ignore the parsed content
|
||||||
|
let body = substitute(body, ';\ze.', ";\n", 'g')
|
||||||
|
call sj#ReplaceCols(from, to, "{\n".body."\n}")
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#JoinCurlyBrackets()
|
||||||
|
let line = getline('.')
|
||||||
|
if line !~ '{\s*$'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
call search('{', 'c', line('.'))
|
||||||
|
|
||||||
|
if eval(s:skip_syntax)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" check if we've got an empty block:
|
||||||
|
if sj#GetMotion('va{') =~ '^{\_s*}$'
|
||||||
|
call sj#ReplaceMotion('va{', '{}')
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = sj#GetMotion('Vi{')
|
||||||
|
let lines = split(body, "\n")
|
||||||
|
let lines = sj#TrimList(lines)
|
||||||
|
|
||||||
|
let body = join(lines, ' ')
|
||||||
|
" just in case we're joining a StructName { key: value, }:
|
||||||
|
let body = substitute(body, ',$', '', '')
|
||||||
|
|
||||||
|
let in_import = 0
|
||||||
|
if line =~ '^\s*use\s\+\%(\k\+::\)\+\s*{$'
|
||||||
|
let in_import = 1
|
||||||
|
endif
|
||||||
|
if !in_import
|
||||||
|
let pos = getpos('.')
|
||||||
|
|
||||||
|
" we might still be in a nested import, let's see if we can find it
|
||||||
|
while searchpair('{', '', '}', 'Wb', s:skip_syntax, 0, 100) > 0
|
||||||
|
if getline('.') =~ '^\s*use\s\+\%(\k\+::\)\+\s*{$'
|
||||||
|
let in_import = 1
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call setpos('.', pos)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if in_import
|
||||||
|
let body = '{'.body.'}'
|
||||||
|
elseif sj#settings#Read('curly_brace_padding')
|
||||||
|
let body = '{ '.body.' }'
|
||||||
|
else
|
||||||
|
let body = '{'.body.'}'
|
||||||
|
endif
|
||||||
|
|
||||||
|
if sj#settings#Read('normalize_whitespace')
|
||||||
|
let body = substitute(body, '\s\+\k\+\zs:\s\+', ': ', 'g')
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va{', body)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#SplitUnwrapIntoEmptyMatch()
|
||||||
|
let unwrap_pattern = '\S\.\%(unwrap\|expect\)('
|
||||||
|
if sj#SearchUnderCursor(unwrap_pattern, 'e', s:skip_syntax) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal! %
|
||||||
|
let unwrap_end_col = col('.')
|
||||||
|
normal! %
|
||||||
|
call search(unwrap_pattern, 'Wb', line('.'))
|
||||||
|
let end_col = col('.')
|
||||||
|
|
||||||
|
let start_col = col('.')
|
||||||
|
while start_col > 0
|
||||||
|
let current_expr = strpart(getline('.'), start_col - 1, end_col)
|
||||||
|
if current_expr =~ '^)'
|
||||||
|
normal! %
|
||||||
|
elseif current_expr =~ '^\%(::\|\.\)'
|
||||||
|
normal! h
|
||||||
|
else
|
||||||
|
if sj#SearchSkip('\%(::\|\.\)\=\k\+\%#', s:skip_syntax, 'Wb', line('.')) <= 0
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if start_col == col('.')
|
||||||
|
" then nothing has changed this loop, break out
|
||||||
|
break
|
||||||
|
else
|
||||||
|
let start_col = col('.')
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
let expr = sj#GetCols(start_col, end_col)
|
||||||
|
if expr == ''
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if start_col >= end_col
|
||||||
|
" the expression is probably split into several lines, let's ignore it
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceCols(start_col, unwrap_end_col, join([
|
||||||
|
\ "match ".expr." {",
|
||||||
|
\ "",
|
||||||
|
\ "}",
|
||||||
|
\ ], "\n"))
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#SplitIfLetIntoMatch()
|
||||||
|
let if_let_pattern = 'if\s\+let\s\+\(.*\)\s\+=\s\+\(.\{-}\)\s*{'
|
||||||
|
let else_pattern = '}\s\+else\s\+{'
|
||||||
|
|
||||||
|
if search(if_let_pattern, 'We', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let match_line = substitute(getline('.'), if_let_pattern, "match \\2 {\n\\1 => {", '')
|
||||||
|
let body = sj#Trim(sj#GetMotion('vi{'))
|
||||||
|
|
||||||
|
" multiple lines or ends with `;` -> wrap it in a block
|
||||||
|
if len(split(body, "\n")) > 1 || body =~ ';'.s:eol_pattern
|
||||||
|
let body = "{\n".body."\n}"
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Is there an else clause?
|
||||||
|
call sj#PushCursor()
|
||||||
|
let else_body = '()'
|
||||||
|
normal! %
|
||||||
|
if search(else_pattern, 'We', line('.')) > 0
|
||||||
|
let else_body = sj#Trim(sj#GetMotion('vi{'))
|
||||||
|
|
||||||
|
" multiple lines or ends with `;` -> wrap it in a block
|
||||||
|
if len(split(else_body, "\n")) > 1 || else_body =~ ';'.s:eol_pattern
|
||||||
|
let else_body = "{\n".else_body."\n}"
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Delete block, delete rest of line:
|
||||||
|
normal! "_da{T}"_D
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Back to the if-let line:
|
||||||
|
call sj#PopCursor()
|
||||||
|
call sj#ReplaceMotion('V', match_line)
|
||||||
|
normal! j$
|
||||||
|
call sj#ReplaceMotion('Va{', body.",\n_ => ".else_body.",\n}")
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#SplitArgs()
|
||||||
|
return s:SplitList(['(', ')'], 'cursor_on_line')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#SplitArray()
|
||||||
|
return s:SplitList(['[', ']'], 'cursor_inside')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#JoinEmptyMatchIntoIfLet()
|
||||||
|
let match_pattern = '\<match\s\+\zs.\{-}\ze\s\+{$'
|
||||||
|
let pattern_pattern = '^\s*\zs.\{-}\ze\s\+=>'
|
||||||
|
|
||||||
|
if search(match_pattern, 'Wc', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let outer_start_lineno = line('.')
|
||||||
|
let [_, match_start_col] = searchpos('\<match\s\+', 'nbW', line('.'))
|
||||||
|
|
||||||
|
" find end point
|
||||||
|
normal! f{%
|
||||||
|
let outer_end_lineno = line('.')
|
||||||
|
|
||||||
|
let inner_start_lineno = search(pattern_pattern, 'Wb', outer_start_lineno)
|
||||||
|
if inner_start_lineno <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let inner_start_lineno = line('.')
|
||||||
|
if getline(inner_start_lineno) =~ '^\s*_\s*=>'
|
||||||
|
" it's a default match, ignore this one for now
|
||||||
|
let inner_start_lineno = search(pattern_pattern, 'Wb', outer_start_lineno)
|
||||||
|
if inner_start_lineno <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if getline(inner_start_lineno) =~ '^\s*_\s*=>'
|
||||||
|
" more than one _ => clause?
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if getline(inner_start_lineno) =~ '{,\=\s*$'
|
||||||
|
" it's a block, mark its area:
|
||||||
|
exe inner_start_lineno
|
||||||
|
normal! 0f{%
|
||||||
|
let inner_end_lineno = line('.')
|
||||||
|
else
|
||||||
|
" not a }, so just one line
|
||||||
|
let inner_end_lineno = inner_start_lineno
|
||||||
|
endif
|
||||||
|
|
||||||
|
if prevnonblank(inner_start_lineno - 1) != outer_start_lineno
|
||||||
|
" the inner start is not immediately after the outer start
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let match_value = sj#Trim(matchstr(getline(outer_start_lineno), match_pattern))
|
||||||
|
let match_pattern = sj#Trim(matchstr(getline(inner_start_lineno), pattern_pattern))
|
||||||
|
|
||||||
|
" currently on inner start, so let's take its contents:
|
||||||
|
if inner_start_lineno == inner_end_lineno
|
||||||
|
" one-line body, take everything up to the comma
|
||||||
|
exe inner_start_lineno
|
||||||
|
let body = substitute(getline('.'), '^\s*.\{-}\s\+=>\s*\(.\{-}\),\=\s*$', '\1', '')
|
||||||
|
else
|
||||||
|
" block body, take everything inside
|
||||||
|
let body = sj#Trim(sj#GetMotion('vi{'))
|
||||||
|
endif
|
||||||
|
|
||||||
|
" look for an else clause
|
||||||
|
call sj#PushCursor()
|
||||||
|
exe outer_start_lineno
|
||||||
|
let else_body = ''
|
||||||
|
if search('^\s*_\s*=>\s*\zs\S', 'W', outer_end_lineno) > 0
|
||||||
|
let fallback_value = strpart(getline('.'), col('.') - 1)
|
||||||
|
|
||||||
|
if fallback_value =~ '^(\s*)\|^{\s*}'
|
||||||
|
" ignore it
|
||||||
|
elseif fallback_value =~ '^{'
|
||||||
|
" the else-clause is going to be in a block
|
||||||
|
let else_body = sj#Trim(sj#GetMotion('vi{'))
|
||||||
|
else
|
||||||
|
" one-line value, remove its trailing comma and any comments
|
||||||
|
let else_body = substitute(fallback_value, ','.s:eol_pattern, '', '')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#PopCursor()
|
||||||
|
|
||||||
|
" jump on outer start
|
||||||
|
exe outer_start_lineno
|
||||||
|
call sj#ReplaceCols(match_start_col, col('$'), 'if let '.match_pattern.' = '.match_value." {\n")
|
||||||
|
normal! $
|
||||||
|
call sj#ReplaceMotion('va{', "{\n".body."\n}")
|
||||||
|
|
||||||
|
if else_body != ''
|
||||||
|
normal! 0f{%
|
||||||
|
call sj#ReplaceMotion('V', "} else {\n".else_body."\n}")
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#SplitImportList()
|
||||||
|
if sj#SearchUnderCursor('^\s*use\s\+\%(\k\+::\)\+{', 'e') <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let prefix = sj#Trim(strpart(getline('.'), 0, col('.') - 1))
|
||||||
|
let body = sj#GetMotion('vi{')
|
||||||
|
let parser = sj#argparser#rust_struct#Construct(1, len(body), body)
|
||||||
|
|
||||||
|
call parser.Process()
|
||||||
|
|
||||||
|
let expanded_imports = []
|
||||||
|
for arg in parser.args
|
||||||
|
let import = arg.argument
|
||||||
|
|
||||||
|
if import == 'self'
|
||||||
|
let expanded_import = substitute(prefix, '::$', ';', '')
|
||||||
|
else
|
||||||
|
let expanded_import = prefix . import . ';'
|
||||||
|
end
|
||||||
|
|
||||||
|
call add(expanded_imports, expanded_import)
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if len(expanded_imports) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let attributes = s:GetLineAttributes(line('.'))
|
||||||
|
|
||||||
|
if len(attributes) > 0
|
||||||
|
let attribute_block = join(attributes, "\n")
|
||||||
|
let expanded_imports = [expanded_imports[0]] + map(expanded_imports[1:-1], 'attribute_block . "\n" . v:val')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let replacement = join(expanded_imports, "\n")
|
||||||
|
if body =~ '\n'
|
||||||
|
" Select a multiline area
|
||||||
|
call sj#ReplaceMotion('va{$o0', replacement . "\n")
|
||||||
|
else
|
||||||
|
call sj#ReplaceMotion('V', replacement)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#JoinImportList()
|
||||||
|
let import_pattern = '^\s*use\s\+\%(\k\+::\)\+'
|
||||||
|
let attribute_pattern = '^\s*#['
|
||||||
|
|
||||||
|
if sj#SearchUnderCursor(import_pattern) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let first_import = getline('.')
|
||||||
|
let first_import = substitute(first_import, ';'.s:eol_pattern, '', '')
|
||||||
|
let imports = [sj#Trim(first_import)]
|
||||||
|
|
||||||
|
let start_line = line('.')
|
||||||
|
let last_line = line('.')
|
||||||
|
let attributes = s:GetLineAttributes(start_line)
|
||||||
|
|
||||||
|
" If there's no attributes, get the next line, otherwise skip the attribute
|
||||||
|
" lines
|
||||||
|
exe 'normal! ' . (len(attributes) + 1) . 'j'
|
||||||
|
|
||||||
|
while sj#SearchUnderCursor(import_pattern) > 0
|
||||||
|
if line('.') == last_line
|
||||||
|
" we haven't moved, stop here
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
|
||||||
|
let local_attributes = s:GetLineAttributes(line('.'))
|
||||||
|
if local_attributes != attributes
|
||||||
|
" This import is not compatible, stop here
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
|
||||||
|
let last_line = line('.')
|
||||||
|
|
||||||
|
let import_line = getline('.')
|
||||||
|
let import_line = substitute(import_line, ';'.s:eol_pattern, '', '')
|
||||||
|
|
||||||
|
call add(imports, sj#Trim(import_line))
|
||||||
|
exe 'normal! ' . (len(attributes) + 1) . 'j'
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if len(imports) <= 1
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" find common prefix based on first two imports
|
||||||
|
let first_prefix_parts = split(imports[0], '::')
|
||||||
|
let second_prefix_parts = split(imports[1], '::')
|
||||||
|
|
||||||
|
if first_prefix_parts[0] != second_prefix_parts[0]
|
||||||
|
" no match at all, nothing we can do
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" find only the next ones that match the common prefix
|
||||||
|
let common_prefix = ''
|
||||||
|
for i in range(1, min([len(first_prefix_parts), len(second_prefix_parts)]) - 1)
|
||||||
|
if first_prefix_parts[i] != second_prefix_parts[i]
|
||||||
|
let common_prefix = join(first_prefix_parts[:(i - 1)], '::')
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if common_prefix == ''
|
||||||
|
if len(imports[0]) > len(imports[1])
|
||||||
|
let longer_import = imports[0]
|
||||||
|
let shorter_import = imports[1]
|
||||||
|
else
|
||||||
|
let longer_import = imports[1]
|
||||||
|
let shorter_import = imports[0]
|
||||||
|
endif
|
||||||
|
|
||||||
|
" it hasn't been changed, meaning we completely matched the shorter import
|
||||||
|
" within the longer.
|
||||||
|
if longer_import == shorter_import
|
||||||
|
" they're perfectly identical, just delete the first line and move on
|
||||||
|
exe start_line . 'delete'
|
||||||
|
return 1
|
||||||
|
elseif stridx(longer_import, shorter_import) == 0
|
||||||
|
" the shorter is included, consider it a prefix, and we'll puts `self`
|
||||||
|
" in there later
|
||||||
|
let common_prefix = shorter_import
|
||||||
|
else
|
||||||
|
" something unexpected went wrong, let's give up
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
let compatible_imports = imports[:1]
|
||||||
|
for import in imports[2:]
|
||||||
|
if stridx(import, common_prefix) == 0
|
||||||
|
call add(compatible_imports, import)
|
||||||
|
else
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
" Get the differences between the imports
|
||||||
|
let differences = []
|
||||||
|
for import in compatible_imports
|
||||||
|
let difference = strpart(import, len(common_prefix))
|
||||||
|
let difference = substitute(difference, '^::', '', '')
|
||||||
|
|
||||||
|
if difference =~ '^{.*}$'
|
||||||
|
" there's a list of imports, merge them together
|
||||||
|
let parser = sj#argparser#rust_struct#Construct(2, len(difference) - 1, difference)
|
||||||
|
call parser.Process()
|
||||||
|
for part in map(parser.args, 'v:val.argument')
|
||||||
|
call add(differences, part)
|
||||||
|
endfor
|
||||||
|
elseif len(difference) == 0
|
||||||
|
" this is the parent module
|
||||||
|
call add(differences, 'self')
|
||||||
|
else
|
||||||
|
call add(differences, difference)
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if exists('*uniq')
|
||||||
|
" remove successive duplicates
|
||||||
|
call uniq(differences)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let replacement = common_prefix . '::{' . join(differences, ', ') . '};'
|
||||||
|
|
||||||
|
let attribute_line_count = (len(compatible_imports) - 1) * len(attributes)
|
||||||
|
let end_line = start_line + len(compatible_imports) + attribute_line_count - 1
|
||||||
|
|
||||||
|
call sj#ReplaceLines(start_line, end_line, replacement)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#JoinArgs()
|
||||||
|
return s:JoinList(['(', ')'])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#rust#JoinArray()
|
||||||
|
return s:JoinList(['[', ']'])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:FunctionReturnType()
|
||||||
|
let found_result = search(')\_s\+->\_s\+\%(\k\|::\)*Result\>', 'Wbn')
|
||||||
|
let found_option = search(')\_s\+->\_s\+\%(\k\|::\)*Option\>', 'Wbn')
|
||||||
|
|
||||||
|
if found_result <= 0 && found_option <= 0
|
||||||
|
return ''
|
||||||
|
elseif found_result > found_option
|
||||||
|
return 'Result'
|
||||||
|
elseif found_option > found_result
|
||||||
|
return 'Option'
|
||||||
|
else
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function s:GetLineAttributes(line)
|
||||||
|
let end_line = prevnonblank(a:line - 1)
|
||||||
|
|
||||||
|
if getline(end_line) !~ '^\s*#['
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
|
||||||
|
let start_line = end_line
|
||||||
|
let tested_line = start_line
|
||||||
|
|
||||||
|
while getline(tested_line) =~ '^\s*#['
|
||||||
|
let start_line = tested_line
|
||||||
|
let tested_line = prevnonblank(tested_line - 1)
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
return getline(start_line, end_line)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:SplitList(delimiter, cursor_position)
|
||||||
|
let start = a:delimiter[0]
|
||||||
|
let end = a:delimiter[1]
|
||||||
|
|
||||||
|
let lineno = line('.')
|
||||||
|
let indent = indent('.')
|
||||||
|
|
||||||
|
if a:cursor_position == 'cursor_inside'
|
||||||
|
let [from, to] = sj#LocateBracesAroundCursor(start, end)
|
||||||
|
elseif a:cursor_position == 'cursor_on_line'
|
||||||
|
let [from, to] = sj#LocateBracesOnLine(start, end)
|
||||||
|
else
|
||||||
|
echoerr "Invalid value for a:cursor_position: ".a:cursor_position
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if from < 0 && to < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if start == '(' && from > 1 && strpart(line, 0, from - 1) =~ '\<fn \k\+\%(<.*>\)$'
|
||||||
|
let parser_type = 'fn'
|
||||||
|
else
|
||||||
|
let parser_type = 'list'
|
||||||
|
endif
|
||||||
|
|
||||||
|
let parser = sj#argparser#rust_list#Construct(parser_type, from + 1, to - 1, line)
|
||||||
|
call parser.Process()
|
||||||
|
let items = parser.args
|
||||||
|
if empty(items)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if sj#settings#Read('trailing_comma')
|
||||||
|
let body = start."\n".join(items, ",\n").",\n".end
|
||||||
|
else
|
||||||
|
let body = start."\n".join(items, ",\n")."\n".end
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va'.start, body)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:JoinList(delimiter)
|
||||||
|
let start = a:delimiter[0]
|
||||||
|
let end = a:delimiter[1]
|
||||||
|
|
||||||
|
let line = getline('.')
|
||||||
|
|
||||||
|
if line !~ start . '\s*$'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call search(start, 'c', line('.'))
|
||||||
|
let body = sj#GetMotion('Vi'.start)
|
||||||
|
|
||||||
|
let lines = split(body, "\n")
|
||||||
|
let lines = sj#TrimList(lines)
|
||||||
|
let body = sj#Trim(join(lines, ' '))
|
||||||
|
let body = substitute(body, ',\s*$', '', '')
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va'.start, start.body.end)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
68
bundle/splitjoin.vim/autoload/sj/scss.vim
Normal file
68
bundle/splitjoin.vim/autoload/sj/scss.vim
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
function! sj#scss#SplitNestedDefinition()
|
||||||
|
if search('{\s*$', 'Wn', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if search('\s\zs\S\+', 'Wbc', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let prefix = sj#Trim(strpart(getline('.'), 0, col('.') - 2))
|
||||||
|
let suffix = sj#Trim(strpart(getline('.'), col('.') - 2, col('$')))
|
||||||
|
let suffix = substitute(suffix, '\s*{$', '', '')
|
||||||
|
|
||||||
|
if prefix == '' || suffix == ''
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('V', prefix.' {')
|
||||||
|
normal! f{
|
||||||
|
let body = sj#GetMotion('vi{')
|
||||||
|
call sj#ReplaceMotion('vi{', suffix." {\n".body."}\n")
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#scss#JoinNestedDefinition()
|
||||||
|
if search('{\s*$', 'We', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let outer_start_lineno = line('.')
|
||||||
|
|
||||||
|
" find end point
|
||||||
|
normal! %
|
||||||
|
let outer_end_lineno = line('.')
|
||||||
|
let inner_end_lineno = prevnonblank(outer_end_lineno - 1)
|
||||||
|
if inner_end_lineno == 0
|
||||||
|
" No inner end } found
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
if getline(inner_end_lineno) !~ '^\s*}\s*$'
|
||||||
|
" not a } character
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
exe inner_end_lineno
|
||||||
|
normal! 0f}%
|
||||||
|
let inner_start_lineno = line('.')
|
||||||
|
|
||||||
|
if prevnonblank(inner_start_lineno - 1) != outer_start_lineno
|
||||||
|
" the inner start is not immediately after the outer start
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let outer_definition = sj#Trim(substitute(getline(outer_start_lineno), '{\s*$', '', ''))
|
||||||
|
let inner_definition = sj#Trim(substitute(getline(inner_start_lineno), '{\s*$', '', ''))
|
||||||
|
|
||||||
|
" currently on inner start, so let's take its contents:
|
||||||
|
let body = sj#Trim(sj#GetMotion('vi{'))
|
||||||
|
|
||||||
|
" jump on outer start
|
||||||
|
exe outer_start_lineno
|
||||||
|
call sj#ReplaceMotion('V', outer_definition.' '.inner_definition. ' {')
|
||||||
|
normal! 0f{
|
||||||
|
call sj#ReplaceMotion('va{', "{\n".body."\n}")
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
37
bundle/splitjoin.vim/autoload/sj/settings.vim
Normal file
37
bundle/splitjoin.vim/autoload/sj/settings.vim
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
" This function accepts multiple option names and returns the value of the
|
||||||
|
" first one that is set. It respects buffer-local values before global ones,
|
||||||
|
" so:
|
||||||
|
"
|
||||||
|
" sj#settings#Read('option_foo', 'option_bar')
|
||||||
|
"
|
||||||
|
" would read the values of, in sequence:
|
||||||
|
"
|
||||||
|
" - b:splitjoin_option_foo
|
||||||
|
" - g:splitjoin_option_foo
|
||||||
|
" - b:splitjoin_option_bar
|
||||||
|
" - g:splitjoin_option_bar
|
||||||
|
"
|
||||||
|
" and return the first one that exists. If none exist, it reads the default
|
||||||
|
" value, if one is set in `g:splitjoin_default_settings`
|
||||||
|
"
|
||||||
|
function! sj#settings#Read(...)
|
||||||
|
let options = a:000
|
||||||
|
|
||||||
|
for option in options
|
||||||
|
if exists('b:splitjoin_'.option)
|
||||||
|
return b:['splitjoin_'.option]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if exists('g:splitjoin_'.option)
|
||||||
|
return g:['splitjoin_'.option]
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
for option in options
|
||||||
|
if has_key(g:splitjoin_default_settings, option)
|
||||||
|
return g:splitjoin_default_settings[option]
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return 0
|
||||||
|
endfunction
|
40
bundle/splitjoin.vim/autoload/sj/sh.vim
Normal file
40
bundle/splitjoin.vim/autoload/sj/sh.vim
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
function! sj#sh#SplitBySemicolon()
|
||||||
|
let line = getline('.')
|
||||||
|
let parser = sj#argparser#sh#Construct(0, col('$'), line)
|
||||||
|
call parser.Process()
|
||||||
|
|
||||||
|
if len(parser.args) <= 1
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let body = join(parser.args, "\n")
|
||||||
|
call sj#ReplaceMotion('V', body)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#sh#SplitWithBackslash()
|
||||||
|
if !search('\S', 'Wc', line('.'))
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
exe "normal! i\\\<cr>"
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#sh#JoinWithSemicolon()
|
||||||
|
if !nextnonblank(line('.') + 1)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#Keeppatterns('s/;\=\s*\n\_s*/; /e')
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#sh#JoinBackslashedLine()
|
||||||
|
if getline('.') !~ '\\\s*$'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#Keeppatterns('s/\\\=\s*\n\_s*//e')
|
||||||
|
return 1
|
||||||
|
endfunction
|
69
bundle/splitjoin.vim/autoload/sj/tex.vim
Normal file
69
bundle/splitjoin.vim/autoload/sj/tex.vim
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
function! sj#tex#SplitBlock()
|
||||||
|
let arg_pattern = '[a-zA-Z*]'
|
||||||
|
let opts_pattern = '\%(\%({.\{-}}\)\|\%(\[.\{-}]\)\)*'
|
||||||
|
|
||||||
|
if searchpair('\s*\zs\\begin{'.arg_pattern.'\{-}}'.opts_pattern, '', '\\end{'.arg_pattern.'\{-}}', 'bc', '') != line('.')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let start = getpos('.')
|
||||||
|
if searchpair('\\begin{'.arg_pattern.'\{-}}', '', '\\end{'.arg_pattern.'\{-}\zs}', '') != line('.')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let end = getpos('.')
|
||||||
|
|
||||||
|
let block = sj#GetByPosition(start, end)
|
||||||
|
|
||||||
|
let pattern = '^\(\\begin{'.arg_pattern.'\{-}}'.opts_pattern.'\)\(.\{-}\)\(\\end{'.arg_pattern.'\{-}}\)$'
|
||||||
|
let match = matchlist(block, pattern)
|
||||||
|
if empty(match)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [_match, open, body, close; _rest] = match
|
||||||
|
let body = sj#Trim(substitute(body, '\\\\', '\\\\'."\n", 'g'))
|
||||||
|
let body = sj#Trim(substitute(body, '\s*\\item', "\n".'\\item', 'g'))
|
||||||
|
let replacement = open."\n".body."\n".close
|
||||||
|
|
||||||
|
call sj#ReplaceByPosition(start, end, replacement)
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#tex#JoinBlock()
|
||||||
|
let arg_pattern = '[a-zA-Z*]'
|
||||||
|
let opts_pattern = '\%(\%({.\{-}}\)\|\%(\[.\{-}]\)\)*'
|
||||||
|
|
||||||
|
if search('\s*\\begin{', 'bcW', line('.')) <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
call search('\\begin{', 'cW', line('.'))
|
||||||
|
|
||||||
|
let start = getpos('.')
|
||||||
|
if searchpair('\\begin{'.arg_pattern.'\{-}}', '', '\\end{'.arg_pattern.'\{-}\zs}') <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let end = getpos('.')
|
||||||
|
|
||||||
|
let block = sj#GetByPosition(start, end)
|
||||||
|
|
||||||
|
let pattern = '^\(\\begin{'.arg_pattern.'\{-}}'.opts_pattern.'\)\_s\+\(.\{-}\)\_s\+\(\\end{'.arg_pattern.'\{-}}\)$'
|
||||||
|
let match = matchlist(block, pattern)
|
||||||
|
if empty(match)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [_match, open, body, close; _rest] = match
|
||||||
|
|
||||||
|
let lines = split(body, '\\\\\_s\+')
|
||||||
|
let body = join(lines, '\\ ')
|
||||||
|
|
||||||
|
if body =~ '\\item'
|
||||||
|
let lines = sj#TrimList(split(body, '\\item'))
|
||||||
|
let body = '\item '.join(lines, ' \item ')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let replacement = open." ".body." ".close
|
||||||
|
|
||||||
|
call sj#ReplaceByPosition(start, end, replacement)
|
||||||
|
return 1
|
||||||
|
endfunction
|
110
bundle/splitjoin.vim/autoload/sj/vim.vim
Normal file
110
bundle/splitjoin.vim/autoload/sj/vim.vim
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
function! sj#vim#Split()
|
||||||
|
if sj#BlankString(getline('.'))
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let new_line = sj#GetMotion('vg_')
|
||||||
|
|
||||||
|
if sj#BlankString(new_line)
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
let add_whitespace = 1
|
||||||
|
|
||||||
|
if col('.') > 1
|
||||||
|
let pair = strpart(getline('.'), col('.') - 2, 2)
|
||||||
|
|
||||||
|
if pair =~ '\s'
|
||||||
|
" we're breaking on whitespace, so make sure to add some:
|
||||||
|
let add_whitespace = 1
|
||||||
|
elseif pair =~ '^\S\S$'
|
||||||
|
" we're breaking a word, so make sure not to have any:
|
||||||
|
let add_whitespace = 0
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if add_whitespace
|
||||||
|
let new_line = "\n\\ ".sj#Trim(new_line)
|
||||||
|
else
|
||||||
|
let new_line = "\n\\".sj#Trim(new_line)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('vg_', new_line)
|
||||||
|
call sj#Keeppatterns('s/\s\+$//e')
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#vim#Join()
|
||||||
|
let continuation_pattern = '^\s*\\'
|
||||||
|
let current_lineno = line('.')
|
||||||
|
let next_lineno = current_lineno + 1
|
||||||
|
let next_line = getline(next_lineno)
|
||||||
|
|
||||||
|
if next_lineno > line('$') || next_line !~ continuation_pattern
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if next_line =~ continuation_pattern.'\s'
|
||||||
|
" Then there's some whitespace after the \, rely on :join
|
||||||
|
keeppatterns exe next_lineno.'s/'.continuation_pattern.'//'
|
||||||
|
exe current_lineno.','.next_lineno.'join'
|
||||||
|
else
|
||||||
|
" No whitespace, let's join them directly
|
||||||
|
keeppatterns exe current_lineno.'s/\n'.continuation_pattern.'//'
|
||||||
|
endif
|
||||||
|
|
||||||
|
if sj#settings#Read('normalize_whitespace')
|
||||||
|
call sj#CompressWhitespaceOnLine()
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#vim#SplitIfClause()
|
||||||
|
let line = getline('.')
|
||||||
|
let pattern = '\v^\s*if .{-} \| .{-} \|\s*endif'
|
||||||
|
|
||||||
|
if line !~# pattern
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let line_no = line('.')
|
||||||
|
let lines = split(line, '|')
|
||||||
|
let lines = map(lines, 'sj#Trim(v:val)')
|
||||||
|
let replacement = join(lines, "\n")
|
||||||
|
|
||||||
|
call sj#ReplaceLines(line_no, line_no, replacement)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#vim#JoinIfClause()
|
||||||
|
let line = getline('.')
|
||||||
|
let pattern = '\v^\s*if'
|
||||||
|
|
||||||
|
if line !~# pattern
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let if_line_no = line('.')
|
||||||
|
let endif_line_pattern = '^'.repeat(' ', indent(if_line_no)).'endif'
|
||||||
|
|
||||||
|
let endif_line_no = search(endif_line_pattern, 'W')
|
||||||
|
|
||||||
|
if endif_line_no <= 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if endif_line_no - if_line_no != 2
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let lines = sj#GetLines(if_line_no, endif_line_no)
|
||||||
|
let lines = map(lines, 'sj#Trim(v:val)')
|
||||||
|
let replacement = join(lines, ' | ')
|
||||||
|
|
||||||
|
call sj#ReplaceLines(if_line_no, endif_line_no, replacement)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
32
bundle/splitjoin.vim/autoload/sj/vue.vim
Normal file
32
bundle/splitjoin.vim/autoload/sj/vue.vim
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
function! sj#vue#SplitCssDefinition()
|
||||||
|
if s:GetVueSection() != 'style'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
return sj#css#SplitDefinition()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#vue#JoinCssDefinition()
|
||||||
|
if s:GetVueSection() != 'style'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
return sj#css#JoinDefinition()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#vue#SplitCssMultilineSelector()
|
||||||
|
if s:GetVueSection() != 'style'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
return sj#css#SplitMultilineSelector()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#vue#JoinCssMultilineSelector()
|
||||||
|
if s:GetVueSection() != 'style'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
return sj#css#JoinMultilineSelector()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:GetVueSection()
|
||||||
|
let l:startofsection = search('\v^\<(template|script|style)\>', 'bnW')
|
||||||
|
return substitute(getline(startofsection), '\v[<>]', '', 'g')
|
||||||
|
endfunction
|
541
bundle/splitjoin.vim/autoload/sj/yaml.vim
Normal file
541
bundle/splitjoin.vim/autoload/sj/yaml.vim
Normal file
@ -0,0 +1,541 @@
|
|||||||
|
" Array Callbacks:
|
||||||
|
" ================
|
||||||
|
|
||||||
|
function! sj#yaml#SplitArray()
|
||||||
|
let [line, line_no, whitespace] = s:ReadCurrentLine()
|
||||||
|
|
||||||
|
let prefix = ''
|
||||||
|
let array_part = ''
|
||||||
|
let indent = 1
|
||||||
|
let end_offset = 0
|
||||||
|
|
||||||
|
let nestedExp = '\v^\s*((-\s+)+)(\[.*\])$'
|
||||||
|
let line = s:StripComment(line)
|
||||||
|
|
||||||
|
" Split arrays which are map properties
|
||||||
|
" E.g.
|
||||||
|
" prop: [1, 2]
|
||||||
|
if line =~ ':\s*\[.*\]$'
|
||||||
|
let [key, array_part] = s:SplitKeyValue(line)
|
||||||
|
let prefix = key . ":\n"
|
||||||
|
|
||||||
|
" Split nested arrays
|
||||||
|
" E.g.
|
||||||
|
" - [1, 2]
|
||||||
|
elseif line =~ nestedExp
|
||||||
|
let prefix = substitute(line, nestedExp, '\1', '')
|
||||||
|
let array_part = substitute(line, nestedExp, '\3', '')
|
||||||
|
let indent = len(substitute(line, '\v[^-]', '', 'g'))
|
||||||
|
let end_offset = -1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if array_part != ''
|
||||||
|
let body = substitute(array_part, '\v^\s*\[(.*)\]\s*$', '\1', '')
|
||||||
|
let array_items = s:SplitArrayBody(body)
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('V', prefix . '- ' . join(array_items, "\n- "))
|
||||||
|
silent! normal! zO
|
||||||
|
call s:SetIndentWhitespace(line_no, whitespace)
|
||||||
|
call s:IncreaseIndentWhitespace(line_no + 1, line_no + len(array_items) + end_offset, whitespace, indent)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#yaml#JoinArray()
|
||||||
|
let [line, line_no, whitespace] = s:ReadCurrentLine()
|
||||||
|
|
||||||
|
let lines = []
|
||||||
|
let first_line = s:StripComment(line)
|
||||||
|
|
||||||
|
let nestedExp = '\v^(\s*(-\s+)+)(-\s+.*)$'
|
||||||
|
let join_type = ''
|
||||||
|
|
||||||
|
" Nested arrays
|
||||||
|
" E.g.
|
||||||
|
" - - 'one'
|
||||||
|
" - 'two'
|
||||||
|
if first_line =~ nestedExp && s:IsValidLineNo(line_no)
|
||||||
|
let join_type = 'nested'
|
||||||
|
let [lines, last_line_no] = s:GetChildren(line_no)
|
||||||
|
let lines = map(lines, 's:StripComment(v:val)')
|
||||||
|
let lines = [substitute(first_line, nestedExp, '\3', '')] + lines
|
||||||
|
let first_line = sj#Rtrim(substitute(first_line, nestedExp, '\1', ''))
|
||||||
|
|
||||||
|
" Normal arrays
|
||||||
|
" E.g.
|
||||||
|
" list:
|
||||||
|
" - 'one'
|
||||||
|
" - 'two'
|
||||||
|
elseif first_line =~ ':$' && s:IsValidLineNo(line_no + 1)
|
||||||
|
let join_type = 'normal'
|
||||||
|
let [lines, last_line_no] = s:GetChildren(line_no)
|
||||||
|
let lines = map(lines, 's:StripComment(v:val)')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !empty(lines)
|
||||||
|
if join_type == 'nested'
|
||||||
|
let body_lines = lines[1:len(lines)]
|
||||||
|
else
|
||||||
|
let body_lines = lines
|
||||||
|
endif
|
||||||
|
|
||||||
|
for line in body_lines
|
||||||
|
if line !~ '^\s*$' && line !~ '^\s*-'
|
||||||
|
" one non-blank line is not part of the array, it must be a nested
|
||||||
|
" construct, can't handle that
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if line =~ nestedExp
|
||||||
|
" can't handle nested subexpressions
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let lines = map(lines, 'sj#Trim(substitute(v:val, "^\\s*-", "", ""))')
|
||||||
|
let lines = filter(lines, '!sj#BlankString(v:val)')
|
||||||
|
let replacement = first_line . ' [' . s:JoinArrayItems(lines) . ']'
|
||||||
|
|
||||||
|
call sj#ReplaceLines(line_no, last_line_no, replacement)
|
||||||
|
silent! normal! zO
|
||||||
|
call s:SetIndentWhitespace(line_no, whitespace)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
" then there's nothing to join
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Map Callbacks:
|
||||||
|
" ================
|
||||||
|
|
||||||
|
function! sj#yaml#SplitMap()
|
||||||
|
let [from, to] = sj#LocateBracesOnLine('{', '}')
|
||||||
|
|
||||||
|
if from >= 0 && to >= 0
|
||||||
|
let [line, line_no, whitespace] = s:ReadCurrentLine()
|
||||||
|
let line = s:StripComment(line)
|
||||||
|
let pairs = sj#ParseJsonObjectBody(from + 1, to - 1)
|
||||||
|
let body = join(pairs, "\n")
|
||||||
|
let body_start = line_no
|
||||||
|
|
||||||
|
let indent_level = 0
|
||||||
|
let end_offset = -1
|
||||||
|
|
||||||
|
" Increase indention if the map is inside a nested array.
|
||||||
|
" E.g.
|
||||||
|
" - - { one: 1 }
|
||||||
|
if line =~ '^\s*-\s'
|
||||||
|
let indent_level = s:NestedArrayLevel(line)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Move body into next line if it is a map property.
|
||||||
|
" E.g.
|
||||||
|
" prop: { one: 1 }
|
||||||
|
" - prop: { one: 1 }
|
||||||
|
if line =~ '^\v\s*(-\s+)*[^{]*:\s+\{.*'
|
||||||
|
let body = "\n" . body
|
||||||
|
let indent_level += 1
|
||||||
|
let end_offset = 0
|
||||||
|
let body_start = line_no + 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceMotion('Va{', body)
|
||||||
|
silent! normal! zO
|
||||||
|
call s:SetIndentWhitespace(line_no, whitespace)
|
||||||
|
call s:IncreaseIndentWhitespace(line_no + 1, line_no + len(pairs) + end_offset, whitespace, indent_level)
|
||||||
|
call sj#Keeppatterns(line_no . 's/\s*$//e')
|
||||||
|
|
||||||
|
if sj#settings#Read('align')
|
||||||
|
let body_end = body_start + len(pairs) - 1
|
||||||
|
call sj#Align(body_start, body_end, 'json_object')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! sj#yaml#JoinMap()
|
||||||
|
let [line, line_no, whitespace] = s:ReadCurrentLine()
|
||||||
|
|
||||||
|
if !s:IsValidLineNo(line_no + 1)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let first_line = s:StripComment(line)
|
||||||
|
let lines = []
|
||||||
|
let last_line_no = 0
|
||||||
|
let join_type = ''
|
||||||
|
|
||||||
|
let nestedExp = '\v^(\s*(-\s+)+)(.*)$'
|
||||||
|
let nestedPropExp = '\v^(\s*(-\s+)+.+:)$'
|
||||||
|
|
||||||
|
" Nested in a map inside an array.
|
||||||
|
" E.g.
|
||||||
|
" - prop:
|
||||||
|
" one: 1
|
||||||
|
if first_line =~ nestedPropExp
|
||||||
|
let join_type = 'nested_in_map_in_array'
|
||||||
|
let [lines, last_line_no] = s:GetChildren(line_no)
|
||||||
|
let first_line = sj#Rtrim(substitute(first_line, nestedPropExp, '\1', ''))
|
||||||
|
|
||||||
|
" Map inside an array.
|
||||||
|
" E.g.
|
||||||
|
" - one: 1
|
||||||
|
" two: 2
|
||||||
|
elseif first_line =~ nestedExp
|
||||||
|
let join_type = 'nested_in_array'
|
||||||
|
let [lines, last_line_no] = s:GetChildren(line_no)
|
||||||
|
let lines = [substitute(first_line, nestedExp, '\3', '')] + lines
|
||||||
|
let first_line = sj#Rtrim(substitute(first_line, nestedExp, '\1', ''))
|
||||||
|
|
||||||
|
if len(lines) <= 1
|
||||||
|
" only 1 line means nothing to join in this case
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Normal map
|
||||||
|
" E.g.
|
||||||
|
" map:
|
||||||
|
" one: 1
|
||||||
|
" two: 2
|
||||||
|
elseif first_line =~ '\k\+:\s*$'
|
||||||
|
let join_type = 'normal'
|
||||||
|
let [lines, last_line_no] = s:GetChildren(line_no)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if len(lines) > 0
|
||||||
|
if join_type == 'nested_in_array'
|
||||||
|
let body_lines = lines[1:len(lines)]
|
||||||
|
else
|
||||||
|
let body_lines = lines
|
||||||
|
endif
|
||||||
|
|
||||||
|
if len(body_lines) > 0
|
||||||
|
let base_indent = len(matchstr(body_lines[0], '^\s*'))
|
||||||
|
endif
|
||||||
|
|
||||||
|
for line in body_lines
|
||||||
|
if line =~ '^\s*-'
|
||||||
|
" one of the lines is a part of an array, we can't handle nested subexpressions
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if len(matchstr(line, '^\s*')) != base_indent
|
||||||
|
" a nested map, can't handle that
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let lines = sj#TrimList(lines)
|
||||||
|
let lines = s:NormalizeWhitespace(lines)
|
||||||
|
let lines = map(lines, 's:StripComment(v:val)')
|
||||||
|
|
||||||
|
if sj#settings#Read('curly_brace_padding')
|
||||||
|
let replacement = first_line . ' { '. join(lines, ', ') . ' }'
|
||||||
|
else
|
||||||
|
let replacement = first_line . ' {'. join(lines, ', ') . '}'
|
||||||
|
endif
|
||||||
|
|
||||||
|
call sj#ReplaceLines(line_no, last_line_no, replacement)
|
||||||
|
silent! normal! zO
|
||||||
|
call s:SetIndentWhitespace(line_no, whitespace)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Helper Functions:
|
||||||
|
" =================
|
||||||
|
|
||||||
|
" Reads line, line number and indention
|
||||||
|
function! s:ReadCurrentLine()
|
||||||
|
let line_no = line('.')
|
||||||
|
let line = getline(line_no)
|
||||||
|
let whitespace = s:GetIndentWhitespace(line_no)
|
||||||
|
|
||||||
|
return [line, line_no, whitespace]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Strip comments from string starting with a #
|
||||||
|
function! s:StripComment(s)
|
||||||
|
return substitute(a:s, '\v\s+#.*$', '', '')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Check if current buffer has the line number
|
||||||
|
function! s:IsValidLineNo(no)
|
||||||
|
return a:no >= 0 && a:no <= line('$')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Normalize whitespace, if enabled
|
||||||
|
function! s:NormalizeWhitespace(lines)
|
||||||
|
if sj#settings#Read('normalize_whitespace')
|
||||||
|
return map(a:lines, 'substitute(v:val, ":\\s\\+", ": ", "")')
|
||||||
|
endif
|
||||||
|
return a:lines
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:GetIndentWhitespace(line_no)
|
||||||
|
return substitute(getline(a:line_no), '^\(\s*\).*$', '\1', '')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:SetIndentWhitespace(line_no, whitespace)
|
||||||
|
silent call sj#Keeppatterns(a:line_no . 's/^\s*/' . a:whitespace)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:IncreaseIndentWhitespace(from, to, whitespace, level)
|
||||||
|
if a:whitespace =~ "\t"
|
||||||
|
let new_whitespace = a:whitespace . repeat("\t", a:level)
|
||||||
|
else
|
||||||
|
let new_whitespace = a:whitespace . repeat(' ', &sw * a:level)
|
||||||
|
endif
|
||||||
|
|
||||||
|
for line_no in range(a:from, a:to)
|
||||||
|
call s:SetIndentWhitespace(line_no, new_whitespace)
|
||||||
|
endfor
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Get following lines with a greater indent than the current line
|
||||||
|
function! s:GetChildren(line_no)
|
||||||
|
let line_no = a:line_no
|
||||||
|
let next_line_no = line_no + 1
|
||||||
|
let indent = indent(line_no)
|
||||||
|
let next_line = getline(next_line_no)
|
||||||
|
|
||||||
|
" Count '- ' as indent, if an object is in an array
|
||||||
|
" E.g. (GetChildren for prop_a)
|
||||||
|
" list:
|
||||||
|
" - prop_a:
|
||||||
|
" - 1
|
||||||
|
" prop_b
|
||||||
|
" - 2
|
||||||
|
let line = getline(line_no)
|
||||||
|
if line =~ '^\s*\(\-\s\s*\)..*:$'
|
||||||
|
let prefix = substitute(getline(a:line_no), '^\s*\(\-\s\s*\)..*:$', '\1', '')
|
||||||
|
let indent += len(prefix)
|
||||||
|
end
|
||||||
|
|
||||||
|
while s:IsValidLineNo(next_line_no) &&
|
||||||
|
\ (sj#BlankString(next_line) || indent(next_line_no) > indent)
|
||||||
|
let next_line_no = next_line_no + 1
|
||||||
|
let next_line = getline(next_line_no)
|
||||||
|
endwhile
|
||||||
|
let next_line_no = next_line_no - 1
|
||||||
|
|
||||||
|
" Preserve trailing empty lines
|
||||||
|
while sj#BlankString(getline(next_line_no)) && next_line_no > line_no
|
||||||
|
let next_line_no = next_line_no - 1
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
return [sj#GetLines(line_no + 1, next_line_no), next_line_no]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Split a string into individual array items.
|
||||||
|
" E.g.
|
||||||
|
" 'one, two' => ['one', 'two']
|
||||||
|
" '{ one: 1 }, { two: 2 }' => ['{ one: 1 }', '{ two: 2 }']
|
||||||
|
function! s:SplitArrayBody(body)
|
||||||
|
let items = []
|
||||||
|
|
||||||
|
let partial_item = ''
|
||||||
|
let rest = sj#Ltrim(a:body)
|
||||||
|
|
||||||
|
while !empty(rest)
|
||||||
|
let char = rest[0]
|
||||||
|
|
||||||
|
if char == '{'
|
||||||
|
let [item, rest] = s:ReadMap(rest)
|
||||||
|
let rest = s:SkipWhitespaceUntilComma(rest)
|
||||||
|
|
||||||
|
call add(items, s:StripCurlyBrackets(item))
|
||||||
|
|
||||||
|
elseif char == '['
|
||||||
|
let [item, rest] = s:ReadArray(rest)
|
||||||
|
let rest = s:SkipWhitespaceUntilComma(rest)
|
||||||
|
|
||||||
|
call add(items, sj#Trim(item))
|
||||||
|
|
||||||
|
elseif char == '"' || char == "'"
|
||||||
|
let [item, rest] = s:ReadString(rest)
|
||||||
|
let rest = s:SkipWhitespaceUntilComma(rest)
|
||||||
|
|
||||||
|
call add(items, sj#Trim(item))
|
||||||
|
|
||||||
|
else
|
||||||
|
let [item, rest] = s:ReadUntil(rest, ',')
|
||||||
|
call add(items, sj#Trim(item))
|
||||||
|
endif
|
||||||
|
|
||||||
|
let rest = sj#Ltrim(rest[1:])
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
return items
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Read string until occurence of end_char
|
||||||
|
function! s:ReadUntil(str, end_char)
|
||||||
|
let idx = 0
|
||||||
|
while idx < len(a:str)
|
||||||
|
if a:str[idx] == a:end_char
|
||||||
|
return idx == 0
|
||||||
|
\ ? ['', a:str[1:]]
|
||||||
|
\ : [a:str[:idx-1], a:str[idx+1:]]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let idx += 1
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
return [a:str, '']
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Read the next string fenced by " or '
|
||||||
|
function! s:ReadString(str)
|
||||||
|
if len(a:str) > 0
|
||||||
|
let fence = a:str[0]
|
||||||
|
if fence == '"' || fence == "'"
|
||||||
|
let [str, rest] = s:ReadUntil(a:str[1:], fence)
|
||||||
|
return [fence . str . fence, rest]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
return ['', a:str]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Read the next array, including nested arrays.
|
||||||
|
" E.q.
|
||||||
|
" '[[1, 2]], [1]' => ['[[1, 2]], ', [1]']
|
||||||
|
function! s:ReadArray(str)
|
||||||
|
return s:ReadContainer(a:str, '[', ']')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Read the next map, including nested maps.
|
||||||
|
" E.q.
|
||||||
|
" '{ one: 1, foo: { two: 2 } }, {}' => ['{ one: 1, foo: { two: 2 } }, ', {}']
|
||||||
|
function! s:ReadMap(str)
|
||||||
|
return s:ReadContainer(a:str, '{', '}')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:ReadContainer(str, start_char, end_char)
|
||||||
|
let content = ''
|
||||||
|
let rest = a:str
|
||||||
|
let depth = 0
|
||||||
|
|
||||||
|
while !empty(rest)
|
||||||
|
let char = rest[0]
|
||||||
|
let rest = rest[1:]
|
||||||
|
|
||||||
|
let content .= char
|
||||||
|
|
||||||
|
if char == a:start_char
|
||||||
|
let depth += 1
|
||||||
|
elseif char == a:end_char
|
||||||
|
let depth -= 1
|
||||||
|
|
||||||
|
if depth == 0 | break | endif
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
return [content, rest]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" skip whitespace and next comma
|
||||||
|
function! s:SkipWhitespaceUntilComma(str)
|
||||||
|
let [space, rest] = s:ReadUntil(a:str, ',')
|
||||||
|
|
||||||
|
if !sj#BlankString(space)
|
||||||
|
throw '"' . space . '" is not whitespace!'
|
||||||
|
end
|
||||||
|
return rest
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:JoinArrayItems(items)
|
||||||
|
return join(map(a:items, 's:AddCurlyBrackets(v:val)'), ', ')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Add curly brackets if required for joining
|
||||||
|
" E.g.
|
||||||
|
" 'one: 1' => '{ one: 1 }'
|
||||||
|
" 'one' => 'one'
|
||||||
|
function! s:AddCurlyBrackets(line)
|
||||||
|
let line = sj#Trim(a:line)
|
||||||
|
|
||||||
|
if line !~ '^\v\[.*\]$' && line !~ '^\v\{.*\}$'
|
||||||
|
let [key, value] = s:SplitKeyValue(line)
|
||||||
|
if key != ''
|
||||||
|
return '{ ' . a:line . ' }'
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
return a:line
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Strip curly brackets if possible
|
||||||
|
" E.g.
|
||||||
|
" '{ one: 1 }' => 'one: 1'
|
||||||
|
" '{ one: 1, two: 2 }' => '{ one: 1, two: 2 }'
|
||||||
|
function! s:StripCurlyBrackets(item)
|
||||||
|
let item = sj#Trim(a:item)
|
||||||
|
|
||||||
|
if item =~ '^{.*}$'
|
||||||
|
let parser = sj#argparser#js#Construct(2, len(item) - 1, item)
|
||||||
|
call parser.Process()
|
||||||
|
|
||||||
|
if len(parser.args) == 1
|
||||||
|
let item = substitute(item, '^{\s*', '', '')
|
||||||
|
let item = substitute(item, '\s*}$', '', '')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
return item
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Split a string into key and value
|
||||||
|
" E.g.
|
||||||
|
" 'one: 1' => ['one', '1']
|
||||||
|
" 'one' => ['', 'one']
|
||||||
|
" 'one:' => ['one', '']
|
||||||
|
" 'a:val' => ['', 'a:val']
|
||||||
|
function! s:SplitKeyValue(line)
|
||||||
|
let line = sj#Trim(a:line)
|
||||||
|
let parts = []
|
||||||
|
|
||||||
|
let first_char = line[0]
|
||||||
|
|
||||||
|
let key = ''
|
||||||
|
let value = ''
|
||||||
|
|
||||||
|
" Read line starts with a fenced string. E.g
|
||||||
|
" 'one': 1
|
||||||
|
" 'one'
|
||||||
|
if first_char == '"' || first_char == "'"
|
||||||
|
let [key, rest] = s:ReadString(line)
|
||||||
|
let [_, value] = s:ReadUntil(rest, ':')
|
||||||
|
else
|
||||||
|
let parts = split(line . ' ', ': ')
|
||||||
|
let [key, value] = [parts[0], join(parts[1:], ': ')]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if value == '' && a:line !~ '\s*:$'
|
||||||
|
let [key, value] = ['', key]
|
||||||
|
endif
|
||||||
|
|
||||||
|
return [sj#Trim(key), sj#Trim(value)]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Calculate the nesting level of an array item
|
||||||
|
" E.g.
|
||||||
|
" - foo => 1
|
||||||
|
" - - bar => 2
|
||||||
|
function! s:NestedArrayLevel(line)
|
||||||
|
let prefix = substitute(a:line, '\v^\s*((-\s+)+).*', '\1', '')
|
||||||
|
let levels = substitute(prefix, '[^-]', '', 'g')
|
||||||
|
return len(levels)
|
||||||
|
endfunction
|
2127
bundle/splitjoin.vim/doc/splitjoin.txt
Normal file
2127
bundle/splitjoin.vim/doc/splitjoin.txt
Normal file
File diff suppressed because it is too large
Load Diff
13
bundle/splitjoin.vim/ftplugin/c/splitjoin.vim
Normal file
13
bundle/splitjoin.vim/ftplugin/c/splitjoin.vim
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#c#SplitIfClause',
|
||||||
|
\ 'sj#c#SplitFuncall',
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#c#JoinFuncall',
|
||||||
|
\ 'sj#c#JoinIfClause',
|
||||||
|
\ ]
|
||||||
|
endif
|
11
bundle/splitjoin.vim/ftplugin/clojure/splitjoin.vim
Normal file
11
bundle/splitjoin.vim/ftplugin/clojure/splitjoin.vim
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#clojure#SplitList',
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#clojure#JoinList',
|
||||||
|
\ ]
|
||||||
|
endif
|
20
bundle/splitjoin.vim/ftplugin/coffee/splitjoin.vim
Normal file
20
bundle/splitjoin.vim/ftplugin/coffee/splitjoin.vim
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#coffee#SplitTernaryClause',
|
||||||
|
\ 'sj#coffee#SplitTripleString',
|
||||||
|
\ 'sj#coffee#SplitString',
|
||||||
|
\ 'sj#coffee#SplitFunction',
|
||||||
|
\ 'sj#coffee#SplitIfClause',
|
||||||
|
\ 'sj#coffee#SplitObjectLiteral',
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#coffee#JoinString',
|
||||||
|
\ 'sj#coffee#JoinFunction',
|
||||||
|
\ 'sj#coffee#JoinIfElseClause',
|
||||||
|
\ 'sj#coffee#JoinIfClause',
|
||||||
|
\ 'sj#coffee#JoinObjectLiteral',
|
||||||
|
\ ]
|
||||||
|
endif
|
15
bundle/splitjoin.vim/ftplugin/cs/splitjoin.vim
Normal file
15
bundle/splitjoin.vim/ftplugin/cs/splitjoin.vim
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
" Use C syntax for C# for now
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#c#SplitIfClause',
|
||||||
|
\ 'sj#c#SplitFuncall',
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#c#JoinFuncall',
|
||||||
|
\ 'sj#c#JoinIfClause',
|
||||||
|
\ ]
|
||||||
|
endif
|
13
bundle/splitjoin.vim/ftplugin/css/splitjoin.vim
Normal file
13
bundle/splitjoin.vim/ftplugin/css/splitjoin.vim
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#css#SplitDefinition',
|
||||||
|
\ 'sj#css#SplitMultilineSelector',
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#css#JoinDefinition',
|
||||||
|
\ 'sj#css#JoinMultilineSelector',
|
||||||
|
\ ]
|
||||||
|
endif
|
16
bundle/splitjoin.vim/ftplugin/cue/splitjoin.vim
Normal file
16
bundle/splitjoin.vim/ftplugin/cue/splitjoin.vim
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#cue#SplitStructLiteral',
|
||||||
|
\ 'sj#cue#SplitArray',
|
||||||
|
\ 'sj#cue#SplitArgs',
|
||||||
|
\ 'sj#cue#SplitImports',
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#cue#JoinStructLiteral',
|
||||||
|
\ 'sj#cue#JoinArray',
|
||||||
|
\ 'sj#cue#JoinArgs',
|
||||||
|
\ ]
|
||||||
|
endif
|
12
bundle/splitjoin.vim/ftplugin/elixir/splitjoin.vim
Normal file
12
bundle/splitjoin.vim/ftplugin/elixir/splitjoin.vim
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#elixir#SplitDoBlock',
|
||||||
|
\ 'sj#elixir#SplitArray',
|
||||||
|
\ 'sj#elixir#SplitPipe',
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#elixir#JoinDoBlock',
|
||||||
|
\ 'sj#elixir#JoinArray',
|
||||||
|
\ 'sj#elixir#JoinCommaDelimitedItems',
|
||||||
|
\ 'sj#elixir#JoinPipe',
|
||||||
|
\ ]
|
11
bundle/splitjoin.vim/ftplugin/elm/splitjoin.vim
Normal file
11
bundle/splitjoin.vim/ftplugin/elm/splitjoin.vim
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#elm#SplitBraces',
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#elm#JoinBraces',
|
||||||
|
\ ]
|
||||||
|
endif
|
13
bundle/splitjoin.vim/ftplugin/eruby/splitjoin.vim
Normal file
13
bundle/splitjoin.vim/ftplugin/eruby/splitjoin.vim
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#eruby#SplitHtmlTags',
|
||||||
|
\ 'sj#eruby#SplitIfClause',
|
||||||
|
\ 'sj#ruby#SplitOptions',
|
||||||
|
\ 'sj#eruby#SplitHtmlAttributes',
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#eruby#JoinIfClause',
|
||||||
|
\ 'sj#ruby#JoinHash',
|
||||||
|
\ 'sj#html#JoinAttributes',
|
||||||
|
\ 'sj#html#JoinTags',
|
||||||
|
\ ]
|
17
bundle/splitjoin.vim/ftplugin/go/splitjoin.vim
Normal file
17
bundle/splitjoin.vim/ftplugin/go/splitjoin.vim
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#go#SplitImports',
|
||||||
|
\ 'sj#go#SplitVars',
|
||||||
|
\ 'sj#go#SplitFunc',
|
||||||
|
\ 'sj#go#SplitFuncCall',
|
||||||
|
\ 'sj#go#SplitStruct',
|
||||||
|
\ 'sj#go#SplitSingleLineCurlyBracketBlock',
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#go#JoinImports',
|
||||||
|
\ 'sj#go#JoinVars',
|
||||||
|
\ 'sj#go#JoinStructDeclaration',
|
||||||
|
\ 'sj#go#JoinStruct',
|
||||||
|
\ 'sj#go#JoinFuncCallOrDefinition',
|
||||||
|
\ 'sj#go#JoinSingleLineFunctionBody',
|
||||||
|
\ ]
|
9
bundle/splitjoin.vim/ftplugin/haml/splitjoin.vim
Normal file
9
bundle/splitjoin.vim/ftplugin/haml/splitjoin.vim
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#haml#SplitInterpolation',
|
||||||
|
\ 'sj#haml#SplitInlineInterpolation',
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#haml#JoinInterpolation',
|
||||||
|
\ 'sj#haml#JoinToInlineInterpolation',
|
||||||
|
\ ]
|
13
bundle/splitjoin.vim/ftplugin/handlebars/splitjoin.vim
Normal file
13
bundle/splitjoin.vim/ftplugin/handlebars/splitjoin.vim
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#html#SplitTags',
|
||||||
|
\ 'sj#html#SplitAttributes',
|
||||||
|
\ 'sj#handlebars#SplitBlockComponent',
|
||||||
|
\ 'sj#handlebars#SplitComponent',
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#html#JoinAttributes',
|
||||||
|
\ 'sj#html#JoinTags',
|
||||||
|
\ 'sj#handlebars#JoinBlockComponent',
|
||||||
|
\ 'sj#handlebars#JoinComponent',
|
||||||
|
\ ]
|
13
bundle/splitjoin.vim/ftplugin/html/splitjoin.vim
Normal file
13
bundle/splitjoin.vim/ftplugin/html/splitjoin.vim
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#html#SplitTags',
|
||||||
|
\ 'sj#html#SplitAttributes'
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#html#JoinAttributes',
|
||||||
|
\ 'sj#html#JoinTags'
|
||||||
|
\ ]
|
||||||
|
endif
|
13
bundle/splitjoin.vim/ftplugin/htmldjango/splitjoin.vim
Normal file
13
bundle/splitjoin.vim/ftplugin/htmldjango/splitjoin.vim
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
" Use html callbacks
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#html#SplitTags'
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#html#JoinTags'
|
||||||
|
\ ]
|
||||||
|
endif
|
17
bundle/splitjoin.vim/ftplugin/java/splitjoin.vim
Normal file
17
bundle/splitjoin.vim/ftplugin/java/splitjoin.vim
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#java#SplitIfClauseBody',
|
||||||
|
\ 'sj#java#SplitIfClauseCondition',
|
||||||
|
\ 'sj#java#SplitLambda',
|
||||||
|
\ 'sj#java#SplitFuncall',
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#java#JoinLambda',
|
||||||
|
\ 'sj#java#JoinIfClauseCondition',
|
||||||
|
\ 'sj#java#JoinFuncall',
|
||||||
|
\ 'sj#java#JoinIfClauseBody',
|
||||||
|
\ ]
|
||||||
|
endif
|
21
bundle/splitjoin.vim/ftplugin/javascript/splitjoin.vim
Normal file
21
bundle/splitjoin.vim/ftplugin/javascript/splitjoin.vim
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#js#SplitFunction',
|
||||||
|
\ 'sj#js#SplitObjectLiteral',
|
||||||
|
\ 'sj#js#SplitFatArrowFunction',
|
||||||
|
\ 'sj#js#SplitArray',
|
||||||
|
\ 'sj#js#SplitOneLineIf',
|
||||||
|
\ 'sj#js#SplitArgs',
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#js#JoinFatArrowFunction',
|
||||||
|
\ 'sj#js#JoinArray',
|
||||||
|
\ 'sj#js#JoinArgs',
|
||||||
|
\ 'sj#js#JoinFunction',
|
||||||
|
\ 'sj#js#JoinOneLineIf',
|
||||||
|
\ 'sj#js#JoinObjectLiteral',
|
||||||
|
\ ]
|
||||||
|
endif
|
@ -0,0 +1 @@
|
|||||||
|
runtime ftplugin/jsx/splitjoin.vim
|
12
bundle/splitjoin.vim/ftplugin/json/splitjoin.vim
Normal file
12
bundle/splitjoin.vim/ftplugin/json/splitjoin.vim
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#js#SplitObjectLiteral',
|
||||||
|
\ 'sj#js#SplitArray',
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#js#JoinArray',
|
||||||
|
\ 'sj#js#JoinObjectLiteral',
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
" JSON does not support trailing commas
|
||||||
|
let b:splitjoin_trailing_comma = 0
|
24
bundle/splitjoin.vim/ftplugin/jsx/splitjoin.vim
Normal file
24
bundle/splitjoin.vim/ftplugin/jsx/splitjoin.vim
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#jsx#SplitJsxExpression',
|
||||||
|
\ 'sj#html#SplitTags',
|
||||||
|
\ 'sj#html#SplitAttributes',
|
||||||
|
\ 'sj#js#SplitObjectLiteral',
|
||||||
|
\ 'sj#js#SplitFatArrowFunction',
|
||||||
|
\ 'sj#js#SplitArray',
|
||||||
|
\ 'sj#js#SplitFunction',
|
||||||
|
\ 'sj#js#SplitOneLineIf',
|
||||||
|
\ 'sj#js#SplitArgs',
|
||||||
|
\ 'sj#jsx#SplitSelfClosingTag'
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#jsx#JoinJsxExpression',
|
||||||
|
\ 'sj#html#JoinAttributes',
|
||||||
|
\ 'sj#jsx#JoinHtmlTag',
|
||||||
|
\ 'sj#js#JoinFatArrowFunction',
|
||||||
|
\ 'sj#js#JoinArray',
|
||||||
|
\ 'sj#js#JoinArgs',
|
||||||
|
\ 'sj#js#JoinFunction',
|
||||||
|
\ 'sj#js#JoinOneLineIf',
|
||||||
|
\ 'sj#js#JoinObjectLiteral',
|
||||||
|
\ ]
|
15
bundle/splitjoin.vim/ftplugin/less/splitjoin.vim
Normal file
15
bundle/splitjoin.vim/ftplugin/less/splitjoin.vim
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#css#SplitMultilineSelector',
|
||||||
|
\ 'sj#scss#SplitNestedDefinition',
|
||||||
|
\ 'sj#css#SplitDefinition',
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#scss#JoinNestedDefinition',
|
||||||
|
\ 'sj#css#JoinDefinition',
|
||||||
|
\ 'sj#css#JoinMultilineSelector',
|
||||||
|
\ ]
|
||||||
|
endif
|
13
bundle/splitjoin.vim/ftplugin/lua/splitjoin.vim
Normal file
13
bundle/splitjoin.vim/ftplugin/lua/splitjoin.vim
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#lua#SplitTable',
|
||||||
|
\ 'sj#lua#SplitFunction',
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#lua#JoinTable',
|
||||||
|
\ 'sj#lua#JoinFunction',
|
||||||
|
\ ]
|
||||||
|
endif
|
22
bundle/splitjoin.vim/ftplugin/perl/splitjoin.vim
Normal file
22
bundle/splitjoin.vim/ftplugin/perl/splitjoin.vim
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#perl#SplitSuffixIfClause',
|
||||||
|
\ 'sj#perl#SplitPrefixIfClause',
|
||||||
|
\ 'sj#perl#SplitAndClause',
|
||||||
|
\ 'sj#perl#SplitOrClause',
|
||||||
|
\ 'sj#perl#SplitHash',
|
||||||
|
\ 'sj#perl#SplitWordList',
|
||||||
|
\ 'sj#perl#SplitSquareBracketedList',
|
||||||
|
\ 'sj#perl#SplitRoundBracketedList',
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#perl#JoinIfClause',
|
||||||
|
\ 'sj#perl#JoinHash',
|
||||||
|
\ 'sj#perl#JoinWordList',
|
||||||
|
\ 'sj#perl#JoinSquareBracketedList',
|
||||||
|
\ 'sj#perl#JoinRoundBracketedList',
|
||||||
|
\ ]
|
||||||
|
endif
|
19
bundle/splitjoin.vim/ftplugin/php/splitjoin.vim
Normal file
19
bundle/splitjoin.vim/ftplugin/php/splitjoin.vim
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#php#SplitMethodChain',
|
||||||
|
\ 'sj#php#SplitArray',
|
||||||
|
\ 'sj#php#SplitIfClause',
|
||||||
|
\ 'sj#php#SplitElseClause',
|
||||||
|
\ 'sj#php#SplitBraces',
|
||||||
|
\ 'sj#html#SplitTags',
|
||||||
|
\ 'sj#php#SplitPhpMarker',
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#php#JoinPhpMarker',
|
||||||
|
\ 'sj#php#JoinMethodChain',
|
||||||
|
\ 'sj#php#JoinArray',
|
||||||
|
\ 'sj#php#JoinBraces',
|
||||||
|
\ 'sj#php#JoinIfClause',
|
||||||
|
\ 'sj#php#JoinElseClause',
|
||||||
|
\ 'sj#php#JoinHtmlTags',
|
||||||
|
\ ]
|
24
bundle/splitjoin.vim/ftplugin/python/splitjoin.vim
Normal file
24
bundle/splitjoin.vim/ftplugin/python/splitjoin.vim
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#python#SplitListComprehension',
|
||||||
|
\ 'sj#python#SplitTuple',
|
||||||
|
\ 'sj#python#SplitAssignment',
|
||||||
|
\ 'sj#python#SplitTernaryAssignment',
|
||||||
|
\ 'sj#python#SplitDict',
|
||||||
|
\ 'sj#python#SplitArray',
|
||||||
|
\ 'sj#python#SplitStatement',
|
||||||
|
\ 'sj#python#SplitImport',
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#python#JoinTuple',
|
||||||
|
\ 'sj#python#JoinDict',
|
||||||
|
\ 'sj#python#JoinArray',
|
||||||
|
\ 'sj#python#JoinTernaryAssignment',
|
||||||
|
\ 'sj#python#JoinStatement',
|
||||||
|
\ 'sj#python#JoinImport',
|
||||||
|
\ 'sj#python#JoinAssignment',
|
||||||
|
\ ]
|
||||||
|
endif
|
12
bundle/splitjoin.vim/ftplugin/r/splitjoin.vim
Normal file
12
bundle/splitjoin.vim/ftplugin/r/splitjoin.vim
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#r#SplitFuncall'
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#r#JoinFuncall',
|
||||||
|
\ 'sj#r#JoinSmart'
|
||||||
|
\ ]
|
||||||
|
endif
|
35
bundle/splitjoin.vim/ftplugin/ruby/splitjoin.vim
Normal file
35
bundle/splitjoin.vim/ftplugin/ruby/splitjoin.vim
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#ruby#SplitModuleNamespace',
|
||||||
|
\ 'sj#ruby#SplitArray',
|
||||||
|
\ 'sj#ruby#SplitArrayLiteral',
|
||||||
|
\ 'sj#ruby#SplitProcShorthand',
|
||||||
|
\ 'sj#ruby#SplitBlock',
|
||||||
|
\ 'sj#ruby#SplitIfClause',
|
||||||
|
\ 'sj#ruby#SplitCachingConstruct',
|
||||||
|
\ 'sj#ruby#SplitWhenThen',
|
||||||
|
\ 'sj#ruby#SplitCase',
|
||||||
|
\ 'sj#ruby#SplitTernaryClause',
|
||||||
|
\ 'sj#ruby#SplitOptions',
|
||||||
|
\ 'sj#ruby#SplitString',
|
||||||
|
\ 'sj#ruby#SplitEndlessDef',
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#ruby#JoinModuleNamespace',
|
||||||
|
\ 'sj#ruby#JoinArray',
|
||||||
|
\ 'sj#ruby#JoinArrayLiteral',
|
||||||
|
\ 'sj#ruby#JoinBlock',
|
||||||
|
\ 'sj#ruby#JoinHash',
|
||||||
|
\ 'sj#ruby#JoinIfClause',
|
||||||
|
\ 'sj#ruby#JoinTernaryClause',
|
||||||
|
\ 'sj#ruby#JoinCachingConstruct',
|
||||||
|
\ 'sj#ruby#JoinContinuedMethodCall',
|
||||||
|
\ 'sj#ruby#JoinHeredoc',
|
||||||
|
\ 'sj#ruby#JoinWhenThen',
|
||||||
|
\ 'sj#ruby#JoinCase',
|
||||||
|
\ 'sj#ruby#JoinOnelineDef',
|
||||||
|
\ ]
|
||||||
|
endif
|
24
bundle/splitjoin.vim/ftplugin/rust/splitjoin.vim
Normal file
24
bundle/splitjoin.vim/ftplugin/rust/splitjoin.vim
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#rust#SplitBlockClosure',
|
||||||
|
\ 'sj#rust#SplitExprClosure',
|
||||||
|
\ 'sj#rust#SplitMatchExpression',
|
||||||
|
\ 'sj#rust#SplitMatchClause',
|
||||||
|
\ 'sj#rust#SplitQuestionMark',
|
||||||
|
\ 'sj#rust#SplitCurlyBrackets',
|
||||||
|
\ 'sj#rust#SplitImportList',
|
||||||
|
\ 'sj#rust#SplitUnwrapIntoEmptyMatch',
|
||||||
|
\ 'sj#rust#SplitIfLetIntoMatch',
|
||||||
|
\ 'sj#rust#SplitArray',
|
||||||
|
\ 'sj#rust#SplitArgs',
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#rust#JoinEmptyMatchIntoIfLet',
|
||||||
|
\ 'sj#rust#JoinMatchClause',
|
||||||
|
\ 'sj#rust#JoinMatchStatement',
|
||||||
|
\ 'sj#rust#JoinClosure',
|
||||||
|
\ 'sj#rust#JoinCurlyBrackets',
|
||||||
|
\ 'sj#rust#JoinImportList',
|
||||||
|
\ 'sj#rust#JoinArray',
|
||||||
|
\ 'sj#rust#JoinArgs',
|
||||||
|
\ ]
|
15
bundle/splitjoin.vim/ftplugin/scss/splitjoin.vim
Normal file
15
bundle/splitjoin.vim/ftplugin/scss/splitjoin.vim
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#css#SplitMultilineSelector',
|
||||||
|
\ 'sj#scss#SplitNestedDefinition',
|
||||||
|
\ 'sj#css#SplitDefinition',
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#scss#JoinNestedDefinition',
|
||||||
|
\ 'sj#css#JoinDefinition',
|
||||||
|
\ 'sj#css#JoinMultilineSelector',
|
||||||
|
\ ]
|
||||||
|
endif
|
9
bundle/splitjoin.vim/ftplugin/sh/splitjoin.vim
Normal file
9
bundle/splitjoin.vim/ftplugin/sh/splitjoin.vim
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#sh#SplitBySemicolon',
|
||||||
|
\ 'sj#sh#SplitWithBackslash',
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#sh#JoinBackslashedLine',
|
||||||
|
\ 'sj#sh#JoinWithSemicolon',
|
||||||
|
\ ]
|
9
bundle/splitjoin.vim/ftplugin/snakemake/splitjoin.vim
Normal file
9
bundle/splitjoin.vim/ftplugin/snakemake/splitjoin.vim
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#coffee#SplitString',
|
||||||
|
\ 'sj#python#SplitStatement',
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#python#JoinStatement',
|
||||||
|
\ 'sj#coffee#JoinString',
|
||||||
|
\ ]
|
1
bundle/splitjoin.vim/ftplugin/svelte/splitjoin.vim
Normal file
1
bundle/splitjoin.vim/ftplugin/svelte/splitjoin.vim
Normal file
@ -0,0 +1 @@
|
|||||||
|
runtime ftplugin/vue/splitjoin.vim
|
7
bundle/splitjoin.vim/ftplugin/tex/splitjoin.vim
Normal file
7
bundle/splitjoin.vim/ftplugin/tex/splitjoin.vim
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#tex#SplitBlock',
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#tex#JoinBlock',
|
||||||
|
\ ]
|
24
bundle/splitjoin.vim/ftplugin/tsx/splitjoin.vim
Normal file
24
bundle/splitjoin.vim/ftplugin/tsx/splitjoin.vim
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#jsx#SplitJsxExpression',
|
||||||
|
\ 'sj#html#SplitTags',
|
||||||
|
\ 'sj#html#SplitAttributes',
|
||||||
|
\ 'sj#js#SplitObjectLiteral',
|
||||||
|
\ 'sj#js#SplitFatArrowFunction',
|
||||||
|
\ 'sj#js#SplitArray',
|
||||||
|
\ 'sj#js#SplitFunction',
|
||||||
|
\ 'sj#js#SplitOneLineIf',
|
||||||
|
\ 'sj#js#SplitArgs',
|
||||||
|
\ 'sj#jsx#SplitSelfClosingTag'
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#jsx#JoinJsxExpression',
|
||||||
|
\ 'sj#html#JoinAttributes',
|
||||||
|
\ 'sj#jsx#JoinHtmlTag',
|
||||||
|
\ 'sj#js#JoinFatArrowFunction',
|
||||||
|
\ 'sj#js#JoinArray',
|
||||||
|
\ 'sj#js#JoinArgs',
|
||||||
|
\ 'sj#js#JoinFunction',
|
||||||
|
\ 'sj#js#JoinOneLineIf',
|
||||||
|
\ 'sj#js#JoinObjectLiteral',
|
||||||
|
\ ]
|
1
bundle/splitjoin.vim/ftplugin/typescript/splitjoin.vim
Normal file
1
bundle/splitjoin.vim/ftplugin/typescript/splitjoin.vim
Normal file
@ -0,0 +1 @@
|
|||||||
|
runtime ftplugin/javascript/splitjoin.vim
|
@ -0,0 +1 @@
|
|||||||
|
runtime ftplugin/tsx/splitjoin.vim
|
13
bundle/splitjoin.vim/ftplugin/vim/splitjoin.vim
Normal file
13
bundle/splitjoin.vim/ftplugin/vim/splitjoin.vim
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#vim#SplitIfClause',
|
||||||
|
\ 'sj#vim#Split',
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#vim#JoinIfClause',
|
||||||
|
\ 'sj#vim#Join',
|
||||||
|
\ ]
|
||||||
|
endif
|
25
bundle/splitjoin.vim/ftplugin/vue/splitjoin.vim
Normal file
25
bundle/splitjoin.vim/ftplugin/vue/splitjoin.vim
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#html#SplitTags',
|
||||||
|
\ 'sj#html#SplitAttributes',
|
||||||
|
\ 'sj#vue#SplitCssDefinition',
|
||||||
|
\ 'sj#vue#SplitCssMultilineSelector',
|
||||||
|
\ 'sj#js#SplitObjectLiteral',
|
||||||
|
\ 'sj#js#SplitFatArrowFunction',
|
||||||
|
\ 'sj#js#SplitArray',
|
||||||
|
\ 'sj#js#SplitFunction',
|
||||||
|
\ 'sj#js#SplitOneLineIf',
|
||||||
|
\ 'sj#js#SplitArgs',
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#html#JoinAttributes',
|
||||||
|
\ 'sj#html#JoinTags',
|
||||||
|
\ 'sj#vue#JoinCssDefinition',
|
||||||
|
\ 'sj#vue#JoinCssMultilineSelector',
|
||||||
|
\ 'sj#js#JoinFatArrowFunction',
|
||||||
|
\ 'sj#js#JoinArray',
|
||||||
|
\ 'sj#js#JoinArgs',
|
||||||
|
\ 'sj#js#JoinFunction',
|
||||||
|
\ 'sj#js#JoinOneLineIf',
|
||||||
|
\ 'sj#js#JoinObjectLiteral',
|
||||||
|
\ ]
|
13
bundle/splitjoin.vim/ftplugin/xml/splitjoin.vim
Normal file
13
bundle/splitjoin.vim/ftplugin/xml/splitjoin.vim
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
" Wrap them in conditions to avoid messing up erb
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#html#SplitTags'
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#html#JoinTags'
|
||||||
|
\ ]
|
||||||
|
endif
|
13
bundle/splitjoin.vim/ftplugin/yaml/splitjoin.vim
Normal file
13
bundle/splitjoin.vim/ftplugin/yaml/splitjoin.vim
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
if !exists('b:splitjoin_split_callbacks')
|
||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#yaml#SplitArray',
|
||||||
|
\ 'sj#yaml#SplitMap'
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('b:splitjoin_join_callbacks')
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#yaml#JoinArray',
|
||||||
|
\ 'sj#yaml#JoinMap'
|
||||||
|
\ ]
|
||||||
|
endif
|
7
bundle/splitjoin.vim/ftplugin/zsh/splitjoin.vim
Normal file
7
bundle/splitjoin.vim/ftplugin/zsh/splitjoin.vim
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
let b:splitjoin_split_callbacks = [
|
||||||
|
\ 'sj#sh#SplitBySemicolon',
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let b:splitjoin_join_callbacks = [
|
||||||
|
\ 'sj#sh#JoinWithSemicolon',
|
||||||
|
\ ]
|
91
bundle/splitjoin.vim/plugin/splitjoin.vim
Normal file
91
bundle/splitjoin.vim/plugin/splitjoin.vim
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
if exists("g:loaded_splitjoin") || &cp
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
let g:loaded_splitjoin = '1.2.0' " version number
|
||||||
|
let s:keepcpo = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
" Defaults:
|
||||||
|
" =========
|
||||||
|
|
||||||
|
let g:splitjoin_default_settings = {
|
||||||
|
\ 'quiet': 0,
|
||||||
|
\ 'disabled_split_callbacks': [],
|
||||||
|
\ 'disabled_join_callbacks': [],
|
||||||
|
\ 'mapping_fallback': 1,
|
||||||
|
\
|
||||||
|
\ 'normalize_whitespace': 1,
|
||||||
|
\ 'trailing_comma': 0,
|
||||||
|
\ 'align': 0,
|
||||||
|
\ 'curly_brace_padding': 1,
|
||||||
|
\ 'ruby_curly_braces': 1,
|
||||||
|
\ 'ruby_heredoc_type': '<<~',
|
||||||
|
\ 'ruby_trailing_comma': 0,
|
||||||
|
\ 'ruby_hanging_args': 1,
|
||||||
|
\ 'ruby_do_block_split': 1,
|
||||||
|
\ 'ruby_options_as_arguments': 0,
|
||||||
|
\ 'ruby_expand_options_in_arrays': 0,
|
||||||
|
\ 'c_argument_split_first_newline': 0,
|
||||||
|
\ 'c_argument_split_last_newline': 0,
|
||||||
|
\ 'coffee_suffix_if_clause': 1,
|
||||||
|
\ 'perl_brace_on_same_line': 1,
|
||||||
|
\ 'php_method_chain_full': 0,
|
||||||
|
\ 'python_brackets_on_separate_lines': 0,
|
||||||
|
\ 'handlebars_closing_bracket_on_same_line': 0,
|
||||||
|
\ 'handlebars_hanging_arguments': 0,
|
||||||
|
\ 'html_attribute_bracket_on_new_line': 0,
|
||||||
|
\ 'java_argument_split_first_newline': 0,
|
||||||
|
\ 'java_argument_split_last_newline': 0,
|
||||||
|
\ 'vim_split_whitespace_after_backslash': 1,
|
||||||
|
\ }
|
||||||
|
|
||||||
|
if !exists('g:splitjoin_join_mapping')
|
||||||
|
let g:splitjoin_join_mapping = 'gJ'
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('g:splitjoin_split_mapping')
|
||||||
|
let g:splitjoin_split_mapping = 'gS'
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Public Interface:
|
||||||
|
" =================
|
||||||
|
|
||||||
|
command! SplitjoinSplit call sj#Split()
|
||||||
|
command! SplitjoinJoin call sj#Join()
|
||||||
|
|
||||||
|
nnoremap <silent> <plug>SplitjoinSplit :<c-u>call sj#Split()<cr>
|
||||||
|
nnoremap <silent> <plug>SplitjoinJoin :<c-u>call sj#Join()<cr>
|
||||||
|
|
||||||
|
if g:splitjoin_join_mapping != ''
|
||||||
|
exe 'nnoremap <silent> '.g:splitjoin_join_mapping.' :<c-u>call <SID>Mapping(g:splitjoin_join_mapping, "sj#Join")<cr>'
|
||||||
|
endif
|
||||||
|
|
||||||
|
if g:splitjoin_split_mapping != ''
|
||||||
|
exe 'nnoremap <silent> '.g:splitjoin_split_mapping.' :<c-u>call <SID>Mapping(g:splitjoin_split_mapping, "sj#Split")<cr>'
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Internal Functions:
|
||||||
|
" ===================
|
||||||
|
|
||||||
|
" Used to create a mapping for the given a:function that falls back to the
|
||||||
|
" built-in key sequence (a:mapping) if the function returns 0, meaning it
|
||||||
|
" didn't do anything.
|
||||||
|
"
|
||||||
|
function! s:Mapping(mapping, function)
|
||||||
|
if !sj#settings#Read('mapping_fallback')
|
||||||
|
call call(a:function, [])
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !v:count
|
||||||
|
if !call(a:function, [])
|
||||||
|
execute 'normal! '.a:mapping
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
execute 'normal! '.v:count.a:mapping
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
let &cpo = s:keepcpo
|
||||||
|
unlet s:keepcpo
|
63
bundle/splitjoin.vim/spec/plugin/c_spec.rb
Normal file
63
bundle/splitjoin.vim/spec/plugin/c_spec.rb
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe "c" do
|
||||||
|
let(:filename) { 'test.c' }
|
||||||
|
|
||||||
|
before :each do
|
||||||
|
vim.set(:expandtab)
|
||||||
|
vim.set(:shiftwidth, 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "if_clause" do
|
||||||
|
set_file_contents "if (val1 && val2 || val3);"
|
||||||
|
|
||||||
|
vim.search 'if'
|
||||||
|
split
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
if (val1
|
||||||
|
&& val2
|
||||||
|
|| val3);
|
||||||
|
EOF
|
||||||
|
|
||||||
|
join
|
||||||
|
|
||||||
|
assert_file_contents "if (val1 && val2 || val3);"
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "function_call" do
|
||||||
|
set_file_contents "myfunction(lots, of, different, parameters)"
|
||||||
|
|
||||||
|
vim.search '('
|
||||||
|
split
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
myfunction(lots,
|
||||||
|
of,
|
||||||
|
different,
|
||||||
|
parameters)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
join
|
||||||
|
|
||||||
|
assert_file_contents "myfunction(lots, of, different, parameters)"
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "ignores strings" do
|
||||||
|
set_file_contents "\"myfunction(several, parameters)\""
|
||||||
|
|
||||||
|
vim.search '('
|
||||||
|
split
|
||||||
|
|
||||||
|
assert_file_contents "\"myfunction(several, parameters)\""
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "ignores comments" do
|
||||||
|
set_file_contents "/* myfunction(several, parameters) */"
|
||||||
|
|
||||||
|
vim.search '('
|
||||||
|
split
|
||||||
|
|
||||||
|
assert_file_contents "/* myfunction(several, parameters) */"
|
||||||
|
end
|
||||||
|
end
|
76
bundle/splitjoin.vim/spec/plugin/clojure_spec.rb
Normal file
76
bundle/splitjoin.vim/spec/plugin/clojure_spec.rb
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe "clojure" do
|
||||||
|
let(:filename) { 'test.clj' }
|
||||||
|
|
||||||
|
specify "Lists with ([ brackets" do
|
||||||
|
set_file_contents "(dispatch [::events/insert-staff-entry day-ord shift unit @why @who])"
|
||||||
|
|
||||||
|
vim.search 'dispatch'
|
||||||
|
split
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
(dispatch
|
||||||
|
[::events/insert-staff-entry day-ord shift unit @why @who])
|
||||||
|
EOF
|
||||||
|
|
||||||
|
join
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
(dispatch [::events/insert-staff-entry day-ord shift unit @why @who])
|
||||||
|
EOF
|
||||||
|
|
||||||
|
vim.search 'day-ord'
|
||||||
|
split
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
(dispatch [::events/insert-staff-entry
|
||||||
|
day-ord
|
||||||
|
shift
|
||||||
|
unit
|
||||||
|
@why
|
||||||
|
@who])
|
||||||
|
EOF
|
||||||
|
|
||||||
|
join
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
(dispatch [::events/insert-staff-entry day-ord shift unit @why @who])
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "Dictionaries" do
|
||||||
|
set_file_contents '#{:a :b :c :d}'
|
||||||
|
|
||||||
|
vim.search ':b'
|
||||||
|
split
|
||||||
|
|
||||||
|
assert_file_contents <<~'EOF'
|
||||||
|
#{:a
|
||||||
|
:b
|
||||||
|
:c
|
||||||
|
:d}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
join
|
||||||
|
|
||||||
|
assert_file_contents '#{:a :b :c :d}'
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "Doesn't get confused with brackets in strings" do
|
||||||
|
set_file_contents '(map (fn [x] (.toUpperCase x)) (.split "Dasher Dancer) Prancer" " "))'
|
||||||
|
|
||||||
|
vim.search 'Dancer'
|
||||||
|
split
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
(map (fn [x] (.toUpperCase x)) (.split
|
||||||
|
"Dasher Dancer) Prancer"
|
||||||
|
" "))
|
||||||
|
EOF
|
||||||
|
|
||||||
|
join
|
||||||
|
|
||||||
|
assert_file_contents '(map (fn [x] (.toUpperCase x)) (.split "Dasher Dancer) Prancer" " "))'
|
||||||
|
end
|
||||||
|
end
|
187
bundle/splitjoin.vim/spec/plugin/coffee_spec.rb
Normal file
187
bundle/splitjoin.vim/spec/plugin/coffee_spec.rb
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
# Note: Coffeescript is not a built-in filetype, so these specs work with no
|
||||||
|
# automatic indentation. It's still possible that bugs would creep in due when
|
||||||
|
# real indentation is factored in, though I've attempted to minimize the
|
||||||
|
# effects of that.
|
||||||
|
#
|
||||||
|
describe "coffee" do
|
||||||
|
let(:filename) { 'test.coffee' }
|
||||||
|
|
||||||
|
# Coffee is not built-in, so let's set it up manually
|
||||||
|
def setup_coffee_filetype
|
||||||
|
vim.set(:filetype, 'coffee')
|
||||||
|
vim.set(:expandtab)
|
||||||
|
vim.set(:shiftwidth, 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "functions" do
|
||||||
|
set_file_contents "(foo, bar) -> console.log foo"
|
||||||
|
setup_coffee_filetype
|
||||||
|
|
||||||
|
split
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
(foo, bar) ->
|
||||||
|
console.log foo
|
||||||
|
EOF
|
||||||
|
|
||||||
|
join
|
||||||
|
|
||||||
|
assert_file_contents "(foo, bar) -> console.log foo"
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "postfix if-clauses" do
|
||||||
|
set_file_contents "console.log bar if foo?"
|
||||||
|
setup_coffee_filetype
|
||||||
|
|
||||||
|
split
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
if foo?
|
||||||
|
console.log bar
|
||||||
|
EOF
|
||||||
|
|
||||||
|
join
|
||||||
|
|
||||||
|
assert_file_contents "console.log bar if foo?"
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "suffix if-clauses" do
|
||||||
|
set_file_contents "if foo? then console.log bar"
|
||||||
|
setup_coffee_filetype
|
||||||
|
|
||||||
|
split
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
if foo?
|
||||||
|
console.log bar
|
||||||
|
EOF
|
||||||
|
|
||||||
|
join
|
||||||
|
|
||||||
|
assert_file_contents "console.log bar if foo?"
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "ternary operator" do
|
||||||
|
set_file_contents <<~EOF
|
||||||
|
do ->
|
||||||
|
foo = if bar? then 'baz' else 'qux'
|
||||||
|
EOF
|
||||||
|
setup_coffee_filetype
|
||||||
|
|
||||||
|
vim.search 'foo'
|
||||||
|
split
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
do ->
|
||||||
|
if bar?
|
||||||
|
foo = 'baz'
|
||||||
|
else
|
||||||
|
foo = 'qux'
|
||||||
|
EOF
|
||||||
|
|
||||||
|
vim.search 'bar'
|
||||||
|
join
|
||||||
|
|
||||||
|
set_file_contents <<~EOF
|
||||||
|
do ->
|
||||||
|
foo = if bar? then 'baz' else 'qux'
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "joining ternary operator without any assignment magic" do
|
||||||
|
set_file_contents <<~EOF
|
||||||
|
if bar?
|
||||||
|
foo = "baz"
|
||||||
|
else
|
||||||
|
baz = "qux"
|
||||||
|
EOF
|
||||||
|
setup_coffee_filetype
|
||||||
|
|
||||||
|
vim.search 'bar'
|
||||||
|
join
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
if bar? then foo = "baz" else baz = "qux"
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "object literals" do
|
||||||
|
set_file_contents 'one = { one: "two", three: "four" }'
|
||||||
|
setup_coffee_filetype
|
||||||
|
|
||||||
|
split
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
one =
|
||||||
|
one: "two"
|
||||||
|
three: "four"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
join
|
||||||
|
|
||||||
|
assert_file_contents 'one = { one: "two", three: "four" }'
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "function calls with object literals" do
|
||||||
|
set_file_contents 'foo = functionCall(one, two, three: four, five: six)'
|
||||||
|
setup_coffee_filetype
|
||||||
|
|
||||||
|
split
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
foo = functionCall one, two,
|
||||||
|
three: four
|
||||||
|
five: six
|
||||||
|
EOF
|
||||||
|
|
||||||
|
join
|
||||||
|
|
||||||
|
assert_file_contents 'foo = functionCall one, two, { three: four, five: six }'
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "strings" do
|
||||||
|
set_file_contents <<~EOF
|
||||||
|
foo = "example with \#{interpolation} and \\"nested\\" quotes"
|
||||||
|
EOF
|
||||||
|
setup_coffee_filetype
|
||||||
|
|
||||||
|
vim.search 'example'
|
||||||
|
split
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
foo = """
|
||||||
|
example with \#{interpolation} and "nested" quotes
|
||||||
|
"""
|
||||||
|
EOF
|
||||||
|
|
||||||
|
join
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
foo = "example with \#{interpolation} and \\"nested\\" quotes"
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "triple strings" do
|
||||||
|
set_file_contents <<~EOF
|
||||||
|
foo = """example with \#{interpolation} and "nested" quotes"""
|
||||||
|
EOF
|
||||||
|
setup_coffee_filetype
|
||||||
|
|
||||||
|
vim.search 'example'
|
||||||
|
split
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
foo = """
|
||||||
|
example with \#{interpolation} and "nested" quotes
|
||||||
|
"""
|
||||||
|
EOF
|
||||||
|
|
||||||
|
join
|
||||||
|
|
||||||
|
assert_file_contents <<~EOF
|
||||||
|
foo = "example with \#{interpolation} and \\"nested\\" quotes"
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user