Mercurial > vim
view runtime/indent/hare.vim @ 32570:5d8cff99a027 v9.0.1617
patch 9.0.1617: charidx() result is not consistent with byteidx()
Commit: https://github.com/vim/vim/commit/577922b917e48285a7a312daf7b5bbc6e272939c
Author: Yegappan Lakshmanan <yegappan@yahoo.com>
Date: Thu Jun 8 17:09:45 2023 +0100
patch 9.0.1617: charidx() result is not consistent with byteidx()
Problem: charidx() and utf16idx() result is not consistent with byteidx().
Solution: When the index is equal to the length of the text return the
lenght of the text instead of -1. (Yegappan Lakshmanan,
closes #12503)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 08 Jun 2023 18:15:04 +0200 |
parents | 1e91e26ceebf |
children | 5c220cf30f1f |
line wrap: on
line source
" Vim indent file " Language: Hare " Maintainer: Amelia Clarke <me@rsaihe.dev> " Last Change: 2022 Sep 22 if exists("b:did_indent") finish endif let b:did_indent = 1 if !has("cindent") || !has("eval") finish endif setlocal cindent " L0 -> don't deindent labels " (s -> use one indent after a trailing ( " m1 -> if ) starts a line, indent it the same as its matching ( " ks -> add an extra indent to extra lines in an if expression or for expression " j1 -> indent code inside {} one level when in parentheses " J1 -> see j1 " *0 -> don't search for unclosed block comments " #1 -> don't deindent lines that begin with # setlocal cinoptions=L0,(s,m1,ks,j1,J1,*0,#1 " Controls which keys reindent the current line. " 0{ -> { at beginning of line " 0} -> } at beginning of line " 0) -> ) at beginning of line " 0] -> ] at beginning of line " !^F -> <C-f> (not inserted) " o -> <CR> or `o` command " O -> `O` command " e -> else " 0=case -> case setlocal indentkeys=0{,0},0),0],!^F,o,O,e,0=case setlocal cinwords=if,else,for,switch,match setlocal indentexpr=GetHareIndent() function! FloorCindent(lnum) return cindent(a:lnum) / shiftwidth() * shiftwidth() endfunction function! GetHareIndent() let line = getline(v:lnum) let prevlnum = prevnonblank(v:lnum - 1) let prevline = getline(prevlnum) let prevprevline = getline(prevnonblank(prevlnum - 1)) " This is all very hacky and imperfect, but it's tough to do much better when " working with regex-based indenting rules. " If the previous line ended with =, indent by one shiftwidth. if prevline =~# '\v\=\s*(//.*)?$' return indent(prevlnum) + shiftwidth() endif " If the previous line ended in a semicolon and the line before that ended " with =, deindent by one shiftwidth. if prevline =~# '\v;\s*(//.*)?$' && prevprevline =~# '\v\=\s*(//.*)?$' return indent(prevlnum) - shiftwidth() endif " TODO: The following edge-case is still indented incorrectly: " case => " if (foo) { " bar; " }; " | // cursor is incorrectly deindented by one shiftwidth. " " This only happens if the {} block is the first statement in the case body. " If `case` is typed, the case will also be incorrectly deindented by one " shiftwidth. Are you having fun yet? " Deindent cases. if line =~# '\v^\s*case' " If the previous line was also a case, don't do any special indenting. if prevline =~# '\v^\s*case' return indent(prevlnum) end " If the previous line was a multiline case, deindent by one shiftwidth. if prevline =~# '\v\=\>\s*(//.*)?$' return indent(prevlnum) - shiftwidth() endif " If the previous line started a block, deindent by one shiftwidth. " This handles the first case in a switch/match block. if prevline =~# '\v\{\s*(//.*)?$' return FloorCindent(v:lnum) - shiftwidth() end " If the previous line ended in a semicolon and the line before that wasn't " a case, deindent by one shiftwidth. if prevline =~# '\v;\s*(//.*)?$' && prevprevline !~# '\v\=\>\s*(//.*)?$' return FloorCindent(v:lnum) - shiftwidth() end let l:indent = FloorCindent(v:lnum) " If a normal cindent would indent the same amount as the previous line, " deindent by one shiftwidth. This fixes some issues with `case let` blocks. if l:indent == indent(prevlnum) return l:indent - shiftwidth() endif " Otherwise, do a normal cindent. return l:indent endif " Don't indent an extra shiftwidth for cases which span multiple lines. if prevline =~# '\v\=\>\s*(//.*)?$' && prevline !~# '\v^\s*case\W' return indent(prevlnum) endif " Indent the body of a case. " If the previous line ended in a semicolon and the line before that was a " case, don't do any special indenting. if prevline =~# '\v;\s*(//.*)?$' && prevprevline =~# '\v\=\>\s*(//.*)?$' && line !~# '\v^\s*}' return indent(prevlnum) endif let l:indent = FloorCindent(v:lnum) " If the previous line was a case and a normal cindent wouldn't indent, indent " an extra shiftwidth. if prevline =~# '\v\=\>\s*(//.*)?$' && l:indent == indent(prevlnum) return l:indent + shiftwidth() endif " If everything above is false, do a normal cindent. return l:indent endfunction " vim: tabstop=2 shiftwidth=2 expandtab