Mercurial > vim
annotate runtime/indent/hare.vim @ 34493:1fa23ccd6d9a v9.1.0153
patch 9.1.0153: Text properties corrupted with fo+=aw and backspace
Commit: https://github.com/vim/vim/commit/7ac1145fbebb66dfee325dc5265309877d941c4e
Author: zeertzjq <zeertzjq@outlook.com>
Date: Wed Mar 6 20:54:22 2024 +0100
patch 9.1.0153: Text properties corrupted with fo+=aw and backspace
Problem: Text properties corrupted with fo+=aw and backspace
Solution: Allocate line and move text properties
(zeertzjq)
closes: #14147
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Wed, 06 Mar 2024 21:00:11 +0100 |
parents | 5c220cf30f1f |
children | ea0402ba92f6 |
rev | line source |
---|---|
30547 | 1 " Vim indent file |
2 " Language: Hare | |
3 " Maintainer: Amelia Clarke <me@rsaihe.dev> | |
4 " Last Change: 2022 Sep 22 | |
33052
5c220cf30f1f
runtime: Set b:undo_indent where missing (#12944)
Christian Brabandt <cb@256bit.org>
parents:
30547
diff
changeset
|
5 " 2023 Aug 28 by Vim Project (undo_indent) |
30547 | 6 |
7 if exists("b:did_indent") | |
8 finish | |
9 endif | |
10 let b:did_indent = 1 | |
11 | |
12 if !has("cindent") || !has("eval") | |
13 finish | |
14 endif | |
15 | |
16 setlocal cindent | |
17 | |
18 " L0 -> don't deindent labels | |
19 " (s -> use one indent after a trailing ( | |
20 " m1 -> if ) starts a line, indent it the same as its matching ( | |
21 " ks -> add an extra indent to extra lines in an if expression or for expression | |
22 " j1 -> indent code inside {} one level when in parentheses | |
23 " J1 -> see j1 | |
24 " *0 -> don't search for unclosed block comments | |
25 " #1 -> don't deindent lines that begin with # | |
26 setlocal cinoptions=L0,(s,m1,ks,j1,J1,*0,#1 | |
27 | |
28 " Controls which keys reindent the current line. | |
29 " 0{ -> { at beginning of line | |
30 " 0} -> } at beginning of line | |
31 " 0) -> ) at beginning of line | |
32 " 0] -> ] at beginning of line | |
33 " !^F -> <C-f> (not inserted) | |
34 " o -> <CR> or `o` command | |
35 " O -> `O` command | |
36 " e -> else | |
37 " 0=case -> case | |
38 setlocal indentkeys=0{,0},0),0],!^F,o,O,e,0=case | |
39 | |
40 setlocal cinwords=if,else,for,switch,match | |
41 | |
42 setlocal indentexpr=GetHareIndent() | |
43 | |
33052
5c220cf30f1f
runtime: Set b:undo_indent where missing (#12944)
Christian Brabandt <cb@256bit.org>
parents:
30547
diff
changeset
|
44 let b:undo_indent = "setl cin< cino< cinw< inde< indk<" |
5c220cf30f1f
runtime: Set b:undo_indent where missing (#12944)
Christian Brabandt <cb@256bit.org>
parents:
30547
diff
changeset
|
45 |
30547 | 46 function! FloorCindent(lnum) |
47 return cindent(a:lnum) / shiftwidth() * shiftwidth() | |
48 endfunction | |
49 | |
50 function! GetHareIndent() | |
51 let line = getline(v:lnum) | |
52 let prevlnum = prevnonblank(v:lnum - 1) | |
53 let prevline = getline(prevlnum) | |
54 let prevprevline = getline(prevnonblank(prevlnum - 1)) | |
55 | |
56 " This is all very hacky and imperfect, but it's tough to do much better when | |
57 " working with regex-based indenting rules. | |
58 | |
59 " If the previous line ended with =, indent by one shiftwidth. | |
60 if prevline =~# '\v\=\s*(//.*)?$' | |
61 return indent(prevlnum) + shiftwidth() | |
62 endif | |
63 | |
64 " If the previous line ended in a semicolon and the line before that ended | |
65 " with =, deindent by one shiftwidth. | |
66 if prevline =~# '\v;\s*(//.*)?$' && prevprevline =~# '\v\=\s*(//.*)?$' | |
67 return indent(prevlnum) - shiftwidth() | |
68 endif | |
69 | |
70 " TODO: The following edge-case is still indented incorrectly: | |
71 " case => | |
72 " if (foo) { | |
73 " bar; | |
74 " }; | |
75 " | // cursor is incorrectly deindented by one shiftwidth. | |
76 " | |
77 " This only happens if the {} block is the first statement in the case body. | |
78 " If `case` is typed, the case will also be incorrectly deindented by one | |
79 " shiftwidth. Are you having fun yet? | |
80 | |
81 " Deindent cases. | |
82 if line =~# '\v^\s*case' | |
83 " If the previous line was also a case, don't do any special indenting. | |
84 if prevline =~# '\v^\s*case' | |
85 return indent(prevlnum) | |
86 end | |
87 | |
88 " If the previous line was a multiline case, deindent by one shiftwidth. | |
89 if prevline =~# '\v\=\>\s*(//.*)?$' | |
90 return indent(prevlnum) - shiftwidth() | |
91 endif | |
92 | |
93 " If the previous line started a block, deindent by one shiftwidth. | |
94 " This handles the first case in a switch/match block. | |
95 if prevline =~# '\v\{\s*(//.*)?$' | |
96 return FloorCindent(v:lnum) - shiftwidth() | |
97 end | |
98 | |
99 " If the previous line ended in a semicolon and the line before that wasn't | |
100 " a case, deindent by one shiftwidth. | |
101 if prevline =~# '\v;\s*(//.*)?$' && prevprevline !~# '\v\=\>\s*(//.*)?$' | |
102 return FloorCindent(v:lnum) - shiftwidth() | |
103 end | |
104 | |
105 let l:indent = FloorCindent(v:lnum) | |
106 | |
107 " If a normal cindent would indent the same amount as the previous line, | |
108 " deindent by one shiftwidth. This fixes some issues with `case let` blocks. | |
109 if l:indent == indent(prevlnum) | |
110 return l:indent - shiftwidth() | |
111 endif | |
112 | |
113 " Otherwise, do a normal cindent. | |
114 return l:indent | |
115 endif | |
116 | |
117 " Don't indent an extra shiftwidth for cases which span multiple lines. | |
118 if prevline =~# '\v\=\>\s*(//.*)?$' && prevline !~# '\v^\s*case\W' | |
119 return indent(prevlnum) | |
120 endif | |
121 | |
122 " Indent the body of a case. | |
123 " If the previous line ended in a semicolon and the line before that was a | |
124 " case, don't do any special indenting. | |
125 if prevline =~# '\v;\s*(//.*)?$' && prevprevline =~# '\v\=\>\s*(//.*)?$' && line !~# '\v^\s*}' | |
126 return indent(prevlnum) | |
127 endif | |
128 | |
129 let l:indent = FloorCindent(v:lnum) | |
130 | |
131 " If the previous line was a case and a normal cindent wouldn't indent, indent | |
132 " an extra shiftwidth. | |
133 if prevline =~# '\v\=\>\s*(//.*)?$' && l:indent == indent(prevlnum) | |
134 return l:indent + shiftwidth() | |
135 endif | |
136 | |
137 " If everything above is false, do a normal cindent. | |
138 return l:indent | |
139 endfunction | |
140 | |
141 " vim: tabstop=2 shiftwidth=2 expandtab |