Using strreplace with variables against running script?

125 Views Asked by At

Update:

A lot of progress was made to the ini result and the self-editing-code result; however, only the functions that make the edits are finished, not the gui/implementation. Will add more soon.

My roommate is trying to replace a section of a script while the script is active.

Goal:

The idea is to replace c:\test with c:\new in the file.
It might not be necessary to reload the script, but it might be necessary: we want to test this.

We tried replacing dir with %dir% and newdir with %newdir%, but that created errors.

The defaults are now showing up because they are declared (thanks Dieisson Silva dos Santos).

It might be ideal to use a gui. Any which way you can, though. Comments welcome!

Possible problems:

  1. Maybe the tf_replace function is not being implemented correctly?
  2. Maybe the variables from the InputBox need some kind of prefix?
  3. Something else?

Problematic code:

;; Use a GUI to change the file.
#Include %A_MyDocuments%\AutoHotKey\Lib\tf.ahk ; the a_mydocuments var needs to be written out because on many devices AHKLv1 thinks the lib directory is in C:\Program Files\Autohotkey.
#Include %A_ScriptDir%
#Include %A_ScriptFullPath% ; Necessary on some devices.
#SingleInstance Force

;; Use a GUI to change the file.
^u::
    olddir = c:\test ; Necessary for default to work in InputBox function.
    newdir = c:\new ; "".
    Gosub, updatefile ; Find all instances of %olddir% in the file and replace them with %newdir%.
    InputBox, oldDir, Edit AHK File, Insert OLD directory name., , 300, 140, , , , ,% olddir
    If ErrorLevel
        Return
    Gosub, updatefile    ; change var
    InputBox, newDir, Edit AHK File, Insert NEW directory name., , 300, 140, , , , ,% newdir
    If ErrorLevel
        Return
    Return

;; Change the file with no gui.
^d::    ; The goal of ctrl+t is to replace all instances of olddir with newdir
;olddir := "c:\test"
;newdir := "c:\new"
    updatefile:
        msgbox, % A_ScriptFullPath
        tf_replace(olddir, newdir, A_ScriptFullPath)
    Return
!f11::exitapp

The function is from tf.ahk (https://github.com/hi5/TF), and it is supposed to replace every occurrence of a string in file.

Excerpt from TF.ahk by Hi5:


TF_Replace(Text, SearchText, ReplaceText="")
    {
     TF_GetData(OW, Text, FileName)
     IfNotInString, Text, %SearchText%
        Return Text ; SearchText not in TextFile so return and do nothing, we have to return Text in case of a variable otherwise it would empty the variable contents bug fix 3.3
     Loop
        {
         StringReplace, Text, Text, %SearchText%, %ReplaceText%, All
         if (ErrorLevel = 0) ; No more replacements needed.
            break
        }
     Return TF_ReturnOutPut(OW, Text, FileName, 0)
    }
2

There are 2 best solutions below

1
Dieisson Silva dos Santos On

You may use a hotkey to toggle the values without changing the file itself.

#SingleInstance Force
^d::
    Gosub, toggle    ; change var(this is needed because in the first run, "var" is blank)
    InputBox, oldDir, Edit AHK File, Insert OLD directory name., , 300, 140, , , , ,% var
    If ErrorLevel
        Return
    Gosub, toggle    ; change var
    InputBox, newDir, Edit AHK File, Insert NEW directory name., , 300, 140, , , , ,% var
    If ErrorLevel
        Return
    Return

^t::    ; Ctrl+t to invert the values C:\test and C:\new
    toggle:
        toggle := !toggle
        var := toggle ? "C:\test" : "C:\new"
    Return

Your default values was not showing, because in your code there's a missing comma in inputbox parameters

InputBox, OutputVar , Title, Prompt, HIDE, Width, Height, X, Y, Locale, Timeout, Default
0
Wolfpack'08 On

Ini version

!u::
FileCreateDir, %A_ScriptDir%\config
FileAppend, `n, %ftConfig%
IniWrite, c:\test, %ftConfig%, paths, u
Return

Self-Editing-Code Version

; HELLO
f := FileOpen(A_ScriptFullPath,  "r")
text := f.read()
f.close()

text := StrReplace(text, "HELLO", "WORLD")
FileDelete, % A_ScriptFullPath
f := fileOpen(A_ScriptFullPath, "w")
f.write(text)
f.close()
return

This is all v1.