Xojo launch/run another app (Mac) - macos

I want my program to launch another desktop application.
Tried shell execute (open appname) but it does not work.
Is there another way ?
Thank you in advance.

Another possibility is use the standard Xojo FolderItem and use the Launch method.
Dim f as folderitem = specialfolder.applications.child("AppName")
if f <> nil and f.exists then
f.launch
end
Reference Documentation:
http://docs.xojo.com/index.php/SpecialFolder
http://docs.xojo.com/index.php/FolderItem.Launch

dim s as new Shell
s.Execute("open -a ""Finder""")
' Check error code and do something about it...
if s.ErrorCode <> 0 then
MsgBox("Error code: " + Str(s.ErrorCode) + EndOfLine + "Output: " + s.Result)
end if
Change "Finder" to whichever application you need, or build a string and pass that to s.Execute(). Be sure to include escaped quotes, especially if the application has spaces in its name.

I'm not familiar with Xojo, however "launching" an application on OS X is complicated. There are many things you need to consider, especially if it's already running.
I recommend you look into two possible options, either use Xojo's ability to launch call native C code to run one of the three -[NSWorkspace launchApplication...] methods: https://developer.apple.com/library/mac/documentation/cocoa/reference/applicationkit/classes/NSWorkspace_Class/Reference/Reference.html#//apple_ref/doc/uid/20000391-SW23
Alternatively, use Apple's open command line tool:
/usr/bin/open -a "App Name"
/usr/bin/open -a "/Applications/App Name.app"

Related

Cannot write files from Lua in Scite on Windows 10?

Using Scite 4.1.3 on Windows 10.
I tried the following Lua script:
function TestFile()
mycontent = "Hello World"
mytmpfilename = os.tmpname()
os.execute("echo aaaa > " .. mytmpfilename) -- create file explicitly;
mytmpfile = io.popen(mytmpfilename, "w") -- w+ crashes Scite in Windows!
mytmpfile:write(mycontent)
mytmpfile:close()
print("readall " .. mytmpfilename .. ": " .. io.popen(mytmpfilename, "r"):read("*a"))
end
If I run this, I get printed:
readall C:\Users\ME\AppData\Local\Temp\s8qk.m:
... which means Lua could not even read this file?! And also, this stupid Windows Explorer prompt shows up:
At end, the content of the C:\Users\ME\AppData\Local\Temp\s8qk.m is still just aaaa.
So obviously, mytmpfile:write part fails silently, and nothing new is written in the file - the only thing that wrote to the file is the echo aaaa > ... executed by cmd.exe via os.execute.
So my question is - how can I write a file with Lua in Scite on Windows? Preferably, without having that stupid "How do you want to open this file?" prompt show up?
Eh, I think I got it ...
See, the OP example uses io.popen - and, if we look at https://man7.org/linux/man-pages/man3/popen.3.html it says:
popen, pclose - pipe stream to or from a process
(emphasis mine).
So, basically, if under Windows I try to do io.popen(filename), then apparently tries to find the process that would be the default "opener" for that file type ... and also therefore the prompt I'm being shown in the OP (and therefore, I could never read or write the files accessed -- or rather, not accessed -- in that way).
However, Programming in Lua : 21.2 – The Complete I/O Model actually uses io.open (notice, no p for process); and then the files seem to open for read/write fine.
So, corrected example from OP should be:
function TestFile()
mycontent = "Hello World"
mytmpfilename = os.tmpname()
-- os.execute("echo aaaa > " .. mytmpfilename) -- create file explicitly; -- no need anymore, with io.open
mytmpfile = io.open(mytmpfilename, "w+") -- w+ crashes Scite in Windows, but only if using io.popen; is fine with io.open!
mytmpfile:write(mycontent)
mytmpfile:close()
print("readall " .. mytmpfilename .. ": " .. io.open(mytmpfilename, "r"):read("*a"))
end

How to pass the identity of the caller Script to the external Script Library?

How to best pass the identity of the caller Script to the external Script Library?
I have found a way to do this successfully ... however the question then becomes "Is it the best way?"
In the external Script Library, I have:
property pCallerScript : 0
on libPassCaller(theCallerScript)
set pCallerScript to theCallerScript
end libPassCaller
followed later in this Library, for example:
set topmostError to pCallerScript's gTerminateThisScript & return & return & localError
I set all this up via the following code in my Calling Script:
property pExternalLib : ""
set pExternalLib to load script file pExternalScriptFile
property passCaller : me
pExternalLib's libPassCaller(passCaller)
So, is this the very best way?

How to execute an external command asynchronously in gVim 8.1 without starting a new cmd every time and append the output to an existing buffer

