├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ ├── question.md │ └── request-new-formatter.md └── workflows │ ├── discord.yml │ └── run-tests.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── addon-info.json ├── autoload ├── codefmt.vim └── codefmt │ ├── autopep8.vim │ ├── black.vim │ ├── buildifier.vim │ ├── clangformat.vim │ ├── cljstyle.vim │ ├── dartfmt.vim │ ├── fish_indent.vim │ ├── formatterhelpers.vim │ ├── gn.vim │ ├── gofmt.vim │ ├── googlejava.vim │ ├── isort.vim │ ├── jsbeautify.vim │ ├── jsonnetfmt.vim │ ├── juliaformatter.vim │ ├── ktfmt.vim │ ├── luaformatterfiveone.vim │ ├── mixformat.vim │ ├── nixpkgs_fmt.vim │ ├── ocamlformat.vim │ ├── ormolu.vim │ ├── prettier.vim │ ├── rubocop.vim │ ├── ruff.vim │ ├── rustfmt.vim │ ├── shfmt.vim │ ├── swiftformat.vim │ ├── yapf.vim │ └── zprint.vim ├── bin └── julia │ ├── .JuliaFormatter.toml │ ├── Manifest.toml │ ├── Project.toml │ ├── format.jl │ ├── install │ └── install.cmd ├── bootstrap.vim ├── doc └── codefmt.txt ├── instant └── flags.vim ├── plugin ├── autocmds.vim ├── commands.vim ├── mappings.vim └── register.vim └── vroom ├── autocmd.vroom ├── autopep8.vroom ├── black.vroom ├── buildifier.vroom ├── clangformat-cursor.vroom ├── clangformat.vroom ├── cljstyle.vroom ├── dartfmt.vroom ├── extensions.vroom ├── fish_indent.vroom ├── gn.vroom ├── gofmt.vroom ├── googlejava.vroom ├── jsbeautify.vroom ├── jsonnetfmt.vroom ├── juliaformatter.vroom ├── ktfmt.vroom ├── luaformatterfiveone.vroom ├── main.vroom ├── mixformat.vroom ├── nixpkgs_fmt.vroom ├── ocamlformat.vroom ├── ormolu.vroom ├── prettier.vroom ├── rubocop.vroom ├── ruff.vroom ├── rustfmt.vroom ├── setupvroom.vim ├── shfmt.vroom ├── swiftformat.vroom ├── yapf.vroom └── zprint.vroom /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | indent_size = 2 7 | indent_style = space 8 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | [*.{md,py,vim,vroom}] 12 | max_line_length = 80 13 | 14 | [*.{py,vim}] 15 | quote_type = single 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | [A clear and concise description of what the bug is.] 12 | 13 | **To Reproduce** 14 | Minimal vimrc: 15 | [If relevant, please provide a minimal vimrc needed to reproduce the issue. You can create a Gist and post it here (example: https://gist.github.com/dbarnett/c129895ce8b783f7559ed7156516c739).] 16 | 17 | Steps to reproduce the behavior: 18 | [ 19 | 1. Go to '...' 20 | 2. Click on '....' 21 | 3. Scroll down to '....' 22 | 4. See error 23 | ] 24 | 25 | **Expected behavior** 26 | [A clear and concise description of what you expected to happen.] 27 | 28 | **OS (version)** 29 | [What is your OS & version, if the problem might depend on platform?] 30 | 31 | **Additional context** 32 | [Add any other context about the problem here.] 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Ask a general question about vim-codefmt 4 | title: '' 5 | labels: question 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/request-new-formatter.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Request new formatter 3 | about: Submit a request for a formatter not already supported (or requested at https://bit.ly/3alNxjb) 4 | title: '' 5 | labels: new formatter 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Formatter tool** 11 | [Name of the tool and link to context] 12 | 13 | **Filetype(s)** 14 | [Applicable languages/filetypes you'd like to use this tool to format] 15 | 16 | **Additional context** 17 | [Add any other context or screenshots about the feature request here.] 18 | -------------------------------------------------------------------------------- /.github/workflows/discord.yml: -------------------------------------------------------------------------------- 1 | name: notify-discord 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request_target: 7 | branches: [master] 8 | issues: 9 | types: [opened] 10 | 11 | jobs: 12 | notify: 13 | runs-on: ubuntu-latest 14 | if: github.repository == 'google/vim-codefmt' 15 | 16 | steps: 17 | - name: Actions for Discord 18 | env: 19 | DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} 20 | uses: Ilshidur/action-discord@0.3.2 21 | -------------------------------------------------------------------------------- /.github/workflows/run-tests.yml: -------------------------------------------------------------------------------- 1 | name: run-tests 2 | 3 | on: [push, pull_request] 4 | 5 | env: 6 | VROOM_VERSION: 0.14.0 7 | MAKTABA_VERSION: 1.14.0 8 | 9 | jobs: 10 | run-tests: 11 | runs-on: ${{ matrix.os }} 12 | strategy: 13 | matrix: 14 | os: 15 | - ubuntu-22.04 16 | vim-flavour: 17 | - vim 18 | - neovim 19 | steps: 20 | - uses: actions/checkout@v2 21 | 22 | - name: Install vim 23 | if: ${{ matrix.vim-flavour == 'vim' }} 24 | run: | 25 | sudo apt update 26 | sudo apt install vim vim-gtk xvfb 27 | - name: Install neovim 28 | if: ${{ matrix.vim-flavour == 'neovim' }} 29 | run: | 30 | sudo apt update 31 | sudo apt install neovim python3-neovim xvfb 32 | - name: Install vroom 33 | run: | 34 | wget https://github.com/google/vroom/releases/download/v${VROOM_VERSION}/vroom_${VROOM_VERSION}-1_all.deb 35 | sudo dpkg -i ./vroom_${VROOM_VERSION}-1_all.deb 36 | - name: Install plugin dependencies 37 | run: | 38 | git clone -b ${MAKTABA_VERSION} https://github.com/google/vim-maktaba.git ../maktaba/ 39 | git clone https://github.com/google/vim-glaive.git ../glaive/ 40 | 41 | - name: Run tests (vim) 42 | if: ${{ matrix.vim-flavour == 'vim' }} 43 | timeout-minutes: 30 44 | run: | 45 | xvfb-run script -q -e -c 'vroom --crawl' 46 | - name: Run tests (neovim) 47 | if: ${{ matrix.vim-flavour == 'neovim' }} 48 | timeout-minutes: 30 49 | run: | 50 | xvfb-run script -q -e -c 'vroom --neovim --crawl' 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /doc/tags 2 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # See https://pre-commit.com for more information 2 | repos: 3 | - repo: https://github.com/google/vimdoc 4 | rev: v0.7.1 5 | hooks: 6 | - id: vimdoc 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: generic 2 | env: 3 | global: 4 | - VROOM_VERSION=0.14.0 5 | jobs: 6 | # This Maktaba version should match the minimum required in instant/flags.vim. 7 | - CI_TARGET=vim MAKTABA_VERSION=1.12.0 8 | - CI_TARGET=vim MAKTABA_VERSION=master 9 | - CI_TARGET=neovim MAKTABA_VERSION=1.12.0 10 | - CI_TARGET=neovim MAKTABA_VERSION=master 11 | before_script: 12 | - sudo apt-get update 13 | - sudo apt-get install python3-dev 14 | - if [ $CI_TARGET = vim ]; then 15 | sudo apt-get install vim-gnome; 16 | elif [ $CI_TARGET = neovim ]; then 17 | eval "$(curl -Ss https://raw.githubusercontent.com/neovim/bot-ci/master/scripts/travis-setup.sh) nightly-x64" && 18 | wget https://bootstrap.pypa.io/pip/3.5/get-pip.py && 19 | sudo python3 get-pip.py && 20 | sudo pip3 install neovim; 21 | fi 22 | - wget https://github.com/google/vroom/releases/download/v${VROOM_VERSION}/vroom_${VROOM_VERSION}-1_all.deb 23 | - sudo dpkg -i ./vroom_${VROOM_VERSION}-1_all.deb 24 | - git clone -b ${MAKTABA_VERSION} https://github.com/google/vim-maktaba.git ../maktaba/ 25 | - git clone https://github.com/google/vim-glaive.git ../glaive/ 26 | services: 27 | - xvfb 28 | script: 29 | - '[ $CI_TARGET = neovim ] && VROOM_ARGS="--neovim" || VROOM_ARGS=""' 30 | - vroom $VROOM_ARGS --crawl ./vroom/ 31 | jobs: 32 | fast_finish: true 33 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributor License Agreement ## 2 | 3 | Patches and contributions are welcome. Before we can accept them, though, we 4 | have to see to the legal details. 5 | 6 | Contributions to any Google project must be accompanied by a Contributor 7 | License Agreement. This is not a copyright **assignment**, it simply gives 8 | Google permission to use and redistribute your contributions as part of the 9 | project. 10 | 11 | * If you are an individual writing original source code and you're sure you 12 | own the intellectual property, then you'll need to sign an [individual 13 | CLA][]. 14 | 15 | * If you work for a company that wants to allow you to contribute your work, 16 | then you'll need to sign a [corporate CLA][]. 17 | 18 | You generally only need to submit a CLA once, so if you've already submitted 19 | one (even if it was for a different project), you probably don't need to do it 20 | again. 21 | 22 | [individual CLA]: https://developers.google.com/open-source/cla/individual 23 | [corporate CLA]: https://developers.google.com/open-source/cla/corporate 24 | 25 | 26 | ## Submitting a patch ## 27 | 28 | 1. It's generally best to start by opening a new issue describing the bug or 29 | feature you're intending to fix. Even if you think it's relatively minor, 30 | it's helpful to know what people are working on. Mention in the initial 31 | issue that you are planning to work on that bug or feature so that it can 32 | be assigned to you. 33 | 34 | 1. Follow the normal process of [forking][] the project, and setup a new 35 | branch to work in. It's important that each group of changes be done in 36 | separate branches in order to ensure that a pull request only includes the 37 | commits related to that bug or feature. 38 | 39 | 1. Any significant changes should almost always be accompanied by tests. The 40 | project already has good test coverage, so look at some of the existing 41 | tests (in the `vroom/` directory) if you're unsure how to go about it. 42 | 43 | 1. Do your best to have [well-formed commit messages][] for each change. 44 | This provides consistency throughout the project, and ensures that commit 45 | messages are able to be formatted properly by various git tools. 46 | 47 | 1. Finally, push the commits to your fork and submit a [pull request][]. 48 | 49 | [forking]: https://help.github.com/articles/fork-a-repo 50 | [well-formed commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html 51 | [pull request]: https://help.github.com/articles/creating-a-pull-request 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Travis Build Status](https://travis-ci.org/google/vim-codefmt.svg?branch=master)](https://travis-ci.org/google/vim-codefmt) 2 | 3 | codefmt is a utility for syntax-aware code formatting. It contains several 4 | built-in formatters, and allows new formatters to be registered by other 5 | plugins. 6 | 7 | For details, see the executable documentation in the `vroom/` directory or the 8 | helpfiles in the `doc/` directory. The helpfiles are also available via `:help 9 | codefmt` if codefmt is installed (and helptags have been generated). 10 | 11 | # Supported File-types 12 | 13 | * [Bazel](https://www.github.com/bazelbuild/bazel) BUILD files (buildifier) 14 | * C, C++ (clang-format) 15 | * [Clojure](https://clojure.org/) 16 | ([zprint](https://github.com/kkinnear/zprint), 17 | [cljstyle](https://github.com/greglook/cljstyle)) 18 | * CSS, Sass, SCSS, Less (js-beautify, prettier) 19 | * Dart (dartfmt) 20 | * Elixir ([`mix format`](https://hexdocs.pm/mix/main/Mix.Tasks.Format.html)) 21 | * Fish 22 | ([fish_indent](https://fishshell.com/docs/current/commands.html#fish_indent)) 23 | * [GN](https://www.chromium.org/developers/gn-build-configuration) (gn) 24 | * Go (gofmt) 25 | * Haskell ([ormolu](https://github.com/tweag/ormolu)) 26 | * HTML (js-beautify, prettier) 27 | * Java (google-java-format or clang-format) 28 | * JavaScript (clang-format, js-beautify, or [prettier](https://prettier.io)) 29 | * JSON (js-beautify) 30 | * Jsonnet ([jsonnetfmt](https://jsonnet.org/learning/tools.html)) 31 | * Julia ([JuliaFormatter](https://github.com/domluna/JuliaFormatter.jl)) 32 | * Kotlin ([ktfmt](https://github.com/facebookincubator/ktfmt)) 33 | * Lua 34 | ([FormatterFiveOne](https://luarocks.org/modules/ElPiloto/formatterfiveone)) 35 | * Markdown (prettier) 36 | * Nix (nixpkgs-fmt) 37 | * OCaml ([ocamlformat](https://github.com/ocaml-ppx/ocamlformat)) 38 | * Protocol Buffers (clang-format) 39 | * Python (Autopep8, Black, isort, Ruff, or YAPF) 40 | * Ruby ([rubocop](https://rubocop.org)) 41 | * Rust ([rustfmt](https://github.com/rust-lang/rustfmt)) 42 | * Shell (shfmt) 43 | * Swift ([swift-format](https://github.com/apple/swift-format)) 44 | * TypeScript (clang-format) 45 | * [Vue](http://vuejs.org) (prettier) 46 | 47 | # Commands 48 | 49 | Use `:FormatLines` to format a range of lines or use `:FormatCode` to format the 50 | entire buffer. Use `:NoAutoFormatBuffer` to disable current buffer formatting. 51 | 52 | # Usage example 53 | 54 | Before: 55 | 56 | ```cpp 57 | int foo(int * x) { return * x** x ; } 58 | ``` 59 | 60 | After running `:FormatCode`: 61 | 62 | ```cpp 63 | int foo(int* x) { return *x * *x; } 64 | ``` 65 | 66 | # Installation 67 | 68 | This example uses [Vundle](https://github.com/gmarik/Vundle.vim), whose 69 | plugin-adding command is `Plugin`. 70 | 71 | ```vim 72 | " Add maktaba and codefmt to the runtimepath. 73 | " (The latter must be installed before it can be used.) 74 | Plugin 'google/vim-maktaba' 75 | Plugin 'google/vim-codefmt' 76 | " Also add Glaive, which is used to configure codefmt's maktaba flags. See 77 | " `:help :Glaive` for usage. 78 | Plugin 'google/vim-glaive' 79 | " ... 80 | call vundle#end() 81 | " the glaive#Install() should go after the "call vundle#end()" 82 | call glaive#Install() 83 | " Optional: Enable codefmt's default mappings on the = prefix. 84 | Glaive codefmt plugin[mappings] 85 | Glaive codefmt google_java_executable="java -jar /path/to/google-java-format-VERSION-all-deps.jar" 86 | ``` 87 | 88 | Make sure you have updated maktaba recently. Codefmt depends upon maktaba to 89 | register formatters. 90 | 91 | # Autoformatting 92 | 93 | Want to just sit back and let autoformat happen automatically? Add this to your 94 | `vimrc` (or any subset): 95 | 96 | ```vim 97 | augroup autoformat_settings 98 | autocmd FileType bzl AutoFormatBuffer buildifier 99 | autocmd FileType c,cpp,proto,javascript,typescript,arduino AutoFormatBuffer clang-format 100 | autocmd FileType clojure AutoFormatBuffer cljstyle 101 | autocmd FileType dart AutoFormatBuffer dartfmt 102 | autocmd FileType elixir,eelixir,heex AutoFormatBuffer mixformat 103 | autocmd FileType fish AutoFormatBuffer fish_indent 104 | autocmd FileType gn AutoFormatBuffer gn 105 | autocmd FileType go AutoFormatBuffer gofmt 106 | autocmd FileType haskell AutoFormatBuffer ormolu 107 | " Alternative for web languages: prettier 108 | autocmd FileType html,css,sass,scss,less,json AutoFormatBuffer js-beautify 109 | autocmd FileType java AutoFormatBuffer google-java-format 110 | autocmd FileType jsonnet AutoFormatBuffer jsonnetfmt 111 | autocmd FileType julia AutoFormatBuffer JuliaFormatter 112 | autocmd FileType kotlin AutoFormatBuffer ktfmt 113 | autocmd FileType lua AutoFormatBuffer luaformatterfiveone 114 | autocmd FileType markdown AutoFormatBuffer prettier 115 | autocmd FileType ocaml AutoFormatBuffer ocamlformat 116 | autocmd FileType python AutoFormatBuffer yapf 117 | " Alternative: autocmd FileType python AutoFormatBuffer autopep8 118 | autocmd FileType ruby AutoFormatBuffer rubocop 119 | autocmd FileType rust AutoFormatBuffer rustfmt 120 | autocmd FileType swift AutoFormatBuffer swift-format 121 | autocmd FileType vue AutoFormatBuffer prettier 122 | augroup END 123 | ``` 124 | 125 | # Configuring formatters 126 | 127 | Most formatters have some options available that can be configured via 128 | [Glaive](https://www.github.com/google/vim-glaive) You can get a quick view of 129 | all codefmt flags by executing `:Glaive codefmt`, or start typing flag names and 130 | use tab completion. See `:help Glaive` for usage details. 131 | 132 | # Installing formatters 133 | 134 | Codefmt defines several built-in formatters. The easiest way to see the list of 135 | available formatters is via tab completion: Type `:FormatCode ` in vim. 136 | Formatters that apply to the current filetype will be listed first. 137 | 138 | To use a particular formatter, type `:FormatCode FORMATTER-NAME`. This will 139 | either format the current buffer using the selected formatter or show an error 140 | message with basic setup instructions for this formatter. Normally you will 141 | trigger formatters via key mappings and/or autocommand hooks. See 142 | vroom/main.vroom to learn more about formatting features, and see 143 | vroom/FORMATTER-NAME.vroom to learn more about usage for individual formatters. 144 | 145 | ## Creating a New Formatter 146 | 147 | Assume a filetype `myft` and a formatter called `MyFormatter`. Our detailed 148 | guide to creating a formatter 149 | [lives here](https://github.com/google/vim-codefmt/wiki/Formatter-Integration-Guide). 150 | 151 | * Create an issue for your new formatter and discuss! 152 | 153 | * Create a new file in `autoload/codefmt/myformatter.vim` See 154 | `autoload/codefmt/buildifier.vim for an example. This is where all the logic 155 | for formatting goes. 156 | 157 | * Register the formatter in [plugin/register.vim](plugin/register.vim) with: 158 | 159 | ```vim 160 | call s:registry.AddExtension(codefmt#myformatter#GetFormatter()) 161 | ``` 162 | 163 | * Create a flag in [instant/flags.vim](instant/flags.vim) 164 | 165 | ```vim 166 | "" 167 | " The path to the buildifier executable. 168 | call s:plugin.Flag('myformatter_executable', 'myformatter') 169 | ``` 170 | 171 | * Create a [vroom](https://github.com/google/vroom) test named 172 | `vroom/myformatter.vroom` to ensure your formatter works properly. 173 | 174 | * Update the README.md to mention your new filetype! 175 | 176 | That's it! Of course, the complicated step is in the details of 177 | `myformatter.vim`. 178 | 179 | // TODO(kashomon): Create a worked example formatter. 180 | -------------------------------------------------------------------------------- /addon-info.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codefmt", 3 | "description": "Syntax-aware code formatting for a variety of languages", 4 | "author": "Google", 5 | "repository": {"type": "git", "url": "git://github.com/google/vim-codefmt"}, 6 | "dependencies": { 7 | "maktaba": {"type": "git", "url": "git://github.com/google/vim-maktaba"} 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /autoload/codefmt/autopep8.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2017 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | "" 20 | " @private 21 | " Invalidates the cached autopep8 version detection info. 22 | function! codefmt#autopep8#InvalidateVersion() abort 23 | unlet! s:autopep8_supports_range 24 | endfunction 25 | 26 | 27 | "" 28 | " @private 29 | " Formatter: autopep8 30 | function! codefmt#autopep8#GetFormatter() abort 31 | let l:formatter = { 32 | \ 'name': 'autopep8', 33 | \ 'setup_instructions': 'Install autopep8 ' . 34 | \ '(https://pypi.python.org/pypi/autopep8/).'} 35 | 36 | function l:formatter.IsAvailable() abort 37 | return executable(s:plugin.Flag('autopep8_executable')) 38 | endfunction 39 | 40 | function l:formatter.AppliesToBuffer() abort 41 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'python') 42 | endfunction 43 | 44 | "" 45 | " Reformat the current buffer with autopep8 or the binary named in 46 | " @flag(autopep8_executable), only targeting the range between {startline} and 47 | " {endline}. 48 | " @throws ShellError 49 | function l:formatter.FormatRange(startline, endline) abort 50 | let l:executable = s:plugin.Flag('autopep8_executable') 51 | if !exists('s:autopep8_supports_range') 52 | let l:version_call = 53 | \ maktaba#syscall#Create([l:executable, '--version']).Call() 54 | " In some cases version is written to stderr, in some to stdout 55 | let l:version_output = empty(version_call.stderr) ? 56 | \ version_call.stdout : version_call.stderr 57 | let l:autopep8_version = 58 | \ matchlist(l:version_output, '\m\Cautopep8 \(\d\+\)\.') 59 | if empty(l:autopep8_version) 60 | throw maktaba#error#Failure( 61 | \ 'Unable to parse version from `%s --version`: %s', 62 | \ l:executable, l:version_output) 63 | else 64 | let s:autopep8_supports_range = l:autopep8_version[1] >= 1 65 | endif 66 | endif 67 | 68 | call maktaba#ensure#IsNumber(a:startline) 69 | call maktaba#ensure#IsNumber(a:endline) 70 | 71 | if s:autopep8_supports_range 72 | call codefmt#formatterhelpers#Format([ 73 | \ l:executable, 74 | \ '--range', string(a:startline), string(a:endline), 75 | \ '-']) 76 | else 77 | call codefmt#formatterhelpers#AttemptFakeRangeFormatting( 78 | \ a:startline, 79 | \ a:endline, 80 | \ [l:executable, '-']) 81 | endif 82 | endfunction 83 | 84 | return l:formatter 85 | endfunction 86 | -------------------------------------------------------------------------------- /autoload/codefmt/black.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2020 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | "" 20 | " @private 21 | " Formatter: black 22 | function! codefmt#black#GetFormatter() abort 23 | let l:formatter = { 24 | \ 'name': 'black', 25 | \ 'setup_instructions': 'Install black ' . 26 | \ '(https://pypi.python.org/pypi/black/).'} 27 | 28 | function l:formatter.IsAvailable() abort 29 | return executable(s:plugin.Flag('black_executable')) 30 | endfunction 31 | 32 | function l:formatter.AppliesToBuffer() abort 33 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'python') 34 | endfunction 35 | 36 | "" 37 | " Reformat the current buffer with black or the binary named in 38 | " @flag(black_executable) 39 | " 40 | " We implement Format(), and not FormatRange{,s}(), because black doesn't 41 | " provide a hook for formatting a range 42 | function l:formatter.Format() abort 43 | let l:executable = s:plugin.Flag('black_executable') 44 | 45 | call codefmt#formatterhelpers#Format([ 46 | \ l:executable, 47 | \ '-']) 48 | endfunction 49 | 50 | return l:formatter 51 | endfunction 52 | -------------------------------------------------------------------------------- /autoload/codefmt/buildifier.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2017 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | "" 20 | " @private 21 | " 22 | " Formatter provider for Bazel BUILD files using buildifier. 23 | function! codefmt#buildifier#GetFormatter() abort 24 | let l:formatter = { 25 | \ 'name': 'buildifier', 26 | \ 'setup_instructions': 'Install buildifier. ' . 27 | \ '(https://github.com/bazelbuild/buildifier).'} 28 | 29 | function l:formatter.IsAvailable() abort 30 | return executable(s:plugin.Flag('buildifier_executable')) 31 | endfunction 32 | 33 | function l:formatter.AppliesToBuffer() abort 34 | return &filetype is# 'bzl' 35 | endfunction 36 | 37 | "" 38 | " Reformat the current buffer with buildifier or the binary named in 39 | " @flag(buildifier) 40 | " @throws ShellError 41 | function l:formatter.Format() abort 42 | let l:lint_flag = s:plugin.Flag('buildifier_lint_mode') 43 | let l:cmd = [ s:plugin.Flag('buildifier_executable') ] 44 | if !empty(l:lint_flag) 45 | let l:cmd += ["--lint=" . l:lint_flag] 46 | endif 47 | let l:warnings_flag = s:plugin.Flag('buildifier_warnings') 48 | if !empty(l:warnings_flag) 49 | let l:cmd += ["--warnings=" . l:warnings_flag] 50 | endif 51 | let l:fname = expand('%:p') 52 | if !empty(l:fname) 53 | let l:cmd += ['-path', l:fname] 54 | endif 55 | 56 | try 57 | " NOTE: Ignores any line ranges given and formats entire buffer. 58 | " buildifier does not support range formatting. 59 | call codefmt#formatterhelpers#Format(l:cmd) 60 | catch 61 | " Parse all the errors and stick them in the quickfix list. 62 | let l:errors = [] 63 | for line in split(v:exception, "\n") 64 | if empty(l:fname) 65 | let l:fname_pattern = 'stdin' 66 | else 67 | let l:fname_pattern = escape(l:fname, '\') 68 | endif 69 | let l:tokens = matchlist(line, 70 | \ '\C\v^\V'. l:fname_pattern . '\v:(\d+):(\d+):\s*(.*)') 71 | if !empty(l:tokens) 72 | call add(l:errors, { 73 | \ "filename": @%, 74 | \ "lnum": l:tokens[1], 75 | \ "col": l:tokens[2], 76 | \ "text": l:tokens[3]}) 77 | endif 78 | endfor 79 | 80 | if empty(l:errors) 81 | " Couldn't parse buildifier error format; display it all. 82 | call maktaba#error#Shout('Error formatting file: %s', v:exception) 83 | else 84 | call setqflist(l:errors, 'r') 85 | cc 1 86 | endif 87 | endtry 88 | endfunction 89 | 90 | return l:formatter 91 | endfunction 92 | -------------------------------------------------------------------------------- /autoload/codefmt/clangformat.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2017 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | function! s:ClangFormatHasAtLeastVersion(minimum_version) abort 20 | if !exists('s:clang_format_version') 21 | let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray( 22 | \ 'clang_format_executable') 23 | if codefmt#ShouldPerformIsAvailableChecks() && !executable(l:cmd[0]) 24 | return 0 25 | endif 26 | 27 | let l:syscall = maktaba#syscall#Create(l:cmd + ['--version']) 28 | " Call with throw_errors disabled because some versions of clang-format 29 | " misbehave and return exit code 1 along with the successful version 30 | " output (see https://github.com/google/vim-codefmt/issues/84). 31 | let l:version_output = l:syscall.Call(0).stdout 32 | let l:version_string = matchstr(l:version_output, '\v\d+(.\d+)+') 33 | " If no version string was matched, cached version will be an empty list. 34 | let s:clang_format_version = map(split(l:version_string, '\.'), 'v:val + 0') 35 | endif 36 | " Always fail check if version couldn't be fetched. 37 | if empty(s:clang_format_version) 38 | return 0 39 | endif 40 | " Compare each dotted version value in turn. 41 | let l:length = max([len(a:minimum_version), len(s:clang_format_version)]) 42 | for i in range(l:length) 43 | " Consider missing version places as zero (e.g. 7 = 7.0 = 7.0.0). 44 | let l:detected_value = get(s:clang_format_version, i, 0) 45 | let l:minimum_value = get(a:minimum_version, i, 0) 46 | " Any place value above or below than its minimum means entire version is 47 | " above or below the minimum. 48 | if l:detected_value > l:minimum_value 49 | return 1 50 | elseif l:detected_value < l:minimum_value 51 | return 0 52 | endif 53 | endfor 54 | " All version numbers were equal, so version was at least minimum. 55 | return 1 56 | endfunction 57 | 58 | 59 | " Inputs are 1-based (row, col) coordinates into lines. 60 | " Returns the corresponding zero-based offset into lines->join("\n") 61 | function! s:PositionToOffset(row, col, lines) abort 62 | let l:offset = a:col - 1 " 1-based to 0-based 63 | if a:row > 1 64 | for l:line in a:lines[0 : a:row - 2] " 1-based to 0-based, exclude current 65 | let l:offset += len(l:line) + 1 " +1 for newline 66 | endfor 67 | endif 68 | return l:offset 69 | endfunction 70 | 71 | 72 | " Input is zero-based offset into lines->join("\n") 73 | " Returns the 1-based [row, col] coordinates into lines. 74 | function! s:OffsetToPosition(offset, lines) abort 75 | let l:lines_consumed = 0 76 | let l:chars_left = a:offset 77 | for l:line in a:lines 78 | let l:line_len = len(l:line) + 1 " +1 for newline 79 | if l:chars_left < l:line_len 80 | break 81 | endif 82 | let l:chars_left -= l:line_len 83 | let l:lines_consumed += 1 84 | endfor 85 | return [l:lines_consumed + 1, l:chars_left + 1] " 0-based to 1-based 86 | endfunction 87 | 88 | 89 | "" 90 | " @private 91 | " Invalidates the cached clang-format version. 92 | function! codefmt#clangformat#InvalidateVersion() abort 93 | unlet! s:clang_format_version 94 | endfunction 95 | 96 | 97 | "" 98 | " @private 99 | " Formatter: clang-format 100 | function! codefmt#clangformat#GetFormatter() abort 101 | let l:formatter = { 102 | \ 'name': 'clang-format', 103 | \ 'setup_instructions': 'Install clang-format from ' . 104 | \ 'http://clang.llvm.org/docs/ClangFormat.html and ' . 105 | \ 'configure the clang_format_executable flag'} 106 | 107 | function l:formatter.IsAvailable() abort 108 | let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray( 109 | \ 'clang_format_executable') 110 | if !empty(l:cmd) && executable(l:cmd[0]) 111 | return 1 112 | else 113 | return 0 114 | endif 115 | endfunction 116 | 117 | function l:formatter.AppliesToBuffer() abort 118 | if codefmt#formatterhelpers#FiletypeMatches( 119 | \ &filetype, 120 | \ ['c', 'cpp', 'cuda', 'proto', 'javascript', 'objc', 'objcpp', 'typescript', 'arduino']) 121 | return 1 122 | endif 123 | " Version 3.6 adds support for java 124 | " http://llvm.org/releases/3.6.0/tools/clang/docs/ReleaseNotes.html 125 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'java') && s:ClangFormatHasAtLeastVersion([3, 6]) 126 | endfunction 127 | 128 | "" 129 | " Reformat buffer with clang-format, only targeting [ranges] if given. 130 | function l:formatter.FormatRanges(ranges) abort 131 | if line('$') == 1 && getline(1) == '' 132 | " If the buffer is completely empty, there's nothing to do 133 | return 134 | endif 135 | 136 | let l:Style_value = s:plugin.Flag('clang_format_style') 137 | if type(l:Style_value) is# type('') 138 | let l:style = l:Style_value 139 | elseif maktaba#value#IsCallable(l:Style_value) 140 | let l:style = maktaba#function#Call(l:Style_value) 141 | else 142 | throw maktaba#error#WrongType( 143 | \ 'clang_format_style flag must be string or callable. Found %s', 144 | \ string(l:Style_value)) 145 | endif 146 | if empty(a:ranges) 147 | return 148 | endif 149 | 150 | let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray( 151 | \ 'clang_format_executable') + ['-style', l:style] 152 | let l:fname = expand('%:p') 153 | if !empty(l:fname) 154 | let l:cmd += ['-assume-filename', l:fname] 155 | endif 156 | 157 | for [l:startline, l:endline] in a:ranges 158 | call maktaba#ensure#IsNumber(l:startline) 159 | call maktaba#ensure#IsNumber(l:endline) 160 | let l:cmd += ['-lines', l:startline . ':' . l:endline] 161 | endfor 162 | 163 | let l:lines = getline(1, line('$')) 164 | 165 | " Version 3.4 introduced support for cursor tracking 166 | " http://llvm.org/releases/3.4/tools/clang/docs/ClangFormat.html 167 | let l:supports_cursor = s:ClangFormatHasAtLeastVersion([3, 4]) 168 | if l:supports_cursor 169 | " Avoid line2byte: https://github.com/vim/vim/issues/5930 170 | let l:cursor_pos = s:PositionToOffset(line('.'), col('.'), l:lines) 171 | let l:cmd += ['-cursor', string(l:cursor_pos)] 172 | endif 173 | 174 | let l:input = join(l:lines, "\n") 175 | let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call() 176 | let l:formatted = split(l:result.stdout, "\n") 177 | 178 | if l:supports_cursor 179 | " With -cursor, the first line is a JSON object. 180 | let l:header = remove(l:formatted, 0) 181 | call maktaba#buffer#Overwrite(1, line('$'), l:formatted) 182 | try 183 | let l:header_json = maktaba#json#Parse(l:header) 184 | let l:offset = maktaba#ensure#IsNumber(l:header_json.Cursor) 185 | " Compute line/col, avoid goto: https://github.com/vim/vim/issues/5930 186 | let [l:new_line, l:new_col] = s:OffsetToPosition(l:offset, l:formatted) 187 | call cursor(l:new_line, l:new_col) 188 | catch 189 | call maktaba#error#Warn('Unable to parse clang-format cursor pos: %s', 190 | \ v:exception) 191 | endtry 192 | else 193 | call maktaba#buffer#Overwrite(1, line('$'), l:formatted) 194 | endif 195 | endfunction 196 | 197 | return l:formatter 198 | endfunction 199 | -------------------------------------------------------------------------------- /autoload/codefmt/cljstyle.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2019 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | "" 20 | " @private 21 | " Formatter: cljstyle 22 | function! codefmt#cljstyle#GetFormatter() abort 23 | let l:formatter = { 24 | \ 'name': 'cljstyle', 25 | \ 'setup_instructions': 26 | \ 'Install cljstyle (https://github.com/greglook/cljstyle) ' . 27 | \ 'and configure the cljstyle_executable flag'} 28 | 29 | function l:formatter.IsAvailable() abort 30 | return executable(s:plugin.Flag('cljstyle_executable')) 31 | endfunction 32 | 33 | function l:formatter.AppliesToBuffer() abort 34 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'clojure') 35 | endfunction 36 | 37 | "" 38 | " Reformat the current buffer with cljstyle. 39 | " 40 | " We implement Format(), and not FormatRange{,s}(), because cljstyle doesn't 41 | " provide a hook for formatting a range 42 | function l:formatter.Format() abort 43 | let l:cmd = [s:plugin.Flag('cljstyle_executable'), 'pipe'] 44 | 45 | call codefmt#formatterhelpers#Format(l:cmd) 46 | endfunction 47 | 48 | return l:formatter 49 | endfunction 50 | -------------------------------------------------------------------------------- /autoload/codefmt/dartfmt.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2017 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | "" 20 | " @private 21 | " Formatter: dartfmt 22 | function! codefmt#dartfmt#GetFormatter() abort 23 | let l:formatter = { 24 | \ 'name': 'dartfmt', 25 | \ 'setup_instructions': 'Install the Dart SDK from ' . 26 | \ 'https://dart.dev/get-dart'} 27 | 28 | function l:formatter.IsAvailable() abort 29 | let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray( 30 | \ 'dartfmt_executable') 31 | if !empty(l:cmd) && executable(l:cmd[0]) 32 | return 1 33 | else 34 | return 0 35 | endif 36 | endfunction 37 | 38 | function l:formatter.AppliesToBuffer() abort 39 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'dart') 40 | endfunction 41 | 42 | "" 43 | " Reformat the current buffer with dart format or the binary named in 44 | " @flag(dartfmt_executable}, only targetting the range from {startline} to 45 | " {endline} 46 | function l:formatter.FormatRange(startline, endline) abort 47 | let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray( 48 | \ 'dartfmt_executable') 49 | try 50 | " dart format does not support range formatting yet: 51 | " https://github.com/dart-lang/dart_style/issues/92 52 | call codefmt#formatterhelpers#AttemptFakeRangeFormatting( 53 | \ a:startline, a:endline, l:cmd) 54 | catch /ERROR(ShellError):/ 55 | " Parse all the errors and stick them in the quickfix list. 56 | let l:errors = [] 57 | for l:line in split(v:exception, "\n") 58 | let l:tokens = matchlist(l:line, 59 | \ '\C\v^line (\d+), column (\d+) of stdin: (.*)') 60 | if !empty(l:tokens) 61 | call add(l:errors, { 62 | \ 'filename': @%, 63 | \ 'lnum': l:tokens[1] + a:startline - 1, 64 | \ 'col': l:tokens[2], 65 | \ 'text': l:tokens[3]}) 66 | endif 67 | endfor 68 | 69 | if empty(l:errors) 70 | " Couldn't parse dartfmt error format; display it all. 71 | call maktaba#error#Shout( 72 | \ 'Failed to format range; showing all errors: %s', v:exception) 73 | else 74 | let l:errorHeaderLines = split(v:exception, "\n")[1 : 5] 75 | let l:errorHeader = join(l:errorHeaderLines, "\n") 76 | call maktaba#error#Shout( 77 | \ "Error formatting file:\n%s\n\nMore errors in the fixlist.", 78 | \ l:errorHeader) 79 | call setqflist(l:errors, 'r') 80 | cc 1 81 | endif 82 | endtry 83 | endfunction 84 | 85 | return l:formatter 86 | endfunction 87 | -------------------------------------------------------------------------------- /autoload/codefmt/fish_indent.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2020 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | function! codefmt#fish_indent#GetFormatter() abort 20 | let l:formatter = { 21 | \ 'name': 'fish_indent', 22 | \ 'setup_instructions': 'Install fish_indent (https://fishshell.com/docs/current/commands.html#fish_indent)' . 23 | \ ' and configure the fish_indent_executable flag'} 24 | 25 | function l:formatter.IsAvailable() abort 26 | return executable(s:plugin.Flag('fish_indent_executable')) 27 | endfunction 28 | 29 | function l:formatter.AppliesToBuffer() abort 30 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'fish') 31 | endfunction 32 | 33 | "" 34 | " Reformat the current buffer with fish_indent or the binary named in 35 | " @flag(fish_indent_executable), only targeting the range between {startline} 36 | " and {endline}. 37 | function l:formatter.FormatRange(startline, endline) abort 38 | let l:cmd = [ s:plugin.Flag('fish_indent_executable') ] 39 | call maktaba#ensure#IsNumber(a:startline) 40 | call maktaba#ensure#IsNumber(a:endline) 41 | " fish_indent does not support range formatting yet: 42 | " https://github.com/fish-shell/fish-shell/issues/6490 43 | call codefmt#formatterhelpers#AttemptFakeRangeFormatting( 44 | \ a:startline, a:endline, l:cmd) 45 | endfunction 46 | 47 | return l:formatter 48 | endfunction 49 | -------------------------------------------------------------------------------- /autoload/codefmt/formatterhelpers.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2020 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | " TODO(google/vim-maktaba#255): Use maktaba's when dropping support for 1.16.0. 20 | function! s:ValueAsList(Value_or_values) abort 21 | return maktaba#value#IsList(a:Value_or_values) ? 22 | \ a:Value_or_values : [a:Value_or_values] 23 | endfunction 24 | 25 | 26 | "" 27 | " @public 28 | " Checks if the given {filetype} matches {expected} filetype(s). 29 | " 30 | " When checking a dotted filetype name (like "c.doxygen"), returns true if any 31 | " piece matches expected filetype(s). 32 | " 33 | " Usage examples: > 34 | " if codefmt#formatterhelpers#FiletypeMatches(&filetype, 'c') 35 | " < > 36 | " if codefmt#formatterhelpers#FiletypeMatches(&filetype, ['c', 'cpp']) 37 | " < 38 | " @throws WrongType 39 | function! codefmt#formatterhelpers#FiletypeMatches(filetype, expected) abort 40 | call maktaba#ensure#TypeMatchesOneOf(a:expected, ['', ['']]) 41 | let l:expected = s:ValueAsList(a:expected) 42 | " TODO(google/vim-maktaba#256): Drop this check when redundant with above. 43 | for l:expected_ft in l:expected 44 | call maktaba#ensure#IsString(l:expected_ft) 45 | endfor 46 | " Check if filetypes match expected (splitting & looping to help support 47 | " dot-separated filetype names). 48 | for l:filetype in split(a:filetype, '\m\.', 0) 49 | if index(l:expected, l:filetype) >= 0 50 | return 1 51 | endif 52 | endfor 53 | return 0 54 | endfunction 55 | 56 | 57 | "" 58 | " @public 59 | " Format lines in the current buffer via a formatter invoked by {cmd}, which 60 | " is a system call represented by either a |maktaba.Syscall| or any argument 61 | " accepted by |maktaba#syscall#Create()|. The command must include any 62 | " arguments for the explicit range line numbers to use, if any. 63 | " 64 | " @throws ShellError if the {cmd} system call fails 65 | function! codefmt#formatterhelpers#Format(cmd) abort 66 | let l:lines = getline(1, line('$')) 67 | let l:input = join(l:lines, "\n") 68 | 69 | let l:result = maktaba#syscall#Create(a:cmd).WithStdin(l:input).Call() 70 | let l:formatted = split(l:result.stdout, "\n") 71 | 72 | call maktaba#buffer#Overwrite(1, line('$'), l:formatted) 73 | endfunction 74 | 75 | 76 | "" 77 | " @public 78 | " Attempt to format a range of lines from {startline} to {endline} in the 79 | " current buffer via a formatter that doesn't natively support range 80 | " formatting, which is invoked via {cmd} (a system call represented by either 81 | " a |maktaba.Syscall| or any argument accepted by |maktaba#syscall#Create()|). 82 | " It uses a hacky strategy of sending those lines to the formatter in 83 | " isolation, which gives bad results if the code on those lines isn't 84 | " a self-contained block of syntax or is part of a larger indent. 85 | " 86 | " If invoking this hack, please make sure to file a feature request against 87 | " the tool for range formatting and post a URL for that feature request above 88 | " code that calls it. 89 | " 90 | " If [ignoreerrors] is nonzero, the syscall ignores errors. This can be helpful 91 | " for formatters that return nonzero results for reasons unrelated to 92 | " formatting. 93 | " 94 | " If [skipfirstnlines] is set to a nonzero number N, the first 95 | " N lines of the formatter output are trimmed. This can be used to trim 96 | " always-present headers. 97 | " 98 | " @default ignoreerrors=0 99 | " @default skipfirstnlines=0 100 | " @throws ShellError if the {cmd} system call fails (and [ignoreerrors] is 0) 101 | " @throws WrongType 102 | function! codefmt#formatterhelpers#AttemptFakeRangeFormatting( 103 | \ startline, endline, cmd, ...) abort 104 | call maktaba#ensure#IsNumber(a:startline) 105 | call maktaba#ensure#IsNumber(a:endline) 106 | 107 | let l:ignoreerrors = a:0 >= 1 ? a:1 : 0 108 | let l:skipfirstnlines = a:0 >= 2 ? a:2 : 0 109 | 110 | call maktaba#ensure#IsNumber(l:ignoreerrors) 111 | call maktaba#ensure#IsNumber(l:skipfirstnlines) 112 | 113 | let l:lines = getline(1, line('$')) 114 | let l:input = join(l:lines[a:startline - 1 : a:endline - 1], "\n") 115 | 116 | let l:result = 117 | \ maktaba#syscall#Create(a:cmd).WithStdin(l:input).Call(!l:ignoreerrors) 118 | let l:formatted = split(l:result.stdout, "\n") 119 | " Special case empty slice: neither l:lines[:0] nor l:lines[:-1] is right. 120 | let l:before = a:startline > 1 ? l:lines[ : a:startline - 2] : [] 121 | let l:full_formatted = l:before + l:formatted[l:skipfirstnlines :] 122 | \ + l:lines[a:endline :] 123 | 124 | call maktaba#buffer#Overwrite(1, line('$'), l:full_formatted) 125 | endfunction 126 | 127 | 128 | "" 129 | " @public 130 | " Resolve a flag (function, string or array) to a normalized array, with special 131 | " handling to convert a spaceless string to a single-element array. This is the 132 | " common case for executables, and more importantly, is backward-compatible for 133 | " existing user settings. 134 | " 135 | " @throws WrongType if the flag doesn't resolve to a string or array 136 | function! codefmt#formatterhelpers#ResolveFlagToArray(flag_name) abort 137 | let l:FlagFn = s:plugin.Flag(a:flag_name) 138 | if maktaba#value#IsFuncref(l:FlagFn) 139 | let l:value = maktaba#function#Call(l:FlagFn) 140 | else 141 | let l:value = l:FlagFn 142 | endif 143 | 144 | " After (conditionally) calling the function, the resulting value should be 145 | " either a list that we can use directly, or a string that we can treat as 146 | " a single-element list, mainly for backward compatibility. 147 | if maktaba#value#IsString(l:value) 148 | if l:value =~ '\s' 149 | " Uh oh, there are spaces in the string. Rather than guessing user intent 150 | " with shell quoting and word splitting, handle this (hopefully unusual) 151 | " case by telling them to update their configuration. 152 | throw maktaba#error#WrongType( 153 | \ '%s flag is a string with spaces, please make it a list. ' . 154 | \ 'Resolved value was: %s', 155 | \ a:flag_name, l:value) 156 | endif 157 | " Convert spaceless string to single-element list. 158 | return [l:value] 159 | elseif maktaba#value#IsList(l:value) 160 | return l:value 161 | endif 162 | 163 | throw maktaba#error#WrongType( 164 | \ '%s flag should be a list after calling. Found %s', 165 | \ a:flag_name, maktaba#value#TypeName(l:value)) 166 | endfunction 167 | -------------------------------------------------------------------------------- /autoload/codefmt/gn.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2017 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | "" 20 | " @private 21 | " Formatter for gn, a chromium build tool. 22 | " Formatter: gn 23 | function! codefmt#gn#GetFormatter() abort 24 | let l:url = 'https://www.chromium.org/developers/how-tos/install-depot-tools' 25 | let l:formatter = { 26 | \ 'name': 'gn', 27 | \ 'setup_instructions': 'install Chromium depot_tools (' . l:url . ')'} 28 | 29 | function l:formatter.IsAvailable() abort 30 | return executable(s:plugin.Flag('gn_executable')) 31 | endfunction 32 | 33 | function l:formatter.AppliesToBuffer() abort 34 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'gn') 35 | endfunction 36 | 37 | "" 38 | " Run `gn format` to format the whole file. 39 | " 40 | " We implement Format(), and not FormatRange{,s}(), because gn doesn't 41 | " provide a hook for formatting a range, and all gn files are supposed 42 | " to be fully formatted anyway. 43 | function l:formatter.Format() abort 44 | let l:executable = s:plugin.Flag('gn_executable') 45 | let l:cmd = [ l:executable, 'format', '--stdin' ] 46 | let l:input = join(getline(1, line('$')), "\n") 47 | 48 | " gn itself prints errors to stdout, but if the error comes from the 49 | " gn.py wrapper script, it is printed to stderr. Use stdout as the 50 | " error message if stderr is empty. 51 | let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call(0) 52 | if !empty(l:result.stdout) 53 | let l:output = l:result.stdout 54 | else 55 | let l:output = l:result.stderr 56 | endif 57 | 58 | " Other formatters generally catch failure as an exception, but 59 | " v:exception contains stderr in that case, and gn prints errors to 60 | " stdout, so we need to check for a shell error ourselves. 61 | if !v:shell_error 62 | let l:formatted = split(l:output, "\n") 63 | call maktaba#buffer#Overwrite(1, line('$'), l:formatted) 64 | else 65 | let l:errors = [] 66 | for line in split(l:output, "\n") 67 | let l:tokens = matchlist(line, '\C\v^ERROR at :(\d+):(\d+):\s*(.*)') 68 | if !empty(l:tokens) 69 | call add(l:errors, { 70 | \ "filename": @%, 71 | \ "lnum": l:tokens[1], 72 | \ "col": l:tokens[2], 73 | \ "text": l:tokens[3]}) 74 | endif 75 | endfor 76 | 77 | if empty(l:errors) 78 | " Couldn't parse errors; display the whole error message. 79 | call maktaba#error#Shout('Error formatting file: %s', l:output) 80 | else 81 | call setqflist(l:errors, 'r') 82 | cc 1 83 | endif 84 | endif 85 | endfunction 86 | 87 | return l:formatter 88 | endfunction 89 | -------------------------------------------------------------------------------- /autoload/codefmt/gofmt.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2017 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | "" 20 | " @private 21 | " Formatter: gofmt 22 | function! codefmt#gofmt#GetFormatter() abort 23 | let l:formatter = { 24 | \ 'name': 'gofmt', 25 | \ 'setup_instructions': 'Install gofmt or goimports and ' . 26 | \ 'configure the gofmt_executable flag'} 27 | 28 | function l:formatter.IsAvailable() abort 29 | return executable(s:plugin.Flag('gofmt_executable')) 30 | endfunction 31 | 32 | function l:formatter.AppliesToBuffer() abort 33 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'go') 34 | endfunction 35 | 36 | "" 37 | " Reformat the current buffer with gofmt or the binary named in 38 | " @flag(gofmt_executable), only targeting the range between {startline} and 39 | " {endline}. 40 | function l:formatter.FormatRange(startline, endline) abort 41 | let l:cmd = [ s:plugin.Flag('gofmt_executable') ] 42 | try 43 | " gofmt does not support range formatting. 44 | " TODO: File a feature request with gofmt and link it here. 45 | call codefmt#formatterhelpers#AttemptFakeRangeFormatting( 46 | \ a:startline, a:endline, l:cmd) 47 | catch /ERROR(ShellError):/ 48 | " Parse all the errors and stick them in the quickfix list. 49 | let l:errors = [] 50 | for l:line in split(v:exception, "\n") 51 | let l:tokens = matchlist(l:line, 52 | \ '\C\v^\:(\d+):(\d+):\s*(.*)') 53 | if !empty(l:tokens) 54 | call add(l:errors, { 55 | \ 'filename': @%, 56 | \ 'lnum': l:tokens[1] + a:startline - 1, 57 | \ 'col': l:tokens[2], 58 | \ 'text': l:tokens[3]}) 59 | endif 60 | endfor 61 | 62 | if empty(l:errors) 63 | " Couldn't parse gofmt error format; display it all. 64 | call maktaba#error#Shout('Error formatting file: %s', v:exception) 65 | else 66 | call setqflist(l:errors, 'r') 67 | cc 1 68 | endif 69 | endtry 70 | endfunction 71 | 72 | return l:formatter 73 | endfunction 74 | -------------------------------------------------------------------------------- /autoload/codefmt/googlejava.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2017 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | "" 19 | " @private 20 | " Formatter: google-java-format 21 | function! codefmt#googlejava#GetFormatter() abort 22 | let l:formatter = { 23 | \ 'name': 'google-java-format', 24 | \ 'setup_instructions': 'Install google-java formatter ' . 25 | \ "(https://github.com/google/google-java-format). \n" . 26 | \ 'Enable with "Glaive codefmt google_java_executable=' . 27 | \ '"java -jar /path/to/google-java-format-VERSION-all-deps.jar" ' . 28 | \ 'in your vimrc' } 29 | 30 | function l:formatter.IsAvailable() abort 31 | let l:exec = s:plugin.Flag('google_java_executable') 32 | if executable(l:exec) 33 | return 1 34 | elseif !empty(l:exec) && l:exec isnot# 'google-java-format' 35 | " The user has specified a custom formatter command. Hope it works. 36 | " /shrug. 37 | return 1 38 | else 39 | return 0 40 | endif 41 | endfunction 42 | 43 | function l:formatter.AppliesToBuffer() abort 44 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'java') 45 | endfunction 46 | 47 | "" 48 | " Reformat the current buffer using java-format, only targeting {ranges}. 49 | function l:formatter.FormatRanges(ranges) abort 50 | if empty(a:ranges) 51 | return 52 | endif 53 | " Split the command on spaces, except when there's a proceeding \ 54 | let l:cmd = split(s:plugin.Flag('google_java_executable'), '\\\@ x[0] . ':' . x[1]}) 72 | call codefmt#formatterhelpers#Format(l:cmd) 73 | endfunction 74 | 75 | return l:formatter 76 | endfunction 77 | -------------------------------------------------------------------------------- /autoload/codefmt/ktfmt.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2017 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | let s:cmdAvailable = {} 19 | 20 | "" 21 | " @private 22 | " Formatter: ktfmt 23 | function! codefmt#ktfmt#GetFormatter() abort 24 | let l:formatter = { 25 | \ 'name': 'ktfmt', 26 | \ 'setup_instructions': 'Install ktfmt ' . 27 | \ '(https://github.com/facebookincubator/ktfmt). ' . 28 | \ "Enable with\nGlaive codefmt ktfmt_executable=" . 29 | \ 'java,-jar,/path/to/ktfmt--jar-with-dependencies.jar ' . 30 | \ "\nin your .vimrc or create a shell script named 'ktfmt'" } 31 | 32 | function l:formatter.IsAvailable() abort 33 | let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray('ktfmt_executable') 34 | if empty(l:cmd) 35 | return 0 36 | endif 37 | let l:joined = join(l:cmd, ' ') 38 | if has_key(s:cmdAvailable, l:joined) 39 | return s:cmdAvailable[l:joined] 40 | endif 41 | if executable(l:cmd[0]) 42 | if l:cmd[0] is# 'java' || l:cmd[0] =~# '/java$' 43 | " Even if java is executable, jar path might be wrong, so run a simple 44 | " command. There's no --version flag, so format an empty file. 45 | let l:success = 0 46 | try 47 | let l:result = maktaba#syscall#Create(l:cmd + ['-']).Call() 48 | let l:success = v:shell_error == 0 49 | catch /ERROR(ShellError)/ 50 | call maktaba#error#Warn( 51 | \ 'ktfmt unavailable, check jar file in `%s -`: %s', 52 | \ l:joined, 53 | \ v:exception) 54 | endtry 55 | let s:cmdAvailable[l:joined] = l:success 56 | else 57 | " command is executable and doesn't look like 'java' so assume yes 58 | let s:cmdAvailable[l:joined] = 1 59 | endif 60 | return s:cmdAvailable[l:joined] 61 | else 62 | if l:cmd[0] =~# ',' 63 | call maktaba#error#Warn( 64 | \ 'ktfmt_executable is a string "%s" but looks like a list. ' 65 | \ . 'Try not quoting the comma-separated value', 66 | \ l:cmd[0]) 67 | endif 68 | " don't cache unavailability, in case user installs the command 69 | return 0 70 | endif 71 | endfunction 72 | 73 | function l:formatter.AppliesToBuffer() abort 74 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'kotlin') 75 | endfunction 76 | 77 | "" 78 | " Reformat the current buffer using ktfmt, only targeting {ranges}. 79 | function l:formatter.FormatRange(startline, endline) abort 80 | " ktfmt requires '-' as a filename arg to read stdin 81 | let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray('ktfmt_executable') 82 | \ + ['-'] 83 | try 84 | " TODO(tstone) Switch to using --lines once that arg is added, see 85 | " https://github.com/facebookincubator/ktfmt/issues/218 86 | call codefmt#formatterhelpers#AttemptFakeRangeFormatting( 87 | \ a:startline, a:endline, l:cmd) 88 | catch /ERROR(ShellError):/ 89 | " Parse all the errors and stick them in the quickfix list. 90 | let l:errors = [] 91 | for l:line in split(v:exception, "\n") 92 | let l:tokens = matchlist(l:line, '\C\v^:(\d+):(\d+):\s*(.*)') 93 | if !empty(l:tokens) 94 | call add(l:errors, { 95 | \ 'filename': @%, 96 | \ 'lnum': l:tokens[1] + a:startline - 1, 97 | \ 'col': l:tokens[2], 98 | \ 'text': l:tokens[3]}) 99 | endif 100 | endfor 101 | if empty(l:errors) 102 | " Couldn't parse ktfmt error format; display it all. 103 | call maktaba#error#Shout('Error formatting range: %s', v:exception) 104 | else 105 | call setqflist(l:errors, 'r') 106 | cc 1 107 | endif 108 | endtry 109 | endfunction 110 | 111 | return l:formatter 112 | endfunction 113 | 114 | 115 | -------------------------------------------------------------------------------- /autoload/codefmt/luaformatterfiveone.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2017 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | "" 20 | " @private 21 | " 22 | " Formatter provider for lua files using luaformatterfiveone. 23 | function! codefmt#luaformatterfiveone#GetFormatter() abort 24 | let l:formatter = { 25 | \ 'name': 'luaformatterfiveone', 26 | \ 'setup_instructions': 'Install luaformatterfiveone with luarocks. ' . 27 | \ '(https://luarocks.org/modules/ElPiloto/formatterfiveone).'} 28 | 29 | function l:formatter.IsAvailable() abort 30 | return executable(s:plugin.Flag('luaformatterfiveone_executable')) 31 | endfunction 32 | 33 | function l:formatter.AppliesToBuffer() abort 34 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'lua') 35 | endfunction 36 | 37 | "" 38 | " Reformat the current buffer with luaformatterfiveone or the binary named in 39 | " @flag(luaformatterfiveone_executable) 40 | " @throws ShellError 41 | function l:formatter.Format() abort 42 | let l:cmd = [ s:plugin.Flag('luaformatterfiveone_executable')] 43 | " Specify we are sending input through stdin 44 | let l:cmd += ['-i'] 45 | 46 | try 47 | call codefmt#formatterhelpers#Format(l:cmd) 48 | catch 49 | " Parse all the errors and stick them in the quickfix list. 50 | let l:errors = [] 51 | for line in split(v:exception, "\n") 52 | let l:fname_pattern = 'stdin' 53 | let l:tokens = matchlist(line, 54 | \ '\C\v^\[string "isCodeValid"\]:(\d+): (.*)') 55 | if !empty(l:tokens) 56 | call add(l:errors, { 57 | \ "filename": @%, 58 | \ "lnum": l:tokens[1], 59 | \ "text": l:tokens[2]}) 60 | endif 61 | endfor 62 | 63 | if empty(l:errors) 64 | " Couldn't parse buildifier error format; display it all. 65 | call maktaba#error#Shout('Error formatting file: %s', v:exception) 66 | else 67 | call setqflist(l:errors, 'r') 68 | cc 1 69 | endif 70 | endtry 71 | endfunction 72 | 73 | return l:formatter 74 | endfunction 75 | -------------------------------------------------------------------------------- /autoload/codefmt/mixformat.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2022 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | let s:plugin = maktaba#plugin#Get('codefmt') 16 | let s:cmdAvailable = {} 17 | 18 | "" 19 | " @private 20 | " Formatter: mixformat 21 | function! codefmt#mixformat#GetFormatter() abort 22 | let l:formatter = { 23 | \ 'name': 'mixformat', 24 | \ 'setup_instructions': 'mix is usually installed with Elixir ' . 25 | \ '(https://elixir-lang.org/install.html). ' . 26 | \ "If mix is not in your path, configure it in .vimrc:\n" . 27 | \ 'Glaive codefmt mix_executable=/path/to/mix' } 28 | 29 | function l:formatter.IsAvailable() abort 30 | let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray('mix_executable') 31 | if codefmt#ShouldPerformIsAvailableChecks() && !executable(l:cmd[0]) 32 | return 0 33 | endif 34 | return 1 35 | endfunction 36 | 37 | function l:formatter.AppliesToBuffer() abort 38 | return codefmt#formatterhelpers#FiletypeMatches( 39 | \ &filetype, ['elixir', 'eelixir', 'heex']) 40 | endfunction 41 | 42 | "" 43 | " Reformat the current buffer using mix format, only targeting {ranges}. 44 | function l:formatter.FormatRange(startline, endline) abort 45 | let l:filename = expand('%:p') 46 | if empty(l:filename) 47 | let l:dir = getcwd() 48 | " Default filename per https://hexdocs.pm/mix/Mix.Tasks.Format.html 49 | let l:filename = 'stdin.exs' 50 | else 51 | let l:dir = s:findMixDir(l:filename) 52 | endif 53 | " mix format docs: https://hexdocs.pm/mix/main/Mix.Tasks.Format.html 54 | let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray('mix_executable') 55 | " Specify stdin as the file 56 | let l:cmd = l:cmd + ['format', '--stdin-filename=' . l:filename, '-'] 57 | let l:syscall = maktaba#syscall#Create(l:cmd).WithCwd(l:dir) 58 | try 59 | " mix format doesn't have a line-range option, but does a reasonable job 60 | " (except for leading indent) when given a full valid expression 61 | call codefmt#formatterhelpers#AttemptFakeRangeFormatting( 62 | \ a:startline, a:endline, l:syscall) 63 | catch /ERROR(ShellError):/ 64 | " Parse all the errors and stick them in the quickfix list. 65 | let l:errors = [] 66 | for l:line in split(v:exception, "\n") 67 | " Example output: 68 | " ** (SyntaxError) foo.exs:57:28: unexpected reserved word: end 69 | " (blank line) 70 | " HINT: it looks like the "end" on line 56 does not have a matching "do" defined before it 71 | " (blank line), (stack trace with 4-space indent) 72 | " TODO gather additional details between error message and stack trace 73 | let l:tokens = matchlist(l:line, 74 | \ printf('\v^\*\* (\(\k+\)) [^:]+:(\d+):(\d+):\s*(.*)')) 75 | if !empty(l:tokens) 76 | call add(l:errors, { 77 | \ 'filename': @%, 78 | \ 'lnum': l:tokens[2] + a:startline - 1, 79 | \ 'col': l:tokens[3], 80 | \ 'text': printf('%s %s', l:tokens[1], l:tokens[4])}) 81 | endif 82 | endfor 83 | if empty(l:errors) 84 | " Couldn't parse mix error format; display it all. 85 | call maktaba#error#Shout('Error formatting range: %s', v:exception) 86 | else 87 | call setqflist(l:errors, 'r') 88 | cc 1 89 | endif 90 | endtry 91 | endfunction 92 | 93 | return l:formatter 94 | endfunction 95 | 96 | " Finds the directory to run mix from. Looks for a mix.exs file first; if that 97 | " is not found looks for a .formatter.exs file, falling back to the parent of 98 | " filepath. 99 | function! s:findMixDir(filepath) abort 100 | let l:path = empty(a:filepath) ? getcwd() : fnamemodify(a:filepath, ':h') 101 | let l:root = findfile('mix.exs', l:path . ';') 102 | if empty(l:root) 103 | let l:root = findfile('.formatter.exs', l:path . ';') 104 | endif 105 | if empty(l:root) 106 | let l:root = l:path 107 | else 108 | let l:root = fnamemodify(l:root, ':h') 109 | endif 110 | return l:root 111 | endfunction 112 | -------------------------------------------------------------------------------- /autoload/codefmt/nixpkgs_fmt.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2017 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | "" 20 | " @private 21 | " 22 | " Formatter provider for .nix files using nixpkgs-fmt. 23 | function! codefmt#nixpkgs_fmt#GetFormatter() abort 24 | let l:formatter = { 25 | \ 'name': 'nixpkgs-fmt', 26 | \ 'setup_instructions': 'Install nixpkgs-fmt. ' . 27 | \ '(https://github.com/nix-community/nixpkgs-fmt).'} 28 | 29 | function l:formatter.IsAvailable() abort 30 | return executable(s:plugin.Flag('nixpkgs_fmt_executable')) 31 | endfunction 32 | 33 | function l:formatter.AppliesToBuffer() abort 34 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'nix') 35 | endfunction 36 | 37 | "" 38 | " Reformat the current buffer with nixpkgs-fmt or the binary named in 39 | " @flag(nixpkgs_fmt_executable) 40 | " @throws ShellError 41 | function l:formatter.Format() abort 42 | let l:cmd = [ s:plugin.Flag('nixpkgs_fmt_executable') ] 43 | 44 | " nixpkgs-fmt does not support range formatting. 45 | call codefmt#formatterhelpers#Format(l:cmd) 46 | endfunction 47 | 48 | return l:formatter 49 | endfunction 50 | -------------------------------------------------------------------------------- /autoload/codefmt/ocamlformat.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2021 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | "" 20 | " @private 21 | " Formatter: ocamlformat 22 | function! codefmt#ocamlformat#GetFormatter() abort 23 | let l:formatter = { 24 | \ 'name': 'ocamlformat', 25 | \ 'setup_instructions': 'Install ocamlformat ' . 26 | \ '(https://github.com/ocaml-ppx/ocamlformat#installation).'} 27 | 28 | function l:formatter.IsAvailable() abort 29 | return executable(s:plugin.Flag('ocamlformat_executable')) 30 | endfunction 31 | 32 | function l:formatter.AppliesToBuffer() abort 33 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'ocaml') 34 | endfunction 35 | 36 | "" 37 | " Reformat the current buffer with ocamlformat or the binary named in 38 | " @flag(ocamlformat_executable) 39 | " @throws ShellError 40 | " 41 | " We implement Format(), and not FormatRange{,s}(), because black doesn't 42 | " provide a hook for formatting a range 43 | function l:formatter.Format() abort 44 | let l:executable = s:plugin.Flag('ocamlformat_executable') 45 | 46 | " ocamlformat requires --name, --impl, or --intf when reading from 47 | " stdin. 48 | let l:inputflags = ['--name', @%] 49 | if len(@%) == 0 50 | " Assume we're formatting an implementation file. 51 | let l:inputflags = ['--impl'] 52 | endif 53 | " TODO(dimitrije): Catch and handle formatting errors more nicely. See how 54 | " it's dome in gofmt.vim. 55 | " For now, an ugly ShellError will be thrown if anything fails here. 56 | call codefmt#formatterhelpers#Format( 57 | \ [l:executable] 58 | \ + l:inputflags 59 | \ + ['-']) 60 | endfunction 61 | 62 | return l:formatter 63 | endfunction 64 | -------------------------------------------------------------------------------- /autoload/codefmt/ormolu.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2021 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | "" 20 | " @private 21 | " Formatter: ormolu 22 | function! codefmt#ormolu#GetFormatter() abort 23 | let l:formatter = { 24 | \ 'name': 'ormolu', 25 | \ 'setup_instructions': 'Install ormolu ' . 26 | \ '(https://hackage.haskell.org/package/ormolu).'} 27 | 28 | function l:formatter.IsAvailable() abort 29 | return executable(s:plugin.Flag('ormolu_executable')) 30 | endfunction 31 | 32 | function l:formatter.AppliesToBuffer() abort 33 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'haskell') 34 | endfunction 35 | 36 | "" 37 | " Reformat the current buffer with ormolu or the binary named in 38 | " @flag(ormolu_executable), only targeting the range between {startline} and 39 | " {endline}. 40 | " @throws ShellError 41 | function l:formatter.FormatRange(startline, endline) abort 42 | let l:cmd = [s:plugin.Flag('ormolu_executable')] 43 | 44 | let l:lines = getline(1, line('$')) 45 | let l:input = join(l:lines, "\n") 46 | 47 | call maktaba#ensure#IsNumber(a:startline) 48 | call maktaba#ensure#IsNumber(a:endline) 49 | 50 | if a:startline > 1 51 | call extend(l:cmd, ['--start-line', string(a:startline)]) 52 | endif 53 | call extend(l:cmd, ['--end-line', string(a:endline)]) 54 | 55 | try 56 | let l:syscall = maktaba#syscall#Create(l:cmd).WithStdin(l:input) 57 | let l:result = l:syscall.Call() 58 | let l:formatted = split(l:result.stdout, "\n") 59 | call maktaba#buffer#Overwrite(1, line('$'), l:formatted) 60 | catch /ERROR(ShellError):/ 61 | call maktaba#error#Shout('Error formatting file: %s', v:exception) 62 | endtry 63 | endfunction 64 | 65 | return l:formatter 66 | endfunction 67 | -------------------------------------------------------------------------------- /autoload/codefmt/prettier.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2018 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | " See https://prettier.io for a list of supported file types. 19 | if !exists('s:SUPPORTED_FILETYPES') 20 | let s:SUPPORTED_FILETYPES = ['javascript', 'markdown', 'html', 'css', 'yaml', 21 | \ 'jsx', 'less', 'scss', 'mdx', 'vue'] 22 | lockvar! s:SUPPORTED_FILETYPES 23 | endif 24 | 25 | 26 | "" 27 | " @private 28 | " Invalidates the cached prettier availability detection. 29 | function! codefmt#prettier#InvalidateIsAvailable() abort 30 | unlet! s:prettier_is_available 31 | endfunction 32 | 33 | 34 | "" 35 | " @private 36 | " Formatter: prettier 37 | function! codefmt#prettier#GetFormatter() abort 38 | let l:formatter = { 39 | \ 'name': 'prettier', 40 | \ 'setup_instructions': 'Install prettier (https://prettier.io/) ' . 41 | \ 'and configure the prettier_executable flag'} 42 | 43 | function l:formatter.IsAvailable() abort 44 | if !exists('s:prettier_is_available') 45 | let s:prettier_is_available = 0 46 | let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray( 47 | \ 'prettier_executable') 48 | if !empty(l:cmd) && executable(l:cmd[0]) 49 | " Unfortunately the availability of npx isn't enough to tell whether 50 | " prettier is available, and npx doesn't have a way of telling us. 51 | " Fetching the prettier version should suffice. 52 | let l:result = maktaba#syscall#Create(l:cmd + ['--version']).Call(0) 53 | if v:shell_error == 0 54 | let s:prettier_is_available = 1 55 | endif 56 | endif 57 | endif 58 | return s:prettier_is_available 59 | endfunction 60 | 61 | function l:formatter.AppliesToBuffer() abort 62 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, s:SUPPORTED_FILETYPES) 63 | endfunction 64 | 65 | "" 66 | " Reformat the current buffer with prettier or the binary named in 67 | " @flag(prettier_executable), only targeting the range between {startline} and 68 | " {endline}. 69 | function l:formatter.FormatRange(startline, endline) abort 70 | let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray( 71 | \ 'prettier_executable') + ['--no-color'] 72 | 73 | " prettier is able to automatically choose the best parser if the filepath 74 | " is provided. Otherwise, fall back to the previous default: babel. 75 | if @% == "" 76 | call extend(l:cmd, ['--parser', 'babel']) 77 | else 78 | call extend(l:cmd, ['--stdin-filepath', expand('%:p')]) 79 | endif 80 | 81 | call maktaba#ensure#IsNumber(a:startline) 82 | call maktaba#ensure#IsNumber(a:endline) 83 | 84 | let l:lines = getline(1, line('$')) 85 | let l:input = join(l:lines, "\n") 86 | if a:startline > 1 87 | let l:lines_start = join(l:lines[0 : a:startline - 1], "\n") 88 | call extend(l:cmd, ['--range-start', string(strchars(l:lines_start))]) 89 | endif 90 | let l:lines_end = join(l:lines[0 : a:endline - 1], "\n") 91 | call extend(l:cmd, ['--range-end', string(strchars(l:lines_end))]) 92 | 93 | call extend(l:cmd, codefmt#formatterhelpers#ResolveFlagToArray( 94 | \ 'prettier_options')) 95 | 96 | try 97 | let l:syscall = maktaba#syscall#Create(l:cmd).WithStdin(l:input) 98 | if isdirectory(expand('%:p:h')) 99 | " Change to the containing directory so that npx will find 100 | " a project-local prettier in node_modules 101 | let l:syscall = l:syscall.WithCwd(expand('%:p:h')) 102 | endif 103 | let l:result = l:syscall.Call() 104 | let l:formatted = split(l:result.stdout, "\n") 105 | call maktaba#buffer#Overwrite(1, line('$'), l:formatted) 106 | catch /ERROR(ShellError):/ 107 | " Parse all the errors and stick them in the quickfix list. 108 | let l:errors = [] 109 | for l:line in split(v:exception, "\n") 110 | let l:tokens = matchlist(l:line, 111 | \ '\C\v^\[error\] stdin: (.*) \((\d+):(\d+)\).*') 112 | if !empty(l:tokens) 113 | call add(l:errors, { 114 | \ 'filename': @%, 115 | \ 'lnum': l:tokens[2], 116 | \ 'col': l:tokens[3], 117 | \ 'text': l:tokens[1]}) 118 | endif 119 | endfor 120 | 121 | if empty(l:errors) 122 | " Couldn't parse prettier error format; display it all. 123 | call maktaba#error#Shout('Error formatting file: %s', v:exception) 124 | else 125 | call setqflist(l:errors, 'r') 126 | cc 1 127 | endif 128 | endtry 129 | endfunction 130 | 131 | return l:formatter 132 | endfunction 133 | -------------------------------------------------------------------------------- /autoload/codefmt/rubocop.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2023 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | let s:plugin = maktaba#plugin#Get('codefmt') 16 | 17 | 18 | "" 19 | " @private 20 | " Formatter: rubocop 21 | function! codefmt#rubocop#GetFormatter() abort 22 | let l:formatter = { 23 | \ 'name': 'rubocop', 24 | \ 'setup_instructions': 'Install rubocop ' . 25 | \ '(https://rubygems.org/gems/rubocop).'} 26 | 27 | function l:formatter.IsAvailable() abort 28 | return executable(s:plugin.Flag('rubocop_executable')) 29 | endfunction 30 | 31 | function l:formatter.AppliesToBuffer() abort 32 | return &filetype is# 'eruby' || &filetype is# 'ruby' 33 | endfunction 34 | 35 | "" 36 | " Reformat the current buffer with rubocop or the binary named in 37 | " @flag(rubocop_executable), only targeting the range between {startline} and 38 | " {endline}. 39 | " 40 | " @throws ShellError 41 | function l:formatter.FormatRange(startline, endline) abort 42 | " See flag explanations at: 43 | " https://docs.rubocop.org/rubocop/1.51/usage/basic_usage.html 44 | let l:cmd = [s:plugin.Flag('rubocop_executable'), '--stdin', @%, '-a', '--no-color', '-fq', '-o', '/dev/null'] 45 | 46 | " Rubocop exits with an error condition if there are lint errors, even 47 | " after successfully formatting. This is annoying for our purpuoses, 48 | " because we have no way to distinguish lint errors from a 'real' falure. 49 | " Use Call(0) to suppress maktaba's error handling. 50 | let l:ignoreerrors = 1 51 | " Rubocop is primarily a linter, and by default it outputs lint errors 52 | " first, followed by a dividing line, and then the formatted result. 53 | " '-o /dev/null' in the command line suppresses any lint errors, but the 54 | " divider is always printed. 55 | let l:skipfirstnlines = 1 56 | 57 | " Rubocop does not support range formatting; see bug: 58 | " https://github.com/Shopify/ruby-lsp/issues/203 59 | call codefmt#formatterhelpers#AttemptFakeRangeFormatting( 60 | \ a:startline, a:endline, l:cmd, l:ignoreerrors, l:skipfirstnlines) 61 | endfunction 62 | 63 | return l:formatter 64 | endfunction 65 | -------------------------------------------------------------------------------- /autoload/codefmt/ruff.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2017 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | function! s:FormatWithArgs(args) abort 20 | let l:executable = s:plugin.Flag('ruff_executable') 21 | let l:lines = getline(1, line('$')) 22 | let l:cmd = [l:executable, 'format'] + a:args + ['-'] 23 | if !empty(@%) 24 | let l:cmd += ['--stdin-filename=' . @%] 25 | endif 26 | let l:input = join(l:lines, "\n") 27 | let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call(0) 28 | if v:shell_error 29 | call maktaba#error#Shout('Error formatting file: %s', l:result.stderr) 30 | return 31 | endif 32 | let l:formatted = split(l:result.stdout, "\n") 33 | 34 | call maktaba#buffer#Overwrite(1, line('$'), l:formatted) 35 | endfunction 36 | 37 | 38 | "" 39 | " @private 40 | " Formatter: ruff 41 | function! codefmt#ruff#GetFormatter() abort 42 | let l:formatter = { 43 | \ 'name': 'ruff', 44 | \ 'setup_instructions': 'Install ruff ' . 45 | \ '(https://docs.astral.sh/ruff/).'} 46 | 47 | function l:formatter.IsAvailable() abort 48 | return executable(s:plugin.Flag('ruff_executable')) 49 | endfunction 50 | 51 | function l:formatter.AppliesToBuffer() abort 52 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'python') 53 | endfunction 54 | 55 | function l:formatter.Format() abort 56 | call s:FormatWithArgs([]) 57 | endfunction 58 | 59 | "" 60 | " Reformat the current buffer with ruff or the binary named in 61 | " @flag(ruff_executable), only targeting the range between {startline} and 62 | " {endline}. 63 | " @throws ShellError 64 | function l:formatter.FormatRange(startline, endline) abort 65 | call maktaba#ensure#IsNumber(a:startline) 66 | call maktaba#ensure#IsNumber(a:endline) 67 | call s:FormatWithArgs(['--range=' . a:startline . ':' . a:endline]) 68 | endfunction 69 | 70 | return l:formatter 71 | endfunction 72 | -------------------------------------------------------------------------------- /autoload/codefmt/rustfmt.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2018 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | "" 20 | " @private 21 | " Formatter: rustfmt 22 | function! codefmt#rustfmt#GetFormatter() abort 23 | let l:formatter = { 24 | \ 'name': 'rustfmt', 25 | \ 'setup_instructions': 'Install ' . 26 | \ 'rustfmt (https://github.com/rust-lang/rustfmt) ' . 27 | \ 'and configure the rustfmt_executable flag'} 28 | 29 | function l:formatter.IsAvailable() abort 30 | return executable(s:plugin.Flag('rustfmt_executable')) 31 | endfunction 32 | 33 | function l:formatter.AppliesToBuffer() abort 34 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'rust') 35 | endfunction 36 | 37 | "" 38 | " Reformat the current buffer with rustfmt or the binary named in 39 | " @flag(rustfmt_executable). 40 | function l:formatter.FormatRange(startline, endline) abort 41 | let l:Rustfmt_options = s:plugin.Flag('rustfmt_options') 42 | if type(l:Rustfmt_options) is# type([]) 43 | let l:rustfmt_options = l:Rustfmt_options 44 | elseif maktaba#value#IsCallable(l:Rustfmt_options) 45 | let l:rustfmt_options = maktaba#function#Call(l:Rustfmt_options) 46 | else 47 | throw maktaba#error#WrongType( 48 | \ 'rustfmt_options flag must be list or callable. Found %s', 49 | \ string(l:Rustfmt_options)) 50 | endif 51 | let l:cmd = [s:plugin.Flag('rustfmt_executable'), '--emit=stdout', '--color=never'] 52 | 53 | call extend(l:cmd, l:rustfmt_options) 54 | try 55 | " NOTE: Ignores any line ranges given and formats entire buffer. 56 | " Even though rustfmt supports formatting ranges through the --file-lines 57 | " flag, it is not still enabled in the stable binaries. 58 | call codefmt#formatterhelpers#Format(l:cmd) 59 | catch /ERROR(ShellError):/ 60 | " Parse all the errors and stick them in the quickfix list. 61 | let l:errors = [] 62 | let l:last_error_text = '' 63 | for l:line in split(v:exception, "\n") 64 | let l:error_text_tokens = matchlist(l:line, 65 | \ '\C\v^error: (.*)') 66 | if !empty(l:error_text_tokens) 67 | let l:last_error_text = l:error_text_tokens[1] 68 | endif 69 | 70 | let l:tokens = matchlist(l:line, 71 | \ '\C\v^.*\:(\d+):(\d+).*') 72 | if !empty(l:tokens) 73 | call add(l:errors, { 74 | \ 'filename': @%, 75 | \ 'lnum': l:tokens[1], 76 | \ 'col': l:tokens[2], 77 | \ 'text': l:last_error_text}) 78 | endif 79 | endfor 80 | 81 | if empty(l:errors) 82 | " Couldn't parse rustfmt error format; display it all. 83 | call maktaba#error#Shout('Error formatting file: %s', v:exception) 84 | else 85 | call setqflist(l:errors, 'r') 86 | cc 1 87 | endif 88 | endtry 89 | endfunction 90 | 91 | return l:formatter 92 | endfunction 93 | -------------------------------------------------------------------------------- /autoload/codefmt/shfmt.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2017 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | "" 20 | " @private 21 | " Formatter: shfmt 22 | function! codefmt#shfmt#GetFormatter() abort 23 | let l:formatter = { 24 | \ 'name': 'shfmt', 25 | \ 'setup_instructions': 'Install shfmt (https://github.com/mvdan/sh) ' . 26 | \ 'and configure the shfmt_executable flag'} 27 | 28 | function l:formatter.IsAvailable() abort 29 | let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray( 30 | \ 'shfmt_executable') 31 | if !empty(l:cmd) && executable(l:cmd[0]) 32 | return 1 33 | else 34 | return 0 35 | endif 36 | endfunction 37 | 38 | function l:formatter.AppliesToBuffer() abort 39 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'sh') 40 | endfunction 41 | 42 | "" 43 | " Reformat the current buffer with shfmt or the binary named in 44 | " @flag(shfmt_executable), only targeting the range between {startline} and 45 | " {endline}. 46 | function l:formatter.FormatRange(startline, endline) abort 47 | let l:Shfmt_options = s:plugin.Flag('shfmt_options') 48 | if type(l:Shfmt_options) is# type([]) 49 | let l:shfmt_options = l:Shfmt_options 50 | elseif maktaba#value#IsCallable(l:Shfmt_options) 51 | let l:shfmt_options = maktaba#function#Call(l:Shfmt_options) 52 | else 53 | throw maktaba#error#WrongType( 54 | \ 'shfmt_options flag must be list or callable. Found %s', 55 | \ string(l:Shfmt_options)) 56 | endif 57 | let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray( 58 | \ 'shfmt_executable') + l:shfmt_options 59 | try 60 | " Feature request for range formatting: 61 | " https://github.com/mvdan/sh/issues/333 62 | call codefmt#formatterhelpers#AttemptFakeRangeFormatting( 63 | \ a:startline, 64 | \ a:endline, 65 | \ l:cmd) 66 | catch /ERROR(ShellError):/ 67 | " Parse all the errors and stick them in the quickfix list. 68 | let l:errors = [] 69 | for l:line in split(v:exception, "\n") 70 | let l:tokens = matchlist(l:line, 71 | \ '\C\v^\:(\d+):(\d+):\s*(.*)') 72 | if !empty(l:tokens) 73 | call add(l:errors, { 74 | \ 'filename': @%, 75 | \ 'lnum': l:tokens[1] + a:startline - 1, 76 | \ 'col': l:tokens[2], 77 | \ 'text': l:tokens[3]}) 78 | endif 79 | endfor 80 | 81 | if empty(l:errors) 82 | " Couldn't parse shfmt error format; display it all. 83 | call maktaba#error#Shout('Error formatting file: %s', v:exception) 84 | else 85 | call setqflist(l:errors, 'r') 86 | cc 1 87 | endif 88 | endtry 89 | endfunction 90 | 91 | return l:formatter 92 | endfunction 93 | -------------------------------------------------------------------------------- /autoload/codefmt/swiftformat.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2022 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | let s:plugin = maktaba#plugin#Get('codefmt') 16 | 17 | 18 | "" 19 | " @private 20 | " Formatter: swift-format 21 | function! codefmt#swiftformat#GetFormatter() abort 22 | let l:formatter = { 23 | \ 'name': 'swift-format', 24 | \ 'setup_instructions': 'Install swift-format from ' . 25 | \ '(https://github.com/apple/swift-format).'} 26 | 27 | function l:formatter.IsAvailable() abort 28 | return executable(s:plugin.Flag('swift_format_executable')) 29 | endfunction 30 | 31 | function l:formatter.AppliesToBuffer() abort 32 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'swift') 33 | endfunction 34 | 35 | "" 36 | " Reformat the current buffer with swift-format or the binary named in 37 | " @flag(swift_format_executable) 38 | " 39 | " We implement Format(), and not FormatRange{,s}(), because swift-format doesn't 40 | " provide a hook for formatting a range 41 | 42 | function l:formatter.Format() abort 43 | let l:executable = s:plugin.Flag('swift_format_executable') 44 | 45 | call codefmt#formatterhelpers#Format([ 46 | \ l:executable]) 47 | endfunction 48 | 49 | return l:formatter 50 | endfunction 51 | -------------------------------------------------------------------------------- /autoload/codefmt/yapf.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2017 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | 16 | let s:plugin = maktaba#plugin#Get('codefmt') 17 | 18 | 19 | "" 20 | " @private 21 | " Formatter: yapf 22 | function! codefmt#yapf#GetFormatter() abort 23 | let l:formatter = { 24 | \ 'name': 'yapf', 25 | \ 'setup_instructions': 'Install yapf ' . 26 | \ '(https://pypi.python.org/pypi/yapf/).'} 27 | 28 | function l:formatter.IsAvailable() abort 29 | return executable(s:plugin.Flag('yapf_executable')) 30 | endfunction 31 | 32 | function l:formatter.AppliesToBuffer() abort 33 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'python') 34 | endfunction 35 | 36 | "" 37 | " Reformat the current buffer with yapf or the binary named in 38 | " @flag(yapf_executable), only targeting the range between {startline} and 39 | " {endline}. 40 | " @throws ShellError 41 | function l:formatter.FormatRange(startline, endline) abort 42 | let l:executable = s:plugin.Flag('yapf_executable') 43 | 44 | call maktaba#ensure#IsNumber(a:startline) 45 | call maktaba#ensure#IsNumber(a:endline) 46 | let l:lines = getline(1, line('$')) 47 | 48 | let l:cmd = [l:executable, '--lines=' . a:startline . '-' . a:endline] 49 | let l:input = join(l:lines, "\n") 50 | 51 | let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call(0) 52 | if v:shell_error 53 | call maktaba#error#Shout('Error formatting file: %s', l:result.stderr) 54 | return 55 | endif 56 | let l:formatted = split(l:result.stdout, "\n") 57 | 58 | call maktaba#buffer#Overwrite(1, line('$'), l:formatted) 59 | endfunction 60 | 61 | return l:formatter 62 | endfunction 63 | -------------------------------------------------------------------------------- /autoload/codefmt/zprint.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2019 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | "" 16 | " @section Recommended zprint mappings, mappings-zprint 17 | " @parentsection mappings 18 | " 19 | " Since zprint only works on top-level Clojure forms, it doesn't make sense to 20 | " format line ranges that aren't complete forms. If you're using vim-sexp 21 | " (https://github.com/guns/vim-sexp), the following mapping replaces the default 22 | " "format the current line" with "format the current top-level form." > 23 | " autocmd FileType clojure nmap == =iF 24 | " < 25 | 26 | 27 | let s:plugin = maktaba#plugin#Get('codefmt') 28 | 29 | 30 | "" 31 | " @private 32 | " Formatter: zprint 33 | function! codefmt#zprint#GetFormatter() abort 34 | let l:formatter = { 35 | \ 'name': 'zprint', 36 | \ 'setup_instructions': 37 | \ 'Install zprint filter (https://github.com/kkinnear/zprint) ' . 38 | \ 'and configure the zprint_executable flag'} 39 | 40 | function l:formatter.IsAvailable() abort 41 | let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray( 42 | \ 'zprint_executable') 43 | return !empty(l:cmd) && executable(l:cmd[0]) 44 | endfunction 45 | 46 | function l:formatter.AppliesToBuffer() abort 47 | return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'clojure') 48 | endfunction 49 | 50 | "" 51 | " Reformat the current buffer with zprint or the binary named in 52 | " @flag(zprint_executable), only targeting the range between {startline} and 53 | " {endline}. 54 | function l:formatter.FormatRange(startline, endline) abort 55 | let l:exe = codefmt#formatterhelpers#ResolveFlagToArray( 56 | \ 'zprint_executable') 57 | let l:opts = codefmt#formatterhelpers#ResolveFlagToArray( 58 | \ 'zprint_options') 59 | 60 | " Prepare the syscall 61 | let l:syscall = maktaba#syscall#Create(l:exe + l:opts) 62 | if isdirectory(expand('%:p:h')) 63 | " Change to the containing directory in case the user has configured 64 | " {:search-config? true} in ~/.zprintrc 65 | let l:syscall = l:syscall.WithCwd(expand('%:p:h')) 66 | endif 67 | 68 | " zprint does not support range formatting yet: 69 | " https://github.com/kkinnear/zprint/issues/122 70 | " This fake range formatting works well for top-level forms, although it's 71 | " not ideal for inner forms because it loses the indentation. 72 | call codefmt#formatterhelpers#AttemptFakeRangeFormatting( 73 | \ a:startline, 74 | \ a:endline, 75 | \ l:syscall) 76 | endfunction 77 | 78 | return l:formatter 79 | endfunction 80 | -------------------------------------------------------------------------------- /bin/julia/.JuliaFormatter.toml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | indent = 2 16 | margin = 80 17 | trailing_comma = false 18 | whitespace_in_kwargs = false 19 | -------------------------------------------------------------------------------- /bin/julia/Manifest.toml: -------------------------------------------------------------------------------- 1 | # This file is machine-generated - editing it directly is not advised 2 | 3 | julia_version = "1.9.3" 4 | manifest_format = "2.0" 5 | project_hash = "93e024a7bf6c9615a79c4b80b3a014b0f1f744c9" 6 | 7 | [[deps.ArgParse]] 8 | deps = ["Logging", "TextWrap"] 9 | git-tree-sha1 = "3102bce13da501c9104df33549f511cd25264d7d" 10 | uuid = "c7e460c6-2fb9-53a9-8c5b-16f535851c63" 11 | version = "1.1.4" 12 | 13 | [[deps.ArgTools]] 14 | uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" 15 | version = "1.1.1" 16 | 17 | [[deps.Artifacts]] 18 | uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" 19 | 20 | [[deps.Base64]] 21 | uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" 22 | 23 | [[deps.CSTParser]] 24 | deps = ["Tokenize"] 25 | git-tree-sha1 = "3ddd48d200eb8ddf9cb3e0189fc059fd49b97c1f" 26 | uuid = "00ebfdb7-1f24-5e51-bd34-a7502290713f" 27 | version = "3.3.6" 28 | 29 | [[deps.CommonMark]] 30 | deps = ["Crayons", "JSON", "PrecompileTools", "URIs"] 31 | git-tree-sha1 = "532c4185d3c9037c0237546d817858b23cf9e071" 32 | uuid = "a80b9123-70ca-4bc0-993e-6e3bcb318db6" 33 | version = "0.8.12" 34 | 35 | [[deps.Compat]] 36 | deps = ["UUIDs"] 37 | git-tree-sha1 = "8a62af3e248a8c4bad6b32cbbe663ae02275e32c" 38 | uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" 39 | version = "4.10.0" 40 | 41 | [deps.Compat.extensions] 42 | CompatLinearAlgebraExt = "LinearAlgebra" 43 | 44 | [deps.Compat.weakdeps] 45 | Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" 46 | LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" 47 | 48 | [[deps.Crayons]] 49 | git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" 50 | uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" 51 | version = "4.1.1" 52 | 53 | [[deps.DataStructures]] 54 | deps = ["Compat", "InteractiveUtils", "OrderedCollections"] 55 | git-tree-sha1 = "3dbd312d370723b6bb43ba9d02fc36abade4518d" 56 | uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" 57 | version = "0.18.15" 58 | 59 | [[deps.Dates]] 60 | deps = ["Printf"] 61 | uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" 62 | 63 | [[deps.Downloads]] 64 | deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] 65 | uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" 66 | version = "1.6.0" 67 | 68 | [[deps.FileWatching]] 69 | uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" 70 | 71 | [[deps.Glob]] 72 | git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" 73 | uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" 74 | version = "1.3.1" 75 | 76 | [[deps.InteractiveUtils]] 77 | deps = ["Markdown"] 78 | uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" 79 | 80 | [[deps.JSON]] 81 | deps = ["Dates", "Mmap", "Parsers", "Unicode"] 82 | git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" 83 | uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" 84 | version = "0.21.4" 85 | 86 | [[deps.JuliaFormatter]] 87 | deps = ["CSTParser", "CommonMark", "DataStructures", "Glob", "Pkg", "PrecompileTools", "Tokenize"] 88 | git-tree-sha1 = "3d5b5b539e4606dcca0e6a467b98a64c8da4850b" 89 | uuid = "98e50ef6-434e-11e9-1051-2b60c6c9e899" 90 | version = "1.0.42" 91 | 92 | [[deps.LibCURL]] 93 | deps = ["LibCURL_jll", "MozillaCACerts_jll"] 94 | uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" 95 | version = "0.6.3" 96 | 97 | [[deps.LibCURL_jll]] 98 | deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] 99 | uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" 100 | version = "7.84.0+0" 101 | 102 | [[deps.LibGit2]] 103 | deps = ["Base64", "NetworkOptions", "Printf", "SHA"] 104 | uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" 105 | 106 | [[deps.LibSSH2_jll]] 107 | deps = ["Artifacts", "Libdl", "MbedTLS_jll"] 108 | uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" 109 | version = "1.10.2+0" 110 | 111 | [[deps.Libdl]] 112 | uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" 113 | 114 | [[deps.Logging]] 115 | uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" 116 | 117 | [[deps.Markdown]] 118 | deps = ["Base64"] 119 | uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" 120 | 121 | [[deps.MbedTLS_jll]] 122 | deps = ["Artifacts", "Libdl"] 123 | uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" 124 | version = "2.28.2+0" 125 | 126 | [[deps.Mmap]] 127 | uuid = "a63ad114-7e13-5084-954f-fe012c677804" 128 | 129 | [[deps.MozillaCACerts_jll]] 130 | uuid = "14a3606d-f60d-562e-9121-12d972cd8159" 131 | version = "2022.10.11" 132 | 133 | [[deps.NetworkOptions]] 134 | uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" 135 | version = "1.2.0" 136 | 137 | [[deps.OrderedCollections]] 138 | git-tree-sha1 = "2e73fe17cac3c62ad1aebe70d44c963c3cfdc3e3" 139 | uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" 140 | version = "1.6.2" 141 | 142 | [[deps.Parsers]] 143 | deps = ["Dates", "PrecompileTools", "UUIDs"] 144 | git-tree-sha1 = "716e24b21538abc91f6205fd1d8363f39b442851" 145 | uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" 146 | version = "2.7.2" 147 | 148 | [[deps.Pkg]] 149 | deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] 150 | uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" 151 | version = "1.9.2" 152 | 153 | [[deps.PrecompileTools]] 154 | deps = ["Preferences"] 155 | git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" 156 | uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" 157 | version = "1.2.0" 158 | 159 | [[deps.Preferences]] 160 | deps = ["TOML"] 161 | git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" 162 | uuid = "21216c6a-2e73-6563-6e65-726566657250" 163 | version = "1.4.1" 164 | 165 | [[deps.Printf]] 166 | deps = ["Unicode"] 167 | uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" 168 | 169 | [[deps.REPL]] 170 | deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] 171 | uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" 172 | 173 | [[deps.Random]] 174 | deps = ["SHA", "Serialization"] 175 | uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" 176 | 177 | [[deps.SHA]] 178 | uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" 179 | version = "0.7.0" 180 | 181 | [[deps.Serialization]] 182 | uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" 183 | 184 | [[deps.Sockets]] 185 | uuid = "6462fe0b-24de-5631-8697-dd941f90decc" 186 | 187 | [[deps.TOML]] 188 | deps = ["Dates"] 189 | uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" 190 | version = "1.0.3" 191 | 192 | [[deps.Tar]] 193 | deps = ["ArgTools", "SHA"] 194 | uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" 195 | version = "1.10.0" 196 | 197 | [[deps.TextWrap]] 198 | git-tree-sha1 = "9250ef9b01b66667380cf3275b3f7488d0e25faf" 199 | uuid = "b718987f-49a8-5099-9789-dcd902bef87d" 200 | version = "1.0.1" 201 | 202 | [[deps.Tokenize]] 203 | git-tree-sha1 = "0454d9a9bad2400c7ccad19ca832a2ef5a8bc3a1" 204 | uuid = "0796e94c-ce3b-5d07-9a54-7f471281c624" 205 | version = "0.5.26" 206 | 207 | [[deps.URIs]] 208 | git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" 209 | uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" 210 | version = "1.5.1" 211 | 212 | [[deps.UUIDs]] 213 | deps = ["Random", "SHA"] 214 | uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" 215 | 216 | [[deps.Unicode]] 217 | uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" 218 | 219 | [[deps.Zlib_jll]] 220 | deps = ["Libdl"] 221 | uuid = "83775a58-1f1d-513f-b197-d71354ab007a" 222 | version = "1.2.13+0" 223 | 224 | [[deps.nghttp2_jll]] 225 | deps = ["Artifacts", "Libdl"] 226 | uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" 227 | version = "1.48.0+0" 228 | 229 | [[deps.p7zip_jll]] 230 | deps = ["Artifacts", "Libdl"] 231 | uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" 232 | version = "17.4.0+0" 233 | -------------------------------------------------------------------------------- /bin/julia/Project.toml: -------------------------------------------------------------------------------- 1 | name = "julia" 2 | uuid = "f7e72769-0d4f-4e1c-bb39-275b23f83607" 3 | authors = ["Trevor Stone "] 4 | version = "0.1.0" 5 | 6 | [deps] 7 | ArgParse = "c7e460c6-2fb9-53a9-8c5b-16f535851c63" 8 | JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899" 9 | -------------------------------------------------------------------------------- /bin/julia/format.jl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env julia 2 | # Copyright 2023 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # This program wraps the JuliaFormatter package with a command line interface 17 | # that takes ranges of lines. Example: 18 | # format.jl --file-path path/to/mycode.jl --lines 1:7 20:35 < mycode.jl 19 | # The bin/format.jl script that ships with JuliaFormatter doesn't take input 20 | # on stdin and doesn't support line ranges, both of which are nice features for 21 | # the vim-codefmt plugin. The --file-path flag lets this program find 22 | # .JuliaFormatter.toml files to determine code style preferences. 23 | 24 | try 25 | @eval using JuliaFormatter 26 | catch ArgumentError 27 | println( 28 | stderr, 29 | "Missing JuliaFormatter package, run $(dirname(PROGRAM_FILE))/install" 30 | ) 31 | exit(2) 32 | end 33 | try 34 | @eval using ArgParse 35 | catch ArgumentError 36 | println( 37 | stderr, 38 | "Missing ArgParse package, run $(dirname(PROGRAM_FILE))/install" 39 | ) 40 | exit(2) 41 | end 42 | 43 | "A range of line numbers to format. Requires `0 < first <= last`." 44 | struct LineRange 45 | first::Int 46 | last::Int 47 | LineRange(first, last) = 48 | first <= 0 || last < first ? error("Invalid line range $first:$last") : 49 | new(first, last) 50 | end 51 | 52 | Base.string(r::LineRange) = "$(r.first):$(r.last)" 53 | 54 | function ArgParse.parse_item(::Type{LineRange}, s::AbstractString) 55 | parts = split(s, ':') 56 | length(parts) == 2 || 57 | throw(ArgumentError("LineRange expecting start:end, got $s")) 58 | LineRange(parse(Int, parts[1]), parse(Int, parts[2])) 59 | end 60 | 61 | "Entry point to run format.jl. argv is the command line arguments." 62 | function main(argv::Vector{<:AbstractString}) 63 | s = ArgParseSettings( 64 | "$(basename(PROGRAM_FILE)): format all or part of Julia code read from stdin", 65 | autofix_names=true 66 | ) 67 | @add_arg_table! s begin 68 | #! format: off 69 | "--file_path" 70 | help = "file path of the code (default: current working directory)" 71 | metavar = "path/to/file.jl" 72 | "--lines" 73 | help = "line range(s) to format (1-based)" 74 | arg_type = LineRange 75 | metavar = "first:last" 76 | nargs = '*' 77 | "--check_install" 78 | help = "exit with status 0 if dependencies are installed, 2 otherwise" 79 | action = :store_true 80 | #! format: on 81 | end 82 | args = parse_args(argv, s, as_symbols=true) 83 | if args[:check_install] 84 | exit(0) # if we got this far, module import succeeded 85 | end 86 | file_path = let p = args[:file_path] 87 | fakefile = "file-path-not-specified" 88 | isnothing(p) ? joinpath(pwd(), fakefile) : abspath(expanduser(p)) 89 | end 90 | # Sort line ranges and check for overlap, which would make things complicated 91 | ranges = sort(args[:lines], by=x -> x.first) 92 | for i = 2:length(ranges) 93 | if ranges[i].first <= ranges[i-1].last 94 | println( 95 | stderr, 96 | "Overlapping --lines ranges $(ranges[i-1]) and $(ranges[i])" 97 | ) 98 | exit(3) 99 | end 100 | end 101 | 102 | config = JuliaFormatter.Configuration( 103 | Dict{String,Any}(JuliaFormatter.find_config_file(file_path)) 104 | ) 105 | opts = [Symbol(k) => v for (k, v) in pairs(config)] 106 | try 107 | if isempty(ranges) 108 | input = read(stdin, String) 109 | output = JuliaFormatter.format_text(input; opts...) 110 | print(output) 111 | else 112 | formatranges(ranges, opts) 113 | end 114 | catch e 115 | message = isdefined(e, :msg) ? e.msg : string(e) 116 | println(stderr, "Format error: $message") 117 | exit(1) 118 | end 119 | end 120 | 121 | """Formats one or more line ranges of `stdin` using options `opts`. 122 | Assumes `ranges` is already sorted. Prints formatted result to `stdout`. 123 | """ 124 | function formatranges(ranges::Vector{LineRange}, opts) 125 | # JuliaFormatter doesn't support line ranges, so use format comment directives 126 | # to turn it on and off at appropriate times. Use a random number as a marker 127 | # so added directives can be removed after. 128 | # NOTE: This approach means line numbers for syntax errors are misleading. 129 | marker = string(rand(UInt32)) 130 | formaton = "# added:$marker\n#! format: on\n" 131 | formatoff = "# added:$marker\n#! format: off\n" 132 | formatpat = r"\s*#! format: (on|off)\s*$" 133 | lines = readlines(stdin) 134 | lnum = 1 # current index in lines; unaffected by directive additions 135 | text = IOBuffer() # will contain the input file with format directives added 136 | requested = true # whether formatting would be on at this point if the formatting were done without line ranges 137 | # disable formatting unless line 1 is in range 138 | if ranges[1].first > 1 139 | print(text, formatoff) 140 | end 141 | for (ri, range) in enumerate(ranges) 142 | # for each line range, add all the lines leading up to the range to text, 143 | # disabling any format directives so we don't turn formatting on outside of 144 | # the requested ranges 145 | for i = lnum:range.first-1 146 | if lnum > length(lines) 147 | @goto eof 148 | end 149 | line = lines[lnum] 150 | lnum += 1 151 | # disable existing formatter directives 152 | if (m = match(formatpat, line)) !== nothing 153 | line = "# disabled:$marker:$line" 154 | requested = m.captures[1] == "on" 155 | end 156 | println(text, line) 157 | end 158 | # if directives wouldn't have disabled this range, turn on formatting 159 | if requested 160 | print(text, formaton) 161 | end 162 | # add each line in the range to text 163 | for i = range.first:range.last 164 | if lnum > length(lines) 165 | @goto eof 166 | end 167 | line = lines[lnum] 168 | lnum += 1 169 | # if there's a format:off directive inside the range, respect that; 170 | # if there's a format:on directive inside the range and formatting had 171 | # been off, enable it at this point 172 | if (m = match(formatpat, line)) !== nothing 173 | line = "# disabled:$marker:$line" 174 | if m.captures[1] == "on" && !requested 175 | requested = true 176 | print(text, formaton) 177 | elseif m.captures[1] == "off" && requested 178 | requested = false 179 | print(text, formatoff) 180 | end 181 | end 182 | println(text, line) 183 | end 184 | # turn off formatting at the end of the range 185 | if lnum <= length(lines) 186 | print(text, formatoff) 187 | end 188 | end 189 | # process lines after the last range 190 | while lnum <= length(lines) 191 | line = lines[lnum] 192 | lnum += 1 193 | if occursin(formatpat, line) 194 | line = "# disabled:$marker:$line" 195 | end 196 | println(text, line) 197 | end 198 | @label eof 199 | # work around https://github.com/domluna/JuliaFormatter.jl/issues/777 200 | # by appending on and off directives at the end 201 | print(text, formaton) 202 | print(text, formatoff) 203 | # now that format directives have been added, format the whole thing 204 | input = String(take!(text)) 205 | output = JuliaFormatter.format_text(input; opts...) 206 | # remove format directives we added and restore ones we disabled 207 | skipnext = false 208 | addedpat = Regex("^\\s*#\\s*added:$marker\\s*\$") 209 | disabledpat = Regex("^\\s*#\\s*disabled:$marker:(.*)", "s") 210 | all = [] 211 | last = "nothing" 212 | for (i, line) in enumerate(readlines(IOBuffer(output))) 213 | push!(all, line) 214 | last = line 215 | if skipnext 216 | skipnext = false 217 | elseif occursin(addedpat, line) 218 | skipnext = true 219 | else 220 | if (m = match(disabledpat, line)) !== nothing 221 | line = m.captures[1] 222 | end 223 | println(line) 224 | end 225 | end 226 | end 227 | 228 | if abspath(PROGRAM_FILE) == @__FILE__ 229 | main(ARGS) 230 | end 231 | -------------------------------------------------------------------------------- /bin/julia/install: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | PROJECT=$(dirname $0) 4 | julia --project="$PROJECT" -e 'using Pkg; Pkg.instantiate(verbose=true)' 5 | -------------------------------------------------------------------------------- /bin/julia/install.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | set PROJECT=%~dp0 3 | julia --project="%PROJECT%" -e 'using Pkg; Pkg.instantiate(verbose=true)' 4 | -------------------------------------------------------------------------------- /bootstrap.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2014 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | " This file can be sourced to install the plugin and its dependencies if no 16 | " plugin manager is available. 17 | 18 | let s:codefmt_path = expand(':p:h') 19 | 20 | if !exists('*maktaba#compatibility#Disable') 21 | try 22 | " To check if Maktaba is loaded we must try calling a maktaba function. 23 | " exists() is false for autoloadable functions that are not yet loaded. 24 | call maktaba#compatibility#Disable() 25 | catch /E117:/ 26 | " Maktaba is not installed. Check whether it's in a nearby directory. 27 | let s:rtpsave = &runtimepath 28 | " We'd like to use maktaba#path#Join, but maktaba doesn't exist yet. 29 | let s:slash = exists('+shellslash') && !&shellslash ? '\' : '/' 30 | let s:guess1 = fnamemodify(s:codefmt_path, ':h') . s:slash . 'maktaba' 31 | let s:guess2 = fnamemodify(s:codefmt_path, ':h') . s:slash . 'vim-maktaba' 32 | if isdirectory(s:guess1) 33 | let &runtimepath .= ',' . s:guess1 34 | elseif isdirectory(s:guess2) 35 | let &runtimepath .= ',' . s:guess2 36 | endif 37 | 38 | try 39 | " If we've just installed maktaba, we need to make sure that vi 40 | " compatibility mode is off. Maktaba does not support vi compatibility. 41 | call maktaba#compatibility#Disable() 42 | catch /E117:/ 43 | " No luck. 44 | let &runtimepath = s:rtpsave 45 | unlet s:rtpsave 46 | " We'd like to use maktaba#error#Shout, but maktaba doesn't exist yet. 47 | echohl ErrorMsg 48 | echomsg 'Maktaba not found, but codefmt requires it. Please either:' 49 | echomsg '1. Place maktaba in the same directory as this plugin.' 50 | echomsg '2. Add maktaba to your runtimepath before using this plugin.' 51 | echomsg 'Maktaba can be found at https://github.com/google/vim-maktaba.' 52 | echohl NONE 53 | finish 54 | endtry 55 | endtry 56 | endif 57 | call maktaba#plugin#GetOrInstall(s:codefmt_path) 58 | -------------------------------------------------------------------------------- /plugin/autocmds.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2014 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | "" 16 | " @section Autocommands, autocmds 17 | " You can enable automatic formatting on a buffer using 18 | " @command(AutoFormatBuffer). 19 | 20 | let [s:plugin, s:enter] = maktaba#plugin#Enter(expand(':p')) 21 | if !s:enter 22 | finish 23 | endif 24 | 25 | 26 | "" 27 | " Automatically reformat when saving files. 28 | augroup codefmt 29 | autocmd! 30 | autocmd BufWritePre * call s:FmtIfAutoEnabled() 31 | augroup END 32 | 33 | function! s:FmtIfAutoEnabled() abort 34 | if get(b:, 'codefmt_auto_format_buffer') 35 | call codefmt#FormatBuffer() 36 | endif 37 | endfunction 38 | -------------------------------------------------------------------------------- /plugin/commands.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2014 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | let [s:plugin, s:enter] = maktaba#plugin#Enter(expand(':p')) 16 | if !s:enter 17 | finish 18 | endif 19 | 20 | "" 21 | " Enables format on save for this buffer using [formatter]. 22 | " @default formatter=[first available for buffer] the formatter to use 23 | function! s:AutoFormatBuffer(...) abort 24 | if a:0 == 1 25 | let b:codefmt_formatter = a:1 26 | endif 27 | let b:codefmt_auto_format_buffer = 1 28 | endfunction 29 | 30 | function! s:FormatLinesAndSetRepeat(startline, endline, ...) abort 31 | call call('codefmt#FormatLines', [a:startline, a:endline] + a:000) 32 | let l:cmd = ":FormatLines " . join(a:000, ' ') . "\" 33 | let l:lines_formatted = a:endline - a:startline + 1 34 | silent! call repeat#set(l:cmd, l:lines_formatted) 35 | endfunction 36 | 37 | function! s:FormatBufferAndSetRepeat(...) abort 38 | call call('codefmt#FormatBuffer', a:000) 39 | let l:cmd = ":FormatCode " . join(a:000, ' ') . "\" 40 | silent! call repeat#set(l:cmd) 41 | endfunction 42 | 43 | "" 44 | " Format the current line or range using [formatter]. 45 | " @default formatter=the default formatter associated with the current buffer 46 | command -nargs=? -bar -range -complete=custom,codefmt#GetSupportedFormatters 47 | \ FormatLines call s:FormatLinesAndSetRepeat(, , ) 48 | 49 | "" 50 | " Format the whole buffer using [formatter]. 51 | " See @section(formatters) for list of valid formatters. 52 | " @default formatter=the default formatter associated with the current buffer 53 | command -nargs=? -bar -complete=custom,codefmt#GetSupportedFormatters 54 | \ FormatCode call s:FormatBufferAndSetRepeat() 55 | 56 | "" 57 | " Enables format on save for this buffer using [formatter]. Also configures 58 | " [formatter] as the default formatter for this buffer via the 59 | " @setting(b:codefmt_formatter) variable. 60 | " @default formatter=the default formatter associated with the current buffer 61 | command -nargs=? -bar -complete=custom,codefmt#GetSupportedFormatters 62 | \ AutoFormatBuffer call s:AutoFormatBuffer() 63 | 64 | "" 65 | " Disables format on save for this buffer. 66 | command -nargs=0 -bar NoAutoFormatBuffer let b:codefmt_auto_format_buffer = 0 67 | 68 | -------------------------------------------------------------------------------- /plugin/mappings.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2014 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | "" 16 | " @section Mappings, mappings 17 | " This plugin provides default mappings that can be enabled via the 18 | " plugin[mappings] flag. You can enable them under the default prefix of 19 | " = ( being "\" by default) or set the plugin[mappings] flag to 20 | " an explicit prefix to use. Or you can define your own custom mappings; see 21 | " plugin/mappings.vim for inspiration. 22 | " 23 | " To format the whole buffer, use b. 24 | " 25 | " Some formatters also support formatting ranges. There are several mappings for 26 | " formatting ranges that mimic vim's built-in |operator|s: 27 | " * Format the current line with the = mapping. 28 | " * by itself acts as an |operator|. Use to format 29 | " over any motion. For instance, i{ will format all lines inside the 30 | " enclosing curly braces. 31 | " * In visual mode, will format the visual selection. 32 | 33 | let [s:plugin, s:enter] = maktaba#plugin#Enter(expand(':p')) 34 | if !s:enter 35 | finish 36 | endif 37 | 38 | 39 | let s:prefix = s:plugin.MapPrefix('=') 40 | 41 | 42 | "" 43 | " Format the contents of the buffer using the associated formatter. 44 | execute 'nnoremap ' s:prefix . 'b' ':FormatCode' 45 | 46 | "" 47 | " Format over the motion that follows. This is a custom operator. 48 | " For instance, i{ will format all lines inside the enclosing curly 49 | " braces. 50 | execute 'nnoremap ' s:prefix 51 | \ ':set opfunc=codefmt#FormatMapg@' 52 | 53 | "" 54 | " Format the current line or range using the formatter associated with the 55 | " current buffer. 56 | execute 'nnoremap ' s:prefix . '=' ':FormatLines' 57 | 58 | "" 59 | " Format the visually selected region using the formatter associated with the 60 | " current buffer. 61 | execute 'vnoremap ' s:prefix ':FormatLines' 62 | -------------------------------------------------------------------------------- /plugin/register.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2015 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | "" 16 | " @section Formatters, formatters 17 | " This plugin has three built-in formatters: clang-format, gofmt, and autopep8. 18 | " More formatters can be registered by other plugins that integrate with 19 | " codefmt. 20 | " 21 | " @subsection Default formatters 22 | " Codefmt will automatically use a default formatter for certain filetypes if 23 | " none is explicitly supplied via an explicit arg to @command(FormatCode) or the 24 | " @setting(b:codefmt_formatter) variable. The default formatter may also depend 25 | " on what plugins are enabled or what other software is installed on your 26 | " system. 27 | " 28 | " The current list of defaults by filetype is: 29 | " * bzl (Bazel): buildifier 30 | " * c, cpp, proto, javascript, typescript: clang-format 31 | " * clojure: cljstyle, zprint 32 | " * dart: dartfmt 33 | " * fish: fish_indent 34 | " * elixir: mixformat 35 | " * gn: gn 36 | " * go: gofmt 37 | " * haskell: ormolu 38 | " * java: google-java-format 39 | " * javascript, json, html, css: js-beautify 40 | " * javascript, html, css, markdown: prettier 41 | " * json, jsonnet: jsonnetfmt 42 | " * julia: JuliaFormatter 43 | " * kotlin: ktfmt 44 | " * lua: luaformatterfiveone 45 | " * nix: nixpkgs-fmt 46 | " * ocaml: ocamlformat 47 | " * python: autopep8, black, ruff, yapf 48 | " * ruby: rubocop 49 | " * rust: rustfmt 50 | " * sh: shfmt 51 | " * swift: swift-format 52 | 53 | 54 | let [s:plugin, s:enter] = maktaba#plugin#Enter(expand(':p')) 55 | if !s:enter 56 | finish 57 | endif 58 | 59 | 60 | let s:registry = s:plugin.GetExtensionRegistry() 61 | call s:registry.SetValidator('codefmt#EnsureFormatter') 62 | 63 | " Formatters that are registered later are given more priority when deciding 64 | " what the default formatter will be for a particular file type. 65 | call s:registry.AddExtension(codefmt#buildifier#GetFormatter()) 66 | call s:registry.AddExtension(codefmt#clangformat#GetFormatter()) 67 | call s:registry.AddExtension(codefmt#cljstyle#GetFormatter()) 68 | call s:registry.AddExtension(codefmt#zprint#GetFormatter()) 69 | call s:registry.AddExtension(codefmt#dartfmt#GetFormatter()) 70 | call s:registry.AddExtension(codefmt#mixformat#GetFormatter()) 71 | call s:registry.AddExtension(codefmt#fish_indent#GetFormatter()) 72 | call s:registry.AddExtension(codefmt#gn#GetFormatter()) 73 | call s:registry.AddExtension(codefmt#gofmt#GetFormatter()) 74 | call s:registry.AddExtension(codefmt#googlejava#GetFormatter()) 75 | call s:registry.AddExtension(codefmt#jsonnetfmt#GetFormatter()) 76 | call s:registry.AddExtension(codefmt#jsbeautify#GetFormatter()) 77 | call s:registry.AddExtension(codefmt#prettier#GetFormatter()) 78 | call s:registry.AddExtension(codefmt#juliaformatter#GetFormatter()) 79 | call s:registry.AddExtension(codefmt#ktfmt#GetFormatter()) 80 | call s:registry.AddExtension(codefmt#luaformatterfiveone#GetFormatter()) 81 | call s:registry.AddExtension(codefmt#nixpkgs_fmt#GetFormatter()) 82 | call s:registry.AddExtension(codefmt#autopep8#GetFormatter()) 83 | call s:registry.AddExtension(codefmt#isort#GetFormatter()) 84 | call s:registry.AddExtension(codefmt#black#GetFormatter()) 85 | call s:registry.AddExtension(codefmt#ruff#GetFormatter()) 86 | call s:registry.AddExtension(codefmt#yapf#GetFormatter()) 87 | call s:registry.AddExtension(codefmt#rubocop#GetFormatter()) 88 | call s:registry.AddExtension(codefmt#rustfmt#GetFormatter()) 89 | call s:registry.AddExtension(codefmt#shfmt#GetFormatter()) 90 | call s:registry.AddExtension(codefmt#swiftformat#GetFormatter()) 91 | call s:registry.AddExtension(codefmt#ormolu#GetFormatter()) 92 | call s:registry.AddExtension(codefmt#ocamlformat#GetFormatter()) 93 | -------------------------------------------------------------------------------- /vroom/autocmd.vroom: -------------------------------------------------------------------------------- 1 | This file demonstrates hooks for automatically formatting code on save. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 10 | 11 | 12 | By default, nothing special happens when you save a buffer. 13 | 14 | % void f() {int i; SomeFunction(parameter,// comment 15 | |i);} 16 | 17 | :doautocmd BufWritePre 18 | void f() {int i; SomeFunction(parameter,// comment 19 | i);} 20 | @end 21 | 22 | 23 | 24 | You can use the AutoFormatBuffer command to enable automatic code formatting 25 | when you save the current buffer. This combined with vim autocommands gives you 26 | the flexibility to automatically format certain buffers based on path, filetype, 27 | or whatever conditions you want to trigger on. 28 | 29 | :AutoFormatBuffer clang-format 30 | % void f() {int i; SomeFunction(parameter,// comment 31 | |i);} 32 | 33 | :doautocmd BufWritePre 34 | ! clang-format --version .* 35 | $ clang-format version 3.3.0 (tags/testing) 36 | ! clang-format .* 37 | $ void f() { 38 | $ int i; 39 | $ SomeFunction(parameter, // comment 40 | $ i); 41 | $ } 42 | void f() { 43 | int i; 44 | SomeFunction(parameter, // comment 45 | i); 46 | } 47 | @end 48 | 49 | Subsequent :FormatCode and :FormatLines invocations will also default to this 50 | same formatter. 51 | 52 | :FormatCode 53 | ! clang-format .* 54 | $ void f() { 55 | $ int i; 56 | $ SomeFunction(parameter, // comment 57 | $ i); 58 | $ } 59 | 60 | You can disable it for the current buffer with :NoAutoFormatBuffer. After that, 61 | the buffer will go back to doing nothing special when you save. 62 | 63 | @clear 64 | :NoAutoFormatBuffer 65 | % void f() {int i; SomeFunction(parameter,// comment 66 | |i);} 67 | 68 | :doautocmd BufWritePre 69 | void f() {int i; SomeFunction(parameter,// comment 70 | i);} 71 | @end 72 | 73 | 74 | 75 | If you don't specify an explicit formatter as an argument to :AutoFormatBuffer, 76 | the default for the current buffer will be used. 77 | 78 | :set filetype=go 79 | :AutoFormatBuffer 80 | % f() 81 | 82 | :doautocmd BufWritePre 83 | ! gofmt .* 84 | $ f() 85 | -------------------------------------------------------------------------------- /vroom/autopep8.vroom: -------------------------------------------------------------------------------- 1 | The built-in autopep8 formatter knows how to format python code. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | 18 | The autopep8 formatter expects the autopep8 executable to be installed on your 19 | system. 20 | 21 | % f() 22 | :FormatCode autopep8 23 | ! autopep8 --version 2>(.*) 24 | $ echo "autopep8 1.0" > \1 (command) 25 | ! autopep8 .* 26 | $ f() 27 | 28 | Notice the "autopep8 --version" syscall. The autopep8 formatter checks the 29 | version of the autopep8 executable to detect whether it natively supports range 30 | formatting. It caches the result, so it only does this once per vim session. 31 | We'll take a closer look at that below. 32 | 33 | The name or path of the autopep8 executable can be configured via the 34 | autopep8_executable flag if the default of "autopep8" doesn't work. 35 | 36 | :Glaive codefmt autopep8_executable='autopep20' 37 | :FormatCode autopep8 38 | ! autopep20 --version 2>(.*) 39 | $ echo "autopep8 1.0" > \1 (command) 40 | ! autopep20 .* 41 | $ f() 42 | :Glaive codefmt autopep8_executable='autopep8' 43 | 44 | Any time this flag is changed, the cached version is invalidated and checked 45 | fresh on the next format invocation. 46 | 47 | 48 | You can format any buffer with autopep8 specifying the formatter explicitly. 49 | 50 | @clear 51 | % if True: pass 52 | 53 | :FormatCode autopep8 54 | ! autopep8 --version 2>(.*) 55 | $ echo "autopep8 1.0" > \1 (command) 56 | ! autopep8 .* - .* 57 | $ if True: 58 | $ pass 59 | if True: 60 | pass 61 | @end 62 | 63 | It can format specific line ranges of code using :FormatLines. 64 | 65 | @clear 66 | % some_tuple=( 1,2, 3,'a' ); 67 | |if bar : bar+=1; bar=bar* bar 68 | |else: bar-=1; 69 | 70 | :2,3FormatLines autopep8 71 | ! autopep8 --range 2 3 - .* 72 | $ some_tuple=( 1,2, 3,'a' ); 73 | $ if bar: 74 | $ bar += 1 75 | $ bar = bar * bar 76 | $ else: 77 | $ bar -= 1 78 | some_tuple=( 1,2, 3,'a' ); 79 | if bar: 80 | bar += 1 81 | bar = bar * bar 82 | else: 83 | bar -= 1 84 | @end 85 | 86 | Notice the --range argument. It's only supported by autopep8 1.0 and higher, and 87 | it appeared in the command line because the formatter detected autopep8 version 88 | 1.0 when it was first invoked, earlier in this file. 89 | 90 | Now let's check what it does for older versions of autopep8. Remember, setting 91 | the autopep8_executable flag makes the formatter forget any cached version. 92 | 93 | @clear 94 | :Glaive codefmt autopep8_executable='autopep8' 95 | % some_tuple=( 1,2, 3,'a' ); 96 | |if bar : bar+=1; bar=bar* bar 97 | |else: bar-=1; 98 | 99 | :3,3FormatLines autopep8 100 | ! autopep8 --version 2>(.*) 101 | $ echo "autopep8 0.9" > \1 (command) 102 | ! autopep8 - 2>.* 103 | $ else: 104 | $ bar -= 1 105 | some_tuple=( 1,2, 3,'a' ); 106 | if bar : bar+=1; bar=bar* bar 107 | else: 108 | bar -= 1 109 | @end 110 | 111 | It didn't pass the --range arg this time. Notice that it also only output part 112 | of the file, because this time only the range being formatted was passed to it 113 | (in this case, just line 3). This fallback range formatting behavior isn't 114 | perfect, but it does okay for most ranges. 115 | -------------------------------------------------------------------------------- /vroom/black.vroom: -------------------------------------------------------------------------------- 1 | The built-in black formatter knows how to format python code. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | 18 | The black formatter expects the black executable to be installed on your 19 | system. 20 | 21 | % f() 22 | :FormatCode black 23 | ! black .* 24 | $ f() 25 | 26 | The name or path of the black executable can be configured via the 27 | black_executable flag if the default of "black" doesn't work. 28 | 29 | :Glaive codefmt black_executable='blackpy3' 30 | :FormatCode black 31 | ! blackpy3 .* 32 | $ f() 33 | :Glaive codefmt black_executable='black' 34 | 35 | 36 | You can format any buffer with black specifying the formatter explicitly. 37 | Here's an example: 38 | 39 | @clear 40 | % if True: pass 41 | 42 | :FormatCode black 43 | ! black .* 44 | $ if True: 45 | $ pass 46 | if True: 47 | pass 48 | @end 49 | 50 | Here's a second example: 51 | 52 | @clear 53 | % some_tuple=( 1,2, 3,'a' ); 54 | |if bar : bar+=1; bar=bar* bar 55 | |else: bar-=1; 56 | 57 | :FormatCode black 58 | ! black .* 59 | $ some_tuple = (1, 2, 3, "a"); 60 | $ if bar: 61 | $ bar += 1 62 | $ bar = bar * bar 63 | $ else: 64 | $ bar -= 1 65 | some_tuple = (1, 2, 3, "a"); 66 | if bar: 67 | bar += 1 68 | bar = bar * bar 69 | else: 70 | bar -= 1 71 | @end 72 | -------------------------------------------------------------------------------- /vroom/buildifier.vroom: -------------------------------------------------------------------------------- 1 | The built-in buildifier formatter knows how to format Bazel BUILD and .bzl 2 | files. If you aren't familiar with basic codefmt usage yet, see main.vroom 3 | first. 4 | 5 | We'll set up codefmt and configure the vroom environment, then jump into some 6 | examples. 7 | 8 | :source $VROOMDIR/setupvroom.vim 9 | 10 | :let g:repeat_calls = [] 11 | :function FakeRepeat(...) 12 | | call add(g:repeat_calls, a:000) 13 | :endfunction 14 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 15 | 16 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 17 | 18 | 19 | The buildifier formatter expects the buildifier executable to be installed on 20 | your system. 21 | 22 | % foo_library(name = "foo", srcs = ["bar.js"],) 23 | :FormatCode buildifier 24 | ! buildifier .* 25 | $ foo_library( 26 | $ name = "foo", 27 | $ srcs = ["bar.js"], 28 | $ ) 29 | 30 | The name or path of the buildifier executable can be configured via the 31 | buildifier_executable flag if the default of "buildifier" doesn't work. 32 | 33 | :Glaive codefmt buildifier_executable='mybuildifier' 34 | :FormatCode buildifier 35 | ! mybuildifier .* 36 | $ foo_library( 37 | $ name = "foo", 38 | $ srcs = ["bar.js"], 39 | $ ) 40 | :Glaive codefmt buildifier_executable='buildifier' 41 | 42 | The bzl filetype will use the buildifier formatter by default. The path to the 43 | file being edited is passed to buildifier so that it can adjust to whether the 44 | file is a BUILD or .bzl file. 45 | 46 | @clear 47 | % foo_library(name = "foo", srcs = ["bar.js"],) 48 | 49 | :silent file /foo/bar/BUILD 50 | :set filetype=bzl 51 | :FormatCode 52 | ! buildifier -path /foo/bar/BUILD .* 53 | $ foo_library( 54 | $ name = "foo", 55 | $ srcs = ["bar.js"], 56 | $ ) 57 | 58 | :set filetype= 59 | 60 | Errors are reported using the quickfix list. 61 | 62 | @clear 63 | % # 64 | % java_package(]) 65 | 66 | :FormatCode buildifier 67 | ! buildifier .*2> (.*) 68 | $ echo 'stdin:2:15: syntax error near ]' >\1 (command) 69 | $ 1 (status) 70 | ~ (1 of 1): syntax error near ] 71 | # 72 | java_package(]) 73 | @end 74 | :echomsg line('.') . ',' . col('.') 75 | ~ 2,15 76 | :echomsg string(map(getqflist(), 77 | |'v:val.lnum . "," . v:val.col . "," . v:val.text')) 78 | ~ ['2,15,syntax error near ]'] 79 | 80 | Note that if the file's path was passed to buildifier, error reports are in a 81 | slightly different format, prefixed with the filename we passed. 82 | 83 | @clear 84 | :silent file /foo/bar/BUILD 85 | :set filetype=bzl 86 | % load() 87 | 88 | :call cursor(1, 1) 89 | :FormatCode 90 | ! buildifier .*2> (.*) 91 | $ echo '/foo/bar/BUILD:1:7: syntax error near )' >\1 (command) 92 | $ 1 (status) 93 | ~ (1 of 1): syntax error near ) 94 | load() 95 | @end 96 | 97 | We'll be on column 6 because there's no column 7. (Buildifier appears to always 98 | report one column past the actual error.) 99 | 100 | :echomsg line('.') . ',' . col('.') 101 | ~ 1,6 102 | :echomsg string(map(getqflist(), 103 | |'v:val.lnum . "," . v:val.col . "," . v:val.text')) 104 | ~ ['1,7,syntax error near )'] 105 | 106 | If there are no errors, then the quickfix list is (currently, see 107 | https://github.com/google/vim-codefmt/issues/58) left alone: 108 | 109 | @clear 110 | :silent file /foo/bar/BUILD 111 | :set filetype=bzl 112 | % load('@io_bazel_rules_go//proto:def.bzl','go_proto_library') 113 | :call cursor(1, 1) 114 | 115 | :FormatCode 116 | ! buildifier -path /foo/bar/BUILD .* 117 | $ load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") 118 | 119 | :echomsg line('.') . ',' . col('.') 120 | ~ 1,1 121 | :echomsg len(getqflist()) 122 | ~ 1 123 | -------------------------------------------------------------------------------- /vroom/clangformat-cursor.vroom: -------------------------------------------------------------------------------- 1 | These examples demonstrate specific cursor positioning behavior related to the 2 | overall clang-format formatting demonstrated in clangformat.vroom. See the 3 | examples in that file first if you're unfamiliar with formatting behavior. 4 | 5 | We'll set up codefmt and configure the vroom environment, then jump into some 6 | examples. 7 | 8 | :source $VROOMDIR/setupvroom.vim 9 | 10 | :let g:repeat_calls = [] 11 | :function FakeRepeat(...) 12 | | call add(g:repeat_calls, a:000) 13 | :endfunction 14 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 15 | 16 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 17 | 18 | 19 | It will keep the cursor in the correct position when formatting code (assuming 20 | that clang-format has a version >= 3.4). 21 | 22 | :Glaive codefmt clang_format_executable='clang-format-3.3' 23 | % int f() { int i = 1; return 1234567890; } 24 | 25 | :FormatCode clang-format 26 | ! clang-format-3.3 --version .* 27 | $ clang-format version 3.3.0 (tags/testing) 28 | ! clang-format-3.3 -style file -lines 1:1 2>.* 29 | $ int f() { 30 | $ int i = 1; 31 | $ return 1234567890; 32 | $ } 33 | int f() { 34 | int i = 1; 35 | return 1234567890; 36 | } 37 | @end 38 | 39 | :Glaive codefmt clang_format_executable='clang-format' 40 | @clear 41 | % int f() { int i = 1; return 1234567890; } 42 | 43 | :goto 33 44 | :echomsg getline('.')[col('.')-1] 45 | ~ 5 46 | :FormatCode clang-format 47 | ! clang-format --version .* 48 | $ clang-format version 3.7.0 (tags/testing) 49 | ! clang-format -style file .* -cursor 32 .*2>.* 50 | $ { "Cursor": 36 } 51 | $ int f() { 52 | $ int i = 1; 53 | $ return 1234567890; 54 | $ } 55 | :echomsg getline('.')[col('.')-1] 56 | ~ 5 57 | 58 | Some vim builds that support textprops had a bug with determining cursor 59 | position (see https://github.com/vim/vim/issues/5930), but codefmt's cursor 60 | positioning should still maintain cursor position correctly for those cases. 61 | 62 | Note: The following test scenario will skip the relevant textprops setup and run 63 | harmlessly without doing any interesting verification in vim versions that don't 64 | support textprops. 65 | 66 | @clear 67 | :function PlaceTextpropIfSupported(lnum, col, length) abort 68 | | if !has('textprops') 69 | | return 70 | | endif 71 | | call prop_type_add('keyword', {}) 72 | | call prop_add(a:lnum, a:col, {'length': a:length, 'type': 'keyword'}) 73 | |endfunction 74 | % int f() { 75 | | int i=1; 76 | | return 1234567890; } 77 | :call PlaceTextpropIfSupported(1, 1, 3) 78 | :call cursor(2, 10) 79 | :echomsg getline('.')[col('.')-1] 80 | ~ = 81 | :FormatCode clang-format 82 | ! clang-format -style file .* -cursor 23 .*2>.* 83 | $ { "Cursor": 18 } 84 | $ int f() { 85 | $ int i = 1; 86 | $ return 1234567890; 87 | $ } 88 | :echomsg getline('.')[col('.')-1] 89 | ~ = 90 | 91 | -------------------------------------------------------------------------------- /vroom/clangformat.vroom: -------------------------------------------------------------------------------- 1 | The built-in clang-format formatter knows how to format code for C/C++ and many 2 | C-like languages. 3 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 4 | 5 | We'll set up codefmt and configure the vroom environment, then jump into some 6 | examples. If you haven't seen the setup code below yet, read through main.vroom 7 | briefly. 8 | 9 | :source $VROOMDIR/setupvroom.vim 10 | 11 | :let g:repeat_calls = [] 12 | :function FakeRepeat(...) 13 | | call add(g:repeat_calls, a:000) 14 | :endfunction 15 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 16 | 17 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 18 | 19 | 20 | The clang-format formatter expects the clang-format executable to be installed 21 | on your system. 22 | 23 | % f(); 24 | :FormatCode clang-format 25 | ! clang-format --version .* 26 | $ clang-format version 3.7.0 (tags/testing) 27 | ! clang-format .* 28 | $ { "Cursor": 0 } 29 | $ f(); 30 | 31 | Notice the "clang-format --version" syscall. The clang-format formatter checks 32 | the version of the clang-format executable to detect what features it supports. 33 | It caches the result, so it only does this once per vim session. We'll take a 34 | closer look at that below. 35 | 36 | Any time this flag is changed, the cached version is invalidated and checked 37 | fresh on the next format invocation. The name or path of the clang-format 38 | executable can be configured via the clang_format_executable flag if the 39 | default of "clang-format" doesn't work. 40 | 41 | :Glaive codefmt clang_format_executable='clang-format-3.9' 42 | :FormatCode clang-format 43 | ! clang-format-3.9 --version .* 44 | $ clang-format version 3.9.0 (tags/testing) 45 | ! clang-format-3.9 .* 46 | $ { "Cursor": 0 } 47 | $ f(); 48 | :Glaive codefmt clang_format_executable='clang-format' 49 | :FormatCode clang-format 50 | ! clang-format --version .* 51 | $ clang-format version 3.9.0 (tags/testing) 52 | ! clang-format .* 53 | $ { "Cursor": 0 } 54 | $ f(); 55 | 56 | 57 | You can format any buffer with clang-format specifying the formatter explicitly. 58 | 59 | @clear 60 | % void f() {int i; SomeFunction(parameter,// comment 61 | |i);} 62 | 63 | :FormatCode clang-format 64 | ! clang-format -style file .*2>.* 65 | $ { "Cursor": 0 } 66 | $ void f() { 67 | $ int i; 68 | $ SomeFunction(parameter, // comment 69 | $ i); 70 | $ } 71 | void f() { 72 | int i; 73 | SomeFunction(parameter, // comment 74 | i); 75 | } 76 | @end 77 | 78 | Several filetypes will use the clang-format formatter by default: c, cpp, and 79 | proto. 80 | 81 | @clear 82 | % f(); 83 | 84 | :set filetype=cpp 85 | :FormatCode 86 | ! clang-format .* 87 | $ { "Cursor": 0 } 88 | $ f(); 89 | 90 | :set filetype=proto 91 | :FormatCode 92 | ! clang-format .* 93 | $ { "Cursor": 0 } 94 | $ f(); 95 | 96 | It will also format javascript and java, but is not necessarily the default if 97 | other formatters are available. 98 | Note: Formatting java requires clang-format >= 3.6. 99 | 100 | :set filetype=javascript 101 | :FormatCode clang-format 102 | ! clang-format .* 103 | $ { "Cursor": 0 } 104 | $ f(); 105 | 106 | :set filetype=java 107 | :FormatCode clang-format 108 | ! clang-format .* 109 | $ { "Cursor": 0 } 110 | $ f(); 111 | 112 | :set filetype= 113 | 114 | It can format specific line ranges of code using :FormatLines. 115 | 116 | @clear 117 | % void f() { 118 | | int i = 2+2; 119 | | int i = 3+3; 120 | | int i = 4+4; 121 | |} 122 | 123 | :3,4FormatLines clang-format 124 | ! clang-format -style file -lines 3:4 .*2>.* 125 | $ { "Cursor": 0 } 126 | $ void f() { 127 | $ int i = 2+2; 128 | $ int i = 3 + 3; 129 | $ int i = 4 + 4; 130 | $ } 131 | void f() { 132 | int i = 2+2; 133 | int i = 3 + 3; 134 | int i = 4 + 4; 135 | } 136 | @end 137 | 138 | Note this will usually maintain cursor position correctly even when the code 139 | under the cursor moves. See clangformat-cursor.vroom for examples. 140 | 141 | You might have wondered where the "-style file" above comes from. The 142 | clang-format tool accepts a "style" option to control the formatting style. By 143 | default, "file" is used to indicate that clang-format should respect 144 | configuration in a .clang-format file in the project directory. You can control 145 | how style is selected via the clang_format_style flag. This flag accepts either 146 | a string value to use everywhere... 147 | 148 | :Glaive codefmt clang_format_style='WebKit' 149 | 150 | @clear 151 | % f(); 152 | :FormatCode clang-format 153 | ! clang-format -style WebKit .*2>.* 154 | $ { "Cursor": 0 } 155 | $ f(); 156 | 157 | ...or a callable that takes no arguments and returns a string style name for the 158 | current buffer. 159 | 160 | :function MaybeWebkitStyle() 161 | | if stridx(expand('%:p'), '/WebKit/') != -1 162 | | return 'WebKit' 163 | | endif 164 | | return 'file' 165 | |endfunction 166 | :Glaive codefmt clang_format_style=`function('MaybeWebkitStyle')` 167 | 168 | :silent file /foo/WebKit/foo.cc 169 | :FormatCode clang-format 170 | ! clang-format -style WebKit -assume-filename .*foo.cc .*2>.* 171 | $ { "Cursor": 0 } 172 | $ f(); 173 | 174 | :silent file /foo/foo.cc 175 | :FormatCode clang-format 176 | ! clang-format -style file -assume-filename .*foo.cc .*2>.* 177 | $ { "Cursor": 0 } 178 | $ f(); 179 | 180 | :Glaive codefmt clang_format_style='file' 181 | 182 | The -assume-filename arg passed above is also related, used by the clang-format 183 | tool to detect any custom style rules particular to the current file. 184 | 185 | 186 | Bug #102. When the buffer is empty, clang-format does _not_ return a cursor 187 | position 188 | 189 | @clear 190 | :FormatCode clang-format 191 | -------------------------------------------------------------------------------- /vroom/cljstyle.vroom: -------------------------------------------------------------------------------- 1 | The cljstyle formatter knows how to format Clojure. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | The cljstyle formatter expects the cljstyle executable to be installed on your 18 | system. 19 | 20 | :FormatCode cljstyle 21 | ! cljstyle .* 22 | $ no-op 23 | 24 | The name or path of the cljstyle executable can be configured via the 25 | cljstyle_executable flag if the default of "cljstyle" doesn't work. 26 | 27 | :Glaive codefmt cljstyle_executable='/usr/local/bin/cljstyle' 28 | :FormatCode cljstyle 29 | ! /usr/local/bin/cljstyle .* 30 | $ no-op 31 | :Glaive codefmt cljstyle_executable='cljstyle' 32 | 33 | You can format an entire buffer with :FormatCode. 34 | 35 | @clear 36 | % (defn x [] (cond nil 1 :else 2)) 37 | |(defn y [] (cond nil 3 :else 4)) 38 | 39 | :FormatCode cljstyle 40 | ! cljstyle .* 41 | $ (defn x 42 | $ [] 43 | $ (cond nil 1 44 | $ :else 2)) 45 | $ (defn y 46 | $ [] 47 | $ (cond nil 3 48 | $ :else 4)) 49 | (defn x 50 | [] 51 | (cond nil 1 52 | :else 2)) 53 | (defn y 54 | [] 55 | (cond nil 3 56 | :else 4)) 57 | @end 58 | 59 | Formatting a specific line range is not supported. 60 | -------------------------------------------------------------------------------- /vroom/dartfmt.vroom: -------------------------------------------------------------------------------- 1 | The built-in dartfmt formatter knows how to format dart code. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | The dart formatter expects the dart executable to be installed on your 18 | system. 19 | 20 | % main(){} 21 | :FormatCode dartfmt 22 | ! dart format .* 23 | $ main(){} 24 | 25 | The name, path, or list of the dart format command can be configured via the 26 | dartfmt_executable flag if the default of ["dart", "format"] doesn't work. 27 | 28 | :Glaive codefmt dartfmt_executable='dartfmt' 29 | :FormatCode dartfmt 30 | ! dartfmt .* 31 | $ main(){} 32 | :Glaive codefmt dartfmt_executable=`['dart', 'format']` 33 | 34 | You can format any buffer with dart format specifying the formatter explicitly. 35 | 36 | @clear 37 | % main() { print("hello "); 38 | |print("world\n");} 39 | 40 | :FormatCode dartfmt 41 | ! dart format .*2>.* 42 | $ main() { 43 | $ \tprint("hello "); 44 | $ \tprint("world\\n"); 45 | $ } 46 | main() { 47 | print("hello "); 48 | print("world\n"); 49 | } 50 | @end 51 | 52 | The dart filetype will use the dart formatter by default. 53 | 54 | @clear 55 | % main(){} 56 | 57 | :set filetype=dart 58 | :FormatCode 59 | ! dart format .* 60 | $ main(){} 61 | 62 | :set filetype= 63 | 64 | It can format specific line ranges of code using :FormatLines. 65 | 66 | @clear 67 | % main () { 68 | |Print("hello "); Print("world\n");} 69 | 70 | :1,2FormatLines dartfmt 71 | ! dart format .*2>.* 72 | $ main() { 73 | $ \tprint("hello "); 74 | $ \tprint("world\\n"); 75 | $ } 76 | main() { 77 | print("hello "); 78 | print("world\n"); 79 | } 80 | @end 81 | 82 | NOTE: the dart formatter does not natively support range formatting, so there 83 | are certain limitations like not being able to format misaligned braces. 84 | -------------------------------------------------------------------------------- /vroom/extensions.vroom: -------------------------------------------------------------------------------- 1 | Codefmt can be extended to support new formatters, using maktaba's extension 2 | registry. 3 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 4 | 5 | First, we need to set up the vroom environment and install codefmt. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | Formatters are described as a dict that has certain fields defined, as 10 | described in the codefmt docs. 11 | 12 | :let formatter1 = {'name': 'formatter1'} 13 | :function formatter1.IsAvailable() 14 | | return 0 15 | |endfunction 16 | :function formatter1.AppliesToBuffer() 17 | | return 0 18 | |endfunction 19 | :function formatter1.Format() 20 | |endfunction 21 | :call maktaba#extension#GetRegistry('codefmt').AddExtension(formatter1) 22 | 23 | If a formatter name is recognized but the formatter isn't available (isn't 24 | configured or is missing dependencies), codefmt will print setup instructions 25 | for that formatter. 26 | 27 | :let fake_format = {'name': 'fake-format', 'setup_instructions': 'RTFM'} 28 | :function fake_format.IsAvailable() 29 | | return 0 30 | |endfunction 31 | :function fake_format.AppliesToBuffer() 32 | | return &filetype is# 'fake' 33 | |endfunction 34 | :function fake_format.Format() 35 | |endfunction 36 | :call maktaba#extension#GetRegistry('codefmt').AddExtension(fake_format) 37 | 38 | :FormatCode fake-format 39 | ~ Formatter "fake-format" is not available. Setup instructions: RTFM 40 | 41 | It will print a similar message if the default formatter for the buffer is not 42 | available. 43 | 44 | :silent file foo.fake 45 | :set filetype=fake 46 | :FormatCode 47 | ~ Formatter "fake-format" is not available. Setup instructions: RTFM 48 | 49 | If there are multiple formatters that apply to the current buffer but none of 50 | them are available, the message will show a line for each. 51 | 52 | :let fake_format2 = copy(fake_format) 53 | :let fake_format2.name = 'fake-format2' 54 | :let fake_format2.setup_instructions = 'LMGTFY' 55 | :call maktaba#extension#GetRegistry('codefmt').AddExtension(fake_format2) 56 | 57 | :FormatCode 58 | ~ Formatter "fake-format2" is not available. Setup instructions: LMGTFY 59 | ~ Formatter "fake-format" is not available. Setup instructions: RTFM 60 | 61 | If the extension is missing fields or doesn't have the right format functions, 62 | ERROR(BadValue) will be shouted to the user when the extension is registered 63 | (or, if codefmt hasn't yet been loaded, when codefmt is loaded). 64 | 65 | :let registry = maktaba#extension#GetRegistry('codefmt') 66 | :call registry.AddExtension({}) 67 | ~ ERROR(BadValue): a:formatter is missing fields: name, IsAvailable, 68 | | AppliesToBuffer 69 | :let formatter = deepcopy(formatter1) 70 | :unlet formatter.Format 71 | :call maktaba#extension#GetRegistry('codefmt').AddExtension(formatter) 72 | ~ ERROR(BadValue): Formatter formatter1 has no format functions. It must have 73 | | at least one of Format, FormatRange, FormatRanges 74 | -------------------------------------------------------------------------------- /vroom/fish_indent.vroom: -------------------------------------------------------------------------------- 1 | The built-in fish_indent knows how to format fish code. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | You can format any buffer with fish_indent specifying the formatter explicitly. 18 | 19 | @clear 20 | % if test 42 -eq $truth; echo '42 is truth'; else; 21 | | echo 'I do not know what to believe'; end 22 | 23 | :FormatCode fish_indent 24 | ! fish_indent .*2>.* 25 | $ if test 42 -eq $truth 26 | $ echo '42 is truth' 27 | $ else 28 | $ echo 'I do not know what to believe' 29 | $ end 30 | if test 42 -eq $truth 31 | echo '42 is truth' 32 | else 33 | echo 'I do not know what to believe' 34 | end 35 | @end 36 | 37 | The fish filetype will use the fish_indent formatter by default. 38 | 39 | @clear 40 | % function f; echo f; end 41 | 42 | :set filetype=fish 43 | :FormatCode 44 | ! fish_indent .*2>.* 45 | $ function f 46 | $ echo f 47 | $ end 48 | function f 49 | echo f 50 | end 51 | @end 52 | :set filetype= 53 | 54 | It can format specific line ranges of code using :FormatLines. 55 | 56 | @clear 57 | % function foo; echo "my name is:"; echo "foo"; end 58 | |function bar; echo "my name is:"; echo "bar"; end 59 | 60 | :1,2FormatLines fish_indent 61 | ! fish_indent .*2>.* 62 | $ function foo echo "my name is:" 63 | $ echo "my name is:" 64 | $ echo "foo" 65 | $ end 66 | $ function bar echo "my name is:"; echo "bar"; end 67 | function foo echo "my name is:" 68 | echo "my name is:" 69 | echo "foo" 70 | end 71 | function bar echo "my name is:"; echo "bar"; end 72 | @end 73 | 74 | Errors are reported. 75 | 76 | @clear 77 | % function f; 78 | :FormatCode fish_indent 79 | ! fish_indent .*2> (.*) 80 | $ echo test error >\1 (command) 81 | $ 1 (status) 82 | ~ Error formatting file:* (glob) 83 | ~ *test error* (glob) 84 | function f; 85 | @end 86 | 87 | The name or path of the fish_indent executable can be configured via the 88 | fish_indent_executable flag if the default of "fish_indent" doesn't work. 89 | 90 | @clear 91 | :Glaive codefmt fish_indent_executable='my_fish_indent' 92 | % function f; 93 | :FormatCode fish_indent 94 | ! my_fish_indent .* 95 | $ function f 96 | function f 97 | @end 98 | :Glaive codefmt fish_indent_executable='fish_indent' 99 | -------------------------------------------------------------------------------- /vroom/gn.vroom: -------------------------------------------------------------------------------- 1 | The built-in gn formatter knows how to format gn build files. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | 18 | The gn formatter expects the gn executable to be installed on your system. 19 | 20 | % buildconfig = "//build/config/BUILDCONFIG.gn" 21 | :FormatCode gn 22 | ! gn .* 23 | $ buildconfig = "//build/config/BUILDCONFIG.gn" 24 | 25 | The name or path of the gn executable can be configured via the 26 | gn_executable flag if the default of "gn" doesn't work. 27 | 28 | :Glaive codefmt gn_executable='mygn' 29 | :FormatCode gn 30 | ! mygn .* 31 | $ buildconfig = "//build/config/BUILDCONFIG.gn" 32 | :Glaive codefmt gn_executable='gn' 33 | 34 | 35 | You can format any buffer with gn specifying the formatter explicitly. 36 | 37 | @clear 38 | % executable("hello") { sources = ["hello.c"] } 39 | :FormatCode gn 40 | ! gn format --stdin .*2>.* 41 | $ executable("hello") { 42 | $ sources = [ 43 | $ "hello.c", 44 | $ ] 45 | $ } 46 | executable("hello") { 47 | sources = [ 48 | "hello.c", 49 | ] 50 | } 51 | @end 52 | 53 | The gn filetype will use the gn formatter by default. 54 | 55 | @clear 56 | % buildconfig = "//build/config/BUILDCONFIG.gn" 57 | 58 | :set filetype=gn 59 | :FormatCode 60 | ! gn .* 61 | $ buildconfig = "//build/config/BUILDCONFIG.gn" 62 | 63 | :set filetype= 64 | -------------------------------------------------------------------------------- /vroom/gofmt.vroom: -------------------------------------------------------------------------------- 1 | The built-in gofmt formatter knows how to format go code. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | 18 | The gofmt formatter expects the gofmt executable to be installed on your system. 19 | 20 | % f() 21 | :FormatCode gofmt 22 | ! gofmt .* 23 | $ f() 24 | 25 | The name or path of the gofmt executable can be configured via the 26 | gofmt_executable flag if the default of "gofmt" doesn't work. 27 | 28 | :Glaive codefmt gofmt_executable='mygofmt' 29 | :FormatCode gofmt 30 | ! mygofmt .* 31 | $ f() 32 | :Glaive codefmt gofmt_executable='gofmt' 33 | 34 | 35 | You can format any buffer with gofmt specifying the formatter explicitly. 36 | 37 | @clear 38 | % package main;import "fmt" 39 | |func main() { fmt.Printf("hello ") 40 | |fmt.Printf("world\n") } 41 | 42 | :FormatCode gofmt 43 | ! gofmt .*2>.* 44 | $ package main 45 | $ 46 | $ import "fmt" 47 | $ 48 | $ func main() { 49 | $ \tfmt.Printf("hello ") 50 | $ \tfmt.Printf("world\\n") 51 | $ } 52 | package main 53 | & 54 | import "fmt" 55 | & 56 | func main() { 57 | fmt.Printf("hello ") 58 | fmt.Printf("world\n") 59 | } 60 | @end 61 | 62 | The go filetype will use the gofmt formatter by default. 63 | 64 | @clear 65 | % f() 66 | 67 | :set filetype=go 68 | :FormatCode 69 | ! gofmt .* 70 | $ f() 71 | 72 | :set filetype= 73 | 74 | It can format specific line ranges of code using :FormatLines. 75 | 76 | @clear 77 | % package main;import "fmt" 78 | |func main() { fmt.Printf("hello ") 79 | |fmt.Printf("world\n") } 80 | 81 | :2,3FormatLines gofmt 82 | ! gofmt .*2>.* 83 | $ func main() { 84 | $ \tfmt.Printf("hello ") 85 | $ \tfmt.Printf("world\\n") 86 | $ } 87 | package main;import "fmt" 88 | func main() { 89 | fmt.Printf("hello ") 90 | fmt.Printf("world\n") 91 | } 92 | @end 93 | 94 | NOTE: the gofmt formatter does not natively support range formatting, so there 95 | are certain limitations like not being able to format misaligned braces. 96 | 97 | 98 | 99 | You can also use goimports (or any other gofmt-like binary) to add imports as 100 | needed by setting the gofmt_executable flag: 101 | 102 | :Glaive codefmt gofmt_executable='goimports' 103 | % package main 104 | |func main() { fmt.Printf("hello world\n") } 105 | 106 | :FormatCode gofmt 107 | ! goimports .*2>.* 108 | $ package main 109 | $ 110 | $ import "fmt" 111 | $ 112 | $ func main() { fmt.Printf("hello world\\n") } 113 | package main 114 | & 115 | import "fmt" 116 | & 117 | func main() { fmt.Printf("hello world\n") } 118 | @end 119 | -------------------------------------------------------------------------------- /vroom/googlejava.vroom: -------------------------------------------------------------------------------- 1 | The built-in google-java formatter knows how to format Java files. If you 2 | aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | 18 | The google-java formatter expects a google-java executable to be installed on 19 | your system. 20 | 21 | % class Foo { public String getFoo() { return "bar"; } } 22 | :FormatCode google-java-format 23 | ! google-java-format .* 24 | $ class Foo { 25 | $ public String getFoo() { 26 | $ return "bar"; 27 | $ } 28 | $ } 29 | 30 | The name or path of the google-java executable can be configured via the 31 | google_java_executable flag if the default of "google-java" doesn't work. 32 | 33 | :Glaive codefmt google_java_executable='java -jar /path/to/google-java.jar' 34 | :FormatCode google-java-format 35 | ! java -jar /path/to/google-java.jar .* 36 | $ class Foo { 37 | $ public String getFoo() { 38 | $ return "bar"; 39 | $ } 40 | $ } 41 | :Glaive codefmt google_java_executable='google-java-format' 42 | 43 | The java filetype will use the clang formatter by default, so the default 44 | functionality is tested there. 45 | -------------------------------------------------------------------------------- /vroom/jsbeautify.vroom: -------------------------------------------------------------------------------- 1 | The built-in js-beautify formatter knows how to format javascript, json, html 2 | and css code. 3 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 4 | 5 | We'll set up codefmt and configure the vroom environment, then jump into some 6 | examples. 7 | 8 | :source $VROOMDIR/setupvroom.vim 9 | 10 | :let g:repeat_calls = [] 11 | :function FakeRepeat(...) 12 | | call add(g:repeat_calls, a:000) 13 | :endfunction 14 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 15 | 16 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 17 | 18 | 19 | The js-beautify formatter expects the js-beautify executable to be installed 20 | on your system. 21 | 22 | % f() 23 | :FormatCode js-beautify 24 | ! js-beautify .* 25 | $ f() 26 | 27 | The name or path of the js-beautify executable can be configured via the 28 | js_beautify_executable flag if the default of "js-beautify" doesn't work. 29 | 30 | :Glaive codefmt js_beautify_executable='myjsb' 31 | :FormatCode js-beautify 32 | ! myjsb .* 33 | $ f() 34 | :Glaive codefmt js_beautify_executable='js-beautify' 35 | 36 | 37 | You can format any buffer with js-beautify specifying the formatter explicitly. 38 | 39 | @clear 40 | % for (i = 0; i < max; i++) { 41 | |a=1234 + 5678 + i; b = 1234*5678+i; c=1234/2+i;} 42 | 43 | :FormatCode js-beautify 44 | ! js-beautify .*2>.* 45 | $ for (i = 0; i < max; i++) { 46 | $ a = 1234 + 5678 + i; 47 | $ b = 1234 * 5678 + i; 48 | $ c = 1234 / 2 + i; 49 | $ } 50 | for (i = 0; i < max; i++) { 51 | a = 1234 + 5678 + i; 52 | b = 1234 * 5678 + i; 53 | c = 1234 / 2 + i; 54 | } 55 | @end 56 | 57 | Several filetypes will use the js-beautify formatter by default: 58 | javascript, json, html and css. 59 | 60 | Note that javascript will currently be picked up by clang-format; 61 | here we specify js-beautify explicitly. 62 | # @TODO: fix default formatter for javascript 63 | 64 | @clear 65 | % f(); 66 | 67 | :set filetype=javascript 68 | :FormatCode js-beautify 69 | ! js-beautify -f - --type js 2>.* 70 | $ f(); 71 | 72 | :set filetype=json 73 | :FormatCode js-beautify 74 | ! js-beautify -f - --type js 2>.* 75 | $ f(); 76 | 77 | :set filetype=html 78 | :FormatCode js-beautify 79 | ! js-beautify -f - --type html 2>.* 80 | $ f(); 81 | 82 | :set filetype=css 83 | :FormatCode js-beautify 84 | ! js-beautify -f - --type css 2>.* 85 | $ f(); 86 | 87 | :set filetype=sass 88 | :FormatCode js-beautify 89 | ! js-beautify -f - --type css 2>.* 90 | $ f(); 91 | 92 | :set filetype=scss 93 | :FormatCode js-beautify 94 | ! js-beautify -f - --type css 2>.* 95 | $ f(); 96 | 97 | :set filetype=less 98 | :FormatCode js-beautify 99 | ! js-beautify -f - --type css 2>.* 100 | $ f(); 101 | 102 | :set filetype= 103 | 104 | 105 | It can format specific line ranges of code using :FormatLines. 106 | 107 | @clear 108 | % for (i = 0; i < max; i++) { 109 | |a=1234 + 5678 + i; b = 1234*5678+i; 110 | |c=1234/2+i;} 111 | 112 | :2,2FormatLines js-beautify 113 | ! js-beautify .*2>.* 114 | $ a = 1234 + 5678 + i; 115 | $ b = 1234 * 5678 + i; 116 | for (i = 0; i < max; i++) { 117 | a = 1234 + 5678 + i; 118 | b = 1234 * 5678 + i; 119 | c=1234/2+i;} 120 | @end 121 | 122 | NOTE: the js-beautify formatter does not natively support range formatting, 123 | so there are certain limitations like not being able to format misaligned 124 | braces. 125 | -------------------------------------------------------------------------------- /vroom/jsonnetfmt.vroom: -------------------------------------------------------------------------------- 1 | 2 | :source $VROOMDIR/setupvroom.vim 3 | 4 | :let g:repeat_calls = [] 5 | :function FakeRepeat(...) 6 | | call add(g:repeat_calls, a:000) 7 | :endfunction 8 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 9 | 10 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 11 | 12 | 13 | The jsonnetfmt formatter expects the jsonnetfmt executable to be installed on 14 | your system. 15 | 16 | % {foo:'bar'} 17 | :FormatCode jsonnetfmt 18 | ! jsonnetfmt .* 19 | $ { foo: 'foo' } 20 | 21 | 22 | The name or path of the jsonnetfmt executable can be configured via the 23 | jsonnetfmt_executable flag if the default of "jsonnetfmt" doesn't work. 24 | 25 | :Glaive codefmt jsonnetfmt_executable='myjsonnetfmt' 26 | :FormatCode jsonnetfmt 27 | ! myjsonnetfmt .* 28 | $ foo_library( 29 | $ name = "foo", 30 | $ srcs = ["bar.js"], 31 | $ ) 32 | :Glaive codefmt jsonnetfmt_executable='jsonnetfmt' 33 | 34 | -------------------------------------------------------------------------------- /vroom/juliaformatter.vroom: -------------------------------------------------------------------------------- 1 | The built-in JuliaFormatter formatter knows how to format Julia files. If you 2 | aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | 18 | The JuliaFormatter formatter uses the bin/julia/format.jl script which is 19 | bundled with codefmt. That script will return an error if Julia or the 20 | JuliaFormatter package are not installed. 21 | 22 | % module Foo bar(x) = x ? "yes" : "no" end 23 | :FormatCode JuliaFormatter 24 | ! .*/bin/julia/format.jl .* 25 | $ module Foo { 26 | $ function bar(x) 27 | $ if x 28 | $ "yes" 29 | $ else 30 | $ "no" 31 | $ end 32 | $ end 33 | $ end 34 | 35 | The name or path of the format.jl script can be configured via the 36 | julia_format_executable flag if the bundled format.jl doesn't work. 37 | 38 | :Glaive codefmt julia_format_executable='/path/to/myscript' 39 | :FormatCode JuliaFormatter 40 | ! /path/to/myscript .* 41 | $ module Foo 42 | $ function bar(x) 43 | $ if x 44 | $ "yes" 45 | $ else 46 | $ "no" 47 | $ end 48 | $ end 49 | $ end 50 | :let g:format_jl = maktaba#path#Join([expand("$VROOMDIR:h:h"), 'bin', 'julia', 'format.jl']) 51 | :Glaive codefmt julia_format_executable=`g:format_jl` 52 | 53 | It can format specific line ranges of code using :FormatLines. 54 | 55 | @clear 56 | % module Foo 57 | |function bar(x) 58 | |print(x ? "yes" : "no") 59 | |print( 60 | |x && 61 | |!x ? 62 | |"impossible" : 63 | |"ok") 64 | |end 65 | |end 66 | 67 | :4,8FormatLines JuliaFormatter 68 | ! .*/bin/julia/format.jl .*--lines 4:8.* 69 | $ module Foo { 70 | $ function bar(x) 71 | $ print(x ? "yes" : "no") 72 | $ print(if x && !x 73 | $ "impossible" 74 | $ else 75 | $ "ok" 76 | $ end) 77 | $ end 78 | $ end 79 | -------------------------------------------------------------------------------- /vroom/ktfmt.vroom: -------------------------------------------------------------------------------- 1 | The built-in ktfmt formatter knows how to format Kotlin files. If you aren't 2 | familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | 18 | The ktfmt formatter expects a ktfmt executable to be installed on your system, 19 | e.g. as a shell wrapper around "java -jar /path/to/ktfmt.jar".. 20 | 21 | % class Foo { public bar() : String { return "bar"; } } 22 | :FormatCode ktfmt 23 | ! ktfmt .* 24 | $ class Foo { 25 | $ public bar(): String { 26 | $ return "bar" 27 | $ } 28 | $ } 29 | 30 | The name or path of the ktfmt executable can be configured via the 31 | ktfmt_executable flag if the default of "ktmft" doesn't work. 32 | 33 | :Glaive codefmt ktfmt_executable=java,-jar,/path/to/ktfmt.jar 34 | :FormatCode ktfmt 35 | ! java -jar /path/to/ktfmt.jar .* 36 | $ class Foo { 37 | $ public bar(): String { 38 | $ return "bar" 39 | $ } 40 | $ } 41 | :Glaive codefmt ktfmt_executable='ktfmt' 42 | -------------------------------------------------------------------------------- /vroom/luaformatterfiveone.vroom: -------------------------------------------------------------------------------- 1 | luaformatterfiveone" formatter only knows how to format lua 5.1 code. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | 18 | luaformatterfiveone expects the lua formatterfiveone executable to be installed 19 | on your system. 20 | 21 | % function hello() 22 | % print("world") 23 | % end 24 | :FormatCode luaformatterfiveone 25 | ! luaformatterfiveone -i 2> .* 26 | $ function hello() 27 | $ print("world") 28 | $ end 29 | 30 | The name or path of the luaformatterfiveone executable can be configured via the 31 | luaformatterfiveone_executable flag if the default of "buildifier" doesn't work. 32 | 33 | :Glaive codefmt luaformatterfiveone_executable='myluaformatterfiveone' 34 | :FormatCode luaformatterfiveone 35 | ! myluaformatterfiveone -i 2> .* 36 | $ function hello() 37 | $ print("world") 38 | $ end 39 | :Glaive codefmt luaformatterfiveone_executable='luaformatterfiveone' 40 | 41 | Errors are reported using the quickfix list. 42 | 43 | @clear 44 | % 13() 45 | :FormatCode luaformatterfiveone 46 | ! luaformatterfiveone -i 2> (.*) 47 | $ 1 (status) 48 | $ echo >\1 ' (command) 49 | |luaformatterfiveone:Unable to format stdin:\n 50 | |[string "isCodeValid"]:1: unexpected symbol near '"'13'" 51 | ~ (1 of 1): unexpected symbol near '13' 52 | :echomsg line('.') . ',' . col('.') 53 | ~ 1,1 54 | :echomsg string(map(getqflist(), 'v:val.lnum . "," . v:val.text')) 55 | ~ ['1,unexpected symbol near ''13'''] 56 | 57 | -------------------------------------------------------------------------------- /vroom/main.vroom: -------------------------------------------------------------------------------- 1 | Vim is useful for editing source code and has some primitive features for 2 | formatting code. Most of these are based on error-prone heuristics and are 3 | better for getting close-enough formatting quickly as you edit, not for closely 4 | adhering to particular formatting guidelines. 5 | 6 | The utilities in codefmt hook vim up to high-quality external formatters like 7 | clang-format that you can trigger on-demand or when saving buffers. 8 | 9 | This file demonstrates the basics of codefmt usage. Other files in this 10 | directory cover various topics of codefmt usage: 11 | 12 | * autopep8.vroom - Configuring and using the built-in autopep8 formatter 13 | * clangformat.vroom - Configuring and using the built-in clang-format formatter 14 | * gofmt.vroom - Configuring and using the built-in gofmt formatter 15 | * yapf.vroom - Configuring and using the built-in yapf formatter 16 | * gn.vroom - Configuring and using the built-in gn formatter 17 | * autocmd.vroom - Automatic hooks like format-on-save 18 | * extensions.vroom - Adding additional formatters for codefmt to use 19 | 20 | In order for these tests to work, maktaba MUST be in the same parent directory 21 | as codefmt. Given that that's the case, all we have to do is source the 22 | setupvroom.vim file, which bootstraps the codefmt plugin and configures it to 23 | work properly under vroom. 24 | 25 | :source $VROOMDIR/setupvroom.vim 26 | 27 | 28 | It integrates with vim-repeat if available for improved repeating support. We'll 29 | stub that out for vroom. 30 | 31 | :let g:repeat_calls = [] 32 | :function FakeRepeat(...) 33 | | call add(g:repeat_calls, a:000) 34 | :endfunction 35 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 36 | 37 | We'll also stub it out to not care whether certain executables are installed on 38 | your system. 39 | 40 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 41 | 42 | 43 | This plugin defines a :FormatCode command that can be used to reformat buffers. 44 | 45 | % void f() {int i; SomeFunction(parameter,// comment 46 | |i);} 47 | 48 | :FormatCode clang-format 49 | ! clang-format --version .* 50 | $ clang-format version 3.3.0 (tags/testing) 51 | ! clang-format .* 52 | $ void f() { 53 | $ int i; 54 | $ SomeFunction(parameter, // comment 55 | $ i); 56 | $ } 57 | void f() { 58 | int i; 59 | SomeFunction(parameter, // comment 60 | i); 61 | } 62 | @end 63 | 64 | 65 | 66 | To format specific line ranges of C++ code using clang-format, use :FormatLines. 67 | 68 | % void f() { 69 | | int i = 2+2; 70 | | int i = 3+3; 71 | | int i = 4+4; 72 | |} 73 | 74 | :let g:repeat_calls = [] 75 | 76 | :3,4FormatLines clang-format 77 | ! clang-format .* -lines 3:4.* 78 | $ void f() { 79 | $ int i = 2+2; 80 | $ int i = 3 + 3; 81 | $ int i = 4 + 4; 82 | $ } 83 | void f() { 84 | int i = 2+2; 85 | int i = 3 + 3; 86 | int i = 4 + 4; 87 | } 88 | @end 89 | 90 | It calls repeat#set to configure the repeat mapping (the "." mapping) to format 91 | the same number of lines again. 92 | 93 | :echomsg string(g:repeat_calls) 94 | ~ [[':FormatLines clang-format^M', 2]] 95 | 96 | 97 | 98 | Even when the text under the cursor moves, formatting preserves the literal 99 | cursor position (except in formatter implementations that can intelligently 100 | preserve logical position; see examples in vroom/clangformat-cursor.vroom). 101 | 102 | % void f() {int i; 103 | |SomeFunction(); 104 | |} 105 | 106 | :call cursor(2, 5) 107 | :FormatCode clang-format 108 | ! clang-format .* 109 | $ void f() { 110 | $ int i; 111 | $ SomeFunction(); 112 | $ } 113 | void f() { 114 | int i; 115 | SomeFunction(); 116 | } 117 | @end 118 | 119 | In this case the cursor is still at position (2, 5), which is no longer over the 120 | F in SomeFunction. 121 | 122 | :echomsg line('.') . ',' . col('.') 123 | ~ 2,5 124 | 125 | 126 | 127 | The examples above pass an explicit formatter argument to :FormatCode and 128 | :FormatLines to select which formatter to use. In day-to-day editing, that would 129 | get old pretty fast, and you'd probably be invoking it through key mappings that 130 | won't take arguments, anyway. For several filetypes, codefmt selects an 131 | appropriate formatter by default. For instance, the built-in gofmt formatter 132 | will be used by default for the go filetype. 133 | 134 | @clear 135 | % f() 136 | :set filetype=go 137 | :FormatCode 138 | ! gofmt .* 139 | $ f() 140 | 141 | This will correctly detect compound dot-separated filetypes (see vim's 142 | `:help 'filetype'`), so gofmt will still be used for "go.otherft": 143 | 144 | @clear 145 | % f() 146 | :set filetype=go.otherft 147 | :FormatCode 148 | ! gofmt .* 149 | $ f() 150 | 151 | (Be aware though that the order of dotted filetypes doesn't affect which 152 | formatter wins if the multiple filetypes each have their own formatter, so in 153 | that case you may need to explicitly choose one instead of relying on defaults.) 154 | 155 | You can also configure which formatter to use on a buffer-by-buffer basis via 156 | b:codefmt_formatter, which will take precedence over the built-in defaulting. 157 | 158 | :let b:codefmt_formatter = 'clang-format' 159 | :FormatCode 160 | ! clang-format .* 161 | $ f() 162 | :unlet b:codefmt_formatter 163 | 164 | If no default formatter is available for a buffer, you'll just see an error. 165 | 166 | :set filetype= 167 | :FormatCode 168 | ~ Not available. codefmt doesn't have a default formatter for this buffer. 169 | 170 | Similarly, you'll see an error if an explicit formatter name isn't recognized. 171 | 172 | :FormatCode nonexistentformatter 173 | ~ "nonexistentformatter" is not a supported formatter. 174 | -------------------------------------------------------------------------------- /vroom/mixformat.vroom: -------------------------------------------------------------------------------- 1 | 2 | The built-in mixformat formatter knows how to format Elixir code. 3 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 4 | 5 | We'll set up codefmt and configure the vroom environment, then jump into some 6 | examples. 7 | 8 | :source $VROOMDIR/setupvroom.vim 9 | 10 | :let g:repeat_calls = [] 11 | :function FakeRepeat(...) 12 | | call add(g:repeat_calls, a:000) 13 | :endfunction 14 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 15 | 16 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 17 | 18 | 19 | The mixformat formatter expects the mix executable to be installed on your 20 | system. 21 | 22 | % IO.puts("Hello world") 23 | :FormatCode mixformat 24 | ! cd .* && mix format .* - 2>.* 25 | $ IO.puts("Hello world") 26 | 27 | The name or path of the mixformat executable can be configured via the 28 | mix_executable flag if the default of "mix" doesn't work. 29 | 30 | :Glaive codefmt mix_executable='someothermix' 31 | :FormatCode mixformat 32 | ! cd .* && someothermix format .* - 2>.* 33 | $ IO.puts("Hello world") 34 | :Glaive codefmt mix_executable='mix' 35 | 36 | 37 | You can format any buffer with mixformat specifying the formatter explicitly. 38 | 39 | @clear 40 | % def foo() do 41 | |IO.puts("Hello"); IO.puts("World"); 42 | |end 43 | 44 | :FormatCode mixformat 45 | ! cd .* && mix format .* - 2>.* 46 | $ def foo() do 47 | $ IO.puts("Hello") 48 | $ IO.puts("World") 49 | $ end 50 | def foo() do 51 | IO.puts("Hello") 52 | IO.puts("World") 53 | end 54 | @end 55 | 56 | The elixir, eelixer, and heex filetypes will use the mixformat formatter 57 | by default. 58 | 59 | @clear 60 | % IO.puts("Hello world") 61 | 62 | :set filetype=elixir 63 | :FormatCode 64 | ! cd .* && mix format .* - 2>.* 65 | $ IO.puts("Hello world") 66 | 67 | :set filetype=eelixir 68 | :FormatCode 69 | ! cd .* && mix format .* - 2>.* 70 | $ IO.puts("Hello world") 71 | 72 | :set filetype=heex 73 | :FormatCode 74 | ! cd .* && mix format .* - 2>.* 75 | $ IO.puts("Hello world") 76 | 77 | :set filetype= 78 | 79 | It can format specific line ranges of code using :FormatLines. 80 | 81 | @clear 82 | % defmodule Foo do 83 | |def bar(list) do 84 | |[head | tail] = list; IO.puts(head) 85 | |end 86 | |end 87 | 88 | :2,4FormatLines mixformat 89 | ! cd .* && mix format .* - 2>.* 90 | $ def bar(list) do 91 | $ [head | tail] = list 92 | $ IO.puts(head) 93 | $ end 94 | defmodule Foo do 95 | def bar(list) do 96 | [head | tail] = list 97 | IO.puts(head) 98 | end 99 | end 100 | @end 101 | 102 | NOTE: the mix formatter does not natively support range formatting, so there 103 | are certain limitations like misaligning indentation levels. 104 | -------------------------------------------------------------------------------- /vroom/nixpkgs_fmt.vroom: -------------------------------------------------------------------------------- 1 | The built-in nixpkgs-fmt formatter knows how to format Nix code. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | 18 | The nixpkgs-fmt formatter expects the nixpkgs-fmt executable to be installed on 19 | your system. 20 | 21 | % f() 22 | :FormatCode nixpkgs-fmt 23 | ! nixpkgs-fmt .* 24 | $ f() 25 | 26 | The name or path of the nixpkgs-fmt executable can be configured via the 27 | nixpkgs_fmt_executable flag if the default of "nixpkgs-fmt" doesn't work. 28 | 29 | :Glaive codefmt nixpkgs_fmt_executable='nixpkgsfmt' 30 | :FormatCode nixpkgs-fmt 31 | ! nixpkgsfmt .* 32 | $ f() 33 | :Glaive codefmt nixpkgs_fmt_executable='nixpkgs-fmt' 34 | 35 | 36 | You can format any buffer with nixpkgs-fmt specifying the formatter explicitly. 37 | Here's an example: 38 | 39 | @clear 40 | % { foo = "bar" ;} 41 | 42 | :FormatCode nixpkgs-fmt 43 | ! nixpkgs-fmt .* 44 | $ { 45 | $ foo = "bar"; 46 | $ } 47 | { 48 | foo = "bar"; 49 | } 50 | @end 51 | -------------------------------------------------------------------------------- /vroom/ocamlformat.vroom: -------------------------------------------------------------------------------- 1 | The ocamlformat formatter knows how to format OCaml. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | 18 | The ocamlformat formatter expects the ocamlformat executable to be installed 19 | on your system. 20 | 21 | % f() 22 | :FormatCode ocamlformat 23 | ! ocamlformat --impl - .*2>.* 24 | $ f() 25 | 26 | The name or path of the ocamlformat executable can be configured via the 27 | ocamlformat_executable flag if the default of "ocamlformat" doesn't work. 28 | 29 | :Glaive codefmt ocamlformat_executable='myocamlformat' 30 | :FormatCode ocamlformat 31 | ! myocamlformat --impl - .*2>.* 32 | $ f() 33 | :Glaive codefmt ocamlformat_executable='ocamlformat' 34 | 35 | You can format any buffer with ocamlformat specifying the formatter explicitly. 36 | 37 | @clear 38 | % open Base 39 | | 40 | | open Stdio 41 | | 42 | | let build_count chan=In_channel.fold_lines chan 43 | | ~init:[] 44 | | ~f: 45 | | (fun counts line -> 46 | | let count = match List.Assoc.find ~equal:String.equal counts line with 47 | | | None -> 0 48 | | | Some x -> x 49 | | in List.Assoc.add ~equal:String.equal counts line ( count + 1 ) 50 | | ) 51 | 52 | :FormatCode ocamlformat 53 | ! ocamlformat --impl - .*2>.* 54 | $ open Base 55 | $ open Stdio 56 | $ 57 | $ let build_count chan = 58 | $ In_channel.fold_lines chan ~init:[] ~f:(fun counts line -> 59 | $ let count = 60 | $ match List.Assoc.find ~equal:String.equal counts line with 61 | $ | None -> 0 62 | $ | Some x -> x 63 | $ in 64 | $ List.Assoc.add ~equal:String.equal counts line (count + 1)) 65 | open Base 66 | open Stdio 67 | 68 | let build_count chan = 69 | In_channel.fold_lines chan ~init:[] ~f:(fun counts line -> 70 | let count = 71 | match List.Assoc.find ~equal:String.equal counts line with 72 | | None -> 0 73 | | Some x -> x 74 | in 75 | List.Assoc.add ~equal:String.equal counts line (count + 1)) 76 | @end 77 | -------------------------------------------------------------------------------- /vroom/ormolu.vroom: -------------------------------------------------------------------------------- 1 | The ormolu formatter knows how to format Haskell. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | 18 | The ormolu formatter expects the ormolu executable to be installed 19 | on your system. 20 | 21 | % f() 22 | :FormatCode ormolu 23 | ! ormolu .* 24 | $ f() 25 | 26 | The name or path of the ormolu executable can be configured via the 27 | ormolu_executable flag if the default of "ormolu" doesn't work. 28 | 29 | :Glaive codefmt ormolu_executable='myormolu' 30 | :FormatCode ormolu 31 | ! myormolu .* 32 | $ f() 33 | :Glaive codefmt ormolu_executable='ormolu' 34 | 35 | You can format any buffer with ormolu specifying the formatter explicitly. 36 | 37 | @clear 38 | % module Main 39 | | 40 | | where 41 | | 42 | |main:: IO () 43 | | 44 | | 45 | |{- this is just a comment -} 46 | |main =pure () 47 | | 48 | |foo :: Int 49 | |foo = 50 | | 5 51 | | + 5 52 | | 53 | |bar :: Int 54 | | bar = 7 55 | 56 | :FormatCode ormolu 57 | ! ormolu .*2>.* 58 | $ module Main where 59 | $ 60 | $ main :: IO () 61 | $ {- this is just a comment -} 62 | $ main = pure () 63 | $ 64 | $ foo :: Int 65 | $ foo = 66 | $ 5 67 | $ + 5 68 | $ 69 | $ bar :: Int 70 | $ bar = 7 71 | module Main where 72 | 73 | main :: IO () 74 | {- this is just a comment -} 75 | main = pure () 76 | 77 | foo :: Int 78 | foo = 79 | 5 80 | + 5 81 | 82 | bar :: Int 83 | bar = 7 84 | @end 85 | 86 | It can format specific line ranges of code using :FormatLines. 87 | 88 | @clear 89 | % module Main (main) where 90 | | 91 | |main :: IO () 92 | |{- this is just a comment -} 93 | |main = pure () 94 | | 95 | |foo :: Int 96 | |foo = 97 | | 5 98 | | + 5 99 | | 100 | |bar :: Int 101 | | bar = 7 102 | 103 | :1,5FormatLines ormolu 104 | ! ormolu .*2>.* 105 | $ module Main (main) where 106 | $ 107 | $ main :: IO () 108 | $ {- this is just a comment -} 109 | $ main = pure () 110 | $ 111 | $ foo :: Int 112 | $ foo = 113 | $ 5 114 | $ + 5 115 | $ 116 | $ bar :: Int 117 | $ bar = 7 118 | module Main (main) where 119 | 120 | main :: IO () 121 | {- this is just a comment -} 122 | main = pure () 123 | 124 | foo :: Int 125 | foo = 126 | 5 127 | + 5 128 | 129 | bar :: Int 130 | bar = 7 131 | @end 132 | -------------------------------------------------------------------------------- /vroom/prettier.vroom: -------------------------------------------------------------------------------- 1 | The prettier formatter knows how to format JavaScript. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | The default value of prettier_executable is a function that checks if npx is 18 | available. We need a deterministic result for these tests, so we'll replace that 19 | with a simple string. 20 | 21 | :Glaive codefmt prettier_executable='prettier' 22 | 23 | The prettier formatter expects the prettier executable to be installed on your 24 | system. 25 | 26 | % function HelloWorld(){if(!greeting){return null};} 27 | :FormatCode prettier 28 | ! cd .* prettier .*--parser babel.* 29 | $ function HelloWorld() { 30 | $ if (!greeting) { 31 | $ return null; 32 | $ } 33 | $ } 34 | 35 | The name or path of the prettier executable can be configured via the 36 | prettier_executable flag if the default of "prettier" doesn't work. 37 | 38 | :Glaive codefmt prettier_executable='myprettier' 39 | :FormatCode prettier 40 | ! cd .* myprettier .* 41 | $ function HelloWorld() { 42 | $ if (!greeting) { 43 | $ return null; 44 | $ } 45 | $ } 46 | :Glaive codefmt prettier_executable='prettier' 47 | 48 | 49 | You can format any buffer with prettier specifying the formatter explicitly. 50 | 51 | @clear 52 | % function HelloWorld(){if(!greeting){return null};} 53 | 54 | :FormatCode prettier 55 | ! cd .* prettier .*2>.* 56 | $ function HelloWorld() { 57 | $ if (!greeting) { 58 | $ return null; 59 | $ } 60 | $ } 61 | function HelloWorld() { 62 | if (!greeting) { 63 | return null; 64 | } 65 | } 66 | @end 67 | 68 | Errors are reported using the quickfix list. 69 | 70 | @clear 71 | % function foo() { 72 | 73 | :FormatCode prettier 74 | ! cd .* prettier .*2> (.*) 75 | $ 2 (status) 76 | $ echo >\1 ' (command) 77 | |[error] stdin: SyntaxError: Unexpected token (2:1)\n 78 | |[error] 1 | function foo() {\n 79 | |[error] > 2 |\n 80 | |[error] | ^' 81 | ~ (1 of 1): SyntaxError: Unexpected token 82 | function foo() { 83 | @end 84 | :echomsg line('.') . ',' . col('.') 85 | ~ 1,1 86 | :echomsg string(map(getqflist(), 87 | |'v:val.lnum . "," . v:val.col . "," . v:val.text')) 88 | ~ ['2,1,SyntaxError: Unexpected token'] 89 | 90 | It can format specific line ranges of code using :FormatLines. 91 | 92 | @clear 93 | % function HelloWorld(){if(!greeting){return null};} 94 | |function Greet(){if(!greeting){return null};} 95 | 96 | :1,1FormatLines prettier 97 | ! cd .* prettier .*--range-end 50.*2>.* 98 | $ function HelloWorld() { 99 | $ if (!greeting) { 100 | $ return null; 101 | $ } 102 | $ } 103 | $ function Greet(){if(!greeting){return null};} 104 | function HelloWorld() { 105 | if (!greeting) { 106 | return null; 107 | } 108 | } 109 | function Greet(){if(!greeting){return null};} 110 | @end 111 | 112 | It is also the default formatter for several file types. 113 | 114 | @clear 115 | % f(); 116 | 117 | :silent file /foo/foo.markdown 118 | :set filetype=markdown 119 | :FormatCode 120 | ! prettier .*--stdin-filepath /foo/foo.markdown.*2>.* 121 | $ f(); 122 | 123 | :silent file /foo/foo.yaml 124 | :set filetype=yaml 125 | :FormatCode 126 | ! prettier .*--stdin-filepath /foo/foo.yaml.*2>.* 127 | $ f(); 128 | 129 | :silent file /foo/foo.jsx 130 | :set filetype=jsx 131 | :FormatCode 132 | ! prettier .*--stdin-filepath /foo/foo.jsx.*2>.* 133 | $ f(); 134 | 135 | :silent file /foo/foo.mdx 136 | :set filetype=mdx 137 | :FormatCode 138 | ! prettier .*--stdin-filepath /foo/foo.mdx.*2>.* 139 | $ f(); 140 | 141 | :silent file /foo/foo.vue 142 | :set filetype=vue 143 | :FormatCode 144 | ! prettier .*--stdin-filepath /foo/foo.vue.*2>.* 145 | $ f(); 146 | -------------------------------------------------------------------------------- /vroom/rubocop.vroom: -------------------------------------------------------------------------------- 1 | Rubocop is a linter and formatter for ruby. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | First, set up the vroom environment. 5 | 6 | :source $VROOMDIR/setupvroom.vim 7 | 8 | :let g:repeat_calls = [] 9 | :function FakeRepeat(...) 10 | | call add(g:repeat_calls, a:000) 11 | :endfunction 12 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 13 | 14 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 15 | 16 | By default, the rubocop executable is called. To use this plugin, rubocop 17 | must be installed on your system. (But not for testing; vroom intercepts 18 | system calls.) 19 | :FormatCode rubocop 20 | ! rubocop .* 21 | 22 | 23 | 24 | The name and path of the Rubocop executable can be configured with a flag: 25 | :Glaive codefmt rubocop_executable=some_other_program 26 | :FormatCode rubocop 27 | ! some_other_program .*-fq.* 28 | :Glaive codefmt rubocop_executable=rubocop 29 | 30 | 31 | 32 | Rubocop does basic whitespace management. Though because it's primarily a 33 | linter, it outputs lint errors first, then a separator. Even with the lint 34 | errors disabled (-fq), you still get the separator. 35 | 36 | % def SomeClass end 37 | :FormatCode rubocop 38 | ! rubocop .*-fq.* 39 | $ ========= 40 | $ def SomeClass 41 | $ end 42 | def SomeClass 43 | end 44 | 45 | 46 | 47 | Being a linter, Rubocop cares about style as well as formatting. 48 | When a buffer is stylistically fine, it returns 0, and everything is OK. 49 | But sometimes it will return 1 even though things have gone well; 50 | we should still use the output when that happens. 51 | 52 | % def SomeClass end 53 | :FormatCode rubocop 54 | ! rubocop .* 55 | $ ========= 56 | $ def SomeClass 57 | $ end 58 | $ 1 (status) 59 | def SomeClass 60 | end 61 | -------------------------------------------------------------------------------- /vroom/ruff.vroom: -------------------------------------------------------------------------------- 1 | The built-in ruff formatter knows how to format python code. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | 18 | The ruff formatter expects the ruff executable to be installed on your 19 | system. 20 | 21 | :silent file somefile.py 22 | % f() 23 | :FormatCode ruff 24 | ! ruff format - --stdin-filename=somefile.py.* 25 | $ f() 26 | 27 | The name or path of the ruff executable can be configured via the 28 | ruff_executable flag if the default of "ruff" doesn't work. 29 | 30 | :Glaive codefmt ruff_executable='/somepath/ruff' 31 | :FormatCode ruff 32 | ! /somepath/ruff format -.* 33 | $ f() 34 | :Glaive codefmt ruff_executable='ruff' 35 | 36 | 37 | You can format any buffer with ruff specifying the formatter explicitly. 38 | 39 | @clear 40 | % if True: pass 41 | 42 | :FormatCode ruff 43 | ! ruff format -.* 44 | $ if True: 45 | $ pass 46 | if True: 47 | pass 48 | @end 49 | 50 | It can format specific line ranges of code using :FormatLines. 51 | 52 | @clear 53 | % some_tuple=( 1,2, 3,'a' ); 54 | |if bar : bar+=1; bar=bar* bar 55 | |else: bar-=1; 56 | 57 | :2,3FormatLines ruff 58 | ! ruff format .*--range=2:3 -.* 59 | $ some_tuple=( 1,2, 3,'a' ); 60 | $ if bar: 61 | $ bar += 1 62 | $ bar = bar * bar 63 | $ else: 64 | $ bar -= 1 65 | some_tuple=( 1,2, 3,'a' ); 66 | if bar: 67 | bar += 1 68 | bar = bar * bar 69 | else: 70 | bar -= 1 71 | @end 72 | -------------------------------------------------------------------------------- /vroom/rustfmt.vroom: -------------------------------------------------------------------------------- 1 | The rustfmt formatter knows how to format Rust code. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | 18 | The rustfmt formatter expects the rustfmt executable to be installed on your 19 | system. 20 | 21 | % fn main(){println!("Hello World!");} 22 | :FormatCode rustfmt 23 | ! rustfmt .* 24 | $ fn main() { 25 | $ println!("Hello World!"); 26 | $ } 27 | 28 | The name or path of the rustfmt executable can be configured via the 29 | rustfmt_executable flag if the default of "rustfmt" doesn't work. 30 | 31 | :Glaive codefmt rustfmt_executable='myrustfmt' 32 | :FormatCode rustfmt 33 | ! myrustfmt .* 34 | $ fn main() { 35 | $ println!("Hello World!"); 36 | $ } 37 | :Glaive codefmt rustfmt_executable='rustfmt' 38 | 39 | 40 | You can format any buffer with rustfmt specifying the formatter explicitly. 41 | 42 | @clear 43 | % fn main(){println!("Hello World!");} 44 | 45 | :FormatCode rustfmt 46 | ! rustfmt .*2>.* 47 | $ fn main() { 48 | $ println!("Hello World!"); 49 | $ } 50 | fn main() { 51 | println!("Hello World!"); 52 | } 53 | @end 54 | 55 | Errors are reported using the quickfix list. 56 | 57 | @clear 58 | % fn main() { 59 | 60 | :FormatCode rustfmt 61 | ! rustfmt .*2> (.*) 62 | $ 2 (status) 63 | $ echo >\1 ' (command) 64 | |error: this file contains an un-closed delimiter\n 65 | | --> :1:13\n 66 | | |\n 67 | |1 | fn main() {\n 68 | | | - ^\n 69 | | | |\n 70 | | | un-closed delimiter' 71 | ~ (1 of 1): this file contains an un-closed delimiter 72 | fn main() { 73 | @end 74 | :echomsg line('.') . ',' . col('.') 75 | ~ 1,11 76 | :echomsg string(map(getqflist(), 77 | |'v:val.lnum . "," . v:val.col . "," . v:val.text')) 78 | ~ ['1,13,this file contains an un-closed delimiter'] 79 | -------------------------------------------------------------------------------- /vroom/setupvroom.vim: -------------------------------------------------------------------------------- 1 | " Copyright 2015 Google Inc. All rights reserved. 2 | " 3 | " Licensed under the Apache License, Version 2.0 (the "License"); 4 | " you may not use this file except in compliance with the License. 5 | " You may obtain a copy of the License at 6 | " 7 | " http://www.apache.org/licenses/LICENSE-2.0 8 | " 9 | " Unless required by applicable law or agreed to in writing, software 10 | " distributed under the License is distributed on an "AS IS" BASIS, 11 | " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | " See the License for the specific language governing permissions and 13 | " limitations under the License. 14 | 15 | " This file is used from vroom scripts to bootstrap the codefmt plugin and 16 | " configure it to work properly under vroom. 17 | 18 | " Codefmt does not support compatible mode. 19 | set nocompatible 20 | 21 | " Set cmdheight to avoid "Hit ENTER to continue" without needing :silent 22 | set cmdheight=10 23 | 24 | " Install the codefmt plugin. 25 | let s:repo = expand(':p:h:h') 26 | execute 'source' s:repo . '/bootstrap.vim' 27 | 28 | " Install Glaive from local dir. 29 | let s:search_dir = fnamemodify(s:repo, ':h') 30 | for s:plugin_dirname in ['glaive', 'vim-glaive'] 31 | let s:bootstrap_path = 32 | \ maktaba#path#Join([s:search_dir, s:plugin_dirname, 'bootstrap.vim']) 33 | if filereadable(s:bootstrap_path) 34 | execute 'source' s:bootstrap_path 35 | break 36 | endif 37 | endfor 38 | 39 | " Force plugin/ files to load since vroom installs the plugin after 40 | " |load-plugins| time. 41 | call maktaba#plugin#Get('codefmt').Load() 42 | 43 | " Support vroom's fake shell executable and don't try to override it to sh. 44 | call maktaba#syscall#SetUsableShellRegex('\v 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | 18 | The shfmt formatter expects the shfmt executable to be installed on your system. 19 | 20 | % f() 21 | :FormatCode shfmt 22 | ! shfmt .* 23 | $ f() 24 | 25 | The name or path of the shfmt executable can be configured via the 26 | shfmt_executable flag if the default of "shfmt" doesn't work. 27 | 28 | :Glaive codefmt shfmt_executable='myshfmt' 29 | :FormatCode shfmt 30 | ! myshfmt .* 31 | $ f() 32 | :Glaive codefmt shfmt_executable='shfmt' 33 | 34 | 35 | You can format any buffer with shfmt specifying the formatter explicitly. 36 | 37 | @clear 38 | % if [ $print_hello_world -eq 1 ]; then echo "hello"; echo "world"; fi 39 | 40 | :FormatCode shfmt 41 | ! shfmt .*2>.* 42 | $ if [ $print_hello_world -eq 1 ]; then 43 | $ echo "hello" 44 | $ echo "world" 45 | $ fi 46 | if [ $print_hello_world -eq 1 ]; then 47 | echo "hello" 48 | echo "world" 49 | fi 50 | @end 51 | 52 | Errors are reported using the quickfix list. 53 | 54 | @clear 55 | % foo() { 56 | 57 | :FormatCode shfmt 58 | ! shfmt .*2> (.*) 59 | $ echo ':1:7: reached EOF without matching { with }' >\1 (command) 60 | $ 1 (status) 61 | ~ (1 of 1): reached EOF without matching { with } 62 | foo() { 63 | @end 64 | :echomsg line('.') . ',' . col('.') 65 | ~ 1,7 66 | :echomsg string(map(getqflist(), 67 | |'v:val.lnum . "," . v:val.col . "," . v:val.text')) 68 | ~ ['1,7,reached EOF without matching { with }'] 69 | 70 | 71 | The sh filetype will use the shfmt formatter by default. 72 | 73 | @clear 74 | % f() 75 | 76 | :set filetype=sh 77 | :FormatCode 78 | ! shfmt .* 79 | $ f() 80 | 81 | :set filetype= 82 | 83 | It can format specific line ranges of code using :FormatLines. 84 | 85 | @clear 86 | % foo() { echo "my name is:"; echo "foo"; } 87 | |bar() { echo "my name is:"; echo "bar"; } 88 | 89 | :1,2FormatLines shfmt 90 | ! shfmt .*2>.* 91 | $ foo() { 92 | $ echo "my name is:" 93 | $ echo "foo" 94 | $ } 95 | $ bar() { echo "my name is:"; echo "bar"; } 96 | foo() { 97 | echo "my name is:" 98 | echo "foo" 99 | } 100 | bar() { echo "my name is:"; echo "bar"; } 101 | @end 102 | 103 | NOTE: the shfmt formatter does not natively support range formatting, so there 104 | are certain limitations like not being able to format misaligned braces. 105 | -------------------------------------------------------------------------------- /vroom/swiftformat.vroom: -------------------------------------------------------------------------------- 1 | The built-in swift-format formatter knows how to format swift code. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | 18 | The swift-format formatter expects the swift-format executable to be installed on your 19 | system. 20 | 21 | % f() 22 | :FormatCode swift-format 23 | ! swift-format .* 24 | $ f() 25 | 26 | You can format any buffer with swift-format specifying the formatter explicitly. 27 | 28 | @clear 29 | % func f(a: String,b:Int)->String{ 30 | | return "a" } 31 | :FormatCode swift-format 32 | ! swift-format .*2>.* 33 | $ func f(a: String, b: Int) -> String { 34 | $ return "a" 35 | $ } 36 | func f(a: String, b: Int) -> String { 37 | return "a" 38 | } 39 | @end 40 | 41 | The swift filetype will use the swift-format formatter by default. 42 | 43 | @clear 44 | % f() 45 | 46 | :set filetype=swift 47 | :FormatCode 48 | ! swift-format .* 49 | $ f() 50 | 51 | :set filetype= 52 | 53 | -------------------------------------------------------------------------------- /vroom/yapf.vroom: -------------------------------------------------------------------------------- 1 | The built-in yapf formatter knows how to format python code. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | 18 | The yapf formatter expects the yapf executable to be installed on your 19 | system. 20 | 21 | % f() 22 | :FormatCode yapf 23 | ! yapf .* 24 | $ f() 25 | 26 | The name or path of the yapf executable can be configured via the 27 | yapf_executable flag if the default of "yapf" doesn't work. 28 | 29 | :Glaive codefmt yapf_executable='yapfpy3' 30 | :FormatCode yapf 31 | ! yapfpy3 .* 32 | $ f() 33 | :Glaive codefmt yapf_executable='yapf' 34 | 35 | 36 | You can format any buffer with yapf specifying the formatter explicitly. 37 | 38 | @clear 39 | % if True: pass 40 | 41 | :FormatCode yapf 42 | ! yapf .* 43 | $ if True: 44 | $ pass 45 | if True: 46 | pass 47 | @end 48 | 49 | It can format specific line ranges of code using :FormatLines. 50 | 51 | @clear 52 | % some_tuple=( 1,2, 3,'a' ); 53 | |if bar : bar+=1; bar=bar* bar 54 | |else: bar-=1; 55 | 56 | :2,3FormatLines yapf 57 | ! yapf --lines=2-3 .* 58 | $ some_tuple=( 1,2, 3,'a' ); 59 | $ if bar: 60 | $ bar += 1 61 | $ bar = bar * bar 62 | $ else: 63 | $ bar -= 1 64 | some_tuple=( 1,2, 3,'a' ); 65 | if bar: 66 | bar += 1 67 | bar = bar * bar 68 | else: 69 | bar -= 1 70 | @end 71 | -------------------------------------------------------------------------------- /vroom/zprint.vroom: -------------------------------------------------------------------------------- 1 | The zprint formatter knows how to format Clojure. 2 | If you aren't familiar with basic codefmt usage yet, see main.vroom first. 3 | 4 | We'll set up codefmt and configure the vroom environment, then jump into some 5 | examples. 6 | 7 | :source $VROOMDIR/setupvroom.vim 8 | 9 | :let g:repeat_calls = [] 10 | :function FakeRepeat(...) 11 | | call add(g:repeat_calls, a:000) 12 | :endfunction 13 | :call maktaba#test#Override('repeat#set', 'FakeRepeat') 14 | 15 | :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) 16 | 17 | The zprint formatter expects the zprint executable to be installed on your 18 | system. 19 | 20 | :FormatCode zprint 21 | ! cd .* zprint .* 22 | $ no-op 23 | 24 | The name or path of the zprint executable can be configured via the 25 | zprint_executable flag if the default of "zprint" doesn't work. 26 | 27 | :Glaive codefmt zprint_executable='/usr/local/bin/zprint' 28 | :FormatCode zprint 29 | ! cd .* /usr/local/bin/zprint .* 30 | $ no-op 31 | :Glaive codefmt zprint_executable='zprint' 32 | 33 | You can format an entire buffer with :FormatCode. 34 | 35 | @clear 36 | % (defn x [] (cond nil 1 :else 2)) 37 | |(defn y [] (cond nil 3 :else 4)) 38 | 39 | :FormatCode zprint 40 | ! cd .* zprint .* 41 | $ (defn x 42 | $ [] 43 | $ (cond nil 1 44 | $ :else 2)) 45 | $ (defn y 46 | $ [] 47 | $ (cond nil 3 48 | $ :else 4)) 49 | (defn x 50 | [] 51 | (cond nil 1 52 | :else 2)) 53 | (defn y 54 | [] 55 | (cond nil 3 56 | :else 4)) 57 | @end 58 | 59 | You can format specific line ranges using :FormatLines. (Since zprint works on 60 | top-level forms, the range of lines should be one or more complete forms, 61 | otherwise zprint will generate an error or incorrectly-formatted code.) 62 | 63 | @clear 64 | % (defn x [] (cond nil 1 :else 2)) 65 | |(defn y [] (cond nil 3 :else 4)) 66 | |(defn z [] (cond nil 5 :else 6)) 67 | 68 | :2,2FormatLines zprint 69 | ! cd .* zprint .* 70 | $ (defn y 71 | $ [] 72 | $ (cond nil 3 73 | $ :else 4)) 74 | (defn x [] (cond nil 1 :else 2)) 75 | (defn y 76 | [] 77 | (cond nil 3 78 | :else 4)) 79 | (defn z [] (cond nil 5 :else 6)) 80 | @end 81 | 82 | Zprint is the default formatter for the clojure file type, so calling 83 | :FormatCode or :FormatLines will use it automatically. 84 | 85 | :set filetype=clojure 86 | :FormatCode 87 | ! cd .* zprint .* 88 | $ no-op 89 | :set filetype& 90 | 91 | If the directory containing the file doesn't exist yet, then the plugin won't 92 | try to change directories: 93 | 94 | :silent file /does-not-exist/x.clj 95 | :set filetype=clojure 96 | :FormatCode 97 | ! zprint .* 98 | $ no-op 99 | :set filetype& 100 | :silent 0file 101 | 102 | The default setting of zprint_options propagates Vim's textwidth setting to 103 | zprint's command-line. 104 | 105 | :set textwidth=123 106 | :FormatCode zprint 107 | ! cd .* zprint .*:width 123.* 108 | $ no-op 109 | :set textwidth& 110 | --------------------------------------------------------------------------------