53

I've been using Vim for a while, and I can't get proper HTML indentation working in PHP files.

For example, what I want is for each child to be indented one tab more than it's parent, as shown below.

<?php
if(isset($sports)) {
    //Do something
?>
<div>
    <label>Uniform Size</label>
    <ul>
        <li class="left"><label for="s" class="small">S</label><input type="radio" name="size[]" value="S" id="s" class="radio" /></li>
        <li class="left"><label for="m" class="small">M</label><input type="radio" name="size[]" value="M" id="m" class="radio" /></li>
        <li class="left"><label for="l" class="small">L</label><input type="radio" name="size[]" value="L" id="l" class="radio" /></li>
        <li class="left"><label for="xl" class="small">XL</label><input type="radio" name="size[]" value="XL" id="xl" class="radio" /></li>
    </ul>
</div>
<?php
}
?>

Using the PHP-correct-Indent script, the code results in being formatted as follows:

<?php
if(isset($sports)) {
    //Do something
?>
<div>
<label>Uniform Size</label>
<ul>
<li class="left"><label for="s" class="small">S</label><input type="radio" name="size[]" value="S" id="s" class="radio" /></li>
<li class="left"><label for="m" class="small">M</label><input type="radio" name="size[]" value="M" id="m" class="radio" /></li>
<li class="left"><label for="l" class="small">L</label><input type="radio" name="size[]" value="L" id="l" class="radio" /></li>
<li class="left"><label for="xl" class="small">XL</label><input type="radio" name="size[]" value="XL" id="xl" class="radio" /></li>
</ul>
</div>
<?php
}
?>

Even with indented HTML which I then add PHP code to, the indentation is ignored, moving new lines of HTML code without any indentation at all.

So, is there any way that I can get the indentation format that I want working with HTML within PHP files, using Vim?

Sasha
  • 2,227
  • 3
  • 23
  • 31

9 Answers9

67

This still bothers me. I only just decided that the best work-around (for me personally) is this:

:set filetype=html

And then highlight your text and hit =. BOOM! HTML formatting succes. (Not ideal, I know, but at least it works.)

steve
  • 3,276
  • 27
  • 25
  • Thanks for this. After a point I find it easier to do this sort of thing than to fight automatic workarounds. – LVB Nov 04 '10 at 04:48
  • 1
    After more than a year of using Vim I've changed my perspective. Toggling between `:set ft=php` and `:set ft=html` is a better solution to the problem. – Sasha Oct 26 '11 at 23:39
  • 43
    To get better php support you might try :set ft=phtml – Joe Mills Mar 06 '12 at 17:10
  • @JoeMills that sounds good I'll try that the next time I'm cursed with writing php. ;) – steve Mar 07 '12 at 21:43
  • 1
    To make this a little less painful, add this to your vimrc: `map h :set ft=html` and `map p :set ft=php` – Jonathan Cutrell Jul 17 '15 at 15:15
  • This is related: http://stackoverflow.com/questions/506075/how-do-i-fix-the-indentation-of-an-entire-file-in-vi (forcing indentation over the whole file with `gg=G''` ) – Stanislav Aug 02 '15 at 04:55
27

There is a set of vimrc instructions on the Vim Wiki called Better indent support for PHP with HTML that will use the correct plugin depending on the block.

There is also a Vundle/Pathogen Plugin that uses the same code but is easier to install and keeps your .vimrc clean.

Pathogen

cd ~/.vim/bundle
git clone https://github.com/captbaritone/better-indent-support-for-php-with-html.git

Vundle

Place in .vimrc

Bundle 'captbaritone/better-indent-support-for-php-with-html'

Run in vim

:BundleInstall
cmc
  • 4,294
  • 2
  • 35
  • 34
