Anaconda (Python) + Cmder (Clink) on Windows - Unify Dueling Custom Prompts - batch-file

If you run Anaconda on windows, you have an activate.bat file which concludes with this line to put your current conda env on the prompt:
set PROMPT=[%CONDA_DEFAULT_ENV%] $P$G
If you run cmder on windows, there is a nice lua script to customize your prompt:
function lambda_prompt_filter()
clink.prompt.value = string.gsub(clink.prompt.value, "{lamb}", "λ")
end
clink.prompt.register_filter(lambda_prompt_filter, 40)
These two scripts do not play very nicely with each other. Clink has an API that seems like I could use to incorporate the change from activate.bat, but I cannot figure out how to call it from a batch file.
My overall goal is to merge these two prompts into the nicer Cmder-style. My thought is to create an environment variable, change activate.bat to check for the existence of the variable, and, if so, call the Clink API to change the prompt instead of set PROMPT. At that point I would think I could create a new filter to cleanly merge the value in. I can't figure out how to call the API from the batch file, though.
Other solutions welcome.
EDIT: Partial, non-working solution
require "os" -- added to top of file, rest in filter function
local sub = os.getenv("CONDA_DEFAULT_ENV")
if sub == nil then
sub = ""
end
print(sub)
clink.prompt.value = string.gsub(clink.prompt.value, "{conda}", sub)
I added a {conda} in the prompt definition at the very beginning; removed the prompt statement from activate.bat, and added this to git_prompt_filter. Prior to using activate, everything is fine - the {conda} gets suppressed by the ''. However, if I use activate and switch into a folder with a git repo to trigger the change, I see:
{conda}C:\...
Does os.getenv not get user set variables? Don't know what else the problem would be. I also tried adding a print, it doesn't print out the contents of CONDA... either.

