Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent auto-close of quote when standing at a word boundary? #129

Open
erikw opened this issue Feb 1, 2022 · 4 comments
Open

Prevent auto-close of quote when standing at a word boundary? #129

erikw opened this issue Feb 1, 2022 · 4 comments

Comments

@erikw
Copy link

erikw commented Feb 1, 2022

Hey, first thanks for this nice plugin!

I've been using this for a while and it works mostly good, except for one type of editing that I do actually a multitude times per day. That is the case of adding single or double quotes around an existing word. Let's say that I have the following text line

apple orange pear

and my goal is to quote the word orange so that the line becomes

apple "orange" pear

If I put my cursor at the the first character of orange and enter insert mode with i

apple orange pear
      ^

and type ", lexima.vim will insert a closing quote like

apple ""orange pear

In this case it is not desirable. Now I have to press backspace, or go to normal mode and press x to remove one of the quotes.

The same is true for when I will add the closing quote after the word. If I stand at the last character for orange and go to insert mode after the cursor with a

apple "orange pear
            ^

and I type ", lexima.vim will also auto-close this to

apple "orange"" pear

And once again I have to remove the quote too much.

As this is something that I do many times per day, I would be very keen on finding a way to make lexima.vim not auto-close when being at a word boundary (or maybe there's a better formulated condition here?)!

Is there already a way to configure this, or to re-define the rule for double and single quotes?

Thanks in advance :)

@cohama
Copy link
Owner

cohama commented Feb 2, 2022

Please try the following settings.

call lexima#add_rule({'char': '"', 'at': '\%#\s*\w'})

If the cursor (\%#) is preceding any spaces (\s*) and a word character (\w) then only one " will be input.

This rule overrides a built-in rule on " because 'at' is longer.

@erikw
Copy link
Author

erikw commented Feb 3, 2022

Thanks! It works for orange but not at the end of pear

Trial 1

apple "orange" "pear
                   ^

becomes

apple "orange" "pear""

Trial 2

I tried to develop something that would consider the end-of-line case and came up with

call lexima#add_rule({'char': '"', 'at': '\%#\s*\w\|\w\%#$'})

This works for all 3 test words. However it does not work to insert an auto-closed quote between words that have >2 spaces between them

If the goal is to insert "banana" between orange pear using auto-closed double quote i.e. transforming (note that there are 2 spaces between orange and pear)

apple orange  pear
            ^

to

apple orange "banana" pear

then typing " insert mode at the middle space as indicated will not auto-close the double quote, which is desired here.

Trial 3

Going back to the original formulation of word boundary, I then tried using use that regex feature

call lexima#add_rule({'char': '"', 'at': '\%#\(\<\|\>\)'})

This seems to work in both the original case + the insert-between-words case above. To test this out further I opened up a source code file (Ruby) and picked a line having some special characters and decided I wanted to transform

private_constant :TOP_LEVEL_TYPES, :CUSTOM_CLASS_KEY {}
                 ^              ^

by quoting :TOP_LEVEL_TYPES to

private_constant ":TOP_LEVEL_TYPES", :CUSTOM_CLASS_KEY {}

This did of course not work becuase special characters are not word boundaries.

Trial 4

Then I though then about the problem from the other way around: maybe we want to auto-complete double quotes only when there are some spaces or nothing before and after the cursor. This condition negated is when we want to insert only one double quote:

call lexima#add_rule({'char': '"', 'at': '\%#\S\|\S\%#'})

So far, this rule seems to actually work for all cases above! :O

@TymekDev
Copy link

I have been using rules that @erikw suggested, but noticed they don't always work for me. For example, |] + " = "|] where I would expect "|"]. Therefore I have created rules that so far work for me:

call lexima#add_rule({'char': '"', 'at': '"\S\{-1,}\%#\|\%#\S\{-1,}"'})
call lexima#add_rule({'char': "'", 'at': "'\S\{-1,}\%#\|\%#\S\{-1,}'"})
call lexima#add_rule({'char': '`', 'at': '`\S\{-1,}\%#\|\%#\S\{-1,}`'})

Every rule is analogous and has two parts. One part handles "words" starting and the other "words" ending with given character. This way it looks like a quoting is being closed.

Additionally, I have a set of rules for opening brackets, so they won't insert a closing bracket if there is one at the end of the word:

call lexima#add_rule({'char': '(', 'at': '\%#\S\{-1,})'})
call lexima#add_rule({'char': '[', 'at': '\%#\S\{-1,}]'})
call lexima#add_rule({'char': '{', 'at': '\%#\S\{-1,}}'})

Examples

Before    Input    After
----------------------------
|foo"     "        "|foo"
----------------------------
"foo|     "        "foo"|
----------------------------
foo|      "        foo"|"
----------------------------
|foo)     (        (|foo)
----------------------------
foo|      (        foo(|)
----------------------------

TymekDev added a commit to TymekDev/dotfiles that referenced this issue Apr 25, 2022
lyokha added a commit to lyokha/dotfiles that referenced this issue Jun 5, 2022
TymekDev pushed a commit to TymekDev/dotfiles that referenced this issue Jul 30, 2022
TymekDev added a commit to TymekDev/dotfiles that referenced this issue Aug 1, 2022
@eight04
Copy link
Contributor

eight04 commented Dec 15, 2023

I found that with this pattern:

call lexima#add_rule({'char': '"', 'at': '"\S\{-1,}\%#\|\%#\S\{-1,}"'})

I won't be able to leave the quote with ":

Before    Input    After
----------------------------
|         "foo"    "foo"|"
----------------------------

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants