<commit_before>#-----------------------------------------------------------------------
# TITLE:
#   shelltool.tcl
#
# AUTHOR:
#   <NAME>
#
# DESCRIPTION:
#   Kite "shell" tool.  By default, this invokes tkcon with the project
#   code.
#
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
# Registration

set ::ktools(shell) {
    arglist     {}
    package     ktools
    ensemble    ::ktools::shelltool
    description "Open interactive Tcl shell"
    intree      yes
}

set ::khelp(shell) {
    The "shell" tool opens an interactive Tcl shell (tkcon) on the 
    project codebase.  If there is an app or appkit, the app's 
    loader script (e.g., bin/myapp.tcl) is loaded in interactive mode
    (the "main" is not called).  

    If there is no appkit, or if the "-plain" option is given, Kite simply 
    adds the project library directories to the auto_path.  In this case,
    the initial state of the shell can be further customized using the
    "shell" statement in the project.kite file.
}

#-----------------------------------------------------------------------
# shelltool ensemble

snit::type ::ktools::shelltool {
    # Make it a singleton
    pragma -hasinstances no -hastypedestroy no

    #-------------------------------------------------------------------
    # Execution 

    # execute argv
    #
    # Executes the tool given the command line arguments.

    typemethod execute {argv} {
        checkargs shell 0 1 {?-plain?} $argv
        set opt [lindex $argv 0]

        # FIRST, locate tkcon.
        set shellapp [FindTkCon]

        # NEXT, set up the rest of command.
        set command $shellapp

        if {[project apploader] ne "" && $opt ne "-plain"} {
            lappend command [project apploader]
        } else {
            set script [WriteShellInitializer]
            lappend command $script
        }

        lappend command &


        # NEXT, execute it in the project root, in the background,
        # and exit.
        vputs "Loading <$command>"
        cd [project root]
        eval exec $command
    }

    # FindTkCon
    #
    # Finds the tkcon app.
    #
    # NOTE: It appears that tkcon is only installed with ActiveTcl on
    # Windows, and so it isn't readily available.  For now I'll look
    # for it in the environment, but ultimately a shell will need to
    # be part of Kite.

    proc FindTkCon {} {
        set app [exec which tkcon]
        if {[file exists $app]} {
            return $app
        }

        set app [exec which tkcon.tcl]

        if {[file exists $app]} {
            return $app
        }

        throw FATAL "Please install the \"tkcon\" shell application."
    }
    
    # WriteShellInitializer
    #
    # Creates .kite/shell.tcl to set up auto_path.

    proc WriteShellInitializer {} {
        # FIRST, add the project's own libraries to the auto_path.
        append out \
            "# shell.tcl -- Kite shell initialization script\n" \
            "lappend auto_path [list [project root lib]]\n"

        # NEXT, add any include libraries to the auto_path
        foreach include [project include names] {
            set lib [project root includes $include lib]
            append out \
                "lappend auto_path [list $lib]\n"
        }

        # NEXT, add any "shell" script from project.kite
        append out "\n" [project shell] "\n"

        set script [project root .kite shell.tcl]<commit_msg>Fixed "kite shell" on windows.<commit_after>#-----------------------------------------------------------------------
# TITLE:
#   shelltool.tcl
#
# AUTHOR:
#   <NAME>
#
# DESCRIPTION:
#   Kite "shell" tool.  By default, this invokes tkcon with the project
#   code.
#
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
# Registration

set ::ktools(shell) {
    arglist     {}
    package     ktools
    ensemble    ::ktools::shelltool
    description "Open interactive Tcl shell"
    intree      yes
}

set ::khelp(shell) {
    The "shell" tool opens an interactive Tcl shell (tkcon) on the 
    project codebase.  If there is an app or appkit, the app's 
    loader script (e.g., bin/myapp.tcl) is loaded in interactive mode
    (the "main" is not called).  

    If there is no appkit, or if the "-plain" option is given, Kite simply 
    adds the project library directories to the auto_path.  In this case,
    the initial state of the shell can be further customized using the
    "shell" statement in the project.kite file.
}

#-----------------------------------------------------------------------
# shelltool ensemble

snit::type ::ktools::shelltool {
    # Make it a singleton
    pragma -hasinstances no -hastypedestroy no

    #-------------------------------------------------------------------
    # Execution 

    # execute argv
    #
    # Executes the tool given the command line arguments.

    typemethod execute {argv} {
        checkargs shell 0 1 {?-plain?} $argv
        set opt [lindex $argv 0]

        # FIRST, locate tkcon.
        set shellapp [FindTkCon]

        # NEXT, set up the rest of command.
        set command $shellapp

        if {[project apploader] ne "" && $opt ne "-plain"} {
            lappend command [project apploader]
        } else {
            set script [WriteShellInitializer]
            lappend command $script
        }

        lappend command &


        # NEXT, execute it in the project root, in the background,
        # and exit.
        vputs "Loading <$command>"
        cd [project root]
        eval exec $command
    }

    # FindTkCon
    #
    # Finds the tkcon app.
    #
    # NOTE: It appears that tkcon is only installed with ActiveTcl on
    # Windows, and so it isn't readily available.  For now I'll look
    # for it in the environment, but ultimately a shell will need to
    # be part of Kite.

    proc FindTkCon {} {
        # FIRST, if this is Windows assume Tkcon is installed as
        # tkcon.tcl next to the the same.
        if {$::tcl_platform(platform) eq "windows"} {
            set bindir [file dirname [info nameofexecutable]]
            set app [file join $bindir tkcon.tcl]
    
            if {[file exists $app]} {
                # It's not clear why "tclsh" is required....
                return [list tclsh $app]
            } else {
                throw FATAL \
                    "Could not find the \"tkcon.tcl\" shell application."
            }
        } 

        # NEXT, look for it installed on the path, Unix-style
        set app [exec which tkcon]

        if {[file exists $app]} {
            return $app
        }

        throw FATAL "Please install the \"tkcon\" shell application."
    }
    
    # WriteShellInitializer
    #
    # Creates .kite/shell.tcl to set up auto_path.

    proc WriteShellInitializer {} {
        # FIRST, add the project's own libraries to the auto_path.
        append out \
            "# shell.tcl -- Kite shell initialization script\n" \
            "lappend auto_path [list [project root lib]]\n"

        # NEXT, add any include libraries to the auto_path
        foreach include [project include names] {
            set lib [project root includes $include lib]
            append out \
                "lappend auto_path [list $lib]\n"
        }

        # NEXT, add any "shell" script from project.kite
        append out "\n" [project shell] "\n"

        set script [project root .kite shell.tcl]
{'fraction_non_alphanumeric': 0.16917591125198098, 'fraction_numerical': 0.000792393026941363, 'mean_word_length': 1.5109416445623343, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1517804', 'n_tokens_mistral': 2104, 'n_tokens_neox': 2009, 'n_words': 778}