main.tcl
README.md

main.tcl

  • main.tcl
  • Variables
  • Common
    • CurrentWTXT main::CurrentWTXT : Gets a current text widget's path.
    • GetWTXT main::GetWTXT : Gets a text widget's path of a tab. TID - ID of the tab
    • ClearCbx main::ClearCbx : Clears a combobox's value and removes it from the combobox' list. cbx - the combobox's path varname - name of variable used in the current namespace
    • SetTabs main::SetTabs : Configures tabs of a text. wtxt - text's path indent - indentation (= tab's length)
    • Help main::Help : Display context helps. suff - suffix of file name
  • Get and show text widget
    • GetText main::GetText : Creates or gets a text widget for a tab. TID - tab's ID doshow - flag "this widget should be displayed" dohighlight - flag "this text should be highlighted" Returns a list of: curfile (current file name), wtxt (text's path), wsbv (scrollbar's path), pos (cursor's position), doinit (flag "initialized") dopack (flag "packed") selrange (selected text's range)
    • ShowText main::ShowText : Displays a current text.
    • UpdateHighlighting main::UpdateHighlighting : Updates the current text's highlighting.
  • Updating gutter & text
    • UpdateGutter main::UpdateGutter : Redraws the gutter.
    • GutterAttrs main::GutterAttrs : Returns list of gutter's data (canvas widget, width, shift)
    • UpdateText main::UpdateText : Redraws a text. wtxt - the text widget's path curfile - file name of the text
    • UpdateTextGutter main::UpdateTextGutter : Redraws both a text and a gutter.
    • UpdateUnitTree main::UpdateUnitTree : Redraws unit tree at need.
    • UpdateAll main::UpdateAll : Updates tree, text and gutter. headers - headers of all selected units
    • UpdateTextGutterTree main::UpdateTextGutterTree : Updates after replacements: text, gutter, unit tree.
    • UpdateIcons main::UpdateIcons : Updates after replacements: icons.
    • UpdateTextGutterTreeIcons main::UpdateTextGutterTreeIcons : Updates after replacements: text, gutter, unit tree, icons.
  • Mark bar
    • FillMarkBar main::FillMarkBar : Fills the mark bar, makes bindings for its tags. args - if set, contains canvas' path It's run from InitActions without *args*. See also: InitActions
    • UpdateMarkBar main::UpdateMarkBar : Updates mark bar at changing -bg color.
    • SetMark main::SetMark : Sets a mark in the mark bar. idx - index of tag used as the mark
    • UnsetMark main::UnsetMark : Unsets a mark in the mark bar or call a popup menu. idx - index of tag used as the mark X - X-coordinate of pointer Y - Y-coordinate of pointer
    • MarkWidth main::MarkWidth : Change the mark bar's width. i - 1/-1 to increment/decrement
    • MarkWidthSave main::MarkWidthSave : Saves alited.ini at need.
    • UnsetOneMark main::UnsetOneMark : Unsets one mark in the mark bar. idx - index of tag used as the mark
    • UnsetAllMarks main::UnsetAllMarks : Unsets all marks in the mark bar.
    • SaveMarks main::SaveMarks : Saves mark data for a text to be closed. wtxt - text's path
    • RestoreMarks main::RestoreMarks : Restores mark data for a text to be shown. fname - file name wtxt - text's path
    • MarkOptions main::MarkOptions : Returns options for marks. idx - index of tag
  • Focus
    • FocusText main::FocusText : Sets a focus on a current text. args - contains tab's ID and a cursor position.
    • FocusInText main::FocusInText : Processes event on the text. TID - tab's ID wtxt - text widget's path
  • Highlight
    • HighlightText main::HighlightText : Highlights a file's syntax constructs. TID - tab's ID curfile - file name wtxt - text widget's path cmd - callback for modifying text cmdpos - callback for changing cursor position fontsize - text font size Depending on a file name, Tcl or C highlighter is called.
    • HighlightLine main::HighlightLine : Highlights a current line of a current text.
  • Line
    • CursorPos main::CursorPos : Displays a current text's row and column in the status bar. wtxt - text widget's path args - contains a cursor position,
    • InsertLine main::InsertLine : Puts a new line into a text, attentive to a previous line's indentation.
    • GotoBracket main::GotoBracket : Processes Alt+B keypressing: "go to a matched bracket". frommenu - yes, if run from a menu search a pair for a bracket highlighted
    • GotoLine main::GotoLine : Processes Ctrl+G keypressing: "go to a line".
  • Event handlers
    • SaveVisitInfo main::SaveVisitInfo : Remembers data about current unit. wtxt - text's path K - key pressed (to check keypressings) s - key's state
    • SaveLast2 main::SaveLast2 : Saves the current text's info in last two visited, to switch them. See also: unit::SwitchUnits
    • AfterUndoRedo main::AfterUndoRedo : Actions after undo/redo.
    • AfterCut main::AfterCut : Actions after cutting text: resets the unit tree's selection.
  • GUI
    • ShowHeader main::ShowHeader : Displays a file's name and modification flag (*) in alited's title. doit - if yes, displays unconditionally. If *doit* is *no*, displays only at changing a file name or a flag.
    • CalcIndentation main::CalcIndentation : Check for "Auto detection of indentation" and calculates it at need. wtxt - text's path doit - if yes, recalculates the indentation
    • CalcPad main::CalcPad : Calculates the indenting pad for the edited text. wtxt - text's path
    • UpdateProjectInfo main::UpdateProjectInfo : Displays a project settings in the status bar. indent - indentation calculated for a text
    • TipStatus main::TipStatus : Gets a tip for a status bar's short info.
    • BindsForText main::BindsForText : Sets bindings for a text. TID - tab's ID wtxt - text widget's path
    • BindsForCode main::BindsForCode : Sets bindings for a code. wtxt - text widget's path curfile - current file's name if {[alited::file::IsTcl $curfile] || [alited::file::IsClang $curfile]} {
    • PackTextWidgets main::PackTextWidgets : Packs a text and its scrollbar. wtxt - text widget's path wsbv - scrollbar widget's path
    • ShowOutdatedTODO main::ShowOutdatedTODO : Shows a balloon with outdated TODO. prj - project's name date - date of TODO todo - text of TODO is - 1 for current day TODO, 2 for "ahead" TODO
    • InitActions main::InitActions : Initializes working with a main form of alited.
    • ProcMessage main::ProcMessage : Handles clicking on message label.
  • Main _create
    • _create main::_create : Creates a main form of the alited.
  •   Main window
  •     Main pan
  •     Tree pan
  •       Tree's toolbar
  •       Tree
  •     Favorites
  •       Favorites' toolbar
  •       Favorites' list
  •     Tab bar & Text
  •     Find units
  •     Info & status bar
  • Main _run
    • _run main::_run : Runs the alited, displaying its main form with attributes 'modal', 'not closed by Esc', 'decorated with Contract/Expand buttons', 'minimal sizes' and 'saved geometry'. After closing the alited, saves its settings (geometry etc.). See also: menu::TearoffCascadeMenu
  • EOF

alited's source

The alited/src directory contains alited's own source files.

Some additional alited's files are also contained in alited/lib/addon directory (alited/lib directory contains all library files).

  • about.tcl - "About alited" dialogue.
  • alited.tcl - The alited's main script to start.
  • bar.tcl - Handles the bar of tabs.
  • check.tcl - "Check Tcl" dialogue and procedures.
  • complete.tcl - Handles auto-completion.
  • edit.tcl - "Edit" menu's procedures.
  • favor.tcl - Handles the favorite and last visited units.
  • favor_ls.tcl - "Saved lists of favorites" dialogue and procedures.
  • file.tcl - "File" menu's procedures.
  • find.tcl - "Find / Replace" dialogue and procedures.
  • format.tcl - "Edit / Formats" menu's procedures.
  • img.tcl - List of images used by alited.
  • indent.tcl - Handles text indentation.
  • info.tcl - Handles the info bar.
  • ini.tcl - Handles initializing alited.
  • keys.tcl - Handles keyboard (mapping etc.).
  • main.tcl - Handles the main form of alited.
  • menu.tcl - Handles alited's menus.
  • msgs.tcl - Localized messages used in several places.
  • paver.tcl - "Tools / Paver" tool.
  • pkgIndex.tcl - Includes README.md text (for Ruff doc generator).
  • pref.tcl - "Preferences" dialogue and procedures.
  • preview.tcl - "Preview (theme, CS)" dialogue called by "Preferences".
  • printer.tcl - "Tools / Project Printer" dialogue and procedures.
  • project.tcl - "Projects" dialogue and procedures.
  • run.tcl - "Tools / Run..." dialogue and procedures.
  • tool.tcl - "Tools" menu's procedures.
  • tree.tcl - Handles the tree of units and files.
  • unit.tcl - Handles the unit tree.
  • unit_tpl.tcl - "Templates" dialogue and procedures.
  • main.tcl
    ###########################################################
    # Name:    main.tcl
    # Author:  Alex Plotnikov  (aplsimple@gmail.com)
    # Date:    06/20/2021
    # Brief:   Handles the main form of alited.
    # License: MIT.
    ###########################################################
    
    # _________________________ Variables ________________________ #
    
    namespace eval main {
      variable findunits 1     ;# where to find units: 1 current file, 2 all
      variable gotoline1 {}    ;# line number of "Go to Line" dialogue
      variable gotoline2 {}    ;# units list of "Go to Line" dialogue
      variable gotolineTID {}  ;# tab ID last used in "Go to Line" dialogue
      variable wcan {} fgcan {} bgcan {}   ;# canvas' path and its colors
      variable saveini no      ;# flag "save alited.ini"
    }
    
    # ________________________ Common _________________________ #
    
    proc main::CurrentWTXT {} {
      # Gets a current text widget's path.
    
      return [lindex [alited::bar::GetBarState] 2]
    }
    #_______________________
    
    proc main::GetWTXT {TID} {
      # Gets a text widget's path of a tab.
      #   TID - ID of the tab
    
      return [alited::bar::GetTabState $TID --wtxt]
    }
    #_______________________
    
    proc main::ClearCbx {cbx varname} {
      # Clears a combobox's value and removes it from the combobox' list.
      #   cbx - the combobox's path
      #   varname - name of variable used in the current namespace
    
      set val [string trim [$cbx get]]
      set values [$cbx cget -values]
      if {[set i [lsearch -exact $values $val]]>-1} {
        set values [lreplace $values $i $i]
        $cbx configure -values $values
      }
      set $varname $values
    }
    #_______________________
    
    proc main::SetTabs {wtxt indent} {
      # Configures tabs of a text.
      #   wtxt - text's path
      #   indent - indentation (= tab's length)
    
      namespace upvar ::alited al al
      set texttabs [expr {$indent * [font measure $al(FONT,txt) 0]}]
      $wtxt configure -tabs "$texttabs left" -tabstyle wordprocessor
    }
    #_______________________
    
    proc main::Help {{suff ""}} {
      # Display context helps.
      #   suff - suffix of file name
    
      alited::Help $::alited::al(WIN) $suff
    }
    
    # ________________________ Get and show text widget _________________________ #
    
    proc main::GetText {TID {doshow no} {dohighlight yes}} {
      # Creates or gets a text widget for a tab.
      #   TID - tab's ID
      #   doshow - flag "this widget should be displayed"
      #   dohighlight - flag "this text should be highlighted"
      # Returns a list of: curfile (current file name),
      # wtxt (text's path), wsbv (scrollbar's path),
      # pos (cursor's position), doinit (flag "initialized")
      # dopack (flag "packed")
      # selrange (selected text's range)
    
      namespace upvar ::alited al al obPav obPav
      set curfile [alited::bar::FileName $TID]
      # initial text and its scrollbar:
      set wtxt [$obPav Text]
      set wsbv [$obPav SbvText]
      # get data of the current tab
      lassign [alited::bar::GetBarState] TIDold fileold wold1 wold2
      lassign [alited::bar::GetTabState $TID --pos --selection --wrap] pos selrange wrap
      set doreload no  ;# obsolete
      set doinit yes
      if {$TIDold eq {-1} && $TID eq {tab0}} {
        ;# first text to edit in original Text widget: create its scrollbar
        BindsForText $TID $wtxt
        ::apave::logMessage "first $curfile"
      } elseif {[GetWTXT $TID] ne {}} {
        # edited text: get its widgets' data
        lassign [alited::bar::GetTabState $TID --wtxt --wsbv] wtxt wsbv
        set doinit no
      } else {
        # till now, not edited text: create its own Text/SbvText widgets
        append wtxt "_$TID"  ;# new text
        append wsbv "_$TID"  ;# new scrollbar
      }
      if {![string is double -strict $pos]} {set pos 1.0}
      # check for previous text and hide it, if it's not the selected one
      set dopack [expr {$TID ne $TIDold}]
      alited::bar::SetTabState $TID --fname $curfile --wtxt $wtxt --wsbv $wsbv
      # create the text and the scrollbar if new
      if {![winfo exists $wtxt]} {
        lassign [GutterAttrs] canvas width shift
        set texopts [lindex [::apave::defaultAttrs tex] 1]
        lassign [::apave::extractOptions texopts -selborderwidth 1] selbw
        text $wtxt {*}$texopts
        $wtxt tag configure sel -borderwidth $selbw
        $obPav themeNonThemed [winfo parent $wtxt]
        $obPav bindGutter $wtxt $canvas $width $shift
        ttk::scrollbar $wsbv -orient vertical -takefocus 0
        $wtxt configure -yscrollcommand "$wsbv set"
        $wsbv configure -command "$wtxt yview"
        BindsForText $TID $wtxt
        alited::file::OutwardChange $TID no
      }
      if {[winfo exists $wold1]} {
        # previous text: save its state
        alited::bar::SetTabState $TIDold --pos [$wold1 index insert] --selection [$wold1 tag ranges sel]
        if {$dopack && $doshow} {
          # hide both previous
          pack forget $wold1  ;# a text
          pack forget $wold2  ;# a scrollbar
          after idle update
        }
      }
      # show the selected text
      if {$doshow} {
        alited::bar::SetBarState [alited::bar::CurrentTabID] $curfile $wtxt $wsbv
      }
      if {$doinit} {
        # if the file isn't read yet, read it and initialize its highlighting
        if {$al(prjindent)>1 && $al(prjindent)<9 && !$al(prjindentAuto)} {
          SetTabs $wtxt $al(prjindent)
        }
        alited::file::DisplayFile $TID $curfile $wtxt $doreload
        RestoreMarks $curfile $wtxt
        if {$al(prjindentAuto)} {
          SetTabs $wtxt [lindex [CalcIndentation $wtxt] 0]
        }
        if {$doshow} {
          HighlightText $TID $curfile $wtxt
        } else {
          alited::file::MakeThemHighlighted $TID  ;# postpone the highlighting till a show
        }
      } elseif {$dohighlight && [alited::file::ToBeHighlighted $wtxt]} {
        HighlightText $TID $curfile $wtxt
        if {$al(TREE,isunits)} alited::tree::RecreateTree
      }
      list $curfile $wtxt $wsbv $pos $doinit $dopack $selrange $wrap
    }
    #_______________________
    
    proc main::ShowText {} {
      # Displays a current text.
    
      namespace upvar ::alited al al obPav obPav
      set TID [alited::bar::CurrentTabID]
      lassign [GetText $TID yes] curfile wtxt wsbv pos doinit dopack selrange wrap
      if {$dopack} {
        PackTextWidgets $wtxt $wsbv
      }
      if {$doinit || $dopack} {
        # for newly displayed text: create also its unit tree
        set al(TREE,units) no
        alited::tree::Create
        after idle alited::main::SaveVisitInfo
      }
      # this code below redraws the tree's scrollbar
      set wtree [$obPav Tree]
      $wtree configure -yscrollcommand [$wtree cget -yscrollcommand]
      FocusText $TID $pos
      focus $wtxt
      alited::tree::SeeTreeItem
      alited::tree::IconContract
      if {$selrange ne {}} {
        catch {$wtxt tag add sel {*}$selrange}
      }
      if {$wrap eq {none}} {
        alited::bar::SetTabState $TID --wrap {}  ;# because it's the very first enter
        alited::file::WrapLines yes
      }
      # update "File" menu and app's header
      alited::menu::CheckMenuItems
      ShowHeader
      # fill Type Templates menu
      catch {after cancel $al(afterFillTTMenu)}
      set al(afterFillTTMenu) [after 500 {after idle alited::unit::FillTypeTplMenu}]
    }
    #_______________________
    
    proc main::UpdateHighlighting {} {
      # Updates the current text's highlighting.
    
      set TID [alited::bar::CurrentTabID]
      lassign [GetText $TID] curfile wtxt
      HighlightText $TID $curfile $wtxt
    }
    
    # ________________________ Updating gutter & text _________________________ #
    
    proc main::UpdateGutter {} {
      # Redraws the gutter.
    
      namespace upvar ::alited obPav obPav
      set wtxt [CurrentWTXT]
      after idle [list after 0 "$obPav fillGutter $wtxt"]
    }
    #_______________________
    
    proc main::GutterAttrs {} {
      # Returns list of gutter's data (canvas widget, width, shift)
    
      namespace upvar ::alited al al obPav obPav
      list [$obPav GutText] $al(ED,gutterwidth) $al(ED,guttershift)
    }
    #_______________________
    
    proc main::UpdateText {{wtxt {}} {curfile {}}} {
      # Redraws a text.
      #   wtxt - the text widget's path
      #   curfile - file name of the text
    
      namespace upvar ::alited obPav obPav
      if {$wtxt eq {}} {set wtxt [CurrentWTXT]}
      if {$curfile eq {}} {set curfile [alited::bar::FileName]}
      if {[alited::file::IsClang $curfile]} {
        ::hl_c::hl_text $wtxt
      } else {
        ::hl_tcl::hl_text $wtxt
      }
    }
    #_______________________
    
    proc main::UpdateTextGutter {} {
      # Redraws both a text and a gutter.
    
      UpdateGutter
      UpdateText
    }
    #_______________________
    
    proc main::UpdateUnitTree {} {
      # Redraws unit tree at need.
    
      set fname [alited::bar::FileName]
      if {$::alited::al(TREE,isunits) && [alited::file::IsUnitFile $fname]} {
        alited::tree::RecreateTree
      }
    }
    #_______________________
    
    proc main::UpdateAll {{headers {}}} {
      # Updates tree, text and gutter.
      #   headers - headers of all selected units
    
      alited::tree::RecreateTree {} $headers
      UpdateTextGutter
      HighlightLine
    }
    #_______________________
    
    proc main::UpdateTextGutterTree {} {
      # Updates after replacements: text, gutter, unit tree.
    
      UpdateTextGutter
      UpdateUnitTree
    }
    #_______________________
    
    proc main::UpdateIcons {} {
      # Updates after replacements: icons.
    
      alited::bar::OnTabSelection [alited::bar::CurrentTabID]
    }
    #_______________________
    
    proc main::UpdateTextGutterTreeIcons {} {
      # Updates after replacements: text, gutter, unit tree, icons.
    
      UpdateTextGutterTree
      UpdateIcons
    }
    
    # ________________________ Mark bar _________________________ #
    
    proc main::FillMarkBar {args} {
      # Fills the mark bar, makes bindings for its tags.
      #   args - if set, contains canvas' path
      # It's run from InitActions without *args*.
      # See also: InitActions
    
      namespace upvar ::alited al al obPav obPav
      variable wcan
      variable fgcan
      variable bgcan
      lassign [MarkOptions] N
      if {[llength $args]} {
        lassign $args wcan
        $wcan create rectangle "0 0 99 9999" -fill $bgcan -outline $bgcan
        return
      }
      lassign [split [winfo geometry [$obPav Text]] x+] -> h
      set hp [expr {int($h/$N-0.5)}]
      $wcan configure -highlightbackground $bgcan -highlightthickness 0
      for {set i 0; set y 1} {$i<($N+1)} {incr i} {
        lassign [MarkOptions $i] -> tip mark
        set y2 [expr {$y+$hp}]
        if {$i==$N} {incr y2 9999}
        set al($mark) [$wcan create rectangle "1 $y 99 $y2" -fill $bgcan -outline $fgcan]
        if {$i<$N} {
          $wcan bind $al($mark) <ButtonPress-1> "alited::main::SetMark $i"
          $wcan bind $al($mark) <ButtonPress-3> "alited::main::UnsetMark $i %X %Y"
          UnsetOneMark $i
        }
        incr y $hp
      }
    }
    #_______________________
    
    proc main::UpdateMarkBar {} {
      # Updates mark bar at changing -bg color.
    
      namespace upvar ::alited al al
      lassign [MarkOptions] N
      for {set i 0} {$i<$N} {incr i} {
        lassign [MarkOptions $i] - - - markdata
        if {![info exists al($markdata)]} {UnsetOneMark $i}
      }
    }
    #_______________________
    
    proc main::SetMark {idx} {
      # Sets a mark in the mark bar.
      #   idx - index of tag used as the mark
    
      namespace upvar ::alited al al
      variable wcan
      lassign [MarkOptions $idx] -> tip mark markdata colors
      $wcan itemconfigure $al($mark) -fill [lindex $colors $idx]
      set tag MARK$idx
      if {[info exists al($markdata)]} {
        lassign $al($markdata) fname pos
        set TID [alited::file::OpenFile $fname]
        if {$TID ne {}} {
          set wtxt [GetWTXT $TID]
          lassign [$wtxt tag ranges $tag] pos2
          if {[string is double -strict $pos2]} {set pos $pos2}
          after idle "::tk::TextSetCursor $wtxt $pos ; alited::main::UpdateAll"
        }
      } else {
        set fname [alited::bar::FileName]
        set wtxt [CurrentWTXT]
        set pos [$wtxt index insert]
        set nl [expr {int($pos)}]
        set al($markdata) [list $fname $pos $wtxt $tag]
        set line [string trim [$wtxt get $nl.0 $nl.end]]
        set lmax 50
        if {[string length $line]>$lmax} {
          set line [string range $line 0 $lmax]...
        }
        set tip [string trim "[file tail $fname] $nl:\n$line"]
        ::baltip::tip $wcan $tip -ctag $al($mark) -shiftX 10 -pause 0
        ::baltip repaint $wcan
      }
      catch {$wtxt tag delete $tag}
      $wtxt tag add $tag $pos
    }
    #_______________________
    
    proc main::UnsetMark {idx X Y} {
      # Unsets a mark in the mark bar or call a popup menu.
      #   idx - index of tag used as the mark
      #   X - X-coordinate of pointer
      #   Y - Y-coordinate of pointer
    
      namespace upvar ::alited al al
      variable wcan
      set disabletips no
      lassign [MarkOptions $idx] N tip mark markdata
      if {[info exists al($markdata)]} {
        set disabletips yes
        UnsetOneMark $idx
      } else {
        set disabletips yes
        set popm $al(WIN).popmMARK
        catch {destroy $popm}
        menu $popm -tearoff 1 -title $al(MC,marks)
        $popm add command -label [msgcat::mc {Clear All}] \
          -command "alited::main::UnsetAllMarks"
        $popm add separator
        set lab [msgcat::mc Width]
        $popm add command -label "$lab +" -command "alited::main::MarkWidth 1"
        $popm add command -label "$lab -" -command "alited::main::MarkWidth -1"
        $popm add separator
        $popm add command -label $al(MC,help) -command {alited::main::Help mark}
        tk_popup $popm $X $Y
      }
      if {$disabletips && ![info exists al(MARK_TIPOFF)]} {
        # disable all default tips on empty marks
        set al(MARK_TIPOFF) 1
        for {set i 0} {$i<$N} {incr i} {
          lassign [MarkOptions $i] - - - data
          if {![info exists al($data)]} {
            UnsetOneMark $i
          }
        }
      }
    }
    #_______________________
    
    proc main::MarkWidth {i} {
      # Change the mark bar's width.
      #   i - 1/-1 to increment/decrement
    
      namespace upvar ::alited al al
      variable wcan
      variable saveini
      set width [$wcan cget -width]
      incr width $i
      if {$width>=5 && $width<=99} {
        $wcan configure -width $width
        set al(markwidth) $width
        set saveini yes
        after 3000 alited::main::MarkWidthSave
      } else {
        bell
      }
    }
    #_______________________
    
    proc main::MarkWidthSave {} {
      # Saves alited.ini at need.
    
      variable saveini
      if {$saveini} {
        set saveini no
        alited::ini::SaveIni
      }
    }
    #_______________________
    
    proc main::UnsetOneMark {idx} {
      # Unsets one mark in the mark bar.
      #   idx - index of tag used as the mark
    
      namespace upvar ::alited al al
      variable wcan
      variable bgcan
      lassign [MarkOptions $idx] N tip mark markdata
      $wcan itemconfigure $al($mark) -fill $bgcan
      ::baltip::tip $wcan $tip -ctag $al($mark) -shiftX 10
      catch {
        lassign $al($markdata) fname pos wtxt tag
        unset al($markdata)
        $wtxt tag delete $tag
      }
    }
    #_______________________
    
    proc main::UnsetAllMarks {} {
      # Unsets all marks in the mark bar.
    
      variable wcan
      variable bgcan
      lassign [MarkOptions] N
      for {set i 0} {$i<$N} {incr i} {
        UnsetOneMark $i
      }
    }
    #_______________________
    
    proc main::SaveMarks {wtxt} {
      # Saves mark data for a text to be closed.
      #   wtxt - text's path
    
      namespace upvar ::alited al al
      foreach tag [$wtxt tag names] {
        if {[string match MARK* $tag]} {
          set idx [string range $tag 4 end]
          lassign [MarkOptions $idx] -> tip mark markdata
          catch {
            lassign $al($markdata) fname pos
            lassign [$wtxt tag ranges $tag] pos
            set al($markdata) [list $fname $pos $wtxt $tag]
          }
        }
      }
    }
    #_______________________
    
    proc main::RestoreMarks {fname wtxt} {
      # Restores mark data for a text to be shown.
      #   fname - file name
      #   wtxt - text's path
    
      namespace upvar ::alited al al
      lassign [MarkOptions] N
      for {set i 0} {$i<$N} {incr i} {
        lassign [MarkOptions $i] N tip mark markdata
        if {[info exists al($markdata)]} {
          lassign $al($markdata) fname2 pos
          if {$fname eq $fname2} {
            set tag MARK$i
            set al($markdata) [list $fname $pos $wtxt $tag]
            catch {$wtxt tag delete $tag}
            $wtxt tag add $tag $pos
          }
        }
      }
    }
    #_______________________
    
    proc main::MarkOptions {{idx 0}} {
      # Returns options for marks.
      #   idx - index of tag
    
      namespace upvar ::alited al al obPav obPav
      variable fgcan
      variable bgcan
      lassign [$obPav csGet] - - - bgcan - - - - fgcan
      if {!$al(TIPS,Marks) || [info exists al(MARK_TIPOFF)]} {
        set tip {}
      } else {
        set tip [msgcat::mc "Left click sets / goes to a mark.\nRight click clears it."]
      }
      # 12 greenish
      lappend colors #00ff00 #00f500 #00eb00 #00e100 #00d700 #00cd00
      lappend colors #00c300 #00b900 #00af00 #00a500 #009b00 #009100
      # 12 reddish
      lappend colors #910000 #9b0000 #a50000 #af0000 #b90000 #c30000
      lappend colors #cd0000 #d70000 #e10000 #eb0000 #f50000 #ff0000
      list [llength $colors] $tip MARK,$idx MARKDATA,$idx $colors
    }
    
    # ________________________ Focus _________________________ #
    
    proc main::FocusText {args} {
      # Sets a focus on a current text.
      #   args - contains tab's ID and a cursor position.
    
      namespace upvar ::alited al al obPav obPav
      lassign $args TID pos
      if {$pos eq {}} {
        set wtxt [CurrentWTXT]
        set TID [alited::bar::CurrentTabID]
        set pos [$wtxt index insert]
      } else {
        set wtxt [GetWTXT $TID]
      }
      # find a current unit/file in the tree
      set ::alited::tree::doFocus no
      set wtree [$obPav Tree]
      catch {
        if {$al(TREE,isunits)} {
          # search the tree for a unit with current line of text
          set itemID [alited::tree::CurrentItemByLine $pos]
        } else {
          # search the tree for a current file
          set fname [alited::bar::FileName]
          set wtree [$obPav Tree]
          while {1} {
            incr iit
            set ID [alited::tree::NewItemID $iit]
            if {![$wtree exists $ID]} break
            lassign [$wtree item $ID -values] -> tip isfile
            if {$tip eq $fname} {
              set itemID $ID
              break
            }
          }
        }
      }
      # display a current item of the tree
      catch {
        if {$itemID ni [$wtree selection]} {$wtree selection set $itemID}
        after 10 alited::tree::SeeSelection
      }
      # focus on the text
      catch {focus -force $wtxt}
      catch {::tk::TextSetCursor $wtxt $pos}
      after idle {set ::alited::tree::doFocus yes}
    }
    #_______________________
    
    proc main::FocusInText {TID wtxt} {
      # Processes <FocusIn> event on the text.
      #   TID - tab's ID
      #   wtxt - text widget's path
    
      namespace upvar ::alited obPav obPav
      if {![alited::bar::BAR isTab $TID]} return
      catch {
        CursorPos $wtxt
        [$obPav TreeFavor] selection set {}
        alited::file::OutwardChange $TID
      }
    }
    
    # ________________________ Highlight _________________________ #
    
    proc main::HighlightText {TID curfile wtxt {cmd ""} {cmdpos ""} {fontsize ""}} {
      # Highlights a file's syntax constructs.
      #   TID - tab's ID
      #   curfile - file name
      #   wtxt - text widget's path
      #   cmd - callback for modifying text
      #   cmdpos - callback for changing cursor position
      #   fontsize - text font size
      # Depending on a file name, Tcl or C highlighter is called.
    
      namespace upvar ::alited al al obPav obPav
      # the language (Tcl or C) is defined by the file's extension
      set ext [string tolower [file extension $curfile]]
      set itwas [info exists al(HL,$wtxt)]
      if {!$itwas || $al(HL,$wtxt) ne $ext} {
        if {$itwas} {
          # remove old syntax
          foreach tag [$wtxt tag names] {
            if {![string match hil* $tag] && $tag ni {sel fndTag}} {
              $wtxt tag delete $tag
            }
          }
        }
        if {$cmd eq {}} {
          set cmd "::alited::edit::Modified $TID"
          set cmdpos ::alited::main::CursorPos
        }
        set clrnams [::hl_tcl::hl_colorNames]
        set clrCURL [lindex [$obPav csGet] 16]
        # get a color list for the highlighting Tcl and C
        foreach lng {{} C} {
          foreach nam $clrnams {
            lappend "${lng}colors" $al(ED,${lng}$nam)
          }
          lappend "${lng}colors" $clrCURL
        }
        set tfont $al(FONT,txt)
        if {$fontsize ne {}} {append tfont " -size $fontsize"}
        if {[alited::file::IsClang $curfile]} {
          lassign [::hl_tcl::addingColors] -> clrCMN2
          lappend Ccolors $clrCMN2
          ::hl_c::hl_init $wtxt -dark [$obPav csDark] \
            -multiline 1 -keywords $al(ED,CKeyWords) \
            -cmd $cmd -cmdpos $cmdpos -font $tfont -colors $Ccolors
        } else {
          set pltext [expr {![alited::file::IsTcl $curfile]}]
          if {$pltext} {
            set plcom [alited::HighlightAddon $wtxt $curfile $colors $fontsize]
            if {$plcom ne {}} {set pltext 0}
          } else {
            set plcom {}
          }
          ::hl_tcl::hl_init $wtxt -dark [$obPav csDark] \
            -multiline $al(prjmultiline) -keywords $al(ED,TclKeyWords) \
            -cmd $cmd -cmdpos $cmdpos -plaintext $pltext -plaincom $plcom \
            -font $tfont -colors $colors
        }
        UpdateText $wtxt $curfile
        BindsForCode $wtxt $curfile
      }
      set al(HL,$wtxt) $ext
    }
    #_______________________
    
    proc main::HighlightLine {} {
      # Highlights a current line of a current text.
    
      set wtxt [CurrentWTXT]
      if {[alited::file::IsClang [alited::bar::FileName]]} {
        ::hl_c::hl_line $wtxt
      } else {
        ::hl_tcl::hl_line $wtxt
      }
    }
    
    # ________________________ Line _________________________ #
    
    proc main::CursorPos {wtxt args} {
      # Displays a current text's row and column in the status bar.
      #   wtxt - text widget's path
      #   args - contains a cursor position,
    
      namespace upvar ::alited obPav obPav
      if {![winfo exists $wtxt]} return
      if {$args eq {}} {set args [$wtxt index {end -1 char}]}
      lassign [split [$wtxt index insert] .] r c
      set R [expr {int([lindex $args 0])}]
      set c [incr c]
      set wrow [$obPav Labstat1]
      set wcol [$obPav Labstat2]
      set textrow "$r / $R"
      set textcol "$c"
      ::baltip tip $wrow $textrow
      ::baltip tip $wcol $textcol
      if {$R>99999} {set textrow "$r / *****"}
      if {$c>9999} {set textcol ****}
      $wrow configure -text $textrow
      $wcol configure -text $textcol
      alited::tree::SaveCursorPos
      alited::edit::RectSelection 1
    }
    #_______________________
    
    proc main::InsertLine {} {
      # Puts a new line into a text, attentive to a previous line's indentation.
    
      set wtxt [CurrentWTXT]
      set ln [expr {int([$wtxt index insert])}]
      set line [$wtxt get $ln.0 $ln.end]
      set leadsp [obj leadingSpaces $line]
      if {[string index [string trimleft $line] 0] eq "\}"} {
        incr leadsp [lindex [CalcIndentation] 0]
      }
      $wtxt insert $ln.0 "[string repeat { } $leadsp]\n"
      set pos $ln.$leadsp
      ::tk::TextSetCursor $wtxt $pos
    }
    #_______________________
    
    proc main::GotoBracket {{frommenu no}} {
      # Processes Alt+B keypressing: "go to a matched bracket".
      #   frommenu - yes, if run from a menu
    
      # search a pair for a bracket highlighted
      set wtxt [CurrentWTXT]
      if {[llength [set tagged [$wtxt tag ranges tagBRACKET]]]==4} {
        set p [$wtxt index insert]
        set p1 [$wtxt index "$p +1c"]
        set p2 [$wtxt index "$p -1c"]
        foreach {pos1 pos2} $tagged {
          if {[incr -]==2 || ($pos1!=$p && $pos1!=$p1 && $pos1!=$p2)} {
            FocusText [alited::bar::CurrentTabID] $pos1
            if {$frommenu} SaveVisitInfo
            break
          }
        }
      }
    }
    #_______________________
    
    proc main::GotoLine {} {
      # Processes Ctrl+G keypressing: "go to a line".
    
      namespace upvar ::alited al al obDl2 obDl2
      set head [msgcat::mc {Go to Line}]
      set prompt1 [msgcat::mc {Line number:}]
      set prompt2 [msgcat::mc {    In unit:}]
      set wtxt [CurrentWTXT]
      set ln 1 ;#[expr {int([$wtxt index insert])}]
      set lmax [expr {int([$wtxt index "end -1c"])}]
      set units [list]
      set TID [alited::bar::CurrentTabID]
      foreach it $al(_unittree,$TID) {
        lassign $it lev leaf fl1 title l1 l2
        if {$leaf && [set title [string trim $title]] ne {}} {
          lappend units $title
        }
      }
      set ::alited::main::gotoline2 [linsert [lsort -nocase $units] 0 {}]
      if {$::alited::main::gotolineTID ne $TID} {
        set ::alited::main::gotoline1 {}
        set ::alited::main::gotolineTID $TID
      }
      after 300 {catch {bind [apave::dlgPath] <F1> {alited::main::Help goline}}}
      lassign [$obDl2 input {} $head [list \
        spx "{$prompt1} {} {-from 1 -to $lmax -selected yes}" "{$ln}" \
        cbx "{$prompt2} {} {-tvar ::alited::main::gotoline1 -state readonly -h 16 -w 25}" \
          "{$::alited::main::gotoline1} $::alited::main::gotoline2" \
      ]] res ln unit
      if {$res} {
        set ::alited::main::gotoline1 $unit
        if {$unit ne {}} {
          # for a chosen unit - a relative line number
          if {[set it [lsearch -index 3 $al(_unittree,$TID) $unit]] >- 1} {
            lassign [lindex $al(_unittree,$TID) $it] lev leaf fl1 title l1 l2
            set l $l1
            set fst 1
            foreach line [split [$wtxt get $l1.0 $l2.end] \n] {
              # gentlemen, use \ for continuation of long lines & strings!
              set continued [expr {[string index $line end] eq "\\"}]
              if {!$continued || $fst} {
                if {$fst} {
                  set l $l1
                  if {[incr ln -1]<1} break
                }
                set fst [expr {!$continued}]
              }
              incr l1
            }
            set ln $l
          }
        }
        after 200 " \
          alited::main::FocusText $TID $ln.0 ; \
          alited::tree::NewSelection {} $ln.0 yes; \
          alited::main::HighlightLine"
      }
    }
    
    # ________________________ Event handlers _________________________ #
    
    proc main::SaveVisitInfo {{wtxt ""} {K ""} {s 0}} {
      # Remembers data about current unit.
      #   wtxt - text's path
      #   K - key pressed (to check keypressings)
      #   s - key's state
    
      namespace upvar ::alited al al obPav obPav
      SaveLast2
      # only for unit tree and not navigation key
      if {!$al(TREE,isunits) || [alited::favor::SkipVisited] || \
      $K in {Tab Up Down Left Right Next Prior Home End Insert} || \
      [string match *Cont* $K]} {
        return
      }
      # check for current text and current unit's lines
      set wcur [CurrentWTXT]
      if {$wtxt eq {}} {
        set wtxt $wcur
      } elseif {$wtxt ne $wcur} {
        return
      }
      set wtree [$obPav Tree]
      set pos [$wtxt index insert]
      lassign [alited::tree::CurrentItemByLine $pos 1] itemID - - - name l1
      set header [alited::unit::GetHeader $wtree $itemID]
      set gokeys [list {}]
      foreach gk {F3 AltQ AltW} {
        lappend gokeys {*}[apave::getTextHotkeys $gk]
      }
      if {$K in $gokeys || ($s & 0b1000)} {
        set l1 -1 ;# to avoid a unit's name spawned in last visits at its change
      }
      alited::favor::LastVisited [$wtree item $itemID] $header $l1
      set selID [$wtree selection]
      if {[llength $selID]<2 && $selID ne $itemID} {
        $wtree selection set $itemID
        $wtree see $itemID
        alited::tree::AddTagSel $wtree $itemID
      }
      set TID [alited::bar::CurrentTabID]
      foreach it $al(_unittree,$TID) {
        set treeID [alited::tree::NewItemID [incr iit]]
        lassign $it lev leaf fl1 title l1 l2
        if {$name eq [alited::tree::UnitTitle $title $l1 $l2]} {
          set al(CPOS,$TID,$header) [::apave::p+ $pos -$l1]
          return
        }
      }
    }
    #_______________________
    
    proc main::SaveLast2 {} {
      # Saves the current text's info in last two visited, to switch them.
      # See also: unit::SwitchUnits
    
      namespace upvar ::alited al al
      catch {
        if {![info exists al(Last2Visited)]} {set al(Last2Visited) [list]}
        set wtxt [CurrentWTXT]
        set pos [$wtxt index insert]
        set TID [alited::bar::CurrentTabID]
        lassign [alited::tree::CurrentItemByLine $pos 1] curitem
        set info [list $TID $curitem $pos]
        lassign [lindex $al(Last2Visited) 0] TID2 curitem2
        if {$TID eq $TID2 && $curitem eq $curitem2} {
          set al(Last2Visited) [lreplace $al(Last2Visited) 0 0 $info]
        } else {
          set al(Last2Visited) [linsert $al(Last2Visited) 0 $info]
          set al(Last2Visited) [lrange $al(Last2Visited) 0 1]
        }
      }
    }
    #_______________________
    
    proc main::AfterUndoRedo {} {
      # Actions after undo/redo.
    
      HighlightLine
      after 0 {after idle {
        alited::main::SaveVisitInfo
        alited::main::UpdateUnitTree
        alited::main::FocusText}
      }
    }
    #_______________________
    
    proc main::AfterCut {} {
      # Actions after cutting text: resets the unit tree's selection.
    
      namespace upvar ::alited al al obPav obPav
      if {$al(TREE,isunits)} {
        [$obPav Tree] selection set {}
        after idle alited::main::FocusText
      }
    }
    
    # ________________________ GUI _________________________ #
    
    proc main::ShowHeader {{doit no}} {
      # Displays a file's name and modification flag (*) in alited's title.
      #   doit - if yes, displays unconditionally.
      # If *doit* is *no*, displays only at changing a file name or a flag.
    
      namespace upvar ::alited al al
      if {[alited::file::IsModified]} {set modif "*"} {set modif " "}
      set TID [alited::bar::CurrentTabID]
      if {$doit || "$modif$TID" ne [alited::bar::BAR cget -ALmodif]} {
        alited::bar::BAR configure -ALmodif "$modif$TID"
        set f [alited::bar::CurrentTab 1]
        set d [file normalize [file dirname [alited::bar::CurrentTab 2]]]
        set ttl [string map [list %f $f %d $d %p $al(prjname)] $al(TITLE)]
        wm title $al(WIN) [string trim "$modif$ttl"]
      }
    }
    #_______________________
    
    proc main::CalcIndentation {{wtxt ""} {doit no}} {
      # Check for "Auto detection of indentation" and calculates it at need.
      #   wtxt - text's path
      #   doit - if yes, recalculates the indentation
    
      namespace upvar ::alited al al
      set res [list $al(prjindent) { }]
      if {$al(prjindentAuto)} {
        if {$wtxt eq {}} {
          if {[catch {set wtxt [CurrentWTXT]}]} {return $res}
        }
        if {![winfo exists $wtxt]} {return $res}
        if {!$doit && [info exists al(_INDENT_,$wtxt)]} {return $al(_INDENT_,$wtxt)}
        foreach line [split [$wtxt get 1.0 end] \n] {
          if {[set lsp [obj leadingSpaces $line]]>0} {
            # check if the indentation is homogeneous
            if {[string first [string repeat { } $lsp] $line]==0} {
              set res [list $lsp { }]
              break
            } elseif {[string first [string repeat \t $lsp] $line]==0} {
              set res [list $lsp \t]
              break
            }
          }
        }
        set al(_INDENT_,$wtxt) $res  ;# to omit the calculation next time
      }
      return $res
    }
    #_______________________
    
    proc main::CalcPad {{wtxt ""}} {
      # Calculates the indenting pad for the edited text.
      #   wtxt - text's path
    
      lassign [CalcIndentation $wtxt] pad padchar
      return [string repeat $padchar $pad]
    }
    #_______________________
    
    proc main::UpdateProjectInfo {{indent {}}} {
      # Displays a project settings in the status bar.
      #   indent - indentation calculated for a text
    
      namespace upvar ::alited al al obPav obPav
      if {$al(prjroot) ne {}} {set stsw normal} {set stsw disabled}
      [$obPav BtTswitch] configure -state $stsw
      if {[catch {set eol [alited::file::EOL]}] || $eol eq {}} {
        if {[set eol $al(prjEOL)] eq {}} {set eol auto}
      } else {
        lassign [split $eol] -> eol
      }
      if {$indent eq {}} {set indent [lindex [CalcIndentation] 0]}
      if {[catch {set enc [alited::file::Encoding]}] || $enc eq {}} {
        set enc utf-8
      } else {
        lassign [split $enc] -> enc
      }
      set info "$enc, eol=$eol, ind=$indent"
      if {$al(prjindentAuto)} {append info /auto}
      [$obPav Labstat4] configure -text $info
    }
    #_______________________
    
    proc main::TipStatus {} {
      # Gets a tip for a status bar's short info.
    
      namespace upvar ::alited al al obPav obPav
      set run "$al(MC,run) "
      switch $al(prjincons) {
        0 {append run $al(MC,intkcon)}
        1 {append run $al(MC,inconsole)}
        2 {append run $al(MC,asis)}
      }
      if {[alited::tool::ComForced]} {
        append run :\ $al(comForce)
      } else {
        lassign [alited::tool::RunArgs] ar rf ex
        append run :\ $ar$rf$ex
      }
      set tip [[$obPav Labstat4] cget -text]
      set tip [string map [list \
        eol= "$al(MC,EOL:) " \
        ind= "$al(MC,indent:) " \
        {, } \n \
        ] $tip]
      return "$run\n\n[msgcat::mc Encoding]: $tip"
    }
    #_______________________
    
    proc main::BindsForText {TID wtxt} {
      # Sets bindings for a text.
      #   TID - tab's ID
      #   wtxt - text widget's path
    
      namespace upvar ::alited al al obPav obPav
      if {[alited::bar::BAR isTab $TID]} {
        bind $wtxt <FocusIn> [list after 500 "::alited::main::FocusInText $TID $wtxt"]
      }
      bind $wtxt <Control-ButtonRelease-1> "::alited::find::LookDecl ; break"
      bind $wtxt <Control-Shift-ButtonRelease-1> {alited::find::SearchWordInSession ; break}
      bind $wtxt <Control-Tab> {alited::bar::ControlTab}
      if {$al(IsWindows)} {
        # unlike Unix, Shift+Key doesn't work in Windows
        bind $wtxt <Tab> \
          [list + if {{%K} eq {Tab} && {%s}==1} "focus [$obPav LbxInfo]; break"]
      }
      bind $wtxt <Alt-BackSpace> {alited::unit::SwitchUnits ; break}
      bind $wtxt <space> "+ alited::unit::PutTypeTemplate $wtxt"
      ::apave::bindToEvent $wtxt <ButtonRelease-1> alited::main::SaveVisitInfo $wtxt
      ::apave::bindToEvent $wtxt <KeyRelease> alited::main::SaveVisitInfo $wtxt %K %s
      ::apave::bindToEvent $wtxt <<Undo>> alited::main::AfterUndoRedo
      ::apave::bindToEvent $wtxt <<Redo>> alited::main::AfterUndoRedo
      ::apave::bindToEvent $wtxt <<Cut>> after 50 {after 50 alited::main::AfterCut}
      alited::keys::ReservedAdd
      alited::keys::BindAllKeys $wtxt no
      alited::edit::BindPluginables $wtxt
    }
    #_______________________
    
    proc main::BindsForCode {wtxt curfile} {
      # Sets bindings for a code.
      #   wtxt - text widget's path
      #   curfile - current file's name
    
    #  if {[alited::file::IsTcl $curfile] || [alited::file::IsClang $curfile]} {
        bind $wtxt <Control-Right> "alited::edit::ControlRight $wtxt %s"
        bind $wtxt <Control-Left> "alited::edit::ControlLeft $wtxt %s"
    #  }
    }
    #_______________________
    
    proc main::PackTextWidgets {wtxt wsbv} {
      # Packs a text and its scrollbar.
      #   wtxt - text widget's path
      #   wsbv - scrollbar widget's path
    
      namespace upvar ::alited al al obPav obPav
      pack $wtxt -side left -expand 1 -fill both
      pack $wsbv -fill y -expand 1
      lassign [GutterAttrs] canvas width shift
      # widgets created outside apave require the theming:
      $obPav csSet [$obPav csCurrent] $al(WIN) -doit
      $obPav bindGutter $wtxt $canvas $width $shift
    }
    #_______________________
    
    proc main::ShowOutdatedTODO {prj date todo is} {
      # Shows a balloon with outdated TODO.
      #   prj - project's name
      #   date - date of TODO
      #   todo - text of TODO
      #   is - 1 for current day TODO, 2 for "ahead" TODO
    
      namespace upvar ::alited al al
      set todo "\n$al(MC,prjName) $prj\n\n$al(MC,on) $date\n\n$todo\n"
      set opts {}
      if {[string first !!! $todo]>-1 || ($is==1 && $al(todoahead))} {
        set opts {-ontop 1 -eternal 1 -fg white -bg red}
      }
      ::alited::Balloon $todo yes 2500 {*}$opts
    }
    #_______________________
    
    proc main::InitActions {} {
      # Initializes working with a main form of alited.
    
      namespace upvar ::alited al al obPav obPav
      # fill the bars waiting for full size of text widget
      alited::bar::FillBar [$obPav BtsBar]
      FillMarkBar
      # check for outdated TODOs for current project
      lassign [alited::project::IsOutdated $al(prjname) yes] is date todo
      if {$is} {
        ShowOutdatedTODO $al(prjname) $date $todo $is
      } else {
        # check other projects
        alited::project::SaveSettings
        alited::project::GetProjects
        set prjname [alited::project::CheckOutdated]
        if {$prjname ne {}} {
          lassign [alited::project::IsOutdated $prjname yes] is date todo
          ShowOutdatedTODO $prjname $date $todo $is
        }
      }
      after idle {alited::main::UpdateGutter; alited::main::FocusText}  ;# get it for sure
      if {$al(INI,isfindrepl)} {
        after idle {after 100 {  ;# for getting a current word to find
          alited::find::_run
          focus $::alited::al(WIN); alited::main::FocusText
          after idle {after 100 {after idle {after 100 alited::main::FocusText}}}
        }}
      }
      # Ctrl-click for Run, e_menu, Tkcon buttons
      foreach ico {run e_menu other} {
        set but [alited::tool::ToolButName $ico]
        bind $but <Control-Button-1> $al(runAsIs)
        set tip [::baltip::cget $but -text][alited::tool::AddTooltipRun]
        after idle [list ::baltip::tip $but $tip]
      }
      foreach ico {undo redo} {
        set but [alited::tool::ToolButName $ico]
        bind $but <Control-Button-1> alited::tool::${ico}All
        set tip [::baltip::cget $but -text]
        append tip "\n\nCtrl+click = [msgcat::mc {All in text}]"
        after idle [list ::baltip::tip $but $tip]
      }
    }
    #_______________________
    
    proc main::ProcMessage {lab} {
      # Handles clicking on message label.
    
      set msg [baltip cget $lab -text]
      alited::Message $msg 3 $lab
    }
    
    # ________________________ Main _create _________________________ #
    
    proc main::_create {} {
      # Creates a main form of the alited.
    
      namespace upvar ::alited al al obPav obPav
      set al(AU!) 0
      $obPav untouchWidgets *.frAText *.lbxInfo *.lbxFlist *.too*
      # make the main apave object and populate it
      $obPav makeWindow $al(WIN).fra alited
    
      # alited_checked
    
    ## ________________________ Main window _________________________ ##
    
      $obPav paveWindow $al(WIN).fra {
        {Menu - - - - - {-array {
          file File
          edit Edit
          search Search
          tool Tools
          setup Setup
          help Help
        }} alited::menu::FillMenu}
    {#
    ### ________________________ Main pan _________________________ ###
    }
        {frat - - - - {pack -fill both}}
        {frat.ToolTop - - - - {pack -side top}
          {-relief flat -borderwidth 0 -array {$::alited::al(atools)}
          -onevent {<ButtonPress-3> "alited::tool::PopupBar %X %Y"}}}
        {fra - - - - {pack -side top -fill both -expand 1 -pady 0}}
        {fra.Pan - - - - {pack -side top -fill both -expand 1} {-orient horizontal
          $::alited::Pan_wh -onevent {<ButtonRelease> alited::tree::AdjustWidth}}}
        {fra.pan.PanL - - - - {add} {-orient vertical $::alited::PanL_wh}}
        {fra.pan.panL.fraBot - - - - {add}}
    {#
    ### ________________________ Tree pan _________________________ ###
    }
        {.PanBM - - - - {pack -fill both -expand 1} {$::alited::PanBM_wh}}
        {.panBM.FraTree - - - - {pack -side top -fill both -expand 1}}
        {fra.pan.panL.fraBot.panBM.fraTree.fra1 - - - - {pack -side top -fill x}}
    {#
    #### ________________________ Tree's toolbar _________________________ ####
    }
        {.BtTswitch - - - - {pack -side left -fill x}
          {-image alimg_gulls -com alited::tree::SwitchTree}}
        {.BtTUpdT - - - - {pack -side left -fill x}
          {-image alimg_retry -tip {$al(MC,updtree)}
        -command alited::main::UpdateAll}}
        {.sev1 - - - - {pack -side left -fill y -padx 5}}
        {.BtTUp - - - - {pack -side left -fill x}
          {-image alimg_up -com {alited::tree::MoveItem up}}}
        {.BtTDown - - - - {pack -side left -fill x}
          {-image alimg_down -com {alited::tree::MoveItem down}}}
        {.sev2 - - - - {pack -side left -fill y -padx 5}}
        {.BtTAddT - - - - {pack -side left -fill x}
          {-image alimg_add -com alited::tree::AddItem}}
        {.BtTRenT - - - - {pack forget -side left -fill x}
          {-image alimg_change -tip "$al(MC,renamefile)\nF2"
          -com {alited::file::RenameFileInTree 0 -geometry pointer+10+10}}}
        {.BtTDelT - - - - {pack -side left -fill x}
          {-image alimg_delete -com alited::tree::DelItem}}
        {.BtTCloT - - - - {pack forget -side left -fill x}
          {-image alimg_copy -com alited::file::CloneFile -tip "$al(MC,clonefile)"}}
        {.BtTOpen - - - - {pack forget -side left -fill x}
          {-image alimg_OpenFile -com ::alited::file::OpenWith -tip "$al(MC,openwith)"}}
        {.lab_ - - - - {pack -anchor center -side left -fill both -expand 1} {-t {  }}}
        {.btTCtr - - - - {pack -side left -fill x}
          {-image alimg_minus -com {alited::tree::ExpandContractTree Tree no} -tip "Contract All"}}
        {.btTExp - - - - {pack -side left -fill x}
          {-image alimg_plus -com {alited::tree::ExpandContractTree Tree} -tip "Expand All"}}
    {#
    #### ________________________ Tree _________________________ ####
    }
        {.sev3 - - - - {pack -side right -fill y -padx 0}}
        {fra.pan.panL.fraBot.panBM.fraTree.fra - - - - {pack -side bottom -fill both -expand 1} {-w 1}}
        {.Tree - - - - {pack -side left -fill both -expand 1}
          {-columns {L1 L2 PRL ID LEV LEAF FL1} -displaycolumns {L1}
          -columnoptions "#0 {-width $al(TREE,cw0)} L1 {-width $al(TREE,cw1) -anchor e}"
          -style TreeNoHL -takefocus 0 -selectmode extended
          -tip {-BALTIP {alited::tree::GetTooltip %i %c} -SHIFTX 10}}}
        {.SbvTree .Tree L - -
          {pack -side right -fill both}}
    {#
    ### ________________________ Favorites _________________________ ###
    }
        {fra.pan.panL.FraFV - - - - {add}}
        {.v_ - - - - {pack -side top -fill x} {-h 5}}
        {fra.pan.panL.fraFV.fra1 - - - - {pack -side top -fill x}}
        {.seh - - - - {pack -side top -fill x -expand 1 -pady 0}}
    {#
    #### ________________________ Favorites' toolbar _________________________ ####
    }
        {.BtTVisitF - - - - {pack -side left -fill x}
          {-image alimg_misc -tip {$al(MC,lastvisit)} -com alited::favor::SwitchFavVisit}}
        {.sev0 - - - - {pack -side left -fill y -padx 5}}
        {.BtTListF - - - - {pack -side left -fill x}
          {-image alimg_SaveFile -tip {$al(MC,FavLists)} -com alited::favor::Lists}}
        {.SevF - - - - {pack -side left -fill y -padx 5}}
        {.BtTAddF - - - - {pack -side left -fill x}
          {-image alimg_add -tip {$al(MC,favoradd)} -com alited::favor::Add}}
        {.BtTRenF - - - - {pack -side left -fill x}
          {-image alimg_change -tip {$al(MC,favorren)} -command ::alited::favor::Rename}}
        {.btTDelF - - - - {pack -side left -fill x}
          {-image alimg_delete -tip {$al(MC,favordel)} -com alited::favor::Delete}}
        {.btTDelAllF - - - - {pack -side left -fill x}
          {-image alimg_trash -tip {$al(MC,favordelall)} -com alited::favor::DeleteAll}}
        {.h_2 - - - - {pack -anchor center -side left -fill both -expand 1}}
        {.sev2 - - - - {pack -side right -fill y -padx 0}}
        {fra.pan.panL.fraFV.fra - - - - {pack -fill both -expand 1} {}}
    {#
    #### ________________________ Favorites' list _________________________ ####
    }
        {.TreeFavor - - - - {pack -side left -fill both -expand 1}
          {-h 5 -style TreeNoHL -columns {C1 C2 C3 C4} -displaycolumns C1
          -show headings -takefocus 0 -tip {-BALTIP {alited::favor::GetTooltip %i} -SHIFTX 10}}}
        {.SbvFavor + L - - {pack -fill both}}
        {fra.pan.PanR - - - - {add} {-orient vertical $::alited::PanR_wh}}
    {#
    ### ________________________ Tab bar & Text _________________________ ###
    }
        {fra.pan.panR.fraTop - - - - {add}}
        {.PanTop - - - - {pack -fill both -expand 1} {$::alited::PanTop_wh}}
        {.panTop.BtsBar  - - - - {pack -side top -fill x -pady 3}}
        {.panTop.canmark - - - - {pack -side left -expand 0 -fill both
          -padx 0 -pady 0 -ipadx 0 -ipady 0} {-w $al(markwidth)
          -afteridle {alited::main::FillMarkBar %w}}}
        {.panTop.GutText - - - - {pack -side left -expand 0 -fill both}}
        {.panTop.FrAText - - - - {pack -side left -expand 1 -fill both
          -padx 0 -pady 0 -ipadx 0 -ipady 0} {-background $::apave::BGMAIN2}}
        {.panTop.frAText.Text - - - - {pack -expand 1 -fill both}
          {-w 80 -h 30 -gutter GutText -gutterwidth $al(ED,gutterwidth)
          -guttershift $al(ED,guttershift)}}
        {.panTop.fraSbv - - - - {pack -side right -fill y}}
    {#
    ### ________________________ Find units _________________________ ###
    }
        {.panTop.fraSbv.SbvText .panTop.frAText.text L - - {pack -fill y}}
        {.FraSbh  - - - - {pack forget -fill x}}
        {.fraSbh.SbhText .panTop.frAText.text T - - {pack -fill x}}
        {fra.pan.panR.fraTop.FraHead  - - - - {pack forget -side bottom -fill x}
          {-padding {4 4 4 4} -relief groove}}
        {.labFind - - - - {pack -side left} {-t {    Unit: }}}
        {.CbxFindSTD - - - - {pack -side left}
          {-tvar ::alited::al(findunit) -values {$al(findunitvals)} -w 30 -tip {$al(MC,findunit)}}}
        {.btT - - - - {pack -side left -padx 4}
          {-t {Find: } -com alited::find::DoFindUnit -w 8 -anchor e -tip {Find Unit}}}
        {.rad1 - - - - {pack -side left -padx 4}
          {-takefocus 0 -var ::alited::main::findunits -t {in all} -value 1}}
        {.rad2 - - - - {pack -side left -padx 4}
          {-takefocus 0 -var ::alited::main::findunits -t {in current} -value 2}}
        {.h_ - - - - {pack -side left -fill x -expand 1}}
        {.btTno - - - - {pack -side left} {-command {alited::find::HideFindUnit}}}
    {#
    ### ________________________ Info & status bar _________________________ ###
    }
        {fra.pan.panR.fraBot - - - - {add}}
        {.fra - - - - {pack -fill both -expand 1}}
        {.fra.LbxInfo - - - - {pack -side left -fill both -expand 1}
          {-h 1 -w 40 -lvar ::alited::info::list -font $al(FONT,defsmall)
          -highlightthickness 0 -onevent {
          <<ListboxSelect>> "alited::info::ListboxSelect %w"
          <ButtonPress-3> "alited::info::PopupMenu %X %Y"}}}
        {.fra.sbv + L - - pack}
        {.fra.SbhInfo .fra.LbxInfo T - - {pack -side bottom -before %w}}
        {.stat - - - - {pack -side bottom} {-array {
          {{$al(MC,Row:)}} 12
          {{$al(MC,Col:)}} 4
          {{} -anchor w -expand 1} 51
          {{} -anchor e} 25
        }}}
      }
      UpdateProjectInfo
      # a pause (and cycles) must be enough for FillBar to have proper -wbar option
      after idle after 50 after idle after 50 after idle after 50 after idle after 50 \
        alited::main::InitActions
      set sbhi [$obPav SbhInfo]
      set lbxi [$obPav LbxInfo]
      pack forget $sbhi
      bind $lbxi <FocusIn> "alited::info::FocusIn $sbhi $lbxi"
      bind $lbxi <FocusOut> "alited::info::FocusOut $sbhi"
      bind [$obPav Labstat3] <Button-1> {alited::main::ProcMessage %W}
      ::baltip tip [$obPav Labstat4] = -command ::alited::main::TipStatus -per10 0
    }
    # ________________________ Main _run _________________________ #
    
    proc main::_run {} {
      # Runs the alited, displaying its main form with attributes
      # 'modal', 'not closed by Esc', 'decorated with Contract/Expand buttons',
      # 'minimal sizes' and 'saved geometry'.
      # After closing the alited, saves its settings (geometry etc.).
      # See also: menu::TearoffCascadeMenu
    
      namespace upvar ::alited al al obPav obPav
      ::apave::setAppIcon $al(WIN) $::alited::img::_AL_IMG(ale)
      after idle after 8 after idle after 8 after idle after 8 {incr ::alited::al(AU!)}
      after 3000 {incr ::alited::al(AU!)} ;# control shot
      after 2000 [list wm iconphoto $al(WIN) -default [::apave::getAppIcon]]
      after 1000 {alited::ini::CheckUpdates no}
      set ans [$obPav showModal $al(WIN) -decor 1 -minsize {500 500} -escape no \
        -onclose alited::Exit {*}$al(GEOM) -resizable 1 -waitme ::alited::al(AU!) \
        -ontop 0]
      # ans==2 means 'no saves of settings' (imaginary mode)
      if {$ans ne {2}} {alited::ini::SaveIni}
      destroy $al(WIN)
      $obPav destroy
      return $ans
    }
    # _________________________________ EOF _________________________________ #
    
    
    main.tcl