Automate running several vim commands and keystrokes - clojure

I want to automate running several commands in vim, i.e. by typing :repl. The commands are:
:ConqueTerm lein repl
<Esc>
:set syntax=clojure
<i>
How do I define a custom vim function (command) that executes the above?
About the above:
clojure - the Clojure programming language (syntax provided by vim-clojure-static
ConqueTerm - a vim plugin that runs a shell interactively in your vim buffer
lein - Leiningen, a Clojure build tool

you could just create a function, and put your commands in that function:
fun! LeinCMD()
execute 'ConqueTerm lein repl'
execute 'set syntax=clojure'
execute 'normal! i'
endf
command! Repl call LeinCMD()
you could source above codes, and type :Repl and Enter to test if it works for you.
EDIT
very nice comments by #Zyx. I just put them in answer, so that readers won't miss valuable information in future.
You need exactly no :execute calls here.
:normal! i is useless, to start insert mode from functions there is :startinsert and :call feedkeys(), former should be preferred. // Note: :normal! i “works” here because :startinsert is run by :ConqueTerm. I.e. due to the way Conque is written you don’t need :startinsert at all, but if it was not already there :normal! i would continue to do nothing useful.
Just mentioned: it would be much nicer to use command -bar: this way you won’t need :execute to chain your command with pipe symbol (try Repl | echo "Here" with and without -bar as a second argument to :command). I think it have been the default option, don’t know why Bram likes to have bad defaults in a number of places.

Have you tried?
function custom_function ()
execute 'ConqueTerm lein repl'
execute 'set syntax=clojure'
return custom_function
endfunction
i don't know if this code will work as i have not tested it

Related

How to set a breakpoint in a Clojure program using Calva?

I am working with a Clojure code and need to make changes in some parts of it. For that, I need to stop it in a breakpoint to see what are the values of atoms, variables, .... one step before new changes. The code I am working with is:
https://github.com/lspector/clojush
I need to stop it in breed.clj,defn perform-genetic-operator-list, at the end of line 99 (num-parents).
I am using Calva in VS code and run the code via the terminal with this command:
"lein run clojush.problems.demos.simple-regression".
I tried putting #break inside "num-parents (:parents (get genetic-operators operator))" as:
num-parents (:parents (get genetic-operators #break operator))
but it did not work and program stops showing some errors. Also I tried instrumentation and again did not work.
Any help is highly appreciated. Thanks!

How to evaluate an expression to be used for a gdb monitor command?

Inside a scripted gdb session I want to use monitor <cmd> where cmd should contain the address of a symbol. For example:
monitor foobar &myVariable
should become to:
monitor foobar 0x00004711
Because the remote side cannot evaluate the expression. Whatever I tried, the string "&myVariable" gets sent instead of the address.
I played around with convenience variables and stuff, but this is the only workaround I found:
# write the command into a file and execute this file
# didn't find a direct way to include the address into the monitor command
set logging overwrite on
set logging on command.tmp
printf "monitor foobar 0x%08x\n", &myVariable
set logging off
source command.tmp
Any ideas to solve this in a more elegant way?
The simplest way to do this is to use the gdb eval command, which was introduced for exactly this purpose. It works a bit like printf:
(gdb) eval "monitor foobar %p", &myVariable
(I didn't actually try this, so caution.)
If your gdb doesn't have eval, then it is on the old side. I would suggest upgrading.
If you can't upgrade, then you can also script this using Python.
If your gdb doesn't have Python, then it is either very old (upgrade!) or compiled without Python support (recompile!).
If you can't manage to get either of these features, then I am afraid the "write out a script and source it" approach is all that is left.

How can I find why system can not run my application?

I have a c++ program that run a command and pass some arguments to it. The code is as follow:
int RunApplication(fs::path applicationPathName,std::string arguments)
{
std::string applicationShortPath=GetShortFileName(applicationPathName);
std::string cmd="\""+applicationShortPath +"\" "+ arguments+" >>log.txt 2>&1 \"";
std::cout<<cmd<<std::endl;
int result=std::system(cmd.c_str());
return result;
}
When I run system command, the cmd window appears shortly and then closes, but the result is 1 and the cmd was not run (the command should generate output which is not generated).
To check that the cmd is correct, I stopped the application just before system line and copy/ paste cmd content to a cmd window and it worked.
I am wondering how can I find why application is not run in system()?
the cmd has this value just before running it:
"D:/DEVELO~3/x64/Debug/enfuse.exe" -w --hard-mask --exposure-weight=1 --saturation-weight=0.328 --contrast-weight=0.164 -o "C:/Users/m/AppData/Local/Temp/1.tif" "C:/Users/m/AppData/Local/Temp/1.jpg" "C:/Users/m/AppData/Local/Temp/2.jpg" >>log.txt 2>&1 "
How can I find why it is not working?
Is there any way that I set the system so it doesn't close cmd window so I can inspect it?
is there any better way to run a command on OS?
Does Boost has any solution for this?
Edit
After running it with cmd /k, I get this error message:
The input line is too long.
How can I fix it other than reducing cmd line?
There are two different things here: if you have to start a suprocess, "system" is not the best way of doing it (better to use the proper API, like CreateProcess, or a multiplatform wrapper, but avoid to go through the command interpreter, to avoid to open to potential malware injection).
But in this case system() is probably the right way to go since you in fact need the command interpreter (you cannot manage things like >>log.txt 2>&1 with only a process creation.)
The problem looks like a failure in the called program: may be the path is not correct or some of the files it has to work with are not existent or accessible with appropriate-permission and so on.
One of the firt thing to do: open a command prompt and paste the string you posted, in there. Does it run? Does it say something about any error?
Another thing to check is how escape sequence are used in C++ literals: to get a '\', you need '\\' since the first is the escape for the second (like \n, or \t etc.). Although it seems not the case, here, it is one of the most common mistakes.
Use cmd /k to keep the terminal: http://ss64.com/nt/cmd.html
Or just spawn cmd.exe instead and inspect the environment, permissions, etc. You can manually paste that command to see whether it would work from that shell. If it does, you know that paths, permssions and environment are ok, so you have some other issue on your hands (argument escaping, character encoding issues)
Check here How to execute a command and get output of command within C++ using POSIX?
Boost.Process is not official yet http://www.highscore.de/boost/process/

GDB python script for bounded instruction tracing

I'm trying to write a GDB script to do instruction tracing in a bounded maner (i.e start addr and stop addr). Perhaps I'm failing at google but I cant seem to find this in existence already.
Here is my stab at it:
python
def start_logging():
gdb.execute("set logging on")
gdb.execute("while $eip != 0xBA10012E9")
gdb.execute("x/1i $eip")
gdb.execute("stepi")
gdb.execute(" end")
gdb.execute("set logging off")
gdb.execute("set pagination off")
gdb.execute("break *0xBA19912CF")
gdb.execute("command 1 $(start_logging())")
gdb.execute("continue")
In my mind this should set up a breakpoint then set the command to run when it hits. When the breakpoint hits it should single step through the code until the end address is hit and then it will turn off logging.
When I run this with gdb the application will break at the correct point but no commands are run.
What am I doing wrong? Sorry if this is the wrong way to go about this please let me know. I'm new to gdb scripting
I see a few odd things in here.
First, it looks like you are trying to split multi-line gdb commands across multiple calls to gdb.execute. I don't believe this will work. Certainly it isn't intended to work.
Second, there's no reason to try to do a "while" loop via gdb.execute. It's better to just do it directly in Python.
Third, I think the "command" line seems pretty wrong as well. I don't really get what it is trying to do, I guess call start_logging when the breakpoint is hit? And then continue? Well, it won't work as written.
What I would suggest is something like:
gdb.execute('break ...')
gdb.execute('run')
while gdb.parse_and_eval('$eip') != 0x...:
gdb.execute('stepi')
If you really want logging, either do the 'set logging' business or just instruct gdb.execute to return a string and log it from Python.

Wmic /format switch invalid XSL?

I have a quick question, should be relatively simple for those who have some more experience in WMI-command processor than I do (and since I'm an absolute beginner thats not hard :-) )
I fail to understand why wmic /format switch works the way it does. I open up cmd.exe and type
wmic process list brief /format:htable > processlist.html
this does exactly what I want and no bothers further on. Whereas if I go to wmic processor, and try to execute the same command exactly as above...
wmic:root\cli>process list brief /format:htable > processlist.html
I receive the error tag: "Invalid XSL format (or) file name."
Here goes the screenshot. Note I have already copied XSL files from wbem to sys32 dir
Can someone explain to me why these 2 commands that for me look exactly the same, with the only difference that one is executed outside wmic environment and the other one is from inside, the latter one doesn't work? I just fail to understand it.
Please advise so I can comprehend this a bit better! :-)
Try this
copy /y %WINDIR%\system32\wbem\en-US\*.xsl %WINDIR%\system32\
And then
wmic:root\cli>process list brief /format:htable.xsl > processlist.html
Note the presence of the extension after "htable"
You are attempting to use CMD.EXE > redirection while you are within the interactive WMIC context. That can't work.
You can use the WMIC /output:filename switch while in interactive mode. Each subsequent command will overwrite the output of the previous command. You can get multiple commands to go to the same file by using /append:filename instead. You can reset the output back to stdout using /output:stdout.
/output:processlist.html
process list brief /format:htable
/output:stdout
Did you try specifying a full path in the wmic:root\cli>process call? My bets are that the first worked because it output the file to the current directory.