godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.13k stars 93 forks source link

Allow writing GDScript comments with `//` in addition to `#` #3794

Closed Gurigraphics closed 2 years ago

Gurigraphics commented 2 years ago

Describe the project you are working on

Ever heard that every programmer is lazy so he wants to automate everything? that's it! This will be used in absolutely every project.

Describe the problem or limitation you are having in your project

To write the Single Line Comments #, I need to use both hands To write the Multi Line Comments """", I need to use both hands, and I still need to erase the four " twice

Describe the feature / enhancement and how it helps to overcome the problem or limitation

I want to be able to customize this. I recognize that shortcuts like "CTRL+K" are much more efficient. Even so, I consider // better than #, and would like to replace

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

// This is the Single Hand Single Line Comment I want

///
This is the Single Hand Multi Line Comments I want
///

If this enhancement will not be used often, can it be worked around with a few lines of script?

No. Comments are very very often used. Every microsecond of time and effort represents years of energy and time savings.

Is there a reason why this should be core and not an add-on in the asset library?

It can be a complement. But, if it's like Code Mirror it's not very difficult to change. If it is not possible or of interest to anyone, the way is to create a plugin for some external editor. Unlikely that this would become default. But for me it will be standard.

Calinou commented 2 years ago

I am against supporting multiple ways to write GDScript comments. There is no practical advantage to it; it only introduces confusion and choice paralysis for beginners. If you really want to use C-style syntax, use C# :slightly_smiling_face:

To write the Single Line Comments #, I need to use both hands

Which keyboard layout are you using? Perhaps using your keyboard's Right Shift key will help you write # symbols faster.

To write the Multi Line Comments """", I need to use both hands, and I still need to erase the four " twice

GDScript considers those as multi-line strings, not multi-line comments. There is no dedicated syntax for multi-line comments in GDScript; you just use a series of lines beginning with #.

Mickeon commented 2 years ago

Not necessarily against this, but I personally feel like the issues at hand could be solved by changing the comment toggle shortcut, or through some theoretical Plugin that replaces keyboard strokes with #.

To write the Multi Line Comments """"

That's no multi-line comment, it's just a multi-line string not assigned to anything. It's kind of like writing...

var something
something

...inside a function. To GDScript, this is valid syntax, but the latter statement actually does nothing tangible. I suppose that such a thing could be its own proposal.

Gurigraphics commented 2 years ago

I am against supporting multiple ways to write GDScript comments. There is no practical advantage to it; it only introduces confusion and choice paralysis for beginners. If you really want to use C-style syntax, use C# πŸ™‚

Thanks for reply. In my opinion learning to use one more symbol is not confusing for anyone. For me, I would just leave /. Because there is no evidence nor scientific that # is better. The # is just a not-so-well-chosen convention that can be overridden.

Which keyboard layout are you using? Perhaps using your keyboard's Right Shift key will help you write # symbols faster.

I use Brazil ABNT2. It's not very different from english I need to use Right Shift key and 3 key to write # The / I need only press /

GDScript considers those as multi-line strings, not multi-line comments. There is no dedicated syntax for multi-line comments in GDScript; you just use a series of lines beginning with #.

Thanks for the clarification. This is multi line comments that I referred https://www.tutorialspoint.com/how-to-write-multi-line-comment-in-java https://www.bitdegree.org/learn/javascript-comment https://www.tutorialspoint.com/comments-in-rust-programming

Gurigraphics commented 2 years ago

...inside a function. To GDScript, this is valid syntax, but the latter statement actually does nothing tangible. I suppose that such a thing could be its own proposal.

Yes. It's almost that. I commented there now. However, the /* */, like javascript, java, rust, etc, still need to press Shift or alphanumeric keyboard to use /* */

In summary, just not using the shift is already better.

aaronfranke commented 2 years ago

If we ever decide to add a floor division operator as //, having // for comments would conflict with this.

Xrayez commented 2 years ago

It looks to me that some languages do cover this use case of not having to press Shift,. Like in Lua:

Just a food for thought for future generations of programmers. πŸ˜›

The # is just a not-so-well-chosen convention that can be overridden.

I tend to agree here.

I use Brazil ABNT2. It's not very different from english I need to use Right Shift key and 3 key to write #

Interesting. The Lua author is from Brazil. πŸ˜ƒ

Gurigraphics commented 2 years ago

If we ever decide to add a floor division operator as //, having // for comments would conflict with this.

Well remembered. In this case you can use !%, because it's not something very used. The simplest symbols should be reserved for what is most used.

!% also means: no rest, I don't want the rest

>>> 5.0 / 2
2.5
>>> 5.0 % 2   
1.0
>>> 5.0 !% 2   
2.0
Gurigraphics commented 2 years ago

It looks to me that some languages do cover this use case of not having to press Shift,. Like in Lua:

  • -- for single line comments
  • --[[ and --]] for multiple line comments
  • ---[[ can be used to disable multiline comment

It's very practical to disable comments. I consider that it is already better that the "multine strings" that the user/dev experiences is very bad. Even so I would prefer to use only "--", "---" and "----"

Interesting. The Lua author is from Brazil. πŸ˜ƒ

Yes. Lua is widely used as a script for other low-level languages because it's as simple as GDScript. Another famous Brazilian language is -> Elixir Elixir also doesn't have multiline comments and use """ """ and #

Gurigraphics commented 2 years ago

Anyway, I don't want to convince and oblige anyone of anything. Everyone uses what they think is best. Can someone point me to the file/class where I change this just for me?

I found this. But I won't find the options """ and # https://github.com/godotengine/godot/blob/master/modules/gdscript/gdscript_tokenizer.cpp

Calinou commented 2 years ago

Anyway, I don't want to convince and oblige anyone of anything. Everyone uses what they think is best. Can someone point me to the file/class where I change this just for me?

If you make this change locally, you will have to recompile all export templates you plan on using, for every Godot version you plan to upgrade to in the future. Otherwise, the exported project will not be able to parse the GDScript code you wrote. It's a lot of work for a small syntax change.

Gurigraphics commented 2 years ago

If you make this change locally, you will have to recompile all export templates you plan on using, for every Godot version you plan to upgrade to in the future. Otherwise, the exported project will not be able to parse the GDScript code you wrote. It's a lot of work for a small syntax change.

Truth. The editor could serve as a transpiler. Import normal and convert. Then export normal. Or like Unity update old projects.

It's easier for me to create a plugin for my code editor. https://editoi.com With this I can take the opportunity to also replace the indentation of the functions that I also don't like.

I write in "Guriscript" like js:

myFun(key){
  if(1==1){
   return key
  }
}

And then this compiles to Hadouken :

  _myFun(): error(1,1): Unexpected indentation
      if(1==1): error(1,2): Unexpected indentation
         return 0  error(1,3): Unexpected indentation
            return 0 error(1,4): Unexpected indentation
                return 0 error(1,5): Unexpected indentation
                   return 0 error(1,6): Unexpected indentation
Gurigraphics commented 2 years ago

I did the usability test and it was excellent.

alt text

It didn't even take me 20 minutes to edit the Code Mirror plugin in my editor. To transpile the functions the most difficult is the typings.

YuriSizov commented 2 years ago

I write in "Guriscript" like js:

@Gurigraphics Or you can just use JS with Godot: https://github.com/GodotExplorer/ECMAScript.

I mean, you do you, but in the interest of preventing you from shooting yourself in a foot, I have to tell you that this is only going to backfire if you try to use this for an actual project. This is not practical, especially to just circumvent learning a new language.

You will have hard time using guides, recipes, and plugins from other people. You will also be unable to look for help from anyone if you do this. So at least consider using the aforementioned project, so you can at least discuss solutions with a community of people who are using the same tech instead of stumbling in the dark on your own.

Gurigraphics commented 2 years ago

For sure. A long time ago Unity had support for something like javascript. The problem was find tutorial on how to do things. With Cocos2D javascript version the same thing happened. There was only documentation in C++

I used Phaser and NW.js. I switched to Godot to be able to use the module GodotSteam which is the best wrapper for the Steam library. It is the only one with all methods implemented and with current SDK 1.53. Another advantage is the 30Mb single executable

I think GDscript is very good. Compared to C++, C# and Java, it is much less bureaucratic. However, in my opinion, to be one of the languages of the future, this could be more "customizable". Which is not synonymous with freedom to create bugs

I don't want to change the language completely. Only two things make the programming experience less enjoyable for me. What are these comments and functions. Gdscript, as language, has other priorities. About changing functions I hadn't even created a topic. I just tried to change it myself. Because if it is possible to go further, why not go?

I did another test. It still doesn't handle all the exceptions, but it worked well.

This is the gdScript code example

extends Node2D

#imports
var scene = preload("scene.gd").new()

func _connect_steam_signals():
    print("Start _connect_steam_signals")
    connect_signal("lobby_created", "_on_LobbyCreated")
    connect_signal("lobby_joined", "_on_LobbyJoined")

func _on_LobbyCreated(status, lobbyId) :
    if(status == Steam.LOBBY_OK):
        print( "STEAM: Lobby created (%s)!" % str(lobbyId) )
    else:
        print("STEAM: Lobby creation failed!")

    if(status == Steam.LOBBY_OK):
        print( "1" )
    else:
        print( "2" )
        if(status == Steam.LOBBY_OK):
            print( "4" )
        else:
            print( "5" )

    print("_on_LobbyCreated")
    print(status)
    print(lobbyId)

    GlobalSteam.setData('LOBBY_ID', lobbyId)

func _on_LobbyJoined(lobbyId, permissions, locked, response):
    print("_on_LobbyJoined")
    print(lobbyId)
    print(permissions)
    print(locked)
    print(response)

# Connect a Steam signal and show the success code
func _connect_signal(this_signal, this_function):
    var SIGNAL_CONNECT: int = Steam.connect(this_signal, self, this_function)
    print("[STEAM] Connecting "+str(this_signal)+" to "+str(this_function)+" successful: "+str(SIGNAL_CONNECT))

This is how I want to write the same thing

extends Node2D

//imports
var scene = preload("scene.gd").new()

def _connect_steam_signals(){
  print("Start _connect_steam_signals")
  connect_signal("lobby_created", "_on_LobbyCreated")
  connect_signal("lobby_joined", "_on_LobbyJoined")   
}

def _on_LobbyCreated(status, lobbyId) {  
  if(status == Steam.LOBBY_OK){
    print( "STEAM: Lobby created (%s)!" % str(lobbyId) )
  }else{
    print("STEAM: Lobby creation failed!")
  }

  if(status == Steam.LOBBY_OK){
    print( "1" )
  }else{    
    print( "2" )        
    if(status == Steam.LOBBY_OK){
      print( "4" )
    }else{
      print( "5" )
    }
  }

  print("_on_LobbyCreated")
  print(status) 
  print(lobbyId) 

  GlobalSteam.setData('LOBBY_ID', lobbyId)  
}

def _on_LobbyJoined(lobbyId, permissions, locked, response){  
  print("_on_LobbyJoined")
  print(lobbyId)
  print(permissions)
  print(locked)
  print(response)  
}

// Connect a Steam signal and show the success code
def _connect_signal(this_signal, this_function){  
  var SIGNAL_CONNECT: int = Steam.connect(this_signal, self, this_function)
  print("[STEAM] Connecting "+str(this_signal)+" to "+str(this_function)+" successful: "+str(SIGNAL_CONNECT))
}

This is the code that transforms this to gdscript

var transpile = {}

transpile.run = {}

var methods = ["includeComments", "isFunction"]
var openCount = 0

transpile.run.includeComments = (line) => {

  if( line.includes("//") ){

    line = line.replace("//", "#")

  }

  return line  
}

transpile.getTab = (max) => {

  var tab = "\t"
  var total = ""  
  for(let i=0; i<max; i++) total+=tab
  return total  
}

transpile.run.isFunction = (line, def) => {

  if(openCount){ //function is open

    if(line == '}' && openCount == 1){ //end function

      openCount = 0

      return ""

    }else if( line.includes('}') && !line.includes('{') ) {

      openCount-=1    

    }else if( line.includes('}') && line.includes('{') ) {

      var one = line.replace("}", "")
      var two = one.replace("{", ":")

      return transpile.getTab(openCount-1) + two

    }else if( line.includes('{') && !line.includes('}') ) { 

      var one = line.replace("{", ":")
      openCount+=1
      return transpile.getTab(openCount-1) + one 

    }

    if(line == '}'){

      return ""
    }  

    var content = transpile.getTab(openCount) + line

    return content

  }else if( def == "def" ){

    openCount = 1  

    var one = line.replace("def", "func")
    var two = one.replace("{", ":")    

    return two

  }else return line

}

transpile.gdscript = async( data ) => {

  var lines = data
  var newLines = []
  var result = []

  for(let method of methods) {

    for(let index in lines){ 

      var line = lines[index].trim()   

      if(!line) {    
        newLines.push("")
      }else{
        var def = line.split(" ")[0]
        var content = transpile.run[method]( line, def )
        newLines.push(content)
      }

    }

    lines = [ ...newLines ]  
    newLines = []

  }

  return lines.join("\n")  
}

There are several ways to do the same thing. Sometimes they are better. Other times it's just personal preferences. Convincing people of what is best is hard. Often they prefer the worst. Because not everything is good in every way.

Xrayez commented 2 years ago

However, in my opinion, to be one of the languages of the future, this could be more "customizable".

I'd say Godot is fairly a NIH engine (the lead developer does not see it as something negative), but this freedom results in inability to customize the engine when you have specific cases to solve (on the user side), so proposals like this are generally seen with a great pushback. The philosophy in Godot is generally: "one way or no way". Of course, that doesn't exclude the possibility to extend the engine, and there are plenty of ways to do this: GDScript plugins, GDExtension etc. I'm talking about the customization part. Note that I'm not implying that this is good or bad, but something to be aware of when writing feature proposals and using the engine.

I just tried to change it myself. Because if it is possible to go further, why not go?

If you do find that you also need the freedom, I suggest forking the engine locally for the project you're working on, it will pay off in the long run. But of course, it also depends on your own skill set and motivation. Of course, go this route only if you find yourself changing other stuff, not just comments style.

This is my personal experience, good luck!

Gurigraphics commented 2 years ago

I'd say Godot is fairly a NIH engine (the lead developer does not see it as something negative), but this freedom results in inability to customize the engine when you have specific cases to solve (on the user side), so proposals like this are generally seen with a great pushback. The philosophy in Godot is generally: "one way or no way". Of course, that doesn't exclude the possibility to extend the engine, and there are plenty of ways to do this: GDScript plugins, GDExtension etc. I'm talking about the customization part. Note that I'm not implying that this is good or bad, but something to be aware of when writing feature proposals and using the engine.

I understand. I also like the "Convention over configuration" concept. If I were asked to put # comments in my engine, I would probably ignore it. Also because I would have more relevant things to do.

Even so, I found the idea that came up interesting: be able to customize the way to write comments and functions. The programmer would be able to choose:

Like lua:

function add(a, b)    
  return a + b
end

Like js:

let add = (a, b) => {
  return a + b
}

Like rust

fn add(a) {
    println!(a);
}

Like python

def add_num(a,b):
    return a+b; 

Like C#

public static int Sum(int a, int b)
{       
 return a+b;
}

Or etc.

Because writing one way or another doesn't even make much difference. I thought this would be more complex, but it's simple to change. However, this is little related to Godot engine. But maybe as an editor plugin.

If you do find that you also need the freedom, I suggest forking the engine locally for the project you're working on, it will pay off in the long run. But of course, it also depends on your own skill set and motivation. Of course, go this route only if you find yourself changing other stuff, not just comments style.

Yes. On the bright side, my interest in compilers increased. I will go deeper into C++ and will even read the "Dragon Book". :)

So, I think I can close this Issue now. Thanks for the comments