@@ -88,14 +88,11 @@ endfunction
8888
8989function s: Put (key ) abort
9090 if b: stw_root is s: null
91- " Splay key to root
92- let b: stw_root = {' key' : a: key , ' left' : s: null , ' right' : s: null }
93- let b: stw_count += 1
91+ let [b: stw_root , b: stw_count ] = [{' key' : a: key , ' left' : s: null , ' right' : s: null }, 1 ]
9492 return
9593 endif
9694
97- let b: stw_root = s: Splay (b: stw_root , a: key )
98-
95+ let b: stw_root = s: Splay (b: stw_root , a: key ) " Splay key to root
9996 " Insert new node at root
10097 let cmp = a: key - b: stw_root .key
10198 if cmp < 0
@@ -112,68 +109,44 @@ function s:Put(key) abort
112109 let n .left .key -= n .key
113110 let b: stw_root = n
114111 let b: stw_count += 1
115- else
116- " Duplicate key
117- endif
118- endfunction
119-
120- function s: Remove (key ) abort
121- if b: stw_root is s: null | return | endif " Empty tree
122- let b: stw_root = s: Splay (b: stw_root , a: key )
123- if a: key != b: stw_root .key | return | endif " Not in tree
124- let b: stw_count -= 1
125-
126- if b: stw_root .left is s: null
127- let b: stw_root = b: stw_root .right
128- if b: stw_root isnot s: null | let b: stw_root .key += a: key | endif
129- else
130- let x = b: stw_root .right
131- let b: stw_root = b: stw_root .left
132- if x isnot s: null | let x .key -= b: stw_root .key | endif
133- call s: Splay (b: stw_root , a: key )
134- let b: stw_root .key += a: key
135- let b: stw_root .right = x
136112 endif
137113endfunction
138114
139- " Remove the specified range of keys from the tree.
115+ " Remove keys in the range [{min}, {max}) from the tree.
140116"
141- " {min} and {max} are inclusive line numbers defining the range to delete
117+ " Does modified Hibbard deletion.
142118function s: RemoveRange (min , max ) abort
143119 if b: stw_root is s: null | return | endif
144- let b: stw_root = s: Splay (b: stw_root , a: min )
120+ let b: stw_root = s: Splay (b: stw_root , a: min ) " Splay around lower bound
121+ let right = b: stw_root .right
122+ if right isnot s: null | let right .key += b: stw_root .key | endif
123+ let b: stw_root .right = s: null
124+
125+ " Remove root if in range
126+ if a: min <= b: stw_root .key && b: stw_root .key < a: max
127+ if b: stw_root .left isnot s: null | let b: stw_root .left .key += b: stw_root .key | endif
128+ let b: stw_root = b: stw_root .left
129+ let b: stw_count -= 1
130+ endif
131+
132+ if right isnot s: null
133+ let right = s: Splay (right , a: max ) " Splay around upper bound
134+ let b: stw_count -= s: NodeCount (right .left )
135+ let right .left = s: null
145136
146- if b: stw_root . right is s: null
147- if a: min <= b: stw_root .key && b: stw_root . key <= a: max
148- if b: stw_root . left isnot s: null | let b: stw_root . left .key += b: stw_root .key | endif
149- let b: stw_root = b: stw_root . left
137+ " If root of right subtree is in range: Remove it
138+ if right .key < a: max
139+ if right . right isnot s: null | let right . right .key += right .key | endif
140+ let right = right . right
150141 let b: stw_count -= 1
151142 endif
152- else
153- " Do modified Hibbard deletion
154- if a: min <= b: stw_root .key && b: stw_root .key <= a: max " Should remove root node but keep left subtree
155- let rootkey = b: stw_root .key
156- let x = b: stw_root .left
157- let b: stw_root = s: Splay (b: stw_root .right , a: max - rootkey + 1 )
158- let b: stw_count -= 1 + s: NodeCount (b: stw_root .left )
159- let b: stw_root .left = x
160-
161- if x isnot s: null | let x .key -= b: stw_root .key | endif
162- let b: stw_root .key += rootkey
163-
164- call s: Remove (a: max ) " Root could still be less than max
165- else " Should keep root node and left subtree
166- let b: stw_root .right = s: Splay (b: stw_root .right , a: max - b: stw_root .key + 1 )
167- let b: stw_count -= s: NodeCount (b: stw_root .right .left )
168- if b: stw_root .key + b: stw_root .right .key <= a: max
169- if b: stw_root .right .right isnot s: null
170- let b: stw_root .right .right .key += b: stw_root .right .key
171- endif
172- let b: stw_root .right = b: stw_root .right .right
173- let b: stw_count -= 1
174- else
175- let b: stw_root .right .left = s: null
176- endif
143+
144+ if b: stw_root is s: null
145+ let b: stw_root = right
146+ elseif right isnot s: null
147+ let b: stw_root = s: Splay (b: stw_root , 1 / 0 ) " Move rightmost to root
148+ let right .key -= b: stw_root .key
149+ let b: stw_root .right = right
177150 endif
178151 endif
179152endfunction
@@ -187,14 +160,12 @@ function StripTrailingWhitespaceListener(bufnr, start, end, added, changes) abor
187160 if s: is_stripping || b: stw_count > g: strip_trailing_whitespace_max_lines | return | endif
188161
189162 " Remove existing in range
190- if a: start < a: end
191- call s: RemoveRange (a: start , a: end - 1 )
192- endif
163+ if a: start < a: end | call s: RemoveRange (a: start , a: end ) | endif
193164
194165 " Adjust line numbers
195- let b: stw_root = s: Splay (b: stw_root , a: start )
196166 if b: stw_root isnot s: null
197- if b: stw_root .key >= a: start
167+ let b: stw_root = s: Splay (b: stw_root , a: end )
168+ if b: stw_root .key >= a: end
198169 let b: stw_root .key += a: added
199170 if b: stw_root .left isnot s: null | let b: stw_root .left .key -= a: added | endif
200171 elseif b: stw_root .right isnot s: null
@@ -207,6 +178,7 @@ function StripTrailingWhitespaceListener(bufnr, start, end, added, changes) abor
207178 let has_trailing_ws = getline (lnum) = ~# ' \s$'
208179 if has_trailing_ws
209180 call s: Put (lnum)
181+
210182 if b: stw_count > g: strip_trailing_whitespace_max_lines
211183 " Max count since unable to recommence (might have missed changes)
212184 let [b: stw_root , b: stw_count ] = [s: null , 1 / 0 ]
@@ -220,7 +192,6 @@ endfunction
220192
221193function s: OnBufEnter () abort
222194 if exists (' b:stw_root' ) | return | endif
223-
224195 let [b: stw_root , b: stw_count ] = [s: null , 0 ]
225196 if has (' nvim' )
226197 lua vim .api.nvim_buf_attach (0 , false, {
@@ -235,14 +206,12 @@ endfunction
235206" Recursively strip lines in the specified tree.
236207function s: StripTree (n , offset) abort
237208 silent execute (a: n .key + a: offset ) ' StripTrailingWhitespace'
238-
239209 if a: n .left isnot s: null | call s: StripTree (a: n .left , a: offset + a: n .key ) | endif
240210 if a: n .right isnot s: null | call s: StripTree (a: n .right , a: offset + a: n .key ) | endif
241211endfunction
242212
243213function s: OnWrite () abort
244214 if ! get (b: , ' strip_trailing_whitespace_enabled' , 1 ) | return | endif
245-
246215 if ! has (' nvim' ) | call listener_flush () | endif
247216
248217 let s: is_stripping = 1
0 commit comments