Cross-platform Emacs Script - windows

I'm trying to code up an Emacs script that has to manipulate the clipboard (just getting the last entry and manipulating it as a string). The problem is that I work on Linux (at home) and Windows (at work). In Windows, I have to use the function (w32-get-clipboard-data), whereas Linux uses (x-get-clipboard) for the same purpose (and each OS helpfully errors out when you use the others' equivalent function).
I really don't want to keep two separate files with the same mode definition; is there any way to check, via elisp, which OS Emacs is currently running, so I can use the appropriate function?
PS. Yes, a reasonable solution is "Stop using Windows at work", and I'm working on it, but I'll need to put up with the thing for at least a month or two yet.

You could check if the functions are bound (if they exist) using fboundp. Then if you want to get really clever you could create your own alias that points at the right one. For example:
(defalias 'my-get-clipboard-data
(cond ((fboundp 'w32-get-clipboard-data) 'w32-get-clipboard-data)
((fboundp 'x-get-clipboard) 'x-get-clipboard)
(t nil)))

See the system-type variable.

Related

Is there a way to use load-mode for files in DrRacket?

I would like to use DrRacket in the same way that it works for some of the ‘legacy languages’. In particular, I would like to go through a file as if it were a sequence of commands issued to the interpreter, and not as a module.
Essentially I want to run at least one file in load-mode, but I’m not sure if it’s possible to do it using DrRacket.
Ideally, I could:
*Specify a file that sets the language and maybe loads some modules, which runs by default at startup.
*Then load a file that is not a module (and has no #lang specification) and run it.
It’d also be nice (since I want to use Scheme) if it would allow redefinitions, just as the legacy languages do.
Yes you can, and in fact, the 'legacy languages' (and 'teaching languages') are actually just implemented as DrRacket Plugins. You can remove them from your copy of DrRacket and even add new ones.
There are various ways to do this depending on if you are okay with a #lang (or #reader) saved in the file. If you're not, its still doable, you just need to use drracket:get/extend:extend-unit-frame to add your tool to DrRacket, and possibly drracket:get/extend:extend-definitions-text to easily extend the definitions window.
I won't go into the details of making a generic DrRacket plugin here, that belongs in a different question...also the DrRacket Plugins Manual has the information you need.1 I will, however, point you in the direction of how you can use DrRacket in load mode out of the box.
Check out the racket/load language. It is designed to run each expression in the top level as if you were at a REPL typing it. I find it very useful for testing the differences between Racket module and top level interactions.
Of course, if you don't make a DrRacket plugin, you will still need to put:
#lang racket/load
at the top of your file, but you otherwise get a 'legacy mode' out of the box.
1If it doesn't please continue to ask questions, and of course we always love help from anyone who is willing to contribute. <3

spawn or system from racket

im trying to write a script for my system that populates static html files from a directory structure.
id prefer to use racket for the task but am having diffaculty finding a few key features, most importantly the ability to spawn a subprocess, such as the C call "system".
what is the easiest way to call the command line, and capture output, from inside of racket.
There are in fact two functions that work vary similar to system in C, they are: system and system*. (There are other ways of spawning off subprocesses, but these two are the simplest and work very similar to many other languages.
Of the two, system is the easier one, and takes in the command you want to run as a string. That way you can do things such as:
(system "ls -l")
While it is a little more complicated to use, I like system* a bit better, as it takes in the arguments as a list, which means you can more easily play with them in Racket proper.
(system* (find-executable-path "ls") "-l")
Now, you can do things such as changing the input and output ports of the command you are running, and even change the current working directory via Racket's parameters. Specifically, you want current-directory, current-input-port, and current-output-port.
You can also use several with- functions to more conveniently change the input and output ports.
Putting it all together, I can, for example, save the results of running ls -l as a string with the following code. (Note that there are better ways to get the contents of your root directory in Racket, this is just an example of using Racket for shell scripting.)
(parameterize ([current-directory "/"])
(with-output-to-string
(λ ()
(system* (find-executable-path "ls") "-l"))))

uncalled variables [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am trying to get started with Lisp and I have some (messy) code that i want to be able to ask the user for a title and url.
Save them in a variable, and then print them out when called. I am running into troubles though. First of all i don't know how to compile my program to run it. Also, the one time when i did run it i got an error about the variable title being uncalled. Can anyone help me with either of these things? Sorry i can't give you more information about the error.
;;Define a function called make-cd that takes four parameters
(defun make-url( title url ))
(list :title title :url url)
;;In the make-url function create a plist that takes the passed values
;; Define global variable db and set its value to nil
(defvar *db* nil)
;; Define a function that takes one paramter and pushes it to the make-url func.
;;(defun add-url (url) (push url *db*))
;; Define a function that takes the *db* variable and makes the output pretty
(defun dump-db ()
(dolist (url *db*)
(format t "~{~a:~10t~a~%~}~%" url)))
(defun prompt-read (prompt)
(format *query-io* "~a: " prompt)
(force-output *query-io*)
(read-line *query-io*))
Perhaps this will help.
Lisp programs aren't always distributed in compiled form. Having your program as just the source code is even better then only having the FASL (that's how Lisp binaries are called) because it makes it easier to fix problems if they are found later.
Traditionally, more complex programs, are arranged by means of ASDF package asdf:defsystem macro. You can read more about it here: http://common-lisp.net/~mmommer/asdf-howto.shtml . You can find examples on the internet, of how this is usually done through using Quicklisp and looking into its ~/quicklisp/dists/quicklisp/software/<name of the program>/ directory to see how other programs are arranged.
Once system is defined by asdf:defsystem, you would use asdf:oos to "operate" on it, that is load it. However, Quicklisp has become a very popular and easy to use utility for working with Lisp systems (it uses ASDF package underneath too). So, considering you have it, you would then (ql:quickload "your-system").
In order to make your system available locally through Quicklisp, I'd recommend doing it this way: In your $HOME directory (on Linux it is usually aliased with tilde ~) in the file: ~/.config/common-lisp/source-registry.conf (you may need to create one, if it's not there already), add something like:
(:source-registry
(:tree (:home "quicklisp/quicklisp/"))
(:tree (:home "Projects/my-project/"))
:inherit-configuration)
The above would imply that ~/Projects/my-project/ directory contains a system definition file (*.asd), where you have described what files belong to the system and instructed on how to load them etc.
For other options for adding local projects, read the Quicklisp FAQ
For more information about source-registry.conf file format read ASDF manual.
This is a bit involved at the beginning, so I'd advise you to just install one project using Quicklisp and study how it is made. Alexandria could be a good start - besides being a generally useful package, it isn't very large and illustrates the matter very well, IMO.
The code you have provided contains errors and will not compile. The error is in your definition of make-url. The proper definition should be:
(defun make-url( title url )
(list :title title :url url))
Notice the difference in parenthesis placements.
In your code you had an additional parenthesis following the parameter list. This closed the defun, causing make-url to be evaluated as a function with no body. The next line was then evaluated as a call to the built-in function list. The arguments were evaluated, and an error was encountered when it attempted to find a value for title. There is no binding in the global environment, a binding for title only exists within the body of make-url.
Also, your definition of add-url is commented out. A semi-colon begins a comment in Lisp.
How to compile and run your program depends on what compiler you are using. If you are using SBCL the function is sb-ext:save-lisp-and-die. A simple program like this would usually be run in a Read-Eval-Print-Loop(REPL), and most compilers will enter one when started. If you have SBCL installed you can start a repl by entering the command 'SBCL' to the command prompt. If your code is in an external file you can then load that using Load.

can I disable the "(Type e to repeat macro)" message in emacs?

So, I've finally made the plunge, and have gotten to the state where I'm quite happy to have switched from vi and vim to emacs... I've been putting stuff in my .emacs file, learning how to evaluate things (not to mention becoming familiar with movement commands), etc. etc. etc.
And now I have a problem with a require line in my .emacs file (a require statement*), which bombs out when I launch emacs (and generally fails to work).
So, this lead me to the following situation:
In the process of trying to debug the above situation, one of the steps I did was to open the file I was trying to require, and evaluate it bit by bit, using C-M-f and C-x C-e (and later just M-x eval-buffer), which all worked fine. But along the way of the section-by-section, I got tired of typing all those, and so I recorded a keyboard macro... C-x ( C-M-f C-x C-e C-x ) and then C-x e... which gave me a message in the minibuffer (I think I'm using the right name), saying (Type e to repeat macro). Which meant I could no longer see the resultant value of the evaluation of each section of code... which, while not critical in this case, I was liking having.
Which leads me to the actual question:
Is there a way to disable that message, and/or to cause the minibuffer to show multiple lines at once?
I know about the *Messages* buffer, and that could have helped, I'm just wondering if there's a way to either disable that message, or otherwise make it coexist with other messages. Any suggestions?
Thanks!
lindes
* - the problem at hand, which is not really my question, is that (require 'ruby-mode/ruby-mode) fails, even though emacs is definitely and successfully (per system call tracing) opening and reading the ruby-mode.el file. I presume this is because the provide line says just 'ruby-mode. I've found a solution for this, but if anyone can point me to any "best practices", I'd appreciate it.
(May I first say: this is the clearest question I've read here in a long time! Well done).
You can hit F4 to run your macro. That does roughly the same thing as C-x e, except it doesn't include that message!
To refine lindes' answer, I'd implement it this way:
(require 'cl) ; for flet
(add-to-list 'minor-mode-alist '(kmacro-repeat-mode " MACRO-REPEAT!"))
(defadvice kmacro-call-macro (around kmacro-call-macro-without-message activate)
"run kmacro-call-macro without any messages"
(flet ((message (&rest args)))
(let ((kmacro-repeat-mode t))
ad-do-it)))
I pulled the modification of minor-mode-alist out because there's no reason to do it multiple times. The rest is using the let and flet to do the temporary binding, which is cleaner and also safe in the presence of nonlocal exits.
Personally, I wouldn't use this advice because it disables the message function for the duration of the macro, which means all macros that actually use message would no longer function the same way. I'd probably just go with an edited version of kmacro-call-macro. Of course you could wrap the call to message with a variable that could selectively message instead.
I don't know about your "hide messages" question.
Regarding features and the require/provide functions, common practice, although I wouldn't go so far as to call it "best", is to name the .el file the same as the feature it "provides".
Not all modules do that. In those cases you need to look into the EL file to figure out the name of the feature the .el file is providing. Or check the documentation, in those rare cases where it exists. Then just use the optional arguments on the require call.
(require 'feature-name "name-of-el-file-that-provides-feature.el")
The .el file must be on your load-path.
To disable the feature completely, you can add this to your .emacs:
(setq kmacro-call-repeat-key nil)
There is no way (currently) to keep the functionality enabled but without the message.
Well, taking the challenge of the "there's no way to do it" answer (for which I am thankful, let it be said), I set out to try and find a way to do this.
I had the thought that it would be nice to have something show up in the mode line, instead of as a message, so...
I read (some web-accessible version of) the source code for kmacro-call-macro, and the elisp Minor Mode Conventions, and various other web pages. I tried some things. I did some debugging. And finally, I came up with this (imperfect -- more on that below) bit of elisp:
;;;;; change kmacro-call-macro (C-x e) to not generate any messages,
;;;;; and instead add a minor mode to the modeline
(defadvice kmacro-call-macro (around kmacro-call-macro-without-message activate)
"run kmacro-call-macro without any messages"
(fset 'saved-message (symbol-function 'message))
(unless (assq 'kmacro-repeat-mode minor-mode-alist)
(setq minor-mode-alist
(cons '(kmacro-repeat-mode " MACRO-REPEAT!") minor-mode-alist)))
(setq kmacro-repeat-mode t)
(defun message (format-string &rest args))
ad-do-it
(fset 'message (symbol-function 'saved-message))
(setq kmacro-repeat-mode nil))
I'm quite certain that this is not the cleanest way to do this -- in fact, it actually seems to be somewhat buggy -- not always turning on and off the mode line message when it ought to. But it mostly works, and this makes me happy.
If anyone has any hints on how to improve it further, I would appreciate them.
I figure another solution is to re-write kmacro-call-macro to basically include this functionality, possibly with another customization variable to control it. Doing so, I imagine, would also allow for the additional information (key to repeat with; repeat-count information) that's in the message to appear. Perhaps that's even possible using defadvice? Maybe influencing the value of ad-return-value via the re-defined message function or something?
Anyway, the above code has been added to my .emacs file, and hopefully will be refined at some point, when I know my way around elisp and its best practices a bit better.
I hope someone else finds this useful.
Again, improvements to this are most welcome.
edit:
I originally had:
(defun message (s &optional rest stuff))
which should really have been (and now is, above):
(defun message (format-string &rest args))
Here's hoping that solves the problems! It's intermittent enough that I consider it too early to tell...

Wrapping a quoted function in emacs-lisp

I use the cscope emacs extension (and find it quite useful). Unfortunately, it's default behaviour of only searching the current directory and below is insufficient for me, so I use the cscope-set-initial-directory to the directory of my choice. Unfortunately this has become insufficient for me as well because I have multiple different projects each with their own "initial" directory.
I have set up hot keys for the three cscope methods I use the most in emacs
(global-set-key [f9] 'cscope-find-this-text-string)
(global-set-key [f8] 'cscope-find-global-definition)
(global-set-key [f7] 'cscope-find-this-symbol)
I figured it would be pretty easy to somehow wrap those calls with a function to run cscope-set-initial-directory on a given path (generated by looking at what the buffer-file-name is). But I have as-yet been unsuccessful!
(global-set-key [f9] (lambda () (interactive) (cscope-set-initial-directory "blah") 'cscope-find-this-text-string))
doesn't work. I've also tried adding hooks to the two cscope-hooks, but neither of those seem to ever get called during my normal usage patterns. I wouldn't even mind running it once every time I switch buffers, but I didn't see a hook for that anywhere either :/.
Can someone help? :)
Disclaimer: I've not installed cscope so cannot test this.
(global-set-key (kbd "<f9>") 'my-cscope-find-this-text-string)
(defun my-cscope-find-this-text-string (dir)
(interactive "DRoot area to start search:")
(let ((default-directory dir))
(call-interactively 'cscope-find-this-text-string)))
The basic idea being you want to prompt for a directory to start from: that's the call to interactive. Then you set the directory: the let statement does that for you. Then you call the original routine you wanted, and by calling it with 'call-interactively you get prompted.
You'd wrap the other two routines similarly.
Once that's working for you, you can get fancier by customizing prompt for a root area to have its own history variable that's shared across the three routines.
Regarding your initial solution, that was a good try. Most don't realize the need for 'interactive to turn the function into a command. The reason the quoted name doesn't work for you is that the quote simply tells the interpreter to treat the symbol as a symbol and not do to anything with it. To call the routine, you'd generally do:
(lambda ()
(c-scope-find-this-text-string "some-string"))
Unfortunately, with a direct call like the one just above, you have to provide an argument (the string to search for). So, you can either add some code to prompt for the string, or use the command's built-in code to do the prompting. That's what the 'call-interactively is used for, it calls the command and invokes its 'interactive form which does the prompting.
Also, it's generally a good idea to bind keystrokes to names of commands, as opposed to bare lambdas, for two reasons: first, if you ever do C-h k (M-x describe-key), you get a meaningful command name, and second, if/when you modify the function, you can do so without having to muck with the binding as well.

Resources