I have tried a few methods, one of them being:
(define (program) (find-system-path 'pref-file))
I have read from the documentation (after attempting the above code) and have noticed it is not what i'd need to use, obviously :) Any ideas?
Would also like to save this information to a variables. VBS example:
script = WScript.ScriptFullName
#lang racket
(display "Program name: ")
(displayln (find-system-path 'run-file))
Output (if saved as "test.rkt" and run with the command racket test.rkt):
Program name: test.rkt
From the racket console REPL, (find-system-path 'run-file) will return #<path:racket>. I didn't try it in DrRacket.
Related
I have some elisp that runs an external 'npm' command.
(defun npm-mode-npm-run ()
"Run the 'npm run' command on a project script."
(interactive)
(let ((command
(completing-read
"Run command: " (npm-mode--get-project-scripts))))
(message "Running npm script: %s" command)
(switch-to-buffer npm-mode--buffer-name command)
(erase-buffer)
(ansi-term (getenv "SHELL") "npm-mode-npm-run")
(comint-send-string "*npm-mode-npm-run*" (format "npm run-script %s\n" command))))
While it does the job, when execution completes the user is left in a buffer that must be killed, and that requires additional confirmation to kill the process.
What I would like is once the program exits, I could press the 'q' key to do all of that, leaving the user in their original buffer.
Is their a good example of how to do this best for modern emacs that I could refer to, or any other specific docs that may be helpful?
Many thanks in advance!
As #jpkotta said, compile is a good option. You can bury the buffer easily, send a TERM signal to the underlying process, etc. Also, you get for free error parsing (syntax coloring + the ability to jump to the offending line) for many languages.
Here is an example of how I use it (in this case to do a quick run of any script I am editing):
(defun juanleon/execute-buffer ()
(interactive)
(let ((compile-command nil))
(compile buffer-file-name)))
Easy to modify to adapt to your code. The let is for avoid adding stuff to compile history (since I use compile a lot for regular compilation, and history is useful).
I'm trying to use geiser-mode in emacs to run racket code.
I've been able to install geiser-mode and launched racket.
Yet when I run a definition twice I got the following error.
this name was defined previously and cannot be re-defined
here is simple example
(define a (* 1 4))
a
run twice
In the debugger
#a: this name was defined previously and cannot be re-defined
#in: a
racket appears to behave differently in a file and the REPL. This file will throw an error:
#lang racket
(define a 5)
(define a 6)
And this REPL session will not:
> (define a 5)
> a
5
> (define a 6)
> a
6
The behavior is because of the way modules work. When working in a file, there is an implicit module. Once the symbol a has been defined in that module another symbol with the same name cannot be defined within that module. The REPL simply expands forms without all the ceremony of modules.
I would like to programmatically detect the program name within Racket code. This can be done in Chicken Scheme with:
#!/bin/sh
#|
exec csi -ss $0 ${1+"$#"}
exit
|#
(define (main)
(display (format "Program: ~a\n" (program-name)))
(exit))
(if (not (equal? (program-name) "csi"))
(main))
How could I emulate this in Racket?
Is this what you want?
(find-system-path 'run-file)
See also racket/cmdline for how to parse the commandline.
http://docs.racket-lang.org/reference/Command-Line_Parsing.html
Note: for this particular pattern of execution, to have a library module that can also be run as a main, use a submodule named main. See Main and Test Submodules, which shows how to do this.
I want to write an emacs function that does the following -
1) Start a new shell named "abc".
2) Change the dir "/opt/abc"
3) In the dir run a shell command "python abc.py"
I have written the following function -
(defun abc-server ()
(interactive)
(shell-command "cd /opt/abc/")
(shell-command "python abc.py"))
The problem with the above -
1) It doesnt start a new shell
2) It doesnt change the dir.
3) When the cmd executes, it opens a browser window, which completely blocks any usage of emacs.
From shell-command's docstring (C-h f shell-command):
If COMMAND ends in ampersand, execute it asynchronously.
The output appears in the buffer `Async Shell Command'.
That buffer is in shell mode.
Also, combine it all into one command line. shell-command makes a new shell every time, so the pwd will not persist from one invocation to another.
(defun abc-server ()
(interactive)
(shell-command "cd /opt/abc/; python abc.py &"))
While #jpkotta's answer is good enough, a proper solution would use the anync primitives of Emacs. For one thing, you can only have one async shell command running at a time, whereas you can have a large number of named subprocesses.
(defun abc-server ()
(interactive)
;; Create buffer ahead of time so we can change its default directory
(save-excursion
(get-buffer-create "*abc-server*")
(cd "/opt/abc") )
(start-process "abc" "*abc-server*" "python" "abc.py") )
(I'm not altogether happy with the save-excursion hoop. I was hoping I could simply let-bind default-directory, but that didn't seem to work as I had expected. Alternatively, you could (start-process "abc" "*abc-server*" "sh" "-c" "cd /opt/abc; python abc.py").)
If you need to extend the command further, I would argue that this is a more scalable platform than the quick and dirty async shell command approach, but if this is all you are ever going to need, it doesn't matter much.
I'm trying to feed flymake output from Haxe compiler, but I don't know how to tell it where the make file lives (ideally, I'd use nxml file instead). So far I have this in the Makefile:
BIN = ./bin
MAIN = com.wunderwafer.Main
SWF = wunderwafer.swf
SWFSETTINGS = -debug -swf-version 10 -swf-header 800:600:31
HFLAGS = -main $(MAIN) $(SWFSETTINGS) -cp ./src -swf $(BIN)/$(SWF)
HC = haxe
default: compile
compile: $(HC) $(HFLAGS)
clean:
$(RM) -r $(BIN)/*
.PHONY: check-syntax
check-syntax:
$(HC) $(HFLAGS)
If I run it later like so:
$ make -k check-syntax
It produces the expected output. However flymake isn't able to find the Makefile (or so it seems) because the files I'm trying to check are deeper inside the src directory.
What is the way to configure flymake so it knows where the makefile is? (or, even better, just execute a shell command, because the common way to compile Haxe code is by using *.nxml settings file.
EDIT:
It looks like I'm getting closer, lots of thanks, but flymake is doing something strange, and I can't understand what exactly it does, so, here's the log:
received 65 byte(s) of output from process 967
file /home/wvxvw/projects/wafer/src/com/wunderwafer/map/Battlefield.hx, init=haxe-flymake-init
parsed 'Error : Invalid class name /home/wvxvw/projects/wafer/build.nxml', no line-err-info
file /home/wvxvw/projects/wafer/src/com/wunderwafer/map/Battlefield.hx, init=haxe-flymake-init
process 967 exited with code 1
cleaning up using haxe-flymake-cleanup
deleted file /tmp/flymake-Battlefield-855Cad.hx
Battlefield.hx: 0 error(s), 0 warning(s) in 0.15 second(s)
switched OFF Flymake mode for buffer Battlefield.hx due to fatal status CFGERR, warning Configuration error has occurred while running (haxe /home/wvxvw/projects/wafer/build.nxml)
The command I'm trying to make it run looks like this:
(defun haxe-flymake-get-cmdline (source base-dir)
"Gets the cmd line for running a flymake session in a Haxe buffer.
This gets called by flymake itself. The output is a list of two elements:
the command to run, and a list of arguments. The resulting command is like:
$ haxe ${project-root}/build.nxml
"
(message "base-dir %s" (file-name-as-directory base-dir))
(list *haxe-compiler*
(list
(concat (file-name-as-directory base-dir)
*build-nxml*))))
The message printed looks like this:
base-dir /home/wvxvw/projects/wafer/
So, as far as I could understand, the resulting command should be:
haxe /home/wvxvw/projects/wafer/build.nxml
But it looks like flymake either adds something in front of the argument or afterwards, which makes Haxe compiler generate the error "Error : Invalid class name" - this error would be given if there was one extra argument, which the compiler would have understood as an extra class to compile. But the log doesn't show what is being sent...
EDIT 2:
I've added:
#!/usr/bin/env bash
echo "$#" > /home/wvxvw/projects/wafer/log
And made flymake invoke this script instead of the compiler, and it passes only one argument, just as I would expect it... sigh
It's a good question. I don't know a simple way of adding in a new "flavor" of make tool into flymake. I know of a way, it's just not simple. This is what I did for php codesniffer - it will be similar for any arbitrary make tool.
First, define an install fn.
(defun fly/phpcs-install ()
"install flymake stuff for PHP CodeSniffer files."
(add-to-list
'flymake-err-line-patterns
(list fly/phpcs-error-pattern 1 2 3 4))
(let* ((key "\\.php\\'")
(phpentry (assoc key flymake-allowed-file-name-masks)))
(if phpentry
(setcdr phpentry '(fly/phpcs-init fly/phpcs-cleanup))
(add-to-list
'flymake-allowed-file-name-masks
(list key 'fly/phpcs-init 'fly/phpcs-cleanup)))))
This installs a new entry into the flymake alist, keyed on .php as a file extension. The entry in flymake's list basically relates the file extension to a pair of functions, one for init and one for cleanup.
The init fn simply returns the command to run to check syntax. This can be a shell command, with the appropriate arguments. For codesniffer this fn looks like this:
(defun fly/phpcs-init ()
"initialize flymake for PHP using the PHP CodeSniffer tool."
(let ((create-temp-f 'fly/phpcs-create-temp-intemp)
(use-relative-base-dir t)
(use-relative-source t)
(get-cmdline-f 'fly/phpcs-get-cmdline)
args
temp-source-file-name)
(setq temp-source-file-name (flymake-init-create-temp-buffer-copy create-temp-f)
args (flymake-get-syntax-check-program-args
temp-source-file-name "."
use-relative-base-dir use-relative-source
get-cmdline-f))
args))
Yikes! Down the rabbit hole we go. The get-cmdline fn looks like this:
(defun fly/phpcs-get-cmdline (source base-dir)
"Gets the cmd line for running a flymake session in a PHP buffer.
This gets called by flymake itself. The output is a list of two elements:
the command to run, and a list of arguments. The resulting command is like:
php.exe -d auto_append_file="" -d auto_prepend_file="" phpcs\scripts\phpcs --report=emacs file.php
"
(list fly/phpcs-phpexe
(list
"-d" "auto_append_file=''"
"-d" "auto_prepend_file=''"
(concat (file-name-as-directory fly/phpcs-phpcs-dir)
"scripts\\phpcs")
(concat "--standard=" fly/phpcs-standard)
"--report=emacs"
"-s" ;; show the fullname of the rule being violated
(expand-file-name source))))
You can see the full elisp at http://www.emacswiki.org/emacs/flyphpcs.el
There's probably a simpler way. I just don't know it.