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

Smarter Inner Object Whitespace Selection #285

Open
jamesb6626 opened this issue Sep 3, 2022 · 3 comments
Open

Smarter Inner Object Whitespace Selection #285

jamesb6626 opened this issue Sep 3, 2022 · 3 comments
Labels
enhancement New feature or request

Comments

@jamesb6626
Copy link

Is your feature request related to a problem? Please describe.
With include_surrounding_whitespace enabled, inner textobjects currently include whitespace in an inconvenient way. In languages such as python, this includes all the whitespace up to and including the newline for the following function, so dif, cif, etc will drag the proceeding function to the cursor.

Describe the solution you'd like
Inner objects should include whitespace (when the setting is enabled), but only where that also lies within the outer object selected without whitespace, if possible. The outer object includes the end marker (end for lua, } for C), but not the start of the next function in python. If something bad happens (are there cases with no outer? could outer not contain inner?) then fall back to including no whitespace.

This would make inner selections more expensive (two objects needed) and less robust (breaks if either of inner/outer does something weird), but hopefully will get the correct match.

Since the inner object is likely wrapped by its outer parts, this should probably be used for both preceding and proceeding whitespace (unlike the current behaviour), but some care might be needed for newlines and indent.
Maybe, as a first try, exclude one newline followed by an indent (non-newline space, possibly empty) in the whitespace that lies between the inner and outer matches at each end (first match at the start, last match at the end, if they exist)? Not sure whether that will work. The idea is to leave the cursor on the correct line, with the correct indent, after e.g. a python def, and to leave the end and } parts of a lua or C function on their own line after that, again with their current indent. Require that the indent is followed by non-blank for the end case, to make sure its the one we want.

For languages such as lua and C, it might be good to include all whitespace according to the rule. Maps dif, cif would place the start and end bit on the same line, with the cursor between. But this should be optional per filetype, so maybe this should be left for later.

Describe alternatives you've considered
Not including surrounding whitespace ruins the well designed behaviour for outer objects.
Allowing the user to disable this for inner objects only should be a job for #156, and this could be done by default.
Unfortunately, the opposite behaviour is best for languages such as lua and C, where the next non-blank after the inner object is part of the function (end or }), so just disabling the behaviour for inner objects will hurt those cases.

Additional context

Example of current behaviour

Try inner function (vif, dif, cif) on the second line of the following two files with include_surrounding_whitespace true/false.

Lua:

function()
  print("hello world")

end

Python:

def a():
    pass


def b():
    pass
@jamesb6626 jamesb6626 added the enhancement New feature or request label Sep 3, 2022
@kiryph
Copy link

kiryph commented Sep 4, 2022

A related observation for Makefiles (:TSInstall make) with following treesitter query in ~/.config/nvim/queries/make/textobjcets.scm:

(rule
  ((recipe) @class.inner)?) @class.outer

Consider following rules in a Makefile:

# Rules
.PHONY: all clean cleanall

all: $(docs)

$(OUTPUT_DIR)%.$(FORMAT): %.graphml $(TEXFILE)
	@echo "Pattern rule"
	$(TEX) $(all_texflags) $<

clean:
	-$(RM) $(foreach ext, $(CLEAN_EXTS), $(docs:%.$(FORMAT)=%.$(ext)))

Screenshot of a vic selection

Screenshot 2022-09-04 at 10 45 17

In my opinion, the @class.inner selection should not contain the linebreak of the targets: prerequisites line and the follow-up line.

Interestingly, playground selects as I would expect:
Screenshot 2022-09-04 at 10 47 14

Using the neovim directive offset! does not help.
https://neovim.io/doc/user/treesitter.html#ts-directive-offset!

@stsewd
Copy link
Member

stsewd commented Sep 29, 2022

I had two open PRs for smarting selecting objects at #150.

@myarcana
Copy link

myarcana commented Apr 3, 2023

I don't think inner objects should include whitespace at all. Only outer objects should include surrounding whitespace.

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

No branches or pull requests

4 participants