Vim: do something in the function based on the character under the cursor?

I am writing a function that edits a specific environment in LaTeX.

The environment basically looks like this:

\begin{quicktikz} ...some stuff... \end{quicktikz} 

or like this:

 \begin*{quicktikz} ...some stuff... \end{quicktikz} 

I want to write a function that switches between them when called from the environment. Since my knowledge of Vim is wrong, I came up with a simple solution:

  • Get cursor position with let save_cursor=getpos(".")
  • Reverse Search \begin{quicktikz} with ?\\begin{quicktikz}\|\\begin\*{quicktikz}
  • Find { and move left using: normal 0f{h
  • Check if the item under the cursor * matches
    • if he does normal x
    • if it does not normal a*<esc>
  • Restore cursor position with call setpos('.',save_cursor)

I know how to do all this except step 3. How to check if char matches under cursor * or not?

If you know the best way to do this, share it, we will be happy.

+6
source share
2 answers

I think the easiest way to get char under the cursor is:

 getline(".")[col(".")-1] 

Alternatively, you can do this with strpart()

 strpart(getline("."), col(".")-1, 1) 

The first expression first calls the getline() function, passing "." as an argument, which means that the line the cursor is in will be returned. Then we use the so-called expr8 or expr- [] (see help ) to get a single character. The past number comes from another function, col() which returns the current cursor column. When indexes start at 0, they are subtracted.

You can use it as

 if getline(".")[col(".")-1] == '*' ... 
+7
source

Let me suggest an alternative implementation of the method you describe.

 :?\\begin\>\zs\*\=?s//\='*'[submatch(0)!='']/|norm!`` 

The above command consists of two separate commands encoded with | (see :help :bar ) in one line. The first is a replacement (see :help :s ) is performed for each line in the specified range,

 ?\\begin\>\zs\*\=? 

According to the syntax of the range (see :help :range ), this range defines only the line, i.e. the previous line, where the pattern \\begin\>\zs\*\= matches the word begin , which is preceded by a backslash, and then optional star symbol. 1 The \zs atom between the parts of the figure corresponds to \begin and * , sets the beginning of the match there. So, the match of the entire template is either empty or contains the symbol of one star. This is not required to specify a string in a range, it is useful to reuse the same pattern later in the command :substitute , where only this star symbol or its empty space should be replaced. For more information on template syntax, see :help /\> :help /\= :help /\zs .

Substitution itself

 s//\='*'[submatch(0)!='']/ 

replaces the first occurrence of the last search pattern (which sets the reverse search in the range) with a string in which the expression '*'[submatch(0)!=''] is evaluated (see :help sub-replace-\= ). As the pattern matches only an empty string or a star symbol, the submatch(0)!='' is evaluated to zero if there is no star after \begin , or one else. The zero index from the string '*' results in a substring containing the first character of this one-character string. The index is one equal to the length of the string, so the index results in an empty string. Thus, when there is a star after \begin , it is replaced by an empty string, when there is no star, the zero interval immediately after \begin is replaced by * .

Second team

 :norm!`` 

uses the fact that the :substitute command stores the current cursor before it starts the replacement. The movement of the `` command returns to the position until the last jump (which occurs in the aforementioned replacement command), restoring the cursor position. 2


1 Be careful with the search, as in ranges, as usual, it wraps around the end of the file when the wrapscan option is wrapscan (it is enabled by default).

2 Do not confuse `` with a command '' that moves the cursor to the first non-blank character in the location bar until the last jump.

+3
source

Source: https://habr.com/ru/post/898108/


All Articles