SciTE - Toggle Block Comment -- NEU!! ​​ Zum Aufheben eines Kommentarblocks ist keinerlei Markierung notwendig!

  • Der Blockkommentar (intern: box comment) in SciTE kann leider nicht getoggled werden.

    Ich habe jetzt ein Skript erstellt, dass Abhilfe schafft. Es funktioniert mit jedem Dateityp, für den die entsprechenden Einträge in den Properties erstellt wurden.


    Anbindung:

    Code: SciTEUser.properties
    # 23 Toggle Block Comment **** freie Nummer suchen
    command.name.23.*=Toggle Block Comment
    command.23.*=dofile $(Lua.User.Scripts.Path)/blockcomment.lua **** hier der Speicherpfad, wenn in Windowsnotation: doppelte Backslash!!
    command.mode.23.*=subsystem:lua,savebefore:no
    command.shortcut.23.*=Ctrl+Shift+Q **** einen freien Hotkey eintragen oder den originalen (Ctrl+Shift+Q) dafür nutzen


    Ich schreibe neue EDITs jetzt mal an vorderer Position, muss man nicht erst alles alte durchwühlen. ;)


    EDIT v0.10

    Habe noch einen Fehler entfernt: Wenn die letzte markierte Zeile mit Text gleichzeitig die letzte Zeile im Editor ist, wurde comment.end hinter diese Zeile statt in eine neu gesetzt. Dadurch wurde beim Toggle die kpl. Zeile statt nur das comment.end gelöscht.



    EDIT v0.9

    Nun habe ich mich nochmals rangesetzt und einiges wieder geändert. Die Funktionsweise ist nun m.M. nach klarer.

    Man kann also recht zügig und ohne genau auf die Position der Markierung zu achten seinen Bereich auswählen.

    Im Skriptkopf findet ihr ein Bsp., wie das aussieht:



    Viel Spaß damit.






    ---------------------------------- alte Versionen -------------------------------

    EDIT v0.4

    Ich habe die Funktion nochmal gründlich überarbeitet und aufgehübscht. Jetzt wird eine leere Zeile vor/nach einer Blockmarkierung ignoriert und sauber umgeswitcht.

    Damit die Funktion automatisch das tut, was der User will, muss erkannt werden, ob bereits eine Blockmarkierung vorliegt oder nicht, bzw. ob der markierte Bereich mit einer Blockmarkierung beginnt (verschachtelte Blöcke sind ja möglich). Es gelten folgende Erkennungsregeln: s. v0.7


    • Markierung startet in einer Leerzeile (nur Zeilenumbruch) und die Folgezeile beginnt mit comment.box.start ==> Blockkommentar aufheben
      anderenfalls ==> Blockkommentar setzen
    • Markierung startet in einer Zeile mit Text, die Zeile beginnt mit comment.box.start ==> Blockkommentar aufheben
      anderenfalls ==> Blockkommentar setzen
    • Markierung endet in einer Leerzeile und die vorletzte Zeile der Markierung beginnt mit comment.box.end ==> beide Zeilen sind Teil des Kommentarblockes und werden gelöscht
    • Markierung endet in einer Zeile, die mit comment.box.end beginnt ==> Zeile wird gelöscht
    • Es müssen mindestens zwei Zeilen markiert werden

    EDIT v0.5

    Jetzt ist auch der überschüssige Zeilenumbruch nach dem Zurücksetzen der Blockmarkierung eliminiert. :thumbup:


    EDIT v0.6

    Wenn zum Entkommentieren falsch markiert wird (leere Zeile vor/nach Kommentarblock in der Markierung) wurden diese Zeilen bisher mit gelöscht. --> gefixed.


    EDIT v0.7

    • NEU!! Zum Aufheben eines Kommentarblocks ist keinerlei Markierung notwendig! Einfach den Cursor in eine beliebige Zeile oberhalb des Kommentarblocks (oder dessen Startzeile) setzen und Hotkey ausführen. Vom ersten gefundenen Kommentar.Start bis zum korrespondierenden Kommentar.End wird der Blockkommentar aufgehoben.
    • Um einen Kommentarblock zu setzen muß mindestens 1 Zeichen markiert werden.
    • Optionale Properties:
      comment.box.ignore.empty.before / comment.box.ignore.empty.after -- Zum Setzen des Kommentarblocks wird geregelt ob eine erste/letzte Leerzeile innerhalb der Markierung mit für den KOmmentar verwendet werden soll oder nicht (Standard: nicht)
      comment.box.output -- mit "1" erfolgt eine Konsolenausgabe zur ausgeführten Aktion, z.B. "++ COMMENT BLOCK - UNSET [line 103-106]"

    EDIT v0.8

    • Start-/Endmarkierung mitten in der jeweiligen Zeile (Zeile gehört zum Block)
    • Endmarkierung in nicht leerer Zeile am Anfang (Zeile gehört nicht zum Block)
  • Da stimmt aber was noch nicht ganz...



    EOL ist bei beiden CR+LF


    Code: local newLine = function(_line, _uncmt)
            ...
            else
                if bmiddle then _line = boxmiddle.._line
    else _line = _line end
            end

    Wofür das else _line = _line ?

  • Das war jetzt sehr gehässig... ich sende ab und sehe direkt die neue Version... jetzt wird nur noch bei beiden eine Leerzeile zu viel eingefügt, wenn der Kommentar wieder entfernt wird.


    Für comment.box.middle würde ich gerne ein TAB verwenden, doch SciTE filtert mir die aus, wenn sie am Ende einer Zeile stehen.

    Schön wäre, wenn es so ginge:

    comment.box.middle.lua=\t

  • jetzt wird nur noch bei beiden eine Leerzeile zu viel eingefügt, wenn der Kommentar wieder entfernt wird.

    Da werde ich mal dran basteln.


    Für comment.box.middle würde ich gerne ein TAB verwenden, doch SciTE filtert mir die aus, wenn sie am Ende einer Zeile stehen.

    Schön wäre, wenn es so ginge:

    comment.box.middle.lua=\t

    Das ist simpel:

    Verwende in der Property @Tab

    und ändere in der Funktion so:

  • Oder etwas flexibler. Eine zusätzliche Propertie anlegen, dann kann es jederzeit geändert werden:

    Code
    comment.box.tab.alternation=@Tab
    comment.box.start.au3=#cs
    comment.box.middle.au3=$(comment.box.tab.alternation)
    comment.box.end.au3=#ce
  • Da werde ich mal dran basteln.

    Ich habe es getestet und soweit ich das beurteilen kann, funktioniert es so:

    Code
    -- proceed with last line
    line = editor:GetLine(self.lineEnd)
    -- if uncomment the last line will ignored
    if not uncomment then
    self.newText = self.newText..self.boxMiddle..line..self.boxEnd
    else
    self.newText = self.newText:gsub('\r\n$', '', 1)
    end


    In der SciTEUser.properties habe ich noch folgende Zeilen hinzugefügt, weil in SciTEGlobal.properties comment.box.end.au3 ein Leerzeichen zu viel enthält und ich für comment.box.middle.au3 lieber auch ein TAB hätte:

    comment.box.end.au3= #CE ; SciTEGlobal.properties

    comment.box.end.au3=#CE ; SciTEUser.properties

    comment.box.middle.au3=; ; SciTEGlobal.properties

    comment.box.middle.au3=@Tab ; SciTEUser.properties


  • Kannst du bitte noch mal rein schauen...


    Markiere ich z.B. zwei Zeilen und lassen das Caret am Ende der zweiten Zeile stehen, funktioniert es, wie erwartet. Setzte ich das Caret aber an den Anfang der zweiten Zeile, dann wurde ja eigentlich nur eine Zeile markiert... werden aber trotzdem zwei Zeilen auskommentiert und es fehlt dann auch ein Zeilenumbruch, damit der Text hinter dem Caret in einer neuen Zeile beginnt.


    Wird nur ein Teil einer Zeile markiert, wird der markierte Teil einfach unterschlagen und der Text hinter dem Caret mit in die selbe Zeile geschrieben, sollte aber eine Zeile tiefer... das sollte auch abgefangen werden.


    Wurde bei self.lineStart und/oder bei self.lineEnd eine leere Zeile markiert, sollten diese nicht berücksichtigt werden. Ist dazwischen nur eine Zeile mit Text, dann bitte nur die in den Block setzen.

  • Setzte ich das Caret aber an den Anfang der zweiten Zeile, dann wurde ja eigentlich nur eine Zeile markiert.

    Eigentlich ist ein schönes Wort. :D

    Denn eigentlich hast du zwei Zeilen markiert - kann ja interpretiert werden als: da gehört jetzt noch eine Leerzeile in den Block und nur wenn die Markierung hinter dem Text endet, ist diese Zeile allein gemeint. ;)

    Ich will aber sowieso noch ein paar Erweiterungen vornehmen, kümmere ich mich am WE drum.

  • BugFix

    Hat den Titel des Themas von „SciTE - Toggle Block Comment“ zu „SciTE - Toggle Block Comment -- NEU!! ​​ Zum Aufheben eines Kommentarblocks ist keinerlei Markierung notwendig!“ geändert.
  • Das stimmt so aber immer noch nicht...


    comment.box.end.au3=#CE

    comment.box.middle.au3=@Tab

    comment.box.tab.alternation=@Tab ; <== Für diese Variable erkenne ich auch bei aller Anstrengung keinen Mehrwert!

    comment.box.ignore.empty.before=1

    comment.box.ignore.empty.after=1

    comment.box.output=0


    Im oberen Ausschnitt habe ich bis vor Exit markiert... das Caret steht in Zeile 17.

    ...und das passiert dann damit... das Exit hinter #CE ist zu viel und das Exit darüber dürfte nicht mit im Kommentarblock sein!


    Gehe ich mit dem Caret nur bis ans Ende von Zeile 16, funktioniert es.

  • comment.box.tab.alternation=@Tab ; <== Für diese Variable erkenne ich auch bei aller Anstrengung keinen Mehrwert!

    Da nur sichtbare Zeichen als Property gesetzt werden können, muss der Anwender über ein Ersatzzeichen mitteilen, dass ein Tab zur Anwendung kommen soll.

    Ich hätte auch festschreiben können: Soll ein Tab als box.middle verwendet werden so muss als Zeichen dafür "T" verwendet werden. In diesem Fall wäre die Property tatsächlich überflüssig.

    Da ich aber dem Anwender freie Wahl bei der Definition für seine Tab-Variable ermöglichen will ("@TAB", "tab", "BunteKuh",...) muss für den Fall, dass Tab verwendet werden soll das/die entsprechende/n Zeichen dort definiert werden und in box.middle wird darauf verwiesen: comment.box.middle.au3=$(comment.box.tab.alternation)

    Im Skript prüfe ich:

    comment.box.middle. nicht-leer ? --> comment.box.middle == comment.box.tab.alternation ? --> OK, TAB soll als box.middle verwendet werden.

    ...und das passiert dann damit... das Exit hinter #CE ist zu viel und das Exit darüber dürfte nicht mit im Kommentarblock sein!

    Du hast sowas von Recht, und ich bin froh dich als Tester zu haben. :thumbup:

    Ich hatte zwar im Vorfeld alle möglichen (und vor allem unmöglichen :D ) Markierungsvarianten überlegt, aber dann 2 vergessen umzusetzen:

    Das ist nun korrigiert. (poste es gleich)


    NEU v 0.8 - s. Post #1


    - Start-/Endmarkierung mitten in der jeweiligen Zeile (Zeile gehört zum Block)

    - Endmarkierung in nicht leerer Zeile am Anfang (Zeile gehört nicht zum Block)

  • Ja... so gefällt mir das! :thumbup:


    Hier noch ein paar Anregungen:

    • Wenn nichts markiert wurde, sollte es egal sein, wo das Caret steht, solange es sich in einer Start-/Endzeile oder sonstwo innerhalb eines Kommentarblocks befindet, um den Kommentarblock wieder zu entfernen.
    • Wenn sich in der Selektion eine Start-/Endzeile befindet, jedoch kein Gegenstück dazu, sollte das als Fehler gewertet und kein Kommentarblock erzeugt werden.
    • comment.box.tab.alternation und comment.box.middle
      Allgemein ist es sicher besser, die Einführung neuer Properties zu vermeiden, wenn sich eine Funktion mit etwa gleichem Aufwand durch bereits vorhandene Properties steuern lässt.
      Was Einrückungen angeht, sollten Kommentarblöcke nicht anders als Funktionsblöcke gehandhabt werden.
      Ich denke, comment.box.middle ist nicht dazu gedacht, um Einrückungen zu definieren, sondern um dem Kommentar ein oder mehrere druckbare Zeichen voranzustellen.

      Anhand folgender Properties kann bestimmt werden, ob bzw. wie comment.box.middle eingerückt wird:
      Globale Properties:
      use.tabs, tabsize, indent.size ; Default: tabsize=4, indent.size=4, use.tabs=1
      File spezifische Properties:
      use.tabs.filepattern, tab.size.filepattern, indent.size.filepattern ; Wurden z.B. für *.au3 keine File spezifischen Properties angegeben, werden die globalen verwendet.

    Bsp.:


  • Wenn nichts markiert wurde, sollte es egal sein, wo das Caret steht, solange es sich in einer Start-/Endzeile oder sonstwo innerhalb eines Kommentarblocks befindet, um den Kommentarblock wieder zu entfernen.

    Das halte ich nicht für sehr sinnvoll. Wenn zuviel Möglichkeiten sind, sind zuviel Fehlinterpretationen möglich. "Der Cursor muss in seiner Zeile oder einer der folgenden Zeilen comment.start finden". Das entspricht auch unserem visuellen Vorgehen: Von oben nach unten.

    Die Position innerhalb eines Kommentarblocks zu erkennen, kann ich zwar sicher für Lua und AutoIt (weil ich da weiß, welcher Style jeweils verwendet wird), aber eben nicht allgemeingültig, weil nirgendwo ausgelesen werden kann, welchen Style der jeweilige Dateityp für Blockkommentare nutzt. Das ist in der Lexer.dll definiert. In den Properties sieht man das nur anhand der Kommentare, die aber auch unterschiedlich und somit nicht zuverlässig sind.

    Wo ich noch mitgehen könnte: Cursor vor/in comment.start Zeile oder in comment.end Zeile

    Allerdings wäre das nicht mehr kongruent in der Anwendungsweise, dann sollte man lieber sagen: in comment.start Zeile oder in comment.end Zeile

    Was meinst du?


    Wenn sich in der Selektion eine Start-/Endzeile befindet, jedoch kein Gegenstück dazu, sollte das als Fehler gewertet und kein Kommentarblock erzeugt werden.

    Ähm, der Anwender hat also ohne Sinn und Verstand ein einzelnes #cs oder #ce in sein Skript geklatscht und das soll ich abfangen? In kleinen Skripten könnte man das tun, aber stell dir mal ein paar tausend Zeilen Code vor. Es muss das gesamte Skript vom Anfang bis zur Cursorposition gescannt werden um die korrelierenden start-end Zuordnungen zu erhalten. Das halte ich nicht für erstrebenswert. Etwas an Denkprozessen darf man ruhig auf den Anwender übertragen. :whistling:


    Ich denke, comment.box.middle ist nicht dazu gedacht, um Einrückungen zu definieren, sondern um dem Kommentar ein oder mehrere druckbare Zeichen voranzustellen.

    OK, da kann ich mitgehen.


    Anhand folgender Properties kann bestimmt werden, ob bzw. wie comment.box.middle eingerückt wird:

    Ja OK. Doch trotzdem muss an irgendeiner Stelle definiert werden: Ja, ich will (auch Kommentarblöcke) einrücken oder eben nicht. Denn ich kann ja nicht vom Anwender unabhängig einfach festlegen, dass eingerückt wird. Also ist zumindest eine weitere Property erforderlich, z.B. comment.box.indent.filepattern=0/1

  • Was meinst du?

    Ja, ok, so wichtig ist das nun auch nicht... habe dazu was getippt, um an den Style zu kommen, sollte eigentlich funktionieren, aber da ist irgendwie der Wurm drin!


    Etwas an Denkprozessen darf man ruhig auf den Anwender übertragen.

    Habe ich mir gedacht, das du das sagst. ;-) Ja, ok, muss auch nicht sein.


    Also ist zumindest eine weitere Property erforderlich

    Auch ok... wobei ich das sicher nie brauchen werde.