This is what I do to reset the prompt and add the conda env name to the prompt:
---
-- Find out the basename of a file/directory (last element after \ or /
-- #return {basename}
---
function basename(inputstr)
sep = "\\/"
local last = nil
local t={} ; i=1
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
--t[i] = str
--i = i + 1
last = str
end
return last
end
---
-- Find out current conda env
-- #return {false|conda env name}
---
function get_conda_env()
env_path = clink.get_env('CONDA_DEFAULT_ENV')
if env_path then
basen = basename(env_path)
return basen
end
return false
end
---
-- after conda activate: reset prompt and add conda env name
---
function conda_prompt_filter()
-- reset to original, e.g. after conda activate destroyed it...
if string.match(clink.prompt.value, "{lamb}") == nil then
-- orig: $E[1;32;40m$P$S{git}{hg}$S$_$E[1;30;40m{lamb}$S$E[0m
-- color codes: "\x1b[1;37;40m"
cwd = clink.get_cwd()
prompt = "\x1b[1;32;40m{cwd} {git}{hg} \n\x1b[1;30;40m{lamb} \x1b[0m"
new_value = string.gsub(prompt, "{cwd}", cwd)
clink.prompt.value = new_value
end
-- add in conda env name
local conda_env = get_conda_env()
if conda_env then
clink.prompt.value = string.gsub(clink.prompt.value, "{lamb}", "["..conda_env.."] {lamb}")
end
end
clink.prompt.register_filter(conda_prompt_filter, 10)

I want to build on #Jan-Schulz answer since it didn't exactly work for me in April 2017.
Instead of editing cmder/vendor/clink/clink.lua I added custom code into cmder/config/prompt.lua which is not overwritten on upgrade (You can add additional modifications to cmder prompt in this file as well using the clink lua api)
I was having an issue where the {lamb} was not being replaced with the proper λ character so I added another filter to run at the end of all processing.
---
-- Find out the basename of a file/directory (last element after \ or /
-- #return {basename}
---
function basename(inputstr)
sep = "\\/"
local last = nil
local t={} ; i=1
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
--t[i] = str
--i = i + 1
last = str
end
return last
end
---
-- Find out current conda env
-- #return {false|conda env name}
---
function get_conda_env()
env_path = clink.get_env('CONDA_DEFAULT_ENV')
if env_path then
basen = basename(env_path)
return basen
end
return false
end
---
-- after conda activate: reset prompt and add conda env name
---
function conda_prompt_filter()
-- reset to original, e.g. after conda activate destroyed it...
if string.match(clink.prompt.value, "{lamb}") == nil then
-- orig: $E[1;32;40m$P$S{git}{hg}$S$_$E[1;30;40m{lamb}$S$E[0m
-- color codes: "\x1b[1;37;40m"
cwd = clink.get_cwd()
prompt = "\x1b[1;32;40m{cwd} {git}{hg} \n\x1b[1;30;40m{lamb} \x1b[0m"
new_value = string.gsub(prompt, "{cwd}", cwd)
clink.prompt.value = new_value
end
-- add in conda env name
local conda_env = get_conda_env()
if conda_env then
clink.prompt.value = string.gsub(clink.prompt.value, "{lamb}", "["..conda_env.."] {lamb}")
end
end
function fix_lamb()
if string.match(clink.prompt.value, "{lamb}") ~= nil then
clink.prompt.value = string.gsub(clink.prompt.value, "{lamb}", "λ")
end
end
clink.prompt.register_filter(conda_prompt_filter, 1)
clink.prompt.register_filter(fix_lamb, 999)

Why not just delete the line from activate.bat and do all the logic in your cmder profile? CONDA_DEFAULT_ENV will be empty if no environment is active.

Related

Is there a way to check if any content of a array is in another array in Roblox

So I am trying to make a script which allows me to ban people but the main script which checks if a player is in the game and in the banned users list to be killed or kicked. Here is my code:
local BannedUsers = {"littleBitsman"}
local Players = game.Players:GetChildren()
wait(10)
for index1,value1 in ipairs(Players) do
for index2,value2 in ipairs(BannedUsers) do
if Players[index1] == BannedUsers[tonumber(index2)] then
local HumanoidToKill = workspace[value1].Character:FindFirstChildWhichIsA("Humanoid")
if HumanoidToKill.Health >= 0 then
HumanoidToKill.Health = 0
print("killed " .. tostring(value1))
end
end
end
end
The wait(10) is so I can test the script without executing too early, and the use of my username is for testing.
Also when I do test it it does nothing at all.
You can use the table.find function.
local BannedUsers = {"littleBitsman"}
for _, player in ipairs(game.Players:GetChildren()) do
if table.find(BannedUsers, player.Name) then
player:Kick("You are banned!")
end
end

Eiffel: how do I do a system call?

Id like to uncompress a file with bzip2 myFile.bz2 which class do I have to use for that?
I tried to find it into base kernel documentation which made the most sense for me and didn't find it
This works:
make
local
l_env:EXECUTION_ENVIRONMENT
do
create l_env
l_env.system ("bzip2 test.txt")
end
My final solution working on linux with pipes is following:
feature -- Commands
piped_command_result (a_command: STRING): detachable PROCESS_COMMAND_RESULT
-- https://groups.google.com/forum/#!topic/eiffel-users/O9KEtBSPrf4
local
l_cmd: READABLE_STRING_32
l_args: ARRAYED_LIST [READABLE_STRING_32]
l_proc: like {BASE_PROCESS_FACTORY}.process_launcher
l_err, l_res: STRING
l_err_spec, l_res_spec: SPECIAL [NATURAL_8]
do
create l_res.make (0)
create l_err.make (0)
create l_res_spec.make_filled (0, 1024)
create l_err_spec.make_filled (0, 1024)
l_cmd := (create {EXECUTION_ENVIRONMENT}).default_shell
if l_cmd.is_empty then
l_cmd := {STRING_32} "/bin/bash" -- or either "/bin/sh"
end
create l_args.make (2)
l_args.extend ("-c")
l_args.extend (a_command)
l_proc := (create {BASE_PROCESS_FACTORY}).process_launcher (l_cmd, l_args, Void)
l_proc.set_hidden (True)
l_proc.set_separate_console (False)
l_proc.redirect_output_to_stream
l_proc.redirect_error_to_stream
l_proc.launch
check
process_launched: l_proc.launched
then
-- read output
from
until
l_proc.has_output_stream_closed or l_proc.has_output_stream_error
loop
l_proc.read_output_to_special (l_res_spec)
append_special_of_natural_8_to_string_8 (l_res_spec, l_res)
end
-- read error
from
until
l_proc.has_error_stream_closed or l_proc.has_error_stream_error
loop
l_proc.read_error_to_special (l_err_spec)
append_special_of_natural_8_to_string_8 (l_err_spec, l_err)
end
l_proc.wait_for_exit
create Result.make (l_proc.exit_code, l_res, l_err)
end
ensure
instance_free: Class
end
feature {NONE} -- Implementation
append_special_of_natural_8_to_string_8 (spec: SPECIAL [NATURAL_8]; a_output: STRING)
local
i,n: INTEGER
do
from
i := spec.lower
n := spec.upper
until
i > n
loop
a_output.append_code (spec[i])
i := i + 1
end
ensure
instance_free: Class
end
Credits to google groups eiffel users
Note that with another user like an app launched by apache, you have to check your environment variables and $PATH so that it can work!

Include files from directory (at run-time)

I want to include files from a folder in my script (I tried to Google but can't seem to find any way to do this with AutoIt). Example of what I want to achieve:
LoadFiles()
Func LoadFiles()
$FL = _FileListToArray(#ScriptDir&"\Test\", "*")
$X=1
Do
#include $FL[$X] <== How ?
$X=$X+1
Until $X=$FL[0]
EndFunc
Can anyone point me in the right direction?
In order to include a file(s) in your compiled script, you need FileInstall.
FileInstall ( "source", "dest" [, flag = 0] )
source The source path of the file to compile. This must be a literal string; it cannot be a variable or the result of a function call. It can be a relative path (using .\ or ..\ in the path) to the source file (.au3).
dest The destination path of the file with trailing backslash if only the directory is used. This can be a variable.
flag [optional] this flag determines whether to overwrite files if they already exist:
$FC_NOOVERWRITE (0) = (default) do not overwrite existing files
$FC_OVERWRITE (1) = overwrite existing files
Another way is adding the files as a resource
Good afternoon! There isn't currently a good way to do what you're asking. I've been working on building a UDF to do what you'd like, but I've been running into a couple of issues with it. I have a working prototype but there are some bugs in it. First things first, download this script and call it _includeDir.au3.
_includeDir.au3
#CS
Name: _includeDir.au3
Developer: Timothy Bomer
Copyright: Amarok Studios LLC 2016
Version: 1.0
Description:
The purpose of this UDF is to dynamically include all files inside of a folder.
It works for the most part, but I am still working on a couple of bugs.
#CE
#Include <File.au3>
Global $mainUDF = "IncludeDirUDF"
Global $includeLib = $mainUDF & "\" & "loadIncludes.au3"
Global $tempLib = $mainUDF & "\" & "lib.txt"
Global $includeRewrite = $mainUDF & "\rewrite.au3"
Global $iDirHolder = ""
Func _includeDir($iDir, $lineToInc = 1, $restart = True)
If (checkInclude()) = 1 Then
FileDelete($tempLib)
return
EndIf
If NOT (FileExists($iDir)) Then
MsgBox(16,"Directory Doesn't Exists | _includeDir","The directory " & $iDir & " does not exist!")
return 0
EndIf
$iDirHolder = $iDir
initializeCheck()
; MsgBox(0,"Include Directory", "Attempting to include: " & $iDir)
populateLib($iDir)
populateIncLib()
finalize($lineToInc, $restart)
EndFunc
Func checkInclude()
FileOpen(#ScriptName, 0)
For $i = 1 to _FileCountLines(#ScriptName)
$checkLine = FileReadLine(#ScriptName, $i)
If ($checkLine = '#Include "IncludeDirUDF\loadIncludes.au3"') Then
return 1
EndIf
Next
EndFunc
; START Initialize Check
Func initializeCheck()
; MsgBox(0,"Checking. . .", "Is this initialized?")
If (FileExists($mainUDF)) Then
If NOT (FileExists($includeLib)) Then
isError(2)
return
EndIf
; MsgBox(0,"Initialized","The UDF has been initialized")
Else
isError(1)
return
EndIf
EndFunc
; END Initialize Check
; START Library Population
Func populateLib($iDir = $iDirHolder)
; MsgBox(0,"Populating","Attempting to populate the library")
If (FileExists($tempLib)) Then
; MsgBox(0,"Temp File Found","The temporary library file has been found. Attempting to populate.")
$tLibCont = _FileListToArray(#ScriptDir & "\" & $iDir & "\", "*")
$iDirSize = $tLibCont[0]
; MsgBox(0,"Size of Included Directory", $iDir & " contains " & $iDirSize & " files to include!")
$writeLib = FileOpen($tempLib, 1)
While $iDirSize > 0
FileWriteLine($writeLib, '#Include "..\' & $iDir & '\' & $tLibCont[$iDirSize] & '"')
$iDirSize -= 1
WEnd
FileClose($writeLib)
Else
isError(3)
return
EndIf
EndFunc
; END Library Population
; START Include Library Population
Func populateIncLib()
; MsgBox(0,"Rewriting. . .", "Attempting to re-write the include library")
#CS
If (FileExists($includeLib)) Then
FileDelete($includeLib)
_FileCreate($includeLib)
EndIf
#CE
FileOpen($tempLib, 0)
For $i = 1 to _FileCountLines($tempLib)
$line = FileReadLine($tempLib, $i)
$reWriteLib = FileOpen($includeLib, 9)
FileWriteLine($reWriteLib, $line)
FileClose($reWriteLib)
Next
FileClose($tempLib)
EndFunc
; END Include Library Population
; START Finalize
Func finalize($lineToInc, $restart)
_FileWriteToLine(#ScriptName, $lineToInc, '#Include "IncludeDirUDF\loadIncludes.au3"', False)
If ($restart = True) Then
runFile(#ScriptName)
EndIf
exit
return
EndFunc
Func runFile($rFile)
$file_loc = $rFile
If #Compiled = 1 Then
$file_exe = FileGetShortName(#AutoItExe & ' /AutoIt3ExecuteScript "' & $file_loc & '"')
Run($file_exe)
Else
$file_au3 = FileGetShortName($file_loc)
Run(#AutoItExe & " " & $file_au3, "", #SW_HIDE)
EndIf
EndFunc
; START Error Reporting
Func isError($eFlag = "", $eMessage = "There was an error!")
If ($eFlag = "") Then
; MsgBox(16,"ERROR", $eMessage)
Exit
EndIf
If ($eFlag = 1) Then
; MsgBox(16,"Not Initialized","This UDF has not been initialized")
DirCreate($mainUDF)
Sleep(250)
initializeCheck()
return
ElseIf ($eFlag = 2) Then
; MsgBox(16,"Missing File","Missing the include library!")
_FileCreate($includeLib)
initializeCheck()
return
ElseIf ($eFlag = 3) Then
; MsgBox(16,"Missing File", "Missing the temporary library! Creating it now!",3)
_FileCreate($tempLib)
populateLib()
return
EndIf
EndFunc
; END Error Reporting
To use this UDF, include the file with:
Include "_includeDir.au3"
Next, call the function by following the below format.
_includeDir("Directory to Include", $lineToIncludeOn, $restart)
The directory to include would be the name of the directory with all of the files you're trying to include.
The $lineToIncludeOn specifies what line of the script the #Include will be written on. This is an optional parameter, and will default to line 1.
Lastly, $restart specifies if the script needs to be restarted or not. Sadly, the biggest bug is that the script needs to be restarted in order for the UDF to include all of the files. Which probably takes away the useful functionality of the entire script. This is an optional parameter, by default, it will be set to True and automatically restart the script.
Here's an example.
INSIDE OF WORKING DIRECTORY
Includes Folder
Example.au3
_includeDir.au3
INSIDE OF Includes Folder
One.au3
Two.au3
Three.au3
Four.au3
Five.au3
One.au3
$oneVar = "First variable"
Two.au3
$twoVar = "Second variable"
Three.au3
$threeVar = "Third variable"
Four.au3
$fourVar = "Fourth variable"
Five.au3
$fiveVar = "Fifth variable"
So, we are going to try to include One.au3, Two.au3, Three.au3, Four.au3, and Five.au3 into Example.au3.
Example.au3
; Exclude the numbers before the code. It's there just to show you the line the code is written on.
(1) #Include "_includeDir.au3"
(2)
(3) _includeDir("Includes Folder")
(4) MsgBox(0,"Included Variables","Variable One: " & $oneVar & #CRLF & "Variable Two: " & $twoVar & #CRLF & "Variable Three: " & $threeVar & #CRLF & "Variable Four: " & $fourVar & #CRLF & "Variable Five: " & $fiveVar)
This will add the line:
#Include "IncludeDirUDF\loadIncludes.au3"
to line one of Examples.au3, then restart Example.au3 to display the variables from the included files. If you changed the files inside of the Included Files directory, you will need to remove the #Include line for the loadIncludes.au3, and delete the folder that was generated. (IncludeDirUDF).
Let's say you don't want the #Include to be written to line one of Example.au3... To specify what line you want it to be written to, simply add the next parameter to the function call. For example, we want to write it to line 5 of Example.au3, we would use this:
_includeDir("Includes Folder", 5)
The last parameter is the restart parameter. This specifies if Example.au3 should be restarted after the directory is included. It is set to True by default. If you want Example.au3 to exit and stay terminated, simply add False to the end of the function call.
_includeDir("Includes Folder", 5, False)
In order to do what you're trying to do, the best way to use this would be to put it at the top of your Example.au3 (or whatever your script is) right underneath the includes. The reason for this is because it will auto-restart your script if when it generates the library and it could cause an error if it's not at the top. I hope this poorly written UDF helps you out! Let me know if there's something it's not doing that you need it to do. If not, let me know and I will fix it! Happy programming my friend! If this is too hard to follow, see my more detailed demonstration on the official AutoIt forum HERE
Thanks,
Tim
This is how i fixed it if anyone have the same issue ..
Only thing IncludeList.au3 have to exsist in the directory before you run the script or you will get include error
#include <WinAPIFiles.au3>
#include <File.au3>
; Delete Old IncludeList.au3
If FileExists("IncludeList.au3") Then
FileDelete("IncludeList.au3")
EndIf
; Get Files From Dir
$IL = _FileListToArray(#ScriptDir&"\Functions\", "*")
; Create New IncludeList.au3
$FH = FileOpen("IncludeList.au3", $FO_APPEND)
; Check For Errors
If #error <> 1 or #error <> 4 Then
; Loop True Files In Dir
For $FC = 1 To UBound($IL)-1 Step +1
; Write New #Include '.\Function\FilesToInclude.au3'
FileWrite($FH, "#Include '.\Functions\"&$IL[$FC]&"'"& #CRLF)
Next
EndIf
; Close File Handler
FileClose($FH)
; Include All The Files In Directory True IncludeList We Created
#include "IncludeList.au3"
; And Now You Can Call Any Functions From The Scripts From That Directory

waf - build works, custom build targets fail

The waf command waf build shows compiler errors (if there are any) while waf debug or waf release does not and always fails, utilizing the following wscript file (or maybe the wscript file has some other shortcomings I am currently not aware of):
APPNAME = 'waftest'
VERSION = '0.0.1'
def configure(ctx):
ctx.load('compiler_c')
ctx.define('VERSION', VERSION)
ctx.define('GETTEXT_PACKAGE', APPNAME)
ctx.check_cfg(atleast_pkgconfig_version='0.1.1')
ctx.check_cfg(package='glib-2.0', uselib_store='GLIB', args=['--cflags', '--libs'], mandatory=True)
ctx.check_cfg(package='gobject-2.0', uselib_store='GOBJECT', args=['--cflags', '--libs'], mandatory=True)
ctx.check_cfg(package='gtk+-3.0', uselib_store='GTK3', args=['--cflags', '--libs'], mandatory=True)
ctx.check_cfg(package='libxml-2.0', uselib_store='XML', args=['--cflags', '--libs'], mandatory=True)
ctx.check_large_file(mandatory=False)
ctx.check_endianness(mandatory=False)
ctx.check_inline(mandatory=False)
ctx.setenv('debug')
ctx.env.CFLAGS = ['-g', '-Wall']
ctx.define('DEBUG',1)
ctx.setenv('release')
ctx.env.CFLAGS = ['-O2', '-Wall']
ctx.define('RELEASE',1)
def pre(ctx):
print ('Building [[[' + ctx.variant + ']]] ...')
def post(ctx):
print ('Building is complete.')
def build(ctx):
ctx.add_pre_fun(pre)
ctx.add_post_fun(post)
# if not ctx.variant:
# ctx.fatal('Do "waf debug" or "waf release"')
exe = ctx.program(
features = ['c', 'cprogram'],
target = APPNAME+'.bin',
source = ctx.path.ant_glob(['src/*.c']),
includes = ['src/'],
export_includes = ['src/'],
uselib = 'GOBJECT GLIB GTK3 XML'
)
# for item in exe.includes:
# print(item)
from waflib.Build import BuildContext
class release(BuildContext):
cmd = 'release'
variant = 'release'
class debug(BuildContext):
cmd = 'debug'
variant = 'debug'
Error resulting from waf debug :
Build failed
-> task in 'waftest.bin' failed (exit status -1):
{task 46697488: c qqq.c -> qqq.c.1.o}
[useless filepaths]
I had a look at the waf demos, read the wafbook at section 6.2.2 but those did not supply me with valuable information in order to fix this issue.
What's wrong, and how do I fix it?
You need to do at least the following:
def configure(ctx):
...
ctx.setenv('debug')
ctx.load('compiler_c')
...
Since the cfg.setenv function resets whole previous environment. If you want to save previous environment, you can do cfg.setenv('debug', env=cfg.env.derive()).
Also, you don't need to explicitly specify the features = ['c', 'cprogram'], since, it's redundant, when you call bld.program(...).
P.S. Don't forget to reconfigure after modifying wscript file.

How to traverse a directory in eiffel?

Simple
How can I get a list of the files that are inside directory using eiffel?
For example:
class CARPETAS
creation
make
feature {NONE}
make is
local
directory: DIRECTORY
path: STRING
do
path := "." -- Current directory
!!directory.scan_with(path)
list_directory(directory)
end
list_directory(directory: DIRECTORY) is
local
i: INTEGER
do
std_output.put_string("Content of " + directory.path + "%N")
from
i := directory.lower
until
i > directory.upper
loop
std_output.put_string("%T" + directory.name(i) + "%N")
i := i + 1
end
end
end
with recent version of Eiffel, I would recommend to use DIRECTORY.entries
local
p: PATH
do
across dir.entries as ic loop
p := ic.item.path
-- then use interface of PATH, such as PATH.name
end
end
note that the base_extension library also provides DIRECTORY_VISITOR , which is helpful to iterate recursively on directories

Resources