Brian Carper
  • 71,150
  • 28
  • 166
  • 168
  • This also works under Cygwin - the file should be located at `~/.vim/indent/php.vim`. If you paste from that page into Cygwin, double-check that the pasted code wasn't screwed up (wrong line breaks and extraneous quotation marks) in the process. – Nathan Long Mar 05 '10 at 16:28
  • Thanks Brian. That seems to be working almost exactly as I want it to. Thank you Naum and bobince as well for your answers. – Sasha Aug 23 '10 at 01:13
  • I followed the tip, but it's not working for me. Do I have to explicit call the function or it's supposed to work out of the box? if I have to call it, what parameter should I pass? – Eligio Becerra Sep 21 '10 at 18:27
  • If you're using pathogen throw this file in your autoload/php/indent folder with the name php.vim and it should work fine. If on MacVim, either reload or restart MacVim. – James Oct 24 '11 at 21:26
  • 1
    This worked perfectly for me. I wrapped it in a Vundle compatible plugin to make it easier to include: https://github.com/captbaritone/better-indent-support-for-php-with-html – Jordan Eldredge May 18 '13 at 20:18
  • It doesn't work for me, but I have better luck with this Bundle/Plugin/Plug: 'Nicklasos/vimphphtml' – Drasill Sep 24 '15 at 08:29
19

After looking really really hard into all solutions, I found out this plugin:

http://www.vim.org/scripts/script.php?script_id=604

It seems to have solved my problems!!!!!

alessioalex
  • 62,577
  • 16
  • 155
  • 122
  • 8
    Instructions are lacking, put this in the `~/.vim/indents` folder – puk Mar 15 '12 at 21:18
  • 1
    this screwed up indentation in my php code files... somehow set the tabstop to 3 spaces. Not worth it, IMHO – mblackwell8 Apr 06 '12 at 00:55
  • 3
    @mblackwell8 You can edit the `php.vim` file, line 27, to control indent spacing. You can set it to the number of spaces you prefer or if rather have tabs, just delete the line. – Nithin Philips Apr 07 '12 at 16:44
  • This is new php 5.4 syntax, try it http://www.vim.org/scripts/script.php?script_id=4159 – Nicklasos Nov 12 '12 at 15:29
14

For me it works good if I first do :set ft=html and then :set syn=php.

gitaarik
  • 42,736
  • 12
  • 98
  • 105
  • I'm using this solution. The only inconvenient is that language support (coc-phpls) stops working. – Diego Somar Jul 24 '20 at 00:17
  • This should really be the correct answer. No plugins or scripts, just vanilla vim settings. – Zac Aug 24 '20 at 19:35
  • Nice! ft=html fixes indenting but messes up the php syntax highlighting, and syn=php fixes it back. – Burrito Nov 04 '21 at 19:24
6

In php+html I found the following is good for me.

:set ft=html # Change the file type to html
=G # to indent all lines 
:set ft=phtml # Change the file type to phtml
=G # to indent all php lines
shin
  • 31,901
  • 69
  • 184
  • 271
2

php-correct-indenting only cares about your PHP, and assumes the readability of the HTML is of no interest. An XML indenter would position the tags nicely, but wouldn't be able to indent the contents of a <?php> processing instruction to match. Maybe there is an indentation script that understands both the C-like syntax of PHP the programming language and [X][HT]ML the markup language being templated, but I've never met one yet - sorry.

Still, I'd like to fiddle with the indenting in your example even before php-correct-indenting mauled it! The <div> element is inside an outer if-statement, but I have no way to see that from the indenting. I'd suggest something like:

<?php if(isset($sports)) { ?>
    <?php
        // Do something
    ?>
    <div>
        <label>Uniform Size</label>
        <ul>
            <li>etc. etc.</li>
        </ul>
    </div>
<?php } ?>
bobince
  • 528,062
  • 107
  • 651
  • 834
1

inside your .vimrc:

:function IndentPHPHTML()
:  set ft=html
:  normal gg=G
:  set ft=php
:endfunction

use ctrl-shift-L (or whatever) to indent

nnoremap <C-S-l> :call IndentPHPHTML()<cr>
Ricardo Schalch
  • 157
  • 3
  • 9
1

i found this solution is much better. http://www.vim.org/scripts/script.php?script_id=1120

supporting HEREDOC html style. which occur frequently in my code.
BTW:it's has more versions than the old one (script id 604, alex posted it above)

xinquan
  • 11
  • 2
0

After searching for days for the solution ,nothing worked and finally this worked,add this to your vimrc

au BufEnter,BufNew *.php :set filetype=html
kapil
  • 625
  • 12
  • 20