Update runtime files
diff --git a/runtime/indent/clojure.vim b/runtime/indent/clojure.vim
index 7c4186e..30a0b47 100644
--- a/runtime/indent/clojure.vim
+++ b/runtime/indent/clojure.vim
@@ -1,12 +1,11 @@
 " Vim indent file
-" Language:     Clojure
-" Author:       Meikel Brandmeyer <mb@kotka.de>
-" URL:          http://kotka.de/projects/clojure/vimclojure.html
-"
-" Maintainer:   Sung Pae <self@sungpae.com>
-" URL:          https://github.com/guns/vim-clojure-static
-" License:      Same as Vim
-" Last Change:  18 July 2016
+" Language:           Clojure
+" Maintainer:         Alex Vear <av@axvr.io>
+" Former Maintainers: Sung Pae <self@sungpae.com>
+"                     Meikel Brandmeyer <mb@kotka.de>
+" URL:                https://github.com/clojure-vim/clojure.vim
+" License:            Vim (see :h license)
+" Last Change:        2021-02-13
 
 if exists("b:did_indent")
 	finish
@@ -87,7 +86,7 @@
 	function! s:match_pairs(open, close, stopat)
 		" Stop only on vector and map [ resp. {. Ignore the ones in strings and
 		" comments.
-		if a:stopat == 0
+		if a:stopat == 0 && g:clojure_maxlines > 0
 			let stopat = max([line(".") - g:clojure_maxlines, 0])
 		else
 			let stopat = a:stopat
@@ -121,7 +120,7 @@
 			if s:syn_id_name() !~? "string"
 				return -1
 			endif
-			if s:current_char() != '\\'
+			if s:current_char() != '\'
 				return -1
 			endif
 			call cursor(0, col("$") - 1)
@@ -170,7 +169,35 @@
 
 		call search('\S', 'W')
 		let w = s:strip_namespace_and_macro_chars(s:current_word())
+
 		if g:clojure_special_indent_words =~# '\V\<' . w . '\>'
+
+			" `letfn` is a special-special-case.
+			if w ==# 'letfn'
+				" Earlier code left the cursor at:
+				"     (letfn [...] ...)
+				"      ^
+
+				" Search and get coordinates of first `[`
+				"     (letfn [...] ...)
+				"            ^
+				call search('\[', 'W')
+				let pos = getcurpos()
+				let letfn_bracket = [pos[1], pos[2]]
+
+				" Move cursor to start of the form this function was
+				" initially called on.  Grab the coordinates of the
+				" closest outer `[`.
+				call cursor(a:position)
+				let outer_bracket = s:match_pairs('\[', '\]', 0)
+
+				" If the located square brackets are not the same,
+				" don't use special-case formatting.
+				if outer_bracket != letfn_bracket
+					return 0
+				endif
+			endif
+
 			return 1
 		endif
 
@@ -190,11 +217,7 @@
 	" Check if form is a reader conditional, that is, it is prefixed by #?
 	" or @#?
 	function! s:is_reader_conditional_special_case(position)
-		if getline(a:position[0])[a:position[1] - 3 : a:position[1] - 2] == "#?"
-			return 1
-		endif
-
-		return 0
+		return getline(a:position[0])[a:position[1] - 3 : a:position[1] - 2] == "#?"
 	endfunction
 
 	" Returns 1 for opening brackets, -1 for _anything else_.
@@ -261,7 +284,7 @@
 		call cursor(paren)
 
 		if s:is_method_special_case(paren)
-			return [paren[0], paren[1] + shiftwidth() - 1]
+			return [paren[0], paren[1] + &shiftwidth - 1]
 		endif
 
 		if s:is_reader_conditional_special_case(paren)
@@ -292,6 +315,19 @@
 			return paren
 		endif
 
+		" If the keyword begins with #, check if it is an anonymous
+		" function or set, in which case we indent by the shiftwidth
+		" (minus one if g:clojure_align_subforms = 1), or if it is
+		" ignored, in which case we use the ( position for indent.
+		if w[0] == "#"
+			" TODO: Handle #=() and other rare reader invocations?
+			if w[1] == '(' || w[1] == '{'
+				return [paren[0], paren[1] + (g:clojure_align_subforms ? 0 : &shiftwidth - 1)]
+			elseif w[1] == '_'
+				return paren
+			endif
+		endif
+
 		" Test words without namespace qualifiers and leading reader macro
 		" metacharacters.
 		"