I want to execute a batch file and display the output on a new buffer. I know I can use !start for this, but I can't figure out how to make it reuse the same command-line instead of starting a new one every time.
I managed to get close by using :terminal instead with send_keys(), checking if the terminal buffer still exists and only starting a new one when it doesn't. The problem with this is that what I get is an interactive shell, so I have to switch to Terminal-Normal mode to be able to navigate the contents of the buffer otherwise cmd steals focus from vim and doesn't let me move around. Also the prompt itself is part of the output, which is annoying.
Here's the code:
fun! MatchAnyInList(list, value)
return index(map(a:list, 'v:val =~# "' . a:value . '"'), 1) >= 0
endfun
" I have no idea what I'm doing
fun! RunBuildBatchFile()
if !exists("g:terminal_bufnum") || MatchAnyInList(['finished', ''], term_getstatus(g:terminal_bufnum))
let g:terminal_bufnum = term_start("cmd", {'hidden': 1})
call term_sendkeys(g:terminal_bufnum, "vcvarsall x64\<CR>")
endif
if bufwinnr(g:terminal_bufnum) < 0
execute "botright sb " . g:terminal_bufnum
call term_setsize(g:terminal_bufnum, 4, 0)
endif
call term_sendkeys(g:terminal_bufnum, "cls\<CR>")
call term_sendkeys(g:terminal_bufnum, "C:\\Path\To\Executable\Command.exe")
if term_getstatus(g:terminal_bufnum)=~# "normal"
call feedkeys("i")
endif
endfun
There's probably a much better way of doing this. I tried looking for information about this stuff online and in the docs but I didn't get anywhere. Any ideas?

Is there a Vim plugin for Ruby which provides a "switch to/from test" command outside of Rails?

Tim Pope's rails.vim provides a command :A (and a set of related commands) which opens the "alternate" file. For most classes, that's the test, and for the test, the class.
It would sure be nice to have that functionality in non-Rails Ruby projects. Is there a plugin which provides that? Bonus points if it helps me create the test file when I create the implementation file. :)
Our hero tpope wrote rake.vim too. It does the very same things rails.vim does but in Ruby projects.
I created the following command that makes it possible to do
:E /pattern/replace
to jump to the file that is the current filename and substituting pattern by replace
For example, if your tests files are in /test/code.js and your src files in /src/code.js you could write the following command:
command! -nargs=* Es :call EditSubstitute("/test/src")
command! -nargs=* Et :call EditSubstitute("/src/test")
to have the command :Es to jump from testfile to source file and the command :Et to jump from source file to testfile.
Here's the function that does that :
function! EditSubstitute(args)
if (len(a:args))<2
return
endif
let s:delimiter = (a:args[0])
let s:split = split(a:args,s:delimiter,1)[1:]
let s:fullpath = expand('%:p')
let s:bar = substitute(s:fullpath, s:split[0], s:split[1], "")
echo (s:bar)
silent execute('edit '.s:bar)
endfunction
command! -nargs=* E :call EditSubstitute(<q-args>)
I know this doesn't really answer your question at all... but I use VIM buffers to provide easy accessibility to a file and its tests.
I keep my test on top, and the file on the bottom. Then I can view both at the same time.
I use NERDTree to make browsing easier too, but that is not a per-requisite.
You can get a full reference of what I use here:
https://github.com/coderjoe/dotfiles
If you like it I'd recommend NOT using my dotfiles from the above repo, but start with something like RyanB's dotfiles and build your own sets based on your own preferences. :)
Have a look at the vimrc of the guy from 'Destroy all software' https://github.com/garybernhardt/dotfiles/blob/master/.vimrc#L280
pressing <leader>. will switch you between your code and the spec code.
-frbl

slash and backslash in Ruby

I want to write a application that works in windows and linux. but I have a path problem because windows use "\" and Linux use "/" .how can I solve this problem.
thanks
In Ruby, there is no difference between the paths in Linux or Windows. The path should be using / regardless of environment. So, for using any path in Windows, replace all \ with /. File#join will work for both Windows and Linux. For example, in Windows:
Dir.pwd
=> "C/Documents and Settings/Users/prince"
File.open(Dir.pwd + "/Desktop/file.txt", "r")
=> #<File...>
File.open(File.join(Dir.pwd, "Desktop", "file.txt"), "r")
=> #<File...>
File.join(Dir.pwd, "Desktop", "file.txt")
=> "C/Documents and Settings/Users/prince/Desktop/file.txt"
As long as Ruby is doing the work, / in path names is ok on Windows
Once you have to send a path for some other program to use, especially in a command line or something like a file upload in a browser, you have to convert the slashes to backslashes when running in Windows.
C:/projects/a_project/some_file.rb'.gsub('/', '\\') works a charm. (That is supposed to be a double backslash - this editor sees it as an escape even in single quotes.)
Use something like this just before sending the string for the path name out of Ruby's control.
You will have to make sure your program knows what OS it is running in so it can decide when this is needed. One way is to set a constant at the beginning of the program run, something like this
::USING_WINDOWS = !!((RUBY_PLATFORM =~ /(win|w)(32|64)$/) || (RUBY_PLATFORM=~ /mswin|mingw/))
(I know this works but I didn't write it so I don't understand the double bang...)
Take a look at File.join: http://www.ruby-doc.org/core/classes/File.html#M000031
Use the Pathname class to generate paths which then will be correct on your system:
a_path = Pathname.new("a_path_goes_here")
The benefit of this is that it will allow you to chain directories by using the + operator:
a_path + "another_path" + "and another"
Calling a_path.to_s will then generate the correct path for the system that you are on.
Yes, it's annoying as a windows users to keep replacing those backslashes to slashes and vice-versa if you need the path to copy it to your filemanager, so i do it like his.
It does no harm if you are on Linux or Mac and saves a lot of nuisance in windows.
path = 'I:\ebooks\dutch\_verdelen\Komma'.gsub(/\\/,'/')
Dir.glob("#{path}/**/*.epub").each do |file|
puts file
end

Resources