Skip to content

Instantly share code, notes, and snippets.

@voldikss
Created August 4, 2020 00:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save voldikss/98b21d5cbdb91267aa1910bc66363536 to your computer and use it in GitHub Desktop.
Save voldikss/98b21d5cbdb91267aa1910bc66363536 to your computer and use it in GitHub Desktop.
" ============================================================================
" FileName: textobj.vim
" Author: voldikss <dyzplus@gmail.com>
" GitHub: https://github.com/voldikss
" ============================================================================
function! lib#textobj#(pattern) abort
let pos = getpos('.')
let lnum = pos[1]
let cnum = pos[2]
let line = getline(lnum)
let [str, start, end] = s:matchstrposlast(line[:cnum-1], a:pattern)
if !empty(str)
let p1 = start + 1
let p2 = end
let [str, start, end] = matchstrpos(line, a:pattern, start)
if end >= cnum
" xxxxxxhttp://github.comxxxxhttp://github.comxxxxxx
" ^
" │
" cursor
let p1 = start + 1
let p2 = end
else
" xxxxxxhttp://github.comxxxxhttp://github.comxxxxxx
" ^
" │
" cursor
let [str, start, end] = matchstrpos(line, a:pattern, end)
if !empty(str)
" xxxxxxhttp://github.comxxxxhttp://github.comxxxxxx
" ^
" │
" cursor
let p1 = start + 1
let p2 = end
" else...
" otherwise, we still use start and end returned in line 13
" since we already assign them to p1 and p2 in L15-L16
" we don't need to handle this situation here
" xxxxxxhttp://github.comxxxx
" ^
" │
" cursor
endif
endif
else
" match from begin to the end of the line, get the first match
let [str, start, end] = matchstrpos(line, a:pattern)
if !empty(str)
" xxxxxhttp://github.comxxxxxx
" ^
" │
" cursor
let p1 = start + 1
let p2 = end
endif
endif
" visual select match part
if exists('p1')
call cursor(lnum, p1)
normal v
call cursor(lnum, p2)
endif
endfunc
function! s:matchstrposlast(str, pat)
let p1 = -1
let p2 = -1
let s = ''
let end = 0
while 1
let [str, start, end] = matchstrpos(a:str, a:pat, end)
if end != -1
let s = str
let p1 = start
let p2 = end
else
break
endif
endwhile
return [s, p1, p2]
endfunc
@voldikss
Copy link
Author

voldikss commented Aug 4, 2020

xxxxxxx https://github.com xxxxxxxxx
xxxxxxx 123456 xxx 123456 xxxxxx
1.1.1.1xxxx127.0.0.1

@voldikss
Copy link
Author

voldikss commented Aug 4, 2020

v1: match from the begin of the line
v2: match from ccurrent cnum, if not matches found, then match from the begin
v3: best logic of searching, but only current line(this gist)
v4: allow to match and select among multiple lines(todo, but https://github.com/kana/vim-textobj-user/blob/master/autoload/textobj/user.vim would be helpful)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment