1
0
Fork 0
mirror of synced 2024-12-25 00:03:20 -05:00

Add support of auto format files.

This commit is contained in:
Kurtis Moxley 2022-05-20 17:05:00 +08:00
parent 25e4662559
commit cdd9fbbddb
25 changed files with 12539 additions and 27 deletions

View file

@ -0,0 +1,7 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.vim text
*.md text

View file

@ -0,0 +1 @@
Before you create an issue, please read and follow the troubleshooting steps [listed here](https://github.com/Chiel92/vim-autoformat#help-the-formatter-doesnt-work-as-expected).

View file

@ -0,0 +1,2 @@
# Ignore vim swap files
*.swp

View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2013 Chiel ten Brinke
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.

View file

@ -0,0 +1,505 @@
# vim-autoformat
Format code with one button press (or automatically on save).
This plugin makes use of external formatting programs to achieve the most decent results.
Check the list of formatprograms below to see which languages are supported by default.
Most formatprograms will obey vim settings, such as `textwidth` and `shiftwidth()`.
You can easily customize existing formatprogram definitions or add your own formatprogram.
When no formatprogram exists (or no formatprogram is installed) for a certain filetype,
vim-autoformat falls back by default to indenting, (using vim's auto indent functionality), retabbing and removing trailing whitespace.
## Requirement
vim-autoformat requires vim to have python support (python 2 or python 3). You can check your vim has python support by running `:echo has("python3")` and `:echo has("python2")`.
#### Neovim
Neovim does not come with python support by default, and additional setup is required.
First install [pynvim](https://github.com/neovim/pynvim)
```
python3 -m pip install pynvim
```
And add the following configuration in your `.vimrc`
```
let g:python3_host_prog="/path/to/python/executable/"
```
## How to install
#### Vundle
Put this in your `.vimrc`.
```vim
Plugin 'Chiel92/vim-autoformat'
```
Then restart vim and run `:PluginInstall`. Alternatively, you could run `:source $MYVIMRC`
to reload your `.vimrc` without restarting vim.
To update the plugin to the latest version, you can run `:PluginUpdate`.
#### Pathogen
Download the source and extract in your bundle directory.
Updating has to be done manually, as far as I'm aware.
#### Other
It is highly recommended to use a plugin manager such as Vundle, since this makes it easy to update plugins or uninstall them.
It also keeps your .vim directory clean.
Still you can decide to download this repository as a zip file or whatever and extract it to your .vim folder.
## How to use
First you should install an external program that can format code of the programming language you are using.
This can either be one of the programs that are listed below as defaultprograms, or a custom program.
For defaultprograms, vim-autoformat knows for which filetypes it can be used.
For using a custom formatprogram, read the text below *How can I change the behaviour of formatters, or add one myself?*
If the formatprogram you want to use is installed in one of the following ways, vim automatically detects it:
* It suffices to make the formatprogram globally available, which is the case if you install it via your package manager.
* Alternatively you can point vim-autoformat to folders containing formatters, by putting the absolute paths to these folders in `g:formatterpath` in your .vimrc, like:
```vim
let g:formatterpath = ['/some/path/to/a/folder', '/home/superman/formatters']
```
Remember that when no formatprograms exists for a certain filetype,
vim-autoformat falls back by default to indenting, retabbing and removing trailing whitespace.
This will fix at least the most basic things, according to vim's indentfile for that filetype.
When you have installed the formatter you need, you can format the entire buffer with the command `:Autoformat`.
You can provide the command with a file type such as `:Autoformat json`, otherwise the buffer's filetype will be used.
Some formatters allow you to format only a part of the file, for instance `clang-format` and
`autopep8`.
To use this, provide a range to the `:Autoformat` command, for instance by visually selecting a
part of your file, and then executing `:Autoformat`.
For convenience it is recommended that you assign a key for this, like so:
```vim
noremap <F3> :Autoformat<CR>
```
Or to have your code be formatted upon saving your file, you could use something like this:
```vim
au BufWrite * :Autoformat
```
You can also format the current line only (without having to make a visual selection) by executing `:AutoformatLine`.
To disable the fallback to vim's indent file, retabbing and removing trailing whitespace, set the following variables to 0.
```vim
let g:autoformat_autoindent = 0
let g:autoformat_retab = 0
let g:autoformat_remove_trailing_spaces = 0
```
To disable or re-enable these option for specific buffers, use the buffer local variants:
`b:autoformat_autoindent`, `b:autoformat_retab` and `b:autoformat_remove_trailing_spaces`.
So to disable autoindent for filetypes that have incompetent indent files, use
```vim
autocmd FileType vim,tex let b:autoformat_autoindent=0
```
You can manually autoindent, retab or remove trailing whitespace with the following respective
commands.
```vim
gg=G
:retab
:RemoveTrailingSpaces
```
For each filetype, vim-autoformat has a list of applicable formatters.
If you have multiple formatters installed that are supported for some filetype, vim-autoformat
tries all formatters in this list of applicable formatters, until one succeeds.
You can set this list manually in your vimrc (see section *How can I change the behaviour of formatters, or add one myself?*,
or change the formatter with the highest priority by the commands `:NextFormatter` and `:PreviousFormatter`.
To print the currently selected formatter use `:CurrentFormatter`.
These latter commands are mostly useful for debugging purposes.
If you have a composite filetype with dots (like `django.python` or `php.wordpress`),
vim-autoformat first tries to detect and use formatters for the exact original filetype, and
then tries the same for all supertypes occurring from left to right in the original filetype
separated by dots (`.`).
### Using multiple formatters for the same file
It is possible to apply multiple formatters for single file, for example, html can use special formatters for js/css etc.
Support can be enabled via the `g:run_all_formatters_<identifier>` option.
In this case, formatters from `g:formatdef_<identifier>` will be applied to the file one by one. Fallback (vim) formatting
isn't used if at least one formatter has finished sucessfully.
Sample config:
```vim
let g:formatters_vue = ['eslint_local', 'stylelint']
let g:run_all_formatters_vue = 1
```
## Default formatprograms
Here is a list of formatprograms that are supported by default, and thus will be detected and used by vim when they are installed properly.
* `buildifier` for __bazel__ build files. (https://github.com/bazelbuild/buildtools/tree/master/buildifier)
* `clang-format` for __C__, __C++__, __Objective-C__, __Protobuf__ (supports formatting ranges).
Clang-format is a product of LLVM source builds.
If you `brew install llvm`, clang-format can be found in /usr/local/Cellar/llvm/bin/.
Vim-autoformat checks whether there exists a `.clang-format` or a `_clang-format` file up in
the current directory's ancestry. Based on that it either uses that file or tries to match
vim options as much as possible.
Details: http://clang.llvm.org/docs/ClangFormat.html.
* `astyle` for __C#__, __C++__, __C__ and __Java__.
Download it here: http://astyle.sourceforge.net/.
*Important: version `2.0.5` or higher is required, since only those versions correctly support piping and are stable enough.*
* `dfmt` for __D__.
It can be built or downloaded from https://github.com/dlang-community/dfmt.
Arch Linux users can install it from the `community` repository with `pacman -S dfmt`.
If `dfmt` is not found in `PATH`, Vim-autoformat will try to use `dub run dfmt` command
to automatically download and run `dfmt`.
* `autopep8` for __Python__ (supports formatting ranges).
It's probably in your distro's repository, so you can download it as a regular package.
For Ubuntu type `sudo apt-get install python-autopep8` in a terminal.
Here is the link to the repository: https://github.com/hhatto/autopep8.
And here the link to its page on the python website: http://pypi.python.org/pypi/autopep8/0.5.2.
* `yapf` for __Python__ (supports formatting ranges).
Vim-autoformat checks whether there exists a `.style.yapf` or a `setup.cfg` file up in the current directory's ancestry.
Based on that it either uses that file or tries to match vim options as much as possible.
Most users can install with the terminal command `sudo pip install yapf` or `pip install --user yapf`.
YAPF has one optional configuration variable to control the formatter style.
For example:
```vim
let g:formatter_yapf_style = 'pep8'
```
`pep8` is the default value, or you can choose: `google`, `facebook`, `chromium`.
Here is the link to the repository: https://github.com/google/yapf
* `black` for __Python__.
Most users can install with the terminal command `sudo pip install black` or `pip install --user black`.
Here is the link to the repository: https://github.com/ambv/black
* `js-beautify` for __Javascript__ and __JSON__.
It can be installed by running `npm install -g js-beautify`.
Note that `nodejs` is needed for this to work.
The python version version is also supported by default, which does not need `nodejs` to run.
Here is the link to the repository: https://github.com/einars/js-beautify.
* `JSCS` for __Javascript__. https://jscs-dev.github.io/
* `gnatpp` for __Ada__. http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gnat_ugn_unw/The-GNAT-Pretty_002dPrinter-gnatpp.html
* `standard` for __Javascript__.
It can be installed by running `npm install -g standard` (`nodejs` is required). No more configuration needed.
More information about the style guide can be found here: http://standardjs.com/.
* `ESlint` for __Javascript__. http://eslint.org/
It can be installed by running `npm install eslint` for a local project or by running `npm install -g eslint` for global use. The linter is then installed locally at `$YOUR_PROJECT/node_modules/.bin/eslint` or globally at `~/.npm-global/bin/eslint`.
When running the formatter, vim will walk up from the current file to search for such local installation and a ESLint configuration file (either `.eslintrc.js` or `eslintrc.json`). When the local version is missing it will fallback to the global version in your home directory. When both requirements are found eslint is executed with the `--fix` argument.
Note that the formatter's name is still `eslint_local` for legacy reasons even though it already supports global `eslint`.
Currently only working on \*nix like OS (Linux, MacOS etc.) as it requires the OS to provide sh like shell syntax.
* `xo` for __Javascript__.
It can be installed by running `npm install -g xo` (`nodejs` is required).
Here is the link to the repository: https://github.com/sindresorhus/xo.
* `JuliaFormatter.jl` for __Julia__.
It can be installed by running `julia -e 'import Pkg; Pkg.add("JuliaFormatter")'`. You will need to install Julia and have the `julia` binary in your `PATH`.
See https://github.com/domluna/JuliaFormatter.jl for more information on how to configure `JuliaFormatter.jl`.
Note that since `vim-autoformat` works by running a subprocess, a new instance of Julia is instantiated every time it is invoked.
And since Julia needs to precompile the code to run `format_text`, this may block the vim instance while the subprocess is running.
Once Julia finishes executing, control will be handled back to the user and the formatted text will replaces the current buffer.
You can consider precompiling `JuliaFormatter.jl` to make this process faster (See [`PackageCompiler.jl`](https://github.com/JuliaLang/PackageCompiler.jl) for more information on that),
or consider using [a dedicated `JuliaFormatter.vim` plugin](https://github.com/kdheepak/JuliaFormatter.vim) that works asynchronously.
* `html-beautify` for __HTML__.
It is shipped with `js-beautify`, which can be installed by running `npm install -g js-beautify`.
Note that `nodejs` is needed for this to work.
Here is the link to the repository: https://github.com/einars/js-beautify.
* `css-beautify` for __CSS__.
It is shipped with `js-beautify`, which can be installed by running `npm install -g js-beautify`.
Note that `nodejs` is needed for this to work.
Here is the link to the repository: https://github.com/einars/js-beautify.
* `stylelint` for __CSS__. https://stylelint.io/
It can be installed by running `npm install stylelint stylelint-config-standard` for a local project or by running `npm install -g stylelint stylelint-config-standard` for global use. The linter is then installed locally at `$YOUR_PROJECT/node_modules/.bin/stylelint` or globally at `~/.npm-global/bin/stylelint`.
When running the formatter, vim will walk up from the current file to search for such local installation. When the local version is missing it will fallback to the global version in your home directory. When both requirements are found styelint is executed with the `--fix` argument.
Currently only working on \*nix like OS (Linux, MacOS etc.) as it requires the OS to provide sh like shell syntax.
* `typescript-formatter` for __Typescript__.
`typescript-formatter` is a thin wrapper around the TypeScript compiler services.
It can be installed by running `npm install -g typescript-formatter`.
Note that `nodejs` is needed for this to work.
Here is the link to the repository: https://github.com/vvakame/typescript-formatter.
* `haxe-formatter` for __Haxe__.
`haxe-formatter` is a thin wrapper around the haxelib formatter library.
It can be installed by running `haxelib install formatter`.
Here is the link to the repository: https://github.com/HaxeCheckstyle/haxe-formatter
* `sass-convert` for __SCSS__.
It is shipped with `sass`, a CSS preprocessor written in Ruby, which can be installed by running `gem install sass`.
Here is the link to the SASS homepage: http://sass-lang.com/.
* `tidy` for __HTML__, __XHTML__ and __XML__.
It's probably in your distro's repository, so you can download it as a regular package.
For Ubuntu type `sudo apt-get install tidy` in a terminal.
* `rbeautify` for __Ruby__.
It is shipped with `ruby-beautify`, which can be installed by running `gem install ruby-beautify`.
Note that compatible `ruby-beautify-0.94.0` or higher version.
Here is the link to the repository: https://github.com/erniebrodeur/ruby-beautify.
This beautifier developed and tested with ruby `2.0+`, so you can have weird results with earlier ruby versions.
* `rubocop` for __Ruby__.
It can be installed by running `gem install rubocop`.
Here is the link to the repository: https://github.com/bbatsov/rubocop
* `gofmt` for __Golang__.
The default golang formatting program is shipped with the golang distribution. Make sure `gofmt` is in your PATH (if golang is installed properly, it should be).
Here is the link to the installation: https://golang.org/doc/install
An alternative formatter is [gofumpt](https://github.com/mvdan/gofumpt), which enforces a stricter format than `gofmt`. To enable `gofumpt` support, you should install it by running `go install mvdan.cc/gofumpt@latest`, and then change the default golang formatter by configuring `let g:formatters_go = ['gofumpt']`.
* `rustfmt` for __Rust__.
It can be installed using `cargo`, the Rust package manager. Up-to-date installation instructions are on the project page: https://github.com/rust-lang/rustfmt#quick-start.
* `dartfmt` for __Dart__.
Part of the Dart SDK (make sure it is on your PATH). See https://www.dartlang.org/tools/dartfmt/ for more info.
* `perltidy` for __Perl__.
It can be installed from CPAN `cpanm Perl::Tidy` . See https://metacpan.org/pod/Perl::Tidy and http://perltidy.sourceforge.net/ for more info.
* `stylish-haskell` for __Haskell__
It can be installed using [`cabal`](https://www.haskell.org/cabal/) build tool. Installation instructions are available at https://github.com/jaspervdj/stylish-haskell#installation
* `purty` for __Purescript__
It can be installed using `npm install purty`. Further instructions available at https://gitlab.com/joneshf/purty
* `remark` for __Markdown__.
A Javascript based markdown processor that can be installed with `npm install -g remark-cli`. More info is available at https://github.com/wooorm/remark.
* `fprettify` for modern __Fortran__.
Download from [official repository](https://github.com/pseewald/fprettify). Install with `./setup.py install` or `./setup.py install --user`.
* `mix format` for __Elixir__.
`mix format` is included with Elixir 1.6+.
* `fixjson` for JSON.
It is a JSON file fixer/formatter for humans using (relaxed) JSON5. It fixes various failures while humans writing JSON and formats JSON codes.
It can be installed with `npm install -g fixjson`. More info is available at https://github.com/rhysd/fixjson.
* `shfmt` for __Shell__.
A shell formatter written in Go supporting POSIX Shell, Bash and mksh that can be installed with `go get -u mvdan.cc/sh/cmd/shfmt`. See https://github.com/mvdan/sh for more info.
* `fish_indent` for __Fish-shell__.
Fish shell builtin fish_indent formatter for fish shell script.
* `luafmt` for __Lua__.
Install `luafmt` with `npm`. See https://github.com/trixnz/lua-fmt for more info.
* `stylua` for __Lua__.
Install `stylua` with `cargo`. See https://github.com/JohnnyMorganz/StyLua for more info.
* `sqlformat` for __SQL__.
Install `sqlparse` with `pip`.
* `cmake-format` for __CMake__.
Install `cmake_format` with `pip`. See https://github.com/cheshirekow/cmake_format for more info.
* `latexindent.pl` for __LaTeX__.
Installation instructions at https://github.com/cmhughes/latexindent.pl. On mac you can install it with `brew install latexindent`, then you have to add `let g:formatdef_latexindent = '"latexindent -"'` to `.vimrc`.
* `ocamlformat` for __OCaml__.
OCamlFormat can be installed with opam: `opam install ocamlformat`.
Details: https://github.com/ocaml-ppx/ocamlformat.
We also provide `ocp-indent` as reserve formatter.
* `asmfmt` for __Assembly__.
An assembly formatter. Can be installed with `go get -u github.com/klauspost/asmfmt/cmd/asmfmt`. See https://github.com/klauspost/asmfmt for more info.
* `nixfmt` for __Nix__.
It can be installed from nixpkgs with `nix-env -iA nixpkgs.nixfmt`. See https://github.com/serokell/nixfmt for more.
* `dhall format` for __Dhall__.
The standard formatter, bundled with the interpreter. See https://github.com/dhall-lang/dhall-lang for more info.
* `terraform fmt` for __Terraform__.
The standard formatter included with Terraform. See https://www.terraform.io/docs/cli/commands/fmt.html for more info.
* `packer fmt` for __Packer__.
The standard formatter included with Packer. See https://www.packer.io/docs/commands/fmt for more info.
* `nginxfmt.py` for __NGINX__.
See https://github.com/slomkowski/nginx-config-formatter for more info.
* `zigformat` for __Zig__.
It is an unofficial binary. You can find the installation instructions from the repo: [zigformat](https://github.com/Himujjal/zigformat)
## Help, the formatter doesn't work as expected!
If you're struggling with getting a formatter to work, it may help to set vim-autoformat in
verbose-mode. Vim-autoformat will then output errors on formatters that failed.
The value of g:autoformat_verbosemode could set as 0, 1 or 2. which means:
0: no message output. 1: only error message output. 2: all message output.
```vim
let g:autoformat_verbosemode=1
" OR:
let verbose=1
```
To read all messages in a vim session type `:messages`. Since one cannot always easily copy
the contents of messages (e.g. for posting it in an issue), vim-autoformats command `:PutMessages` may
help. It puts the messages in the current buffer, allowing you to do whatever you want.
#### Reporting bugs
Please report bugs by creating an issue in this repository.
When there are problems with getting a certain formatter to work, provide the output of verbose
mode in the issue.
## How can I change the behaviour of formatters, or add one myself?
If you need a formatter that is not among the defaults, or if you are not satisfied with the default formatting behaviour that is provided by vim-autoformat, you can define it yourself.
*The formatprogram must read the unformatted code from the standard input, and write the formatted code to the standard output.*
#### Basic definitions
The formatprograms that available for a certain `<filetype>` are defined in `g:formatters_<filetype>`.
This is a list containing string identifiers, which point to corresponding formatter definitions.
The formatter definitions themselves are defined in `g:formatdef_<identifier>` as a string
expression.
Defining any of these variable manually in your .vimrc, will override the default value, if existing.
For example, a complete definition in your .vimrc for C# files could look like this:
```vim
let g:formatdef_my_custom_cs = '"astyle --mode=cs --style=ansi -pcHs4"'
let g:formatters_cs = ['my_custom_cs']
```
In this example, `my_custom_cs` is the identifier for our formatter definition.
The first line defines how to call the external formatter, while the second line tells
vim-autoformat that this is the only formatter that we want to use for C# files.
*Please note the double quotes in `g:formatdef_my_custom_cs`*.
This allows you to define the arguments dynamically:
```vim
let g:formatdef_my_custom_cs = '"astyle --mode=cs --style=ansi -pcHs".&shiftwidth'
let g:formatters_cs = ['my_custom_cs']
```
Please notice that `g:formatdef_my_custom_cs` contains an expression that can be evaluated, as required.
As you see, this allows us to dynamically define some parameters.
In this example, the indent width that astyle will use, depends on the buffer local value of `&shiftwidth`, instead of being fixed at 4.
So if you're editing a csharp file and change the `shiftwidth` (even at runtime), the `g:formatdef_my_custom_cs` will change correspondingly.
For the default formatprogram definitions, the options `expandtab`, `shiftwidth` and `textwidth` are taken into account whenever possible.
This means that the formatting style will match your current vim settings as much as possible.
You can have look look at the exact default definitions for more examples.
They are defined in `vim-autoformat/plugin/defaults.vim`.
As a small side note, in the actual defaults the function `shiftwidth()` is used instead of the
property. This is because it falls back to the value of `tabstop` if `shiftwidth` is 0.
If you have a composite filetype with dots (like `django.python` or `php.wordpress`),
vim-autoformat internally replaces the dots with underscores so you can specify formatters
through `g:formatters_django_python` and so on.
To override these options for a local buffer, use the buffer local variants:
`b:formatters_<filetype>` and `b:formatdef_<identifier>`. This can be useful, for example, when
working with different projects with conflicting formatting rules, with each project having settings
in its own vimrc or exrc file:
```vim
let b:formatdef_custom_c='"astyle --mode=c --suffix=none --options=/home/user/special_project/astylerc"'
let b:formatters_c = ['custom_c']
```
#### Ranged definitions
If your format program supports formatting specific ranges, you can provide a format
definition which allows to make use of this.
The first and last line of the current range can be retrieved by the variables `a:firstline` and
`a:lastline`. They default to the first and last line of your file, if no range was explicitly
specified.
So, a ranged definition could look like this.
```vim
let g:formatdef_autopep8 = "'autopep8 - --range '.a:firstline.' '.a:lastline"
let g:formatters_python = ['autopep8']
```
This would allow the user to select a part of the file and execute `:Autoformat`, which
would then only format the selected part.
## Contributing
This project is community driven. I don't actively do development on vim-autoformat myself,
as it's current state fulfills my personal needs.
However, I will review pull requests and keep an eye on the general sanity of the code.
If you have any improvements on this plugin or on this readme, if you have some
formatter definition that can be added to the defaults, or if you experience problems, please
open a pull request or an issue in this repository.
## Major Change Log
### October 2018
* We also take the returncode of the formatter process into account, not just the presence of output on stderr.
### March 2016
* We don't use the option formatprg internally anymore, to always have the possible of using the default `gq` command.
* More fallback options have been added.
### June 2015
* *Backward incompatible patch!*
* Multiple formatters per filetype are now supported.
* Configuration variable names changed.
* Using `gq` as alias for `:Autoformat` is no longer supported.
* `:Autoformat` now supports ranges.
* Composite filetypes are fully supported.
### December 20 2013
* `html-beautify` is now the new default for HTML since it seems to be better maintained, and seems to handle inline javascript neatly.
* The `formatters/` folder is no longer supported anymore, because it is unnecessary.
* `js-beautify` can no longer be installed as a bundle, since it only makes this plugin unnecessarily complex.
### March 27 2013
* The default behaviour of gq is enabled again by removing the fallback on auto-indenting.
Instead, the fallback is only used when running the command `:Autoformat`.
### March 16 2013
* The options `expandtab`, `shiftwidth`, `tabstop` and `softtabstop` are not overwritten anymore.
* This obsoletes `g:autoformat_no_default_shiftwidth`
* `g:formatprg_args_expr_<filetype>` is introduced.
### March 13 2013
* It is now possible to prevent vim-autoformat from overwriting your settings for `tabstop`, `softtabstop`, `shiftwidth` and `expandtab` in your .vimrc.
### March 10 2013
* When no formatter is installed or defined, vim will now auto-indent the file instead. This uses the indentfile for that specific filetype.
### March 9 2013
* Customization of formatprograms can be done easily now, as explained in the readme.
* I set the default tabwidth to 4 for all formatprograms as well as for vim itself.
* phpCB has been removed from the defaults, due to code-breaking behaviour.

View file

@ -0,0 +1,404 @@
" Function for getting the verbose mode level
function! s:GetVerboseMode(...)
let verbose = &verbose
if exists("g:autoformat_verbosemode ")
if g:autoformat_verbosemode > verbose
let verbose = g:autoformat_verbosemode
endif
endif
return verbose
endfunction
" Function for finding the formatters for this filetype
" Result is stored in b:formatters
function! s:FindFormatters(...)
" Detect verbosity
let verbose = s:GetVerboseMode()
" Extract filetype to be used
let ftype = a:0 ? a:1 : &filetype
" Support composite filetypes by replacing dots with underscores
let compoundtype = substitute(ftype, "[.]", "_", "g")
if ftype =~? "[.]"
" Try all super filetypes in search for formatters in a sane order
let ftypes = [compoundtype] + split(ftype, "[.]")
else
let ftypes = [compoundtype]
endif
" Support multiple formatters per file type
let run_all_formatters_var = "g:run_all_formatters_".compoundtype
if exists(run_all_formatters_var)
let b:run_all_formatters = eval(run_all_formatters_var)
else
let b:run_all_formatters = 0
endif
" Warn for backward incompatible configuration
let old_formatprg_var = "g:formatprg_".compoundtype
let old_formatprg_args_var = "g:formatprg_args_".compoundtype
let old_formatprg_args_expr_var = "g:formatprg_args_expr_".compoundtype
if exists(old_formatprg_var) || exists(old_formatprg_args_var) || exists(old_formatprg_args_expr_var)
echohl WarningMsg |
\ echomsg "WARNING: the options g:formatprg_<filetype>, g:formatprg_args_<filetype> and g:formatprg_args_expr_<filetype> are no longer supported as of June 2015, due to major backward-incompatible improvements. Please check the README for help on how to configure your formatters." |
\ echohl None
endif
" Detect configuration for all possible ftypes
let b:formatters = []
for supertype in ftypes
let formatters_var = "b:formatters_".supertype
if !exists(formatters_var)
let formatters_var = "g:formatters_".supertype
endif
if !exists(formatters_var)
" No formatters defined
if verbose > 0
echoerr "No formatters defined for supertype ".supertype
endif
else
let formatters = eval(formatters_var)
if type(formatters) != type([])
echoerr formatters_var." is not a list"
else
let b:formatters = b:formatters + formatters
endif
endif
endfor
if len(b:formatters) == 0
" No formatters defined
if verbose > 0
echoerr "No formatters defined for filetype '".ftype."'."
endif
return 0
endif
return 1
endfunction
" Try all formatters, starting with the currently selected one, until one
" works. If none works, autoindent the buffer.
function! s:TryAllFormatters(...) range
" Detect verbosity
let verbose = s:GetVerboseMode()
" Make sure formatters are defined and detected
if !call('<SID>FindFormatters', a:000)
" No formatters defined
if verbose > 0
echomsg "No format definitions are defined for this filetype."
endif
call s:Fallback()
return 0
endif
" Make sure index exist and is valid
if !exists('b:current_formatter_index')
let b:current_formatter_index = 0
endif
if b:current_formatter_index >= len(b:formatters)
let b:current_formatter_index = 0
endif
" Try all formatters, starting with selected one
let s:index = b:current_formatter_index
" Save if at least one formatter was successful
let l:formatter_run_successfully = 0
while 1
" Formatter definition must be existent
let formatdef_var = 'b:formatdef_'.b:formatters[s:index]
if !exists(formatdef_var)
let formatdef_var = 'g:formatdef_'.b:formatters[s:index]
endif
if !exists(formatdef_var)
echoerr "No format definition found in '".formatdef_var."'."
return 0
endif
" Eval twice, once for getting definition content,
" once for getting the final expression
let b:formatprg = eval(eval(formatdef_var))
if verbose > 1
echomsg "Trying definition from ".formatdef_var
echomsg "Evaluated formatprg: ".b:formatprg
endif
" Detect if +python or +python3 is available, and call the corresponding function
if !has("python") && !has("python3")
echohl WarningMsg |
\ echomsg "WARNING: vim has no support for python, but it is required to run the formatter!" |
\ echohl None
return 1
endif
if has("python3")
if verbose > 1
echomsg "Using python 3 code..."
endif
let success = s:TryFormatterPython3()
else
if verbose > 1
echomsg "Using python 2 code..."
endif
let success = s:TryFormatterPython()
endif
let s:index = (s:index + 1) % len(b:formatters)
if success == 0
if verbose > 1
echomsg "Definition in '".formatdef_var."' was successful."
endif
" Check if we can run few formatters in row
if b:run_all_formatters == 1
let l:formatter_run_successfully += 1
if s:index != b:current_formatter_index
if verbose > 1
echomsg "Running next chained formatter."
endif
endif
else
return 1
endif
else
if verbose > 0
echomsg "Definition in '".formatdef_var."' was unsuccessful."
endif
endif
if s:index == b:current_formatter_index
if b:run_all_formatters == 1 && l:formatter_run_successfully >= 1
if verbose > 1
echomsg l:formatter_run_successfully." formatters were successfuly run."
endif
return 1
else
if verbose > 0
echomsg "No format definitions were successful."
endif
" Tried all formatters, none worked
call s:Fallback()
return 0
endif
endif
endwhile
endfunction
function! s:Fallback()
" Detect verbosity
let verbose = s:GetVerboseMode()
if exists('b:autoformat_remove_trailing_spaces') ? b:autoformat_remove_trailing_spaces == 1 : g:autoformat_remove_trailing_spaces == 1
if verbose > 1
echomsg "Removing trailing whitespace..."
endif
call s:RemoveTrailingSpaces()
endif
if exists('b:autoformat_retab') ? b:autoformat_retab == 1 : g:autoformat_retab == 1
if verbose > 1
echomsg "Retabbing..."
endif
retab
endif
if exists('b:autoformat_autoindent') ? b:autoformat_autoindent == 1 : g:autoformat_autoindent == 1
if verbose > 1
echomsg "Autoindenting..."
endif
" Autoindent code
exe "normal! gg=G"
endif
endfunction
" Call formatter
" If stderr is empty, apply result, return 0
" Otherwise, return 1
" +python version
function! s:TryFormatterPython()
" Detect verbosity
let verbose = s:GetVerboseMode()
python << EOF
import vim, subprocess, os
from subprocess import Popen, PIPE
text = os.linesep.join(vim.current.buffer[:]) + os.linesep
formatprg = vim.eval('b:formatprg')
verbose = bool(int(vim.eval('verbose')))
env = os.environ.copy()
if int(vim.eval('exists("g:formatterpath")')):
extra_path = vim.eval('g:formatterpath')
env['PATH'] = os.pathsep.join(extra_path) + os.pathsep + env['PATH']
# When an entry is unicode, Popen can't deal with it in Python 2.
# As a pragmatic fix, we'll omit that entry.
newenv = {}
for key,val in env.iteritems():
if type(key) == type(val) == str:
newenv[key] = val
env=newenv
p = subprocess.Popen(formatprg, env=env, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdoutdata, stderrdata = p.communicate(text)
formattername = vim.eval('b:formatters[s:index]')
if stderrdata:
if verbose > 0:
print('Formatter {} has errors: {}'.format(formattername, stderrdata))
vim.command('return 1')
elif p.returncode > 0:
if verbose > 0:
print('Formatter {} gives nonzero returncode: {}'.format(formattername, p.returncode))
vim.command('return 1')
else:
# It is not certain what kind of line endings are being used by the format program.
# Therefore we simply split on all possible eol characters.
possible_eols = ['\r\n', os.linesep, '\r', '\n']
# Often shell commands will append a newline at the end of their output.
# It is not entirely clear when and why that happens.
# However, extra newlines are almost never required, while there are linters that complain
# about superfluous newlines, so we remove one empty newline at the end of the file.
for eol in possible_eols:
eol_len = len(eol)
if len(stdoutdata) > 0 and stdoutdata[-eol_len:] == eol:
stdoutdata = stdoutdata[:-eol_len]
lines = [stdoutdata]
for eol in possible_eols:
lines = [splitline for line in lines for splitline in line.split(eol)]
if vim.current.buffer[:] != lines:
vim.current.buffer[:] = lines
EOF
return 0
endfunction
" +python3 version
function! s:TryFormatterPython3()
" Detect verbosity
let verbose = s:GetVerboseMode()
python3 << EOF
import vim, subprocess, os
from subprocess import Popen, PIPE
# The return code is `failure`, unless otherwise specified
vim.command('return 1')
text = bytes(os.linesep.join(vim.current.buffer[:]) + os.linesep, 'utf-8')
formatprg = vim.eval('b:formatprg')
verbose = bool(int(vim.eval('verbose')))
env = os.environ.copy()
if int(vim.eval('exists("g:formatterpath")')):
extra_path = vim.eval('g:formatterpath')
env['PATH'] = os.pathsep.join(extra_path) + os.pathsep + env['PATH']
try:
p = subprocess.Popen(formatprg, env=env, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdoutdata, stderrdata = p.communicate(text)
except (BrokenPipeError, IOError):
if verbose > 0:
raise
else:
formattername = vim.eval('b:formatters[s:index]')
if stderrdata:
if verbose > 0:
print('Formatter {} has errors: {}'.format(formattername, stderrdata))
elif p.returncode > 0:
if verbose > 0:
print('Formatter {} gives nonzero returncode: {}'.format(formattername, p.returncode))
elif not stdoutdata:
if verbose > 0:
print('Formatter {} gives empty result: {}'.format(formattername, stderrdata))
else:
# It is not certain what kind of line endings are being used by the format program.
# Therefore we simply split on all possible eol characters.
possible_eols = ['\r\n', os.linesep, '\r', '\n']
stdoutdata = stdoutdata.decode('utf-8')
# Often shell commands will append a newline at the end of their output.
# It is not entirely clear when and why that happens.
# However, extra newlines are almost never required, while there are linters that complain
# about superfluous newlines, so we remove one empty newline at the end of the file.
for eol in possible_eols:
eol_len = len(eol)
if len(stdoutdata) > 0 and stdoutdata[-eol_len:] == eol:
stdoutdata = stdoutdata[:-eol_len]
lines = [stdoutdata]
for eol in possible_eols:
lines = [splitline for line in lines for splitline in line.split(eol)]
if vim.current.buffer[:] != lines:
vim.current.buffer[:] = lines
vim.command('return 0')
EOF
endfunction
" Create a command for formatting the entire buffer
" Save and recall window state to prevent vim from jumping to line 1
" Write and read viminfo to restore marks
command! -nargs=? -range=% -complete=filetype -bar
\ Autoformat let winview=winsaveview()|wviminfo|<line1>,<line2>call s:TryAllFormatters(<f-args>)|call winrestview(winview)|rviminfo
" Create a command for formatting a single line, or range of lines
" Save and recall window state to prevent vim from jumping to line 1
" Write and read viminfo to restore marks
command! -nargs=? -range -complete=filetype -bar
\ AutoformatLine let winview=winsaveview()|wviminfo|<line1>,<line2>call s:TryAllFormatters(<f-args>)|call winrestview(winview)|rviminfo
" Functions for iterating through list of available formatters
function! s:NextFormatter()
call s:FindFormatters()
if !exists('b:current_formatter_index')
let b:current_formatter_index = 0
endif
let b:current_formatter_index = (b:current_formatter_index + 1) % len(b:formatters)
echomsg 'Selected formatter: '.b:formatters[b:current_formatter_index]
endfunction
function! s:PreviousFormatter()
call s:FindFormatters()
if !exists('b:current_formatter_index')
let b:current_formatter_index = 0
endif
let l = len(b:formatters)
let b:current_formatter_index = (b:current_formatter_index - 1 + l) % l
echomsg 'Selected formatter: '.b:formatters[b:current_formatter_index]
endfunction
function! s:CurrentFormatter()
call s:FindFormatters()
if !exists('b:current_formatter_index')
let b:current_formatter_index = 0
endif
echomsg 'Selected formatter: '.b:formatters[b:current_formatter_index]
endfunction
" Create commands for iterating through formatter list
command! NextFormatter call s:NextFormatter()
command! PreviousFormatter call s:PreviousFormatter()
command! CurrentFormatter call s:CurrentFormatter()
" Other commands
function! s:RemoveTrailingSpaces()
let user_gdefault = &gdefault
try
set nogdefault
silent! %s/\s\+$
finally
let &gdefault = user_gdefault
endtry
endfunction
command! RemoveTrailingSpaces call s:RemoveTrailingSpaces()

View file

@ -0,0 +1,747 @@
"
" This file contains default settings and all format program definitions and links these to filetypes
"
" Vim-autoformat configuration variables
if !exists('g:autoformat_autoindent')
let g:autoformat_autoindent = 1
endif
if !exists('g:autoformat_retab')
let g:autoformat_retab = 1
endif
if !exists('g:autoformat_remove_trailing_spaces')
let g:autoformat_remove_trailing_spaces = 1
endif
if !exists('g:autoformat_verbosemode')
let g:autoformat_verbosemode = 0
endif
" Ada
if !exists('g:formatdef_gnatpp')
let g:formatdef_gnatpp = "'cat > /tmp/adafile; gnatpp --pipe /tmp/adafile; rm -f /tmp/adafile'"
endif
if !exists('g:formatters_ada')
let g:formatters_ada = ['gnatpp']
endif
" Python
if !exists('g:formatdef_autopep8')
" Autopep8 will not do indentation fixes when a range is specified, so we
" only pass a range when there is a visual selection that is not the
" entire file. See #125.
let g:formatdef_autopep8 = '"autopep8 -".(g:DoesRangeEqualBuffer(a:firstline, a:lastline) ? " --range ".a:firstline." ".a:lastline : "")." ".(&textwidth ? "--max-line-length=".&textwidth : "")'
endif
" There doesn't seem to be a reliable way to detect if are in some kind of visual mode,
" so we use this as a workaround. We compare the length of the file against
" the range arguments. If there is no range given, the range arguments default
" to the entire file, so we return false if the range comprises the entire file.
function! g:DoesRangeEqualBuffer(first, last)
return line('$') != a:last - a:first + 1
endfunction
" Yapf supports multiple formatter styles: pep8, google, chromium, or facebook
if !exists('g:formatter_yapf_style')
let g:formatter_yapf_style = 'pep8'
endif
if !exists('g:formatdef_yapf')
let s:configfile_def = "'yapf -l '.a:firstline.'-'.a:lastline"
let s:noconfigfile_def = "'yapf --style=\"{based_on_style:'.g:formatter_yapf_style.',indent_width:'.shiftwidth().(&textwidth ? ',column_limit:'.&textwidth : '').'}\" -l '.a:firstline.'-'.a:lastline"
let g:formatdef_yapf = "g:YAPFFormatConfigFileExists() ? (" . s:configfile_def . ") : (" . s:noconfigfile_def . ")"
endif
function! g:YAPFFormatConfigFileExists()
return len(findfile(".style.yapf", expand("%:p:h").";")) || len(findfile("setup.cfg", expand("%:p:h").";")) || filereadable(exists('$XDG_CONFIG_HOME') ? expand('$XDG_CONFIG_HOME/yapf/style') : expand('~/.config/yapf/style'))
endfunction
if !exists('g:formatdef_black')
let g:formatdef_black = '"black -q ".(&textwidth ? "-l".&textwidth : "")." -"'
endif
if !exists('g:formatters_python')
let g:formatters_python = ['autopep8','yapf', 'black']
endif
" C#
if !exists('g:formatdef_astyle_cs')
if filereadable('.astylerc')
let g:formatdef_astyle_cs = '"astyle --mode=cs --options=.astylerc"'
elseif filereadable(expand('~/.astylerc')) || exists('$ARTISTIC_STYLE_OPTIONS')
let g:formatdef_astyle_cs = '"astyle --mode=cs"'
else
let g:formatdef_astyle_cs = '"astyle --mode=cs --style=ansi --indent-namespaces -pcH".(&expandtab ? "s".shiftwidth() : "t")'
endif
endif
if !exists('g:formatters_cs')
let g:formatters_cs = ['astyle_cs']
endif
if !exists('g:formatters_bzl')
let g:formatters_bzl = ['buildifier']
endif
" Generic C, C++, Objective-C
if !exists('g:formatdef_clangformat')
let s:configfile_def = "'clang-format -lines='.a:firstline.':'.a:lastline.' --assume-filename=\"'.expand('%:p').'\" -style=file'"
let s:noconfigfile_def = "'clang-format -lines='.a:firstline.':'.a:lastline.' --assume-filename=\"'.expand('%:p').'\" -style=\"{BasedOnStyle: WebKit, AlignTrailingComments: true, '.(&textwidth ? 'ColumnLimit: '.&textwidth.', ' : '').'IndentWidth: '.shiftwidth().', TabWidth: '.&tabstop.', '.(&expandtab ? 'UseTab: Never' : 'UseTab: Always').'}\"'"
let g:formatdef_clangformat = "g:ClangFormatConfigFileExists() ? (" . s:configfile_def . ") : (" . s:noconfigfile_def . ")"
endif
function! g:ClangFormatConfigFileExists()
return len(findfile(".clang-format", expand("%:p:h").";")) || len(findfile("_clang-format", expand("%:p:h").";")) || len(findfile("~/.clang-format", expand("%:p:h").";")) || len(findfile("~/_clang-format", expand("%:p:h").";"))
endfunction
" C
if !exists('g:formatdef_astyle_c')
if filereadable('.astylerc')
let g:formatdef_astyle_c = '"astyle --mode=c --options=.astylerc"'
elseif filereadable(expand('~/.astylerc')) || exists('$ARTISTIC_STYLE_OPTIONS')
let g:formatdef_astyle_c = '"astyle --mode=c"'
else
let g:formatdef_astyle_c = '"astyle --mode=c --style=ansi -pcH".(&expandtab ? "s".shiftwidth() : "t")'
endif
endif
if !exists('g:formatters_c')
let g:formatters_c = ['clangformat', 'astyle_c']
endif
" C++
if !exists('g:formatdef_astyle_cpp')
if filereadable('.astylerc')
let g:formatdef_astyle_cpp = '"astyle --mode=c --options=.astylerc"'
elseif filereadable(expand('~/.astylerc')) || exists('$ARTISTIC_STYLE_OPTIONS')
let g:formatdef_astyle_cpp = '"astyle --mode=c"'
else
let g:formatdef_astyle_cpp = '"astyle --mode=c --style=ansi -pcH".(&expandtab ? "s".shiftwidth() : "t")'
endif
endif
if !exists('g:formatters_cpp')
let g:formatters_cpp = ['clangformat', 'astyle_cpp']
endif
" Objective C
if !exists('g:formatters_objc')
let g:formatters_objc = ['clangformat']
endif
" D
if !exists('g:formatdef_dfmt')
if executable('dfmt')
let s:dfmt_command = 'dfmt'
else
let s:dfmt_command = 'dub run -q dfmt --'
endif
let s:configfile_def = '"' . s:dfmt_command . '"'
let s:noconfigfile_def = '"' . s:dfmt_command . ' -t " . (&expandtab ? "space" : "tab") . " --indent_size " . shiftwidth() . (&textwidth ? " --soft_max_line_length " . &textwidth : "")'
let g:formatdef_dfmt = 'g:EditorconfigFileExists() ? (' . s:configfile_def . ') : (' . s:noconfigfile_def . ')'
let g:formatters_d = ['dfmt']
endif
function! g:EditorconfigFileExists()
return len(findfile(".editorconfig", expand("%:p:h").";"))
endfunction
" Protobuf
if !exists('g:formatters_proto')
let g:formatters_proto = ['clangformat']
endif
" Java
if !exists('g:formatdef_astyle_java')
if filereadable('.astylerc')
let g:formatdef_astyle_java = '"astyle --mode=java --options=.astylerc"'
elseif filereadable(expand('~/.astylerc')) || exists('$ARTISTIC_STYLE_OPTIONS')
let g:formatdef_astyle_java = '"astyle --mode=java"'
else
let g:formatdef_astyle_java = '"astyle --mode=java --style=java -pcH".(&expandtab ? "s".shiftwidth() : "t")'
endif
endif
if !exists('g:formatters_java')
let g:formatters_java = ['astyle_java']
endif
" Javascript
if !exists('g:formatdef_jsbeautify_javascript')
if filereadable('.jsbeautifyrc')
let g:formatdef_jsbeautify_javascript = '"js-beautify"'
elseif filereadable(expand('~/.jsbeautifyrc'))
let g:formatdef_jsbeautify_javascript = '"js-beautify"'
else
let g:formatdef_jsbeautify_javascript = '"js-beautify -X -".(&expandtab ? "s ".shiftwidth() : "t").(&textwidth ? " -w ".&textwidth : "")'
endif
endif
if !exists('g:formatdef_jscs')
let g:formatdef_jscs = '"jscs -x"'
endif
if !exists('g:formatdef_standard_javascript')
let g:formatdef_standard_javascript = '"standard --fix --stdin"'
endif
if !exists('g:formatdef_prettier')
let g:formatdef_prettier = '"prettier --stdin-filepath ".expand("%:p").(&textwidth ? " --print-width ".&textwidth : "")." --tab-width=".shiftwidth()'
endif
" This is an xo formatter (inspired by the above eslint formatter)
" To support ignore and overrides options, we need to use a tmp file
" So we create a tmp file here and then remove it afterwards
if !exists('g:formatdef_xo_javascript')
function! g:BuildXOLocalCmd()
let l:xo_js_tmp_file = fnameescape(tempname().".js")
let content = getline('1', '$')
call writefile(content, l:xo_js_tmp_file)
return "xo --fix ".l:xo_js_tmp_file." 1> /dev/null; exit_code=$?
\ cat ".l:xo_js_tmp_file."; rm -f ".l:xo_js_tmp_file."; exit $exit_code"
endfunction
let g:formatdef_xo_javascript = "g:BuildXOLocalCmd()"
endif
function! s:NodeJsFindPathToExecFile(exec_name)
let l:path = fnamemodify(expand('%'), ':p')
" find formatter & config file
let l:prog = findfile('node_modules/.bin/'.a:exec_name, l:path.";")
if empty(l:prog)
let l:prog = findfile('~/.npm-global/bin/'.a:exec_name)
if empty(l:prog)
let l:prog = findfile('/usr/local/bin/'.a:exec_name)
endif
else
let l:prog = getcwd()."/".l:prog
endif
return l:prog
endfunction
" Setup ESLint local. Setup is done on formatter execution if ESLint and
" corresponding config is found they are used, otherwiese the formatter fails.
" No windows support at the moment.
if !exists('g:formatdef_eslint_local')
" returns unique file name near original
function! g:BuildESLintTmpFile(path, ext)
let l:i = 0
let l:result = a:path.'_eslint_tmp_'.l:i.a:ext
while filereadable(l:result) && l:i < 100000
let l:i = l:i + 1
let l:result = a:path.'_eslint_tmp_'.l:i.a:ext
endwhile
if filereadable(l:result)
echoerr "Temporary file could not be created for ".a:path
echoerr "Tried from ".a:path.'_eslint_tmp_0'.a:ext." to ".a:path.'_eslint_tmp_'.l:i.a:ext
return ''
endif
return l:result
endfunction
function! g:BuildESLintLocalCmd()
let l:path = fnamemodify(expand('%'), ':p')
let l:ext = ".".expand('%:p:e')
let verbose = &verbose || g:autoformat_verbosemode == 1
if has('win32')
return "(>&2 echo 'ESLint not supported on win32')"
endif
" find formatter & config file
let l:prog = s:NodeJsFindPathToExecFile('eslint')
"initial
let l:cfg = findfile('.eslintrc.js', l:path.";")
if empty(l:cfg)
let l:cfg_fallbacks = [
\'.eslintrc.yaml',
\'.eslintrc.yml',
\'.eslintrc.json',
\'.eslintrc',
\]
for i in l:cfg_fallbacks
let l:tcfg = findfile(i, l:path.";")
if !empty(l:tcfg)
break
endif
endfor
if !empty(l:tcfg)
let l:cfg = fnamemodify(l:tcfg, ":p")
else
let l:cfg = findfile('~/.eslintrc.js')
for i in l:cfg_fallbacks
if !empty(l:cfg)
break
endif
let l:cfg = findfile("~/".i)
endfor
endif
endif
if (empty(l:cfg) || empty(l:prog))
if verbose > 0
return "(>&2 echo 'No local or global ESLint program and/or config found')"
endif
return
endif
" This formatter uses a temporary file as ESLint has not option to print
" the formatted source to stdout without modifieing the file.
let l:eslint_tmp_file = g:BuildESLintTmpFile(l:path, l:ext)
let content = getline('1', '$')
call writefile(content, l:eslint_tmp_file)
return l:prog." -c ".l:cfg." --fix ".l:eslint_tmp_file." 1> /dev/null; exit_code=$?
\ cat ".l:eslint_tmp_file."; rm -f ".l:eslint_tmp_file."; exit $exit_code"
endfunction
let g:formatdef_eslint_local = "g:BuildESLintLocalCmd()"
endif
if !exists('g:formatters_javascript')
let g:formatters_javascript = [
\ 'eslint_local',
\ 'jsbeautify_javascript',
\ 'jscs',
\ 'standard_javascript',
\ 'prettier',
\ 'xo_javascript',
\ 'stylelint',
\ ]
endif
" Vue
if !exists('g:formatters_vue')
let g:formatters_vue = [
\ 'eslint_local',
\ 'stylelint',
\ ]
endif
" JSON
if !exists('g:formatdef_jsbeautify_json')
if filereadable('.jsbeautifyrc')
let g:formatdef_jsbeautify_json = '"js-beautify"'
elseif filereadable(expand('~/.jsbeautifyrc'))
let g:formatdef_jsbeautify_json = '"js-beautify"'
else
let g:formatdef_jsbeautify_json = '"js-beautify -".(&expandtab ? "s ".shiftwidth() : "t")'
endif
endif
if !exists('g:formatdef_fixjson')
let g:formatdef_fixjson = '"fixjson"'
endif
if !exists('g:formatters_json')
let g:formatters_json = [
\ 'jsbeautify_json',
\ 'fixjson',
\ 'prettier',
\ ]
endif
" Julia
if !exists('g:formatdef_juliaformatter')
function! g:BuildJuliaCmd()
return 'julia -e "using JuliaFormatter; print(format_text(read(\"' . expand("%:p") . '\", String)))"'
endfunction
let g:formatdef_juliaformatter = 'g:BuildJuliaCmd()'
endif
if !exists('g:formatters_julia')
let g:formatters_julia = ['juliaformatter']
endif
" HTML
if !exists('g:formatdef_htmlbeautify')
let g:formatdef_htmlbeautify = '"html-beautify - -".(&expandtab ? "s ".shiftwidth() : "t").(&textwidth ? " -w ".&textwidth : "")'
endif
if !exists('g:formatdef_tidy_html')
let g:formatdef_tidy_html = '"tidy -q --show-errors 0 --show-warnings 0 --force-output --indent auto --indent-spaces ".shiftwidth()." --vertical-space yes --tidy-mark no -wrap ".&textwidth'
endif
if !exists('g:formatters_html')
let g:formatters_html = ['htmlbeautify', 'tidy_html', 'stylelint']
endif
" XML
if !exists('g:formatdef_tidy_xml')
let g:formatdef_tidy_xml = '"tidy -q -xml --show-errors 0 --show-warnings 0 --force-output --indent auto --indent-spaces ".shiftwidth()." --vertical-space yes --tidy-mark no -wrap ".&textwidth'
endif
if !exists('g:formatters_xml')
let g:formatters_xml = ['tidy_xml']
endif
" SVG
if !exists('g:formatters_svg')
let g:formatters_svg = ['tidy_xml']
endif
" XHTML
if !exists('g:formatdef_tidy_xhtml')
let g:formatdef_tidy_xhtml = '"tidy -q --show-errors 0 --show-warnings 0 --force-output --indent auto --indent-spaces ".shiftwidth()." --vertical-space yes --tidy-mark no -asxhtml -wrap ".&textwidth'
endif
if !exists('g:formatters_xhtml')
let g:formatters_xhtml = ['tidy_xhtml']
endif
" Ruby
if !exists('g:formatdef_rbeautify')
let g:formatdef_rbeautify = '"rbeautify ".(&expandtab ? "-s -c ".shiftwidth() : "-t")'
endif
if !exists('g:formatdef_rubocop')
" The pipe to sed is required to remove some rubocop output that could not
" be suppressed.
let g:formatdef_rubocop = "'rubocop --auto-correct -o /dev/null -s '.bufname('%').' \| sed -n 2,\\$p'"
endif
if !exists('g:formatters_ruby')
let g:formatters_ruby = ['rbeautify', 'rubocop']
endif
" CSS
" Setup stylelint. Setup is done on formatter execution
" if stylelint is found, otherwise the formatter fails.
" No windows support at the moment.
if !exists('g:formatdef_stylelint')
function! g:BuildStyleLintCmd()
let verbose = &verbose || g:autoformat_verbosemode == 1
if has('win32')
return "(>&2 echo 'stylelint not supported on win32')"
endif
" find formatter
let l:prog = s:NodeJsFindPathToExecFile('stylelint')
if (empty(l:prog))
if verbose > 0
return "(>&2 echo 'No local or global stylelint program found')"
endif
return
endif
return l:prog." --fix --stdin --stdin-filename ".bufname('%')
endfunction
let g:formatdef_stylelint = "g:BuildStyleLintCmd()"
endif
if !exists('g:formatdef_cssbeautify')
let g:formatdef_cssbeautify = '"css-beautify -f - -s ".shiftwidth()'
endif
if !exists('g:formatters_css')
let g:formatters_css = ['cssbeautify', 'prettier', 'stylelint']
endif
" SCSS
if !exists('g:formatdef_sassconvert')
let g:formatdef_sassconvert = '"sass-convert -F scss -T scss --indent " . (&expandtab ? shiftwidth() : "t")'
endif
if !exists('g:formatters_scss')
let g:formatters_scss = ['sassconvert', 'prettier', 'stylelint']
endif
" Less
if !exists('g:formatters_less')
let g:formatters_less = ['prettier', 'stylelint']
endif
" Typescript
if !exists('g:formatdef_tsfmt')
let g:formatdef_tsfmt = "'tsfmt --stdin '.bufname('%')"
endif
if !exists('g:formatters_typescript')
let g:formatters_typescript = ['tsfmt', 'prettier']
endif
" Haxe
if !exists('g:formatdef_haxe_formatter')
let g:formatdef_haxe_formatter = "'haxelib run formatter --stdin --source " . fnamemodify("%", ":p:h") . "'"
endif
if !exists('g:formatters_haxe')
let g:formatters_haxe = ["haxe_formatter"]
endif
" Golang
" Two definitions are provided for two versions of gofmt.
" See issue #59
if !exists('g:formatdef_gofmt_1')
let g:formatdef_gofmt_1 = '"gofmt -tabs=".(&expandtab ? "false" : "true")." -tabwidth=".shiftwidth()'
endif
if !exists('g:formatdef_gofmt_2')
let g:formatdef_gofmt_2 = '"gofmt"'
endif
if !exists('g:formatdef_goimports')
let g:formatdef_goimports = '"goimports"'
endif
if !exists('g:formatdef_gofumpt')
let g:formatdef_gofumpt = '"gofumpt"'
endif
if !exists('g:formatters_go')
let g:formatters_go = ['gofmt_1', 'goimports', 'gofmt_2', 'gofumpt']
endif
" Rust
if !exists('g:formatdef_rustfmt')
let g:formatdef_rustfmt = '"rustfmt --edition 2018"'
endif
if !exists('g:formatters_rust')
let g:formatters_rust = ['rustfmt']
endif
" Zig
if !exists('g:formatdef_zigfmt')
let g:formatdef_zigfmt = '"zig fmt --stdin"'
endif
if !exists('g:formatters_zig')
let g:formatters_zig = ['zigfmt']
endif
" Dart
if !exists('g:formatdef_dart_format')
let g:formatdef_dart_format = '"dart format"'
endif
if !exists('g:formatters_dart')
let g:formatters_dart = ['dart_format']
endif
" Perl
if !exists('g:formatdef_perltidy')
" use perltidyrc file if readable
if (has("win32") && (filereadable("perltidy.ini") ||
\ filereadable($HOMEPATH."/perltidy.ini"))) ||
\ ((has("unix") ||
\ has("mac")) && (filereadable(".perltidyrc") ||
\ filereadable(expand("~/.perltidyrc")) ||
\ filereadable("/usr/local/etc/perltidyrc") ||
\ filereadable("/etc/perltidyrc")))
let g:formatdef_perltidy = '"perltidy -q -st"'
else
let g:formatdef_perltidy = '"perltidy --perl-best-practices --format-skipping -q "'
endif
endif
if !exists('g:formatters_perl')
let g:formatters_perl = ['perltidy']
endif
" Haskell
if !exists('g:formatdef_stylish_haskell')
let g:formatdef_stylish_haskell = '"stylish-haskell"'
endif
if !exists('g:formatters_haskell')
let g:formatters_haskell = ['stylish_haskell']
endif
" Purescript
if !exists('g:formatdef_purty')
let g:formatdef_purty = '"purty -"'
endif
if !exists('g:formatters_purescript')
let g:formatters_purescript = ['purty']
endif
" Markdown
if !exists('g:formatdef_remark_markdown')
let g:formatdef_remark_markdown = '"remark --silent --no-color"'
endif
if !exists('g:formatters_markdown')
let g:formatters_markdown = ['remark_markdown', 'prettier', 'stylelint']
endif
" Graphql
if !exists('g:formatters_graphql')
let g:formatters_graphql = ['prettier']
endif
" Fortran
if !exists('g:formatdef_fprettify')
let g:formatdef_fprettify = '"fprettify --no-report-errors --indent=".shiftwidth()'
endif
if !exists('g:formatters_fortran')
let g:formatters_fortran = ['fprettify']
endif
" Elixir
if !exists('g:formatters_elixir')
let s:configfile_def = '"mix format --dot-formatter " . findfile(".formatter.exs", expand("%:p:h").";") . " -"'
let s:noconfigfile_def = '"mix format -"'
let g:formatdef_mix_format = 'g:ElixirconfigFileExists() ? (' . s:configfile_def . ') : (' . s:noconfigfile_def . ')'
let g:formatters_elixir = ['mix_format']
endif
function! g:ElixirconfigFileExists()
return len(findfile(".formatter.exs", expand("%:p:h").";"))
endfunction
" Shell
if !exists('g:formatdef_shfmt')
let g:formatdef_shfmt = '"shfmt -i ".(&expandtab ? shiftwidth() : "0")'
endif
if !exists('g:formatters_sh')
let g:formatters_sh = ['shfmt']
endif
" Fish shell
if !exists('g:formatdef_fish_indent')
let g:formatdef_fish_indent = '"fish_indent"'
endif
if !exists('g:formatters_fish')
let g:formatters_fish = ['fish_indent']
endif
" Lua
if !exists('g:formatdef_luafmt')
let g:formatdef_luafmt = "'luafmt --stdin '.bufname('%')"
endif
if !exists('g:formatdef_stylua')
let g:formatdef_stylua = "'stylua --search-parent-directories --stdin-filepath ' . expand('%:p') .' -- -'"
endif
if !exists('g:formatters_lua')
let g:formatters_lua = ['luafmt', 'stylua']
endif
" SQL
if !exists('g:formatdef_sqlformat')
let g:formatdef_sqlformat = '"sqlformat --reindent --indent_width ".shiftwidth()." --keywords upper --identifiers lower -"'
endif
if !exists('g:formatters_sql')
let g:formatters_sql = ['sqlformat']
endif
" CMake
if !exists('g:formatdef_cmake_format')
let g:formatdef_cmake_format = '"cmake-format - --tab-size ".shiftwidth()." ".(&textwidth ? "--line-width=".&textwidth : "")'
endif
if !exists('g:formatters_cmake')
let g:formatters_cmake = ['cmake_format']
endif
" Latex
if !exists('g:formatdef_latexindent')
let g:formatdef_latexindent = '"latexindent.pl -"'
endif
if !exists('g:formatters_latex')
let g:formatters_tex = ['latexindent']
endif
" OCaml
if !exists('g:formatdef_ocp_indent')
let g:formatdef_ocp_indent = '"ocp-indent"'
endif
if !exists('g:formatdef_ocamlformat')
if filereadable('.ocamlformat')
let g:formatdef_ocamlformat = '"ocamlformat --enable-outside-detected-project --name " . expand("%:p") . " -"'
else
let g:formatdef_ocamlformat = '"ocamlformat --profile=ocamlformat --enable-outside-detected-project --name " . expand("%:p") . " -"'
endif
endif
if !exists('g:formatters_ocaml')
let g:formatters_ocaml = ['ocamlformat', 'ocp_indent']
endif
" Assembly
if !exists('g:formatdef_asm_format')
let g:formatdef_asm_format = '"asmfmt"'
endif
if !exists('g:formatters_asm')
let g:formatters_asm = ['asm_format']
endif
" Nix
if !exists('g:formatdef_nix_format')
let g:formatdef_nix_format = '"nixfmt"'
endif
if !exists('g:formatters_nix')
let g:formatters_nix = ['nix_format']
endif
" Dhall
if !exists('g:formatdef_dhall_format')
let g:formatdef_dhall_format = '"dhall --ascii format"'
endif
if !exists('g:formatters_dhall')
let g:formatters_dhall = ['dhall_format']
endif
" Terraform
if !exists('g:formatdef_terraform_format')
let g:formatdef_terraform_format = '"terraform fmt -"'
endif
if !exists('g:formatters_terraform')
let g:formatters_terraform = ['terraform_format']
endif
" Packer
if !exists('g:formatdef_packer_format')
let g:formatdef_packer_format = '"packer fmt -"'
endif
if !exists('g:formatters_packer')
let g:formatters_packer = ['packer_format']
endif
" Nginx
if !exists('g:formatdef_nginxfmt')
let g:formatdef_nginxfmt = '"nginxfmt.py -i ".shiftwidth()." -"'
endif
if !exists('g:formatters_nginx')
let g:formatters_nginx = ['nginxfmt']
endif

View file

@ -0,0 +1,20 @@
" Simple python-based random number generator
function! g:RandomInt()
if has("python3")
python3 << EOF
import random
result = random.randrange(1, 1000000)
vim.command('return ' + str(result))
EOF
else
python << EOF
import random
result = random.randrange(1, 1000000)
vim.command('return ' + str(result))
EOF
endif
endfunction
" Put the uncopyable messages text into the buffer
command! PutMessages redir @" | messages | redir END | put

View file

@ -0,0 +1,4 @@
using System; class Program { static int Main(string[] args) { Console.WriteLine(args[0]); int i = 0; i++; return 0; }
public int Foo() { switch (1) { case 1: int i = 0; default: int j = 1; }
}
}

View file

@ -0,0 +1,258 @@
module prettify_selftest
implicit none
private
public :: dp, test_routine, &
test_function, test_type, str_function
integer, parameter :: dp = selected_real_kind ( 15 , 307)
type test_type
real (kind =dp ) :: r = 1.0d-3
integer :: i
end type test_type
contains
subroutine test_routine( &
r, i, j, k, l)
integer, intent(in) :: r, i, j, k
integer, intent (out) :: l
l = test_function(r,i,j,k)
end &
subroutine
pure function test_function(r, i, j, &
k) &
result(l)
integer, intent(in) :: r, i, j, k
integer :: l
l=r + i +j +k
end function
function &
str_function(a) result(l)
character(len=*) :: a
integer :: l
if(len(a)<5)then
l=0
else
l=1
endif
end function
end module
program example_prog
use example, only: dp, test_routine, test_function, test_type,str_function
implicit none
integer :: r,i,j,k,l,my_integer,m
integer, dimension(5) :: arr
integer, dimension(20) :: big_arr
integer :: endif
type(test_type) :: t
real(kind=dp) :: r1, r2, r3, r4, r5, r6
integer, pointer :: point
point=> null( )
! 1) white space formatting !
!***************************!
! example 1.1
r=1;i=-2;j=3;k=4;l=5
r2 = 0.0_dp; r3= 1.0_dp; r4 =2.0_dp; r5=3.0_dp; r6 = 4.0_dp
r1=-(r2**i*(r3+r5*(-r4)-r6))-2.e+2
if( r.eq.2.and.r<=5) i=3
write(*, *)(merge(3, 1, i<=2))
write(*, *)test_function(r,i,j , k)
t % r = 4.0_dp
t%i = str_function( "t % i = " )
! example 1.2
my_integer=2
i=3
j=5
big_arr = [1, 2, 3, 4, 5, &
6, 7, 8, 9, 10, &
11, 12, 13, 14, 15, &
16, 17, 18, 19, 20]
! example 1.3: disabling auto-formatter:
my_integer = 2 !&
i = 3 !&
j = 5 !&
!&<
my_integer = 2
i = 3
j = 5
!&>
big_arr = [ 1, 2, 3, 4, 5, & !&
6, 7, 8, 9, 10, & !&
11, 12, 13, 14, 15, & !&
16, 17, 18, 19, 20] !&
! example 1.4:
big_arr = [1, 2, 3, 4, 5,&
& 6, 7, 8, 9, 10, &
& 11, 12, 13, 14, 15,&
&16, 17, 18, 19, 20]
! 2) auto indentation for loops !
!*******************************!
! example 2.1
l = 0
do r= 1 , 10
select case (r)
case(1)
do_label: do i = 1,100
if (i<=2) then
m =0
do while(m <4)
m =m+1
do k=1,3
if (k==1) l =l +1
end do
enddo
endif
enddo do_label
case ( 2 )
l=i + j + k
end select
enddo
! example 2.2
do m = 1, 2
do r = 1, 3
write (*, *) r
do k = 1, 4
do l = 1, 3
do i = 4, 5
do my_integer = 1, 1
do j = 1, 2
write (*, *) test_function(m, r, k, l) + i
enddo
enddo
enddo
enddo
enddo
enddo
enddo
! 3) auto alignment for linebreaks !
!************************************!
! example 3.1
l = test_function(1, 2, test_function(1, 2, 3, 4), 4) + 3 *(2+1)
l = test_function (1, 2, test_function(1,2, 3, 4),4) +&
3*(2+ 1 )
l = test_function(1, 2, &
test_function(1, 2, 3, 4), 4)+ &
3 * (2+1)
l = test_function(1, 2, &
test_function(1, 2, 3, &
4), 4) + &
3*(2 + 1)
! example 3.2
arr = [1, (/3,4, 5/), 6] + [ 1, 2,3, 4,5 ]
arr = [1,(/ 3, 4, 5 /) , &
6] +[1,2, 3, 4, 5 ]
arr = [1,(/3,4,5/), &
6]+ &
[1, 2, 3, 4, 5]
arr = [1, (/3, 4, &
5/), &
6] + &
[1, 2,3, 4, 5 ]
! example 3.3
l = test_function(1, 2, &
3, 4)
l = test_function( &
1, 2, 3, 4)
arr = [1, 2, &
3, 4, 5]
arr = [ &
1, 2, 3, 4, 5]
! 4) more complex formatting and tricky test cases !
!**************************************************!
! example 4.1
l = 0
do r = 1, 10
select case ( r )
case( 1)
do i=1,100;if (i<=2) then! comment
do j = 1,5
do k= 1, 3
l = l + 1
! unindented comment
! indented comment
end do; enddo
elseif ( .not. j ==4 ) then
my_integer = 4
else
write (*,*) " hello"
endif
enddo
case(2 )
l = i+ j + k
end select
enddo
! example 4.2
if ( &
l == &
111) &
then
do k = 1, 2
if (k == 1) &
l = test_function(1, &
test_function(r=4, i=5, &
j=6, k=test_function(1,2*(3*(1 +1)), str_function ( ")a!(b['(;=dfe"), &
9) + &
test_function(1, 2, 3, 4)), 9, 10) &
! test_function(1,2,3,4)),9,10) &
! +13*str_function('') + str_function('"')
+ 13*str_function('') + str_function('"')
end & ! comment
! comment
do
endif
! example 4.3
arr = [1,( /3,4, &
5 /),&
6 ]+ &
[1,2, 3, 4,5] ; arr = [1, 2,&
3, 4, 5]
! example 4.4
endif = 3
if(endif==2)then
endif=5
else if(endif==3)then
write(*,*)endif
endif
! example 4.5
do i=1,2;if(.true.)then
write(*, *)"hello"
endif; enddo
end program

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
public class Blastoff{ public static void main(String[] args) { public static void countdown(int n, int m) { if (n == 0) { System.out.println("Blastoff!"); } else { System.out.println(n); countdown(n - 1); } } }}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,92 @@
# Examples from perltidy webpage.....
#Some code with side comments
my $lines = 0; # checksum: #lines
my $bytes = 0; # checksum: #bytes
my $sum = 0; # checksum: system V sum
my $patchdata = 0; # saw patch data
my $pos = 0; # start of patch data
my $endkit = 0; # saw end of kit
my $fail = 0; # failed
#A loop
$_ = <<'EOL';
$url = new URI::URL "http://www/"; die if $url eq "xXx";
EOL
LOOP:{print(" digits"),redo LOOP if/\G\d+\b[,.;]?\s*/gc;print(" lowercase"),
redo LOOP if/\G[a-z]+\b[,.;]?\s*/gc;print(" UPPERCASE"),redo LOOP
if/\G[A-Z]+\b[,.;]?\s*/gc;print(" Capitalized"),
redo LOOP if/\G[A-Z][a-z]+\b[,.;]?\s*/gc;
print(" MiXeD"),redo LOOP if/\G[A-Za-z]+\b[,.;]?\s*/gc;print(
" alphanumeric"),redo LOOP if/\G[A-Za-z0-9]+\b[,.;]?\s*/gc;print(" line-noise"
),redo LOOP if/\G[^A-Za-z0-9]+/gc;print". That's all!\n";}
#A hash definition list
%unitscale=("in",72,"pt",72.27/72,"pc",12,"mm",72/25.4,"cm",72/2.54,
"\\hsize",100,"\\vsize",100,"\\textwidth",100,"\\textheight",100,
"\\pagewidth",100,"\\linewidth",100);
#A matrix
my $a_box = [ [ $a11, $a12, $a13, $a14, $a15, $a16 ],
[ $a21, $a22, $a23, $a24, $a25, $a26 ], [ $a31, $a32, $a33, $a34, $a35, $a36 ],
[ $a41, $a42, $a43, $a44, $a45, $a46 ], [ $a51, $a52, $a53, $a54, $a55, $a56 ],
[ $a61, $a62, $a63, $a64, $a65, $a66 ], ];
#A complex data structure
%TV=(flintstones=>{series=>"flintstones",nights=>[qw(monday thursday friday)],
members=>[{name=>"fred",role=>"lead",age=>36,},{name=>"wilma",role=>"wife",
age=>31,},{name=>"pebbles",role=>"kid",age=>4,},],},jetsons=>{series=>"jetsons",
nights=>[qw(wednesday saturday)],members=>[{name=>"george",role=>"lead",age=>41,
},{name=>"jane",role=>"wife",age=>39,},{name=>"elroy",role=>"kid",age=>9,},],},
simpsons=>{series=>"simpsons",nights=>[qw(monday)],members=>[{name=>"homer",
role=>"lead",age=>34,},{name=>"marge",role=>"wife",age=>37,},{name=>"bart",
role=>"kid",age=>11,},],},);
#Cleaning up code from a code generator
#A good application of perltidy is to clean up code which has been produced by a code generator. Here is a snippet advent.t which was generated from Fortran source by a translation tool.
{
L9140:
if ($msccom::obj==$msccom::food) {
goto L8142;
}
if ($msccom::obj==$msccom::bird||$msccom::obj==$msccom::snake||$msccom::obj==$msccom::clam||$msccom::obj==$msccom::oyster||$msccom::obj==$msccom::dwarf||$msccom::obj==$msccom::dragon||$msccom::obj==$msccom::troll||$msccom::obj==$msccom::bear) {
$msccom::spk=71;
}
goto L2011;
#
# DRINK. IF NO OBJECT, ASSUME WATER AND LOOK FOR IT HERE. IF WATER IS
# THE BOTTLE, DRINK THAT, ELSE MUST BE AT A WATER LOC, SO DRINK STREAM.
#
L9150:
if ($msccom::obj==0&&$liqloc->($placom::loc)!=$msccom::water&&($liq->(0)!=$msccom::water||!$here->($msccom::bottle))) {
goto L8000;
}
if ($msccom::obj!=0&&$msccom::obj!=$msccom::water) {
$msccom::spk=110;
}
if ($msccom::spk==110||$liq->(0)!=$msccom::water||!$here->($msccom::bottle)) {
goto L2011;
}
$placom::prop->($msccom::bottle)=1;
$placom::place->($msccom::water)=0;
$msccom::spk=74;
goto L2011;
#
# RUB. YIELDS VARIOUS SNIDE REMARKS.
#
L9160:
if ($msccom::obj!=$placom::lamp) {
$msccom::spk=76;
}
goto L2011;
#
# THROW. SAME AS DISCARD UNLESS AXE. THEN SAME AS ATTACK EXCEPT IGNOR
# AND IF DWARF IS PRESENT THEN ONE MIGHT BE KILLED. (ONLY WAY TO DO SO
# AXE ALSO SPECIAL FOR DRAGON, BEAR, AND TROLL. TREASURES SPECIAL FOR
#
L9170:
if ($toting->($msccom::rod2)&&$msccom::obj==$msccom::rod&&!$toting->($msccom::rod)) {
$msccom::obj=$msccom::rod2;
}
}

View file

@ -0,0 +1,208 @@
#! /usr/bin/env python
"""Tkinter-based GUI for websucker.
Easy use: type or paste source URL and destination directory in
their respective text boxes,click GO or hit return,and presto.
"""
from Tkinter import *
import Tkinter
import websucker
import sys
import os
import threading
import Queue
import time
VERBOSE=2
try:
class Canceled(Exception):
"Exception used to cancel run()."
except (NameError,TypeError):
Canceled=__name__+".Canceled"
class SuckerThread(websucker.Sucker):
stopit=0
savedir=None
rootdir=None
def __init__(self,msgq):
self.msgq=msgq
websucker.Sucker.__init__(self)
self.setflags(verbose=VERBOSE)
self.urlopener.addheaders=[('User-agent','websucker/%s'%websucker.__version__),]
def message(self,format,*args):
if args:
format=format%args
##print format
self.msgq.put(format)
def run1(self,url):
try:
try:
self.reset()
self.addroot(url)
self.run()
except Canceled:
self.message("[canceled]")
else:
self.message("[done]")
finally:
self.msgq.put(None)
def savefile(self,text,path):
if self.stopit:
raise Canceled
websucker.Sucker.savefile(self,text,path)
def getpage(self,url):
if self.stopit:
raise Canceled
return websucker.Sucker.getpage(self,url)
def savefilename(self,url):
path=websucker.Sucker.savefilename(self,url)
if self.savedir:
n=len(self.rootdir)
if path[:n] == self.rootdir:
path=path[n:]
while path[:1] == os.sep:
path=path[1:]
path=os.path.join(self.savedir,path)
return path
def XXXaddrobot(self,*args):
pass
def XXXisallowed(self,*args):
return 1
class App:
sucker=None
msgq=None
def __init__(self,top):
self.top=top
top.columnconfigure(99,weight=1)
self.url_label=Label(top,text="URL:")
self.url_label.grid(row=0,column=0,sticky='e')
self.url_entry=Entry(top,width=60,exportselection=0)
self.url_entry.grid(row=0,column=1,sticky='we',
columnspan=99)
self.url_entry.focus_set()
self.url_entry.bind("<Key-Return>",self.go)
self.dir_label=Label(top,text="Directory:")
self.dir_label.grid(row=1,column=0,sticky='e')
self.dir_entry=Entry(top)
self.dir_entry.grid(row=1,column=1,sticky='we',
columnspan=99)
self.go_button=Button(top,text="Go",command=self.go)
self.go_button.grid(row=2,column=1,sticky='w')
self.cancel_button=Button(top,text="Cancel",
command=self.cancel,
state=DISABLED)
self.cancel_button.grid(row=2,column=2,sticky='w')
self.auto_button=Button(top,text="Paste+Go",
command=self.auto)
self.auto_button.grid(row=2,column=3,sticky='w')
self.status_label=Label(top,text="[idle]")
self.status_label.grid(row=2,column=4,sticky='w')
self.top.update_idletasks()
self.top.grid_propagate(0)
def message(self,text,*args):
if args:
text=text % args
self.status_label.config(text=text)
def check_msgq(self):
while not self.msgq.empty():
msg=self.msgq.get()
if msg is None:
self.go_button.configure(state=NORMAL)
self.auto_button.configure(state=NORMAL)
self.cancel_button.configure(state=DISABLED)
if self.sucker:
self.sucker.stopit=0
self.top.bell()
else:
self.message(msg)
self.top.after(100,self.check_msgq)
def go(self,event=None):
if not self.msgq:
self.msgq=Queue.Queue(0)
self.check_msgq()
if not self.sucker:
self.sucker=SuckerThread(self.msgq)
if self.sucker.stopit:
return
self.url_entry.selection_range(0,END)
url=self.url_entry.get()
url=url.strip()
if not url:
self.top.bell()
self.message("[Error: No URL entered]")
return
self.rooturl=url
dir=self.dir_entry.get().strip()
if not dir:
self.sucker.savedir=None
else:
self.sucker.savedir=dir
self.sucker.rootdir=os.path.dirname(
websucker.Sucker.savefilename(self.sucker,url))
self.go_button.configure(state=DISABLED)
self.auto_button.configure(state=DISABLED)
self.cancel_button.configure(state=NORMAL)
self.message( '[running...]')
self.sucker.stopit=0
t=threading.Thread(target=self.sucker.run1,args=(url,))
t.start()
def cancel(self):
if self.sucker:
self.sucker.stopit=1
self.message("[canceling...]")
def auto(self):
tries=['PRIMARY','CLIPBOARD']
text=""
for t in tries:
try:
text=self.top.selection_get(selection=t)
except TclError:
continue
text=text.strip()
if text:
break
if not text:
self.top.bell()
self.message("[Error: clipboard is empty]")
return
self.url_entry.delete(0,END)
self.url_entry.insert(0,text)
self.go()
class AppArray:
def __init__(self,top=None):
if not top:
top=Tk()
top.title("websucker GUI")
top.iconname("wsgui")
top.wm_protocol('WM_DELETE_WINDOW',self.exit)
self.top=top
self.appframe=Frame(self.top)
self.appframe.pack(fill='both')
self.applist=[]
self.exit_button=Button(top,text="Exit",command=self.exit)
self.exit_button.pack(side=RIGHT)
self.new_button=Button(top,text="New",command=self.addsucker)
self.new_button.pack(side=LEFT)
self.addsucker()
##self.applist[0].url_entry.insert(END,"http://www.python.org/doc/essays/")
def addsucker(self):
self.top.geometry("")
frame=Frame(self.appframe,borderwidth=2,relief=GROOVE)
frame.pack(fill='x')
app=App(frame)
self.applist.append(app)
done=0
def mainloop(self):
while not self.done:
time.sleep(0.1)
self.top.update()
def exit(self):
for app in self.applist:
app.cancel()
app.message("[exiting...]")
self.done=1
def main():
AppArray().mainloop()
if __name__ == '__main__':
main()

View file

@ -0,0 +1,33 @@
require 'inifile'
# Reads settings from init file
class Settings
attr_reader :jusername, :jpassword, :jurl
def initialize(path)
settings = read(path)
parse(settings)
end
private
def read(path)
settings = IniFile.load(path)
fail "File #{path} not found!" unless settings
settings
end
def parse(settings)
jira = settings['jira']
fail "Init file hasn't [jira] section!" unless jira
@jusername = jira['username']
@jpassword = jira['password']
@jurl = jira['url']
fail "Init file hasn't username option!" unless jusername
fail "Init file hasn't password option!" unless jpassword
fail "Init file hasn't url option!" unless jurl
end
end

View file

@ -0,0 +1 @@
body{overflow:hidden;background:#000000;background-image:url(images/bg.gif);background-repeat:no-repeat;background-position:left top;}

View file

@ -0,0 +1,4 @@
{
"test": "test",
"test": [1, 2, 3]
}

View file

@ -0,0 +1 @@
selECT * FROM foo WHERE id IN (SELECT id FROM bar);

View file

@ -0,0 +1 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> <title> </title></head><body> <script type="text/javascript">function bla(foo) { }</script><br /> <form> <input type="text" name="NUMBER" onkeypress= "RETURN ISnUMBERkEY(EVENT)" /> </form></body></html>

View file

@ -0,0 +1 @@
<catalog> <book id="bk101"> <author>Gambardella, Matthew</author> <title>XML Developer's Guide</title> <genre>Computer</genre> <price>44.95</price> <publish_date>2000-10-01</publish_date> <description>An in-depth look at creating applications with XML.</description> </book> <book id="bk102"> <author>Ralls, Kim</author> <title>Midnight Rain</title> <genre>Fantasy</genre> <price>5.95</price> <publish_date>2000-12-16</publish_date> <description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</description> </book> <book id="bk103"> <author>Corets, Eva</author> <title>Maeve Ascendant</title> <genre>Fantasy</genre> <price>5.95</price> <publish_date>2000-11-17</publish_date> <description>After the collapse of a nanotechnology society in England, the young survivors lay the foundation for a new society.</description> </book> <book id="bk104"> <author>Corets, Eva</author> <title>Oberon's Legacy</title> <genre>Fantasy</genre> <price>5.95</price> <publish_date>2001-03-10</publish_date> <description>In post-apocalypse England, the mysterious agent known only as Oberon helps to create a new life for the inhabitants of London. Sequel to Maeve Ascendant.</description> </book> <book id="bk105"> <author>Corets, Eva</author> <title>The Sundered Grail</title> <genre>Fantasy</genre> <price>5.95</price> <publish_date>2001-09-10</publish_date> <description>The two daughters of Maeve, half-sisters, battle one another for control of England. Sequel to Oberon's Legacy.</description> </book> <book id="bk106"> <author>Randall, Cynthia</author> <title>Lover Birds</title> <genre>Romance</genre> <price>4.95</price> <publish_date>2000-09-02</publish_date> <description>When Carla meets Paul at an ornithology conference, tempers fly as feathers get ruffled.</description> </book> <book id="bk107"> <author>Thurman, Paula</author> <title>Splish Splash</title> <genre>Romance</genre> <price>4.95</price> <publish_date>2000-11-02</publish_date> <description>A deep sea diver finds true love twenty thousand leagues beneath the sea.</description> </book> <book id="bk108"> <author>Knorr, Stefan</author> <title>Creepy Crawlies</title> <genre>Horror</genre> <price>4.95</price> <publish_date>2000-12-06</publish_date> <description>An anthology of horror stories about roaches, centipedes, scorpions and other insects.</description> </book> <book id="bk109"> <author>Kress, Peter</author> <title>Paradox Lost</title> <genre>Science Fiction</genre> <price>6.95</price> <publish_date>2000-11-02</publish_date> <description>After an inadvertant trip through a Heisenberg Uncertainty Device, James Salway discovers the problems of being quantum.</description> </book> <book id="bk110"> <author>O'Brien, Tim</author> <title>Microsoft .NET: The Programming Bible</title> <genre>Computer</genre> <price>36.95</price> <publish_date>2000-12-09</publish_date> <description>Microsoft's .NET initiative is explored in detail in this deep programmer's reference.</description> </book> <book id="bk111"> <author>O'Brien, Tim</author> <title>MSXML3: A Comprehensive Guide</title> <genre>Computer</genre> <price>36.95</price> <publish_date>2000-12-01</publish_date> <description>The Microsoft MSXML3 parser is covered in detail, with attention to XML DOM interfaces, XSLT processing, SAX and more.</description> </book> <book id="bk112"> <author>Galos, Mike</author> <title>Visual Studio 7: A Comprehensive Guide</title> <genre>Computer</genre> <price>49.95</price> <publish_date>2001-04-16</publish_date> <description>Microsoft Visual Studio 7 is explored in depth, looking at how Visual Basic, Visual C++, C#, and ASP+ are integrated into a comprehensive development environment.</description> </book></catalog>

View file

@ -1,2 +0,0 @@
# http://stackoverflow.com/a/932982
!.gitignore

View file

@ -1 +0,0 @@
Undo dir for VIM

View file

@ -109,7 +109,7 @@ let g:multi_cursor_quit_key = '<Esc>'
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => surround.vim config
" Annotate strings with gettext
" Annotate strings with gettext
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
vmap Si S(i_<esc>f)
au FileType mako vmap Si S"i${ _(<esc>2f"a) }<esc>
@ -119,25 +119,25 @@ au FileType mako vmap Si S"i${ _(<esc>2f"a) }<esc>
" => lightline
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let g:lightline = {
\ 'colorscheme': 'wombat',
\ 'active': {
\ 'left': [ ['mode', 'paste'],
\ ['fugitive', 'readonly', 'filename', 'modified'] ],
\ 'right': [ [ 'lineinfo' ], ['percent'] ]
\ },
\ 'component': {
\ 'readonly': '%{&filetype=="help"?"":&readonly?"🔒":""}',
\ 'modified': '%{&filetype=="help"?"":&modified?"+":&modifiable?"":"-"}',
\ 'fugitive': '%{exists("*FugitiveHead")?FugitiveHead():""}'
\ },
\ 'component_visible_condition': {
\ 'readonly': '(&filetype!="help"&& &readonly)',
\ 'modified': '(&filetype!="help"&&(&modified||!&modifiable))',
\ 'fugitive': '(exists("*FugitiveHead") && ""!=FugitiveHead())'
\ },
\ 'separator': { 'left': ' ', 'right': ' ' },
\ 'subseparator': { 'left': ' ', 'right': ' ' }
\ }
\ 'colorscheme': 'wombat',
\ 'active': {
\ 'left': [ ['mode', 'paste'],
\ ['fugitive', 'readonly', 'filename', 'modified'] ],
\ 'right': [ [ 'lineinfo' ], ['percent'] ]
\ },
\ 'component': {
\ 'readonly': '%{&filetype=="help"?"":&readonly?"🔒":""}',
\ 'modified': '%{&filetype=="help"?"":&modified?"+":&modifiable?"":"-"}',
\ 'fugitive': '%{exists("*FugitiveHead")?FugitiveHead():""}'
\ },
\ 'component_visible_condition': {
\ 'readonly': '(&filetype!="help"&& &readonly)',
\ 'modified': '(&filetype!="help"&&(&modified||!&modifiable))',
\ 'fugitive': '(exists("*FugitiveHead") && ""!=FugitiveHead())'
\ },
\ 'separator': { 'left': ' ', 'right': ' ' },
\ 'subseparator': { 'left': ' ', 'right': ' ' }
\ }
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Vimroom
@ -152,10 +152,10 @@ nnoremap <silent> <leader>z :Goyo<cr>
" => Ale (syntax checker and linter)
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let g:ale_linters = {
\ 'javascript': ['eslint'],
\ 'python': ['flake8'],
\ 'go': ['go', 'golint', 'errcheck']
\}
\ 'javascript': ['eslint'],
\ 'python': ['flake8'],
\ 'go': ['go', 'golint', 'errcheck']
\}
nmap <silent> <leader>a <Plug>(ale_next_wrap)
@ -186,3 +186,26 @@ let g:EditorConfig_exclude_patterns = ['fugitive://.*']
" Copy the link to the line of a Git repository to the clipboard
nnoremap <leader>v :.GBrowse!<CR>
xnoremap <leader>v :'<'>GBrowse!<CR>
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Coc.nvim
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Use tab for trigger completion with characters ahead and navigate.
" NOTE: Use command ':verbose imap <tab>' to make sure tab is not mapped by
" other plugin before putting this into your config.
"inoremap <silent><expr> <TAB>
"" \ pumvisible() ? "\<C-n>" :
"" \ <SID>check_back_space() ? "\<TAB>" :
"" \ coc#refresh()
"inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
" Make <CR> auto-select the first completion item and notify coc.nvim to
" format on enter, <cr> could be remapped by other vim plugin
inoremap <silent><expr> <cr> pumvisible() ? coc#_select_confirm()
\: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Vim-autoformat
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let g:python3_host_prog="/usr/bin/python3"
autocmd BufWrite * :Autoformat