nvim-treesitter-textobjects icon indicating copy to clipboard operation
nvim-treesitter-textobjects copied to clipboard

@annotation.inner and @annotation.outer

Open nik-rev opened this issue 1 year ago • 9 comments

I'd like to @annotation.inner and @annotation.outer

if this gets accepted, i'll do a PR for typescript

@annotation.inner and @annotation.outer

(type_annotation
  (_) @annotation.inner) @annotation.outer

If we have

let isStringVar: IsString<string> = true;
  • @annotation.inner: IsString<string>
  • @annotation.outer: : IsString<string>

We can use a different name, it's not a big deal to me

nik-rev avatar Sep 08 '24 00:09 nik-rev

In my opinion this is quite niche. But if this can be added to many languages (e.g. python, rust, C, ...), it would make more sense.

Some languages have type annotation (TS and Python) and others have just type as a mandatory field (C, Rust). So maybe instead of calling it annotation, it can be called something else?

By the way, also note that you can make custom queries for yourself. Even if this doesn't get accepted you can still use it and do whatever you can imagine!

kiyoon avatar Sep 08 '24 08:09 kiyoon

Yes, I repeat that the bar for adding new types of textobjects is quite high. You need to make a much better case for a new one, including

  1. multiple(!) concrete(!) examples showing where and how this would be useful;
  2. showing how this cannot be achieved with any existing textobject.

Remember that consistency across languages is a primary project goal here; we will not make special exceptions for "the best language eva", and especially not web frontend. Such additions belong to dedicated language plugins (as @kiyoon wrote, you can easily extend the bundled queries in your config or a plugin; this is by design).

clason avatar Sep 08 '24 08:09 clason

Yes, I repeat that the bar for adding new types of textobjects is quite high. You need to make a much better case for a new one, including

1. multiple(!) concrete(!) examples showing where and how this would be useful;

2. showing how this cannot be achieved with any existing textobject.

Remember that consistency across languages is a primary project goal here; we will not make special exceptions for "the best language eva", and especially not web frontend. Such additions belong to dedicated language plugins (as @kiyoon wrote, you can easily extend the bundled queries in your config or a plugin; this is by design).

Languages that this would impact

Ok, so first, example for all languages (to show that this is useful in more than just typescript, and to consider the scope of a possible PR implementing all of them. I'd be happy to do it) This was generated with chat gpt

All Languages that support types

apex

Integer age: Integer = 30;
  • @annotation.inner: Integer
  • @annotation.outer: : Integer

c

int age = 30;
  • @annotation.inner: int
  • @annotation.outer: int

c_sharp

string name = "John";
  • @annotation.inner: string
  • @annotation.outer: string

cpp

int count = 42;
  • @annotation.inner: int
  • @annotation.outer: int

dart

int value = 100;
  • @annotation.inner: int
  • @annotation.outer: int

ecma

let isDone: boolean = false;
  • @annotation.inner: boolean
  • @annotation.outer: : boolean

elixir

name :: String.t() = "Alice"
  • @annotation.inner: String.t()
  • @annotation.outer: :: String.t()

go

var isAvailable bool = true
  • @annotation.inner: bool
  • @annotation.outer: var isAvailable bool

haskell

age :: Int
age = 25
  • @annotation.inner: Int
  • @annotation.outer: :: Int

hcl

variable "count" {
  type = number
}
  • @annotation.inner: number
  • @annotation.outer: type = number

hlsl

float lightIntensity = 1.0f;
  • @annotation.inner: float
  • @annotation.outer: float

java

int speed = 60;
  • @annotation.inner: int
  • @annotation.outer: int

javascript

let message: string = "Hello";
  • @annotation.inner: string
  • @annotation.outer: : string

jsx

let isVisible: boolean = true;
  • @annotation.inner: boolean
  • @annotation.outer: : boolean

julia

x::Int = 42
  • @annotation.inner: Int
  • @annotation.outer: :: Int

kotlin

val age: Int = 28
  • @annotation.inner: Int
  • @annotation.outer: : Int

lua

local age: number = 30
  • @annotation.inner: number
  • @annotation.outer: : number

nim

let pi: float = 3.14
  • @annotation.inner: float
  • @annotation.outer: : float

odin

pi: f64 = 3.1415;
  • @annotation.inner: f64
  • @annotation.outer: : f64

perl

my int $age = 25;
  • @annotation.inner: int
  • @annotation.outer: my int

php

$price: float = 19.99;
  • @annotation.inner: float
  • @annotation.outer: : float

python

age: int = 25
  • @annotation.inner: int
  • @annotation.outer: : int

r

age: numeric = 30
  • @annotation.inner: numeric
  • @annotation.outer: : numeric

ruby

age: Integer = 30
  • @annotation.inner: Integer
  • @annotation.outer: : Integer

rust

let temperature: f64 = 36.6;
  • @annotation.inner: f64
  • @annotation.outer: : f64

scala

val name: String = "John"
  • @annotation.inner: String
  • @annotation.outer: : String

scss

$primary-color: Color = #333;
  • @annotation.inner: Color
  • @annotation.outer: : Color

swift

var isActive: Bool = true
  • @annotation.inner: Bool
  • @annotation.outer: : Bool

terraform

variable "replicas" {
  type = number
}
  • @annotation.inner: number
  • @annotation.outer: type = number

tsx

const isOnline: boolean = true;
  • @annotation.inner: boolean
  • @annotation.outer: : boolean

typescript

const value: string = "hello";
  • @annotation.inner: string
  • @annotation.outer: : string

v

mut count: int = 10
  • @annotation.inner: int
  • @annotation.outer: : int

verilog

logic [7:0] data = 8'b10101010;
  • @annotation.inner: [7:0]
  • @annotation.outer: logic [7:0]

vim

let g:age: number = 25
  • @annotation.inner: number
  • @annotation.outer: : number

wgsl

var<private> color: vec4<f32> = vec4<f32>(1.0, 0.0, 0.0, 1.0);
  • @annotation.inner: vec4
  • @annotation.outer: : vec4

yaml

port: !!int 8080
  • @annotation.inner: !!int
  • @annotation.outer: : !!int

zig

const value: i32 = 42;
  • @annotation.inner: i32
  • @annotation.outer: : i32

Why is this useful?

Changing the type of an assignment is an incredibly common task, at least for me. This isn't possible with any of the current text objects.

I had considered some alternatives, e.g. something like this:

  • Creating a keybind that will go at the end of the previous or next LHS assignment
  • Then it will move 1 word to place the cursor where the "type annotation" is (since they're mandatory in some languages)

But this will be awkward e.g. if the type annotation has spaces, wraps over several lines, etc.

I know I could make queries myself, but if I can get a PR for this then it'll improve the experience of, I imagine a lot of people (I'd assume its likely lots more than if @regex.inner or @regex.outer was added)

It'd be great to be able to just instantly remove a type assignment e.g. with daa or change its value with cia (assuming it was mapped to da for .outer and ia for .inner

Name

I don't have a strong opinion on the name, I had considered @type prefix but that can be confusing. Or @declaration is another alternative

nik-rev avatar Sep 08 '24 13:09 nik-rev

Without prejudicating any decision on whether this should be added: the name must follow the corresponding highlight capture.

clason avatar Sep 08 '24 13:09 clason

Without prejudicating any decision on whether this should be added: the name must follow the corresponding highlight capture.

Ok, so here's some information then

In C its type: (_) In typescript its type: (type_annotation (_))

So how about the name @type ?

nik-rev avatar Sep 08 '24 13:09 nik-rev

Alternative suggestion: @type that will capture just any type, not necesserily a type_annotation or equivalents in other languages

nik-rev avatar Sep 08 '24 13:09 nik-rev

Since this will be even more useful and will extend to various contextx e.g. assertions or predicates

nik-rev avatar Sep 08 '24 13:09 nik-rev

In C its type: () In typescript its type: (type_annotation ())

The capture, not the node name. (The latter are very language-dependent, the former not -- that is the point.)

clason avatar Sep 08 '24 13:09 clason

In C its type: () In typescript its type: (type_annotation ())

The capture, not the node name. (The latter are very language-dependent, the former not -- that is the point.)

In that case I think @annotation is the most fitting. In languages where they are not required, they are still referred to and recognised. "annotation" does not seem to imply the word "optional"

Research:

Rust: https://users.rust-lang.org/t/is-there-a-semantic-difference-between-type-annotation-and-ascription/70259

C: https://stackoverflow.com/questions/19345630/c-style-type-annotations-vs-others

nik-rev avatar Sep 08 '24 15:09 nik-rev

i dont use neovim anymore so, someone else can have this issue

nik-rev avatar Jan 02 '25 15:01 nik-rev