@@ -299,19 +335,19 @@
 		let ww = s:strip_namespace_and_macro_chars(w)
 
 		if &lispwords =~# '\V\<' . ww . '\>'
-			return [paren[0], paren[1] + shiftwidth() - 1]
+			return [paren[0], paren[1] + &shiftwidth - 1]
 		endif
 
 		if g:clojure_fuzzy_indent
 			\ && !s:match_one(g:clojure_fuzzy_indent_blacklist, ww)
 			\ && s:match_one(g:clojure_fuzzy_indent_patterns, ww)
-			return [paren[0], paren[1] + shiftwidth() - 1]
+			return [paren[0], paren[1] + &shiftwidth - 1]
 		endif
 
 		call search('\v\_s', 'cW')
 		call search('\v\S', 'W')
 		if paren[0] < line(".")
-			return [paren[0], paren[1] + (g:clojure_align_subforms ? 0 : shiftwidth() - 1)]
+			return [paren[0], paren[1] + (g:clojure_align_subforms ? 0 : &shiftwidth - 1)]
 		endif
 
 		call search('\v\S', 'bW')
diff --git a/runtime/indent/html.vim b/runtime/indent/html.vim
index ec4fac5..7019bd4 100644
--- a/runtime/indent/html.vim
+++ b/runtime/indent/html.vim
@@ -1,7 +1,7 @@
 " Vim indent script for HTML
 " Maintainer:	Bram Moolenaar
 " Original Author: Andy Wokula <anwoku@yahoo.de>
-" Last Change:	2020 Dec 11
+" Last Change:	2021 Jan 26
 " Version:	1.0 "{{{
 " Description:	HTML indent script with cached state for faster indenting on a
 "		range of lines.
@@ -941,11 +941,11 @@
       let idx = match(text, '<' . s:tagname . '\s\+\zs\w')
     endif
     if idx == -1
-      " after just "<tag" indent one level more
+      " after just "<tag" indent two levels more
       let idx = match(text, '<' . s:tagname . '$')
       if idx >= 0
-	call cursor(lnum, idx)
-	return virtcol('.') + shiftwidth()
+	call cursor(lnum, idx + 1)
+	return virtcol('.') - 1 + shiftwidth() * 2
       endif
     endif
     if idx > 0
diff --git a/runtime/indent/ruby.vim b/runtime/indent/ruby.vim
index 23b61fd..657aa76 100644
--- a/runtime/indent/ruby.vim
+++ b/runtime/indent/ruby.vim
@@ -4,7 +4,6 @@
 " Previous Maintainer:	Nikolai Weibull <now at bitwi.se>
 " URL:			https://github.com/vim-ruby/vim-ruby
 " Release Coordinator:	Doug Kearns <dougkearns@gmail.com>
-" Last Change:		2019 Dec 08
 
 " 0. Initialization {{{1
 " =================
@@ -27,7 +26,12 @@
 
 if !exists('g:ruby_indent_block_style')
   " Possible values: "expression", "do"
-  let g:ruby_indent_block_style = 'expression'
+  let g:ruby_indent_block_style = 'do'
+endif
+
+if !exists('g:ruby_indent_hanging_elements')
+  " Non-zero means hanging indents are enabled, zero means disabled
+  let g:ruby_indent_hanging_elements = 1
 endif
 
 setlocal nosmartindent
@@ -322,7 +326,11 @@
 
     if searchpair(escape(bracket_pair[0], '\['), '', bracket_pair[1], 'bW', s:skip_expr) > 0
       if closing_bracket == ')' && col('.') != col('$') - 1
-        let ind = virtcol('.') - 1
+        if g:ruby_indent_hanging_elements
+          let ind = virtcol('.') - 1
+        else
+          let ind = indent(line('.'))
+        end
       elseif g:ruby_indent_block_style == 'do'
         let ind = indent(line('.'))
       else " g:ruby_indent_block_style == 'expression'
@@ -547,7 +555,9 @@
     let [opening, closing] = s:ExtraBrackets(info.plnum)
 
     if opening.pos != -1
-      if opening.type == '(' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0
+      if !g:ruby_indent_hanging_elements
+        return indent(info.plnum) + info.sw
+      elseif opening.type == '(' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0
         if col('.') + 1 == col('$')
           return indent(info.plnum) + info.sw
         else
@@ -632,8 +642,7 @@
       " TODO (2016-10-07) Wrong/unused? How could it be "1"?
       return indent(info.plnum) - 1
       " If previous line is a continuation return its indent.
-      " TODO: the || s:IsInString() thing worries me a bit.
-    elseif s:Match(info.plnum, s:non_bracket_continuation_regex) || s:IsInString(info.plnum, strlen(line))
+    elseif s:Match(info.plnum, s:non_bracket_continuation_regex)
       return indent(info.plnum)
     endif
   endif
diff --git a/runtime/indent/testdir/html.ok b/runtime/indent/testdir/html.ok
index ba2fd3f..c0dfc9d 100644
--- a/runtime/indent/testdir/html.ok
+++ b/runtime/indent/testdir/html.ok
@@ -19,7 +19,7 @@
 	</div>
 
 	<div
-	    class="foo bar">
+		class="foo bar">
 	    text
 	</div>
 
diff --git a/runtime/indent/testdir/vim.in b/runtime/indent/testdir/vim.in
index f652dbd..699e4c2 100644
--- a/runtime/indent/testdir/vim.in
+++ b/runtime/indent/testdir/vim.in
@@ -15,6 +15,21 @@
 \ ]
 endif
 
+" TODO: add searchpair() to find matching {
+"for x in [
+"{
+"key: 'value'
+"},
+"]
+"eval 0
+"endfor
+
+for x in [
+{key: 'value'},
+]
+eval 0
+endfor
+
 " END_INDENT
 
 " START_INDENT
diff --git a/runtime/indent/testdir/vim.ok b/runtime/indent/testdir/vim.ok
index b8592c1..f597d97 100644
--- a/runtime/indent/testdir/vim.ok
+++ b/runtime/indent/testdir/vim.ok
@@ -15,6 +15,21 @@
 		\ ]
 endif
 
+" TODO: add searchpair() to find matching {
+"for x in [
+"{
+"key: 'value'
+"},
+"]
+"eval 0
+"endfor
+
+for x in [
+	{key: 'value'},
+	]
+    eval 0
+endfor
+
 " END_INDENT
 
 " START_INDENT
diff --git a/runtime/indent/vim.vim b/runtime/indent/vim.vim
index b031d1f..d2f5f31 100644
--- a/runtime/indent/vim.vim
+++ b/runtime/indent/vim.vim
@@ -1,7 +1,7 @@
 " Vim indent file
 " Language:	Vim script
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2021 Jan 21
+" Last Change:	2021 Feb 13
 
 " Only load this indent file when no other was loaded.
 if exists("b:did_indent")
@@ -99,7 +99,9 @@
     let ind = ind + shiftwidth()
   else
     " A line starting with :au does not increment/decrement indent.
-    if prev_text !~ '^\s*au\%[tocmd]'
+    " A { may start a block or a dict.  Assume that when a } follows it's a
+    " terminated dict.
+    if prev_text !~ '^\s*au\%[tocmd]' && prev_text !~ '^\s*{.*}'
       let i = match(prev_text, '\(^\||\)\s*\(export\s\+\)\?\({\|\(if\|wh\%[ile]\|for\|try\|cat\%[ch]\|fina\|finall\%[y]\|fu\%[nction]\|def\|el\%[seif]\)\>\)')
       if i >= 0
 	let ind += shiftwidth()
@@ -152,13 +154,17 @@
   endif
 
   " Below a line starting with "]" we must be below the end of a list.
-  if prev_text_end =~ '^\s*]'
+  " Include a "}" and "},} in case a dictionary ends too.
+  if prev_text_end =~ '^\s*\(},\=\s*\)\=]'
     let ind = ind - shiftwidth()
   endif
 
+  let ends_in_comment = has('syntax_items')
+	      \ && synIDattr(synID(lnum, col('$'), 1), "name") =~ '\(Comment\|String\)$'
+
   " A line ending in "{"/"[} is most likely the start of a dict/list literal,
-  " indent the next line more.  Not for a continuation line.
-  if prev_text_end =~ '[{[]\s*$' && !found_cont
+  " indent the next line more.  Not for a continuation line or {{{.
+  if !ends_in_comment && prev_text_end =~ '\s[{[]\s*$' && !found_cont
     let ind = ind + shiftwidth()
   endif