Autohotkey: modify text file without ever opening - autohotkey

I'll start off by saying that I've sat around trying to figure out this for a good 8hrs and now I'm coming here to ask for help.
I want to be able to have a text file that starts at 0 and will increase by 1 every time I press the hotkey. I want this to happen without having the file open. This will be used as a counter.

Ken made a point with regard to knowing the initial value. If you want to ADD a number at the bottom you can use:
fileappend, %Counter%`n, C:\Temp\Counter.txt
Or if you want to JUST have that one number:
filedelete, C:\Temp\Counter.txt
fileappend, %Counter%, C:\Temp\Counter.txt
If you want to store a variable, you can use the .ini files to store various variables.
IniWrite, %TextCounter%, %A_ScriptDir%\Counter.ini, Counter, Nr
IniRead, TextCounter, %A_ScriptDir%\Counter.ini, Counter, Nr

I see this is an old question but it never got answered correctly. If you want to store a single number in a file and then increment that number with a hotkey here is a simplified version of the process:
FileRead to store the current number from the file into a variable
FileDelete to delete the old file (if you don't delete the file each time, step 4 will turn the file into a list of numbers.
add 1 to the variable.
FileAppend to store the updated variable back in the file.

Related

Appending a .txt document with contents of clipboard using autohotkey

!w::
Sendinput ^c ; copy selection
Sleep 1000 ; gives time for the copy to work
FileAppend, `n`n%clipboard%, C:\Users\John Salter\ToAnki.txt; Add clipboard content to the end of a text file. Insert 2 new lines before inserting the clipboard with `n`n
Return
This is the script I've been trying to use. I was concerned about the space in between "John" and "Salter" so tried it in other locations but it still doesn't work.
I get no error messages.
The content of the the clipboard is altered, so the problem lies beneath the second line.
The use of FileAppend would seem to work looking at the help documentation.
Can anybody figure out what's going wrong?
Thanks!
A comment flag that appears on the same line as a command is
not considered to mark a comment unless it has at least one space or
tab to its left.
FileAppend, `n`n%clipboard%, C:\Users\John Salter\ToAnki.txt ; Add clipboard content to the end of a text file. Insert 2 new lines before inserting the clipboard with `n`n

Start App from file storing settings and load them at startup

I'm working on an App in app designer. Within the app the user will select a bunch of options before running some calculations.
To simplify this process I added a "Save as..." menu so that the user can save the current settings to a file (.mat) and reload them when they open the app the next time.
What I'm trying to achieve is that the user can double click on the previously saved .mat file, which will launch the app and the app will automatically read the double clicked file and load all the settings.
All this needs to happen after the app is compiled and distributed as an executable.
I'm thinking that one way to achieve this is to make a startup window of the app that calls the main window passing the file path as parameter.
Any suggestion would be really appreciated.
Hi, I think I may have a fairly simple, albeit involved, solution for you.
Brief solution overview (TL;DR)
Save the settings from the app with an extension other than .mat, e.g. .mydat. Add an App Input Argument and have the startupFcn treat the argument as a file name to a *.mydat file and be sure to also handle the case that the argument is left out. After the first output file is saved, use windows Open with... to select your app. Now double clicking the *.mydat file will open your app's .exe and will provide the file name of the clicked file to the input argument in your startupFcn.
An example in MATLAB 2018a as a compiled exe on windows 10.
Ok, to start. Let's setup a simple app (I called it runAppFromData) that takes a string input to an edit field and saves it in a file called 'settingsValues.mydat'. It looks like:
The callback for the Save button collects the Value into a local variable called value and then saves it to disk:
% Button pushed function: Save
function save(app, event)
value = app.InputField.Value;%#ok
% User selects save location
saveLocation = uigetdir();
% Now just save the value variable to the selected location.
save(fullfile(saveLocation,'settingsValues.mydat'), 'value', '-mat');
end
I don't know when appdesigner added the feature to "run app with inputs" but I have it with 2018a:
We make a single input, fileName that expects a file name as a string (you'll see why below). So add the input and click OK. Then we're sent to "code view" at the startupFcn. Here we'll write the logic that parses the input file. For my simple example app, I load the input file into a struct and then send the value to the edit field:
% Code that executes after component creation
function startupFcn(app, fileName)
if nargin < 2 % app is itself an argument
% just continue running the application without error
return
end
% fileName is a string, so let's load it into a struc
S = load(fileName, '-mat');
% The value field will be there because that is how we wrote it
app.InputField.Value = S.value;
end
Note, I performed a nargin check to handle the first-run case (and anytime the app is run from the actual executable).
MATLAB doesn't care what the file extension is of a matlab file and if you have an unknown file extension, e.g. .mydata, double-clicking the file in windows will ask you to choose the application, which works to your benefit for deployment:
A couple things to consider.
When the app is opened from the .exe it will always show the default values. If you want to input some other default values you can edit your windows shortcut Target field to supply a file path for the desired input file (see here). This saves recompiling with new defaults, but the file has to remain somewhere (you can package it with the app too).
Sorry this answer got soo long! I hope it helps!
You can't double click a .mat file and open an entire executable, but you can definitely add a startup function that asks you to open a .mat file. My suggestion though would be to make sure that you have a template file at least in place, so that the user doesn't run into problems the first time running the program where there is no file to open.

Trying to make a script that takes first word from a txt file, writes it, repeat till all words written

I have a text file, it has several lines. 1 line = 1 word
Now I want a script, if I press a specific button it will write the first word (first line). If I press the button again, the next word will be written, it goes like that till all words are written. I have tried to code it but it will only write the first word and will keep writing it.. It won't take next word and I don't know why because actually I have made a variable that increases...
Here is my code:
F11::
Index = 1
Array := Object()
Loop, Read, C:\Users\Emilia\Desktop\list.txt
{
Array.Push(A_LoopReadLine)
}
Send % Array[Index]
Index++
Use FileReadLine with a line number parameter
Keep the index variable outside in the global context so it doesn't get reset to 1 each time
Use SendPlay to send the word at once, not character-by-character.
You can switch the default send mode with SendMode play command.
Send Enter key at the end by adding {Enter} in the send command.
index = 1
F11::
FileReadLine line, C:\Users\Emilia\Desktop\list.txt, index
SendPlay %line%{Enter}
index++
Return

Pause Matlab without breakpoint

I have a script that is running a lot more time than I expected, it has been running for the last 3 days and only achieved 55% progress.
I would be perfectly happy to stop it at about 67% (I can live without the remaining 33%) But If I stop it now (ctrl+c or ctlr+break), I will lose all the data.
So is there a way to pause Matlab, perhaps into debug mode so I can check the variables without losing data?
The command (needs to be input manually before you start your function!)
dbstop if error
should catch a ctrl-c and leave you in debug mode.
I assume that you are doing something iteratively here and not relying on a built-in matlab function.
The way I usually solve the issue you have is to have an iteration counter and an if statement on that counter - when the condition is met, the statement has a breakpoint.
Something like this:
itCounter = 0;
itHalt = 100;
while (someCondition)
if (itCounter == itHalt)
itCounter = 0; %<= Put a breakpoint here
else
itCounter = itCounter+1;
end
% Here you calculate away whatever you need to calculate
end
This way, in every itHalt iterations you get a breakpoint. Also, since we're dealing with matlab, you can change the value of itHalt as you see fit as soon as the breakpoint is hit.
I'm thinking to an alternative solution:
Let's have a script which basically consists of a main loop.
The script periodically writes information about the execution status (e. g. the number of iteration done) into a log file.
Also, the script periodically reads a number from the input file
1 meaning "continue"
0 meaning "stop the script execution"
At the beginning of the simulation, 1 is written in the file.
The user can read the log and can decide, at a certain point, to stop the script.
To do it, he has just to change 1 to 0 in the file as save it.
An if section exemines the value read on it.
If 1, nothing appens and the script continues running.
If 0, a break statement terminates the main loop and the script stops.
Just before the break statement, in the if section, the script saves the whole workspace into a .mat file.
The user has now access to MatLab (he can evan close MatLab) and can look, for example, at the output files generated up to that moment by the script, process them, make somo plot and so on.
Then he might decide to continue the execution of the script from the point in which it has been stopped.
At the begining of the script, a variable controls the way the script has to be executed:
Mode 0: start from the beginning
Mode 1: resume the script
An if - else section maneges the user selection.
In particular, if Mode 1 is selected, the script loads the previously saved workspace (stored in a .mat file), then the value of some variables of the script are set to the old values.
As an example: the script was stopped when the index of the for loop was, say, 100.
if the for loop is defined as
for i=start_loop_1:100000
in the Mode 1 of the if, start_loop_1 is set to i+1 (the value of i was saved in the .mat file).
This allows the loop "continuing" the execution from the point in which it was stopped.
In order to effectively "resume" the running of the script, some other variables used in the script might require to be managed in the same way in the Mode 1 section.
In tha case of a "big", "complicated" script this might be difficult, but ... not impossible
This solution has been implemented in the following script.
I can see a potential criticality consisting in the unlucky case in which the user saves the file containing 1,0 at the same time the script reads it.
% Flag to select the running mode
% Mode 0: start from the beginning
% Mode 1: resume the running
continue_my_script=1;
% if "Mode 1" has been selected, the "old" workspace is loaded and some
% variables are properly set
if(continue_my_script == 1)
load my_script_data
start_loop_1=i+1;
start_loop_2=1;
% if Mode 0 has been selected some variables are set to their default value
else
start_loop_1=1;
start_loop_2=1;
% counter to enable writing of the log file
cnt_log=0;
% counter to enable reading the "go / no go" input file
cnt_go=0;
end
% Definition of the condition for writing the log file (in this case, a
% certain number of iterations")
log_iter=13;
% Definition of the condition for reading the "go / no go" input file (in
% this case, a certain number of iterations")
go_nogo_iter=20;
% Starting point of the "real script"
for i=start_loop_1:100000
% Increment the log counter
cnt_log=cnt_log+1;
% if "log_iter" have been done, update the log file
if(cnt_log == log_iter)
cnt_log=0;
t=clock;
fp=fopen('my_script_log.log','wt');
fprintf(fp,'i= %d at %d %d %f\n',i,floor(t(4)),floor(t(5)),t(6));
fclose(fp);
end
% Another loop of the script
for j=start_loop_2:100000
a(i,j)=sqrt(i);
end
% Increment the "read input file" counter
cnt_go=cnt_go+1;
% if "go_nogo_iter" have been done, read the go_nogo input file
if(cnt_go == go_nogo_iter)
cnt_go=0;
fp1=fopen('my_script_go.log','rt');
go_nogo=fscanf(fp1,'%d');
fclose(fp1);
% If the user made the decision to stop the execution, save the workspace
% and exit; otherwise ... do noting, just continue running
if(go_nogo == 0)
save my_script_data
break;
end
end
end
Hope this helps.
Okay, just to rephrase what I said in the comments with inputs from other users who commented. If your script is a MATLAB script, (Not a function), all the variables will be accessible from the workspace as long as you did not explicitly called 'clear' in the script if the script is stopped. In the usual case, ctrl+c will terminate the running script. The MATLAB variables used in the script will still be accessible from the MATLAB Workspace.
I don't think there is anything you can do while the code is already running, unless you put some hooks in place beforehand. Some of these other suggestions are good for that. Here is another one that I like: say you are leaving for the night, but coming back the next day, so you want your code to run for 14 hours and then stop and be waiting for you with however much data it got to in that time.
start_time = now;
final_time = start_time + 10/86400; % datenums are in days in Matlab, so +14/24 for 14 hours
% alternative: final_time = datenum('12-Aug-2015 09:00:00');
while now < final_time
% do work
disp('Working...')
pause(1)
end
% potential clean up code to save results
disp('Clean up code.')

{AHK} Defining controls (/Assigning tasks) for those GUI buttons that were creted after script launch

Lets say with some action during running script, you create gui with several buttons via Loop.
Loop, 5
{
Gui, Add, Button,, Number %A_Index%)
}
Gui, Show
How do u then assign actions upon pressing one of buttons?
It seems you cant do it after script launch, and tricks like
ButtonNumber%A_Index%: ;even if i was doing it inside loop.
do something here bla bla
return
do not work.
To do things even worse, i wanted to created these buttons (here for test) from contents of a file, say, each lines text gets utilized to name a button.
you can find similar mini-projects in AHK help files. Buts lets stick with this simple analog.
May be:
Storing and Responding to User Input, third option Variable or g-label is the anwser. Yet it asks for static/global var, but i have troubles declaring these. And g-labels i am not familiar with.
Other option i had in mind is- creating pre-defined buttons (a lot), rename them to my values (from file), and discard rest. hopefully i will be able to use predefined controls.
P.S
AHK help file is a real mess, as a beginner i find it pretty had to fish out complete and meaningful information, instead you have to search and take a bite here and there.
One way is to use a parsing loop and one g-label for all the buttons, then use A_guiControl to get the variable name of the button that called the sub-routine
Example:
; fileread, file_content, Path-to-file
file_content =
(
line with text one
line with text more
line with text other
line with text something
line with text two
)
Loop, parse, File_content, `n, `r
{
Gui, Add, Button, vMyButton%A_index% gButtons, %A_LoopField%
}
Gui, Show
return
Buttons:
msgbox % A_GuiControl
return
GuiClose:
ExitApp
Hope it helps
I have found one possible anwser to my problem. Basicly it involves g-label functionality that blackholyman (lel) suggested.
Using same g-label for all my buttons combined with A_GuiControl comparison inside button control.
Since i have stored buton names in a file, in one line with other data, that is relevant for this button, i can compare each line, by parsing, with button name (A_GuiControl), thats makes me able to retrieve relevant data inside assigned g-label.
May be some one will find it useful. Ill add code later.