I was coding up a script for a research project using SBCL, and this is the first time I tried SB-TREAHD. Each thread will call external shell command several times, for which sb-ext:run-program is used.
The problem is that whenever ext:run-program is presented, the program can run into dead lock (where I did not use anything like mutex excplicitly). I experiment it for a while and couldn't find any solution. A simplified version of the code which can still make the dead lock happen is as follows:
(use-package :sb-thread)
;;; Global Settings
(defparameter *path-num* 4)
(defparameter *testing* nil)
(defparameter *training* nil)
(defparameter *shared-folder* "shared")
(defparameter *template* "template.conf")
(defparameter *pwd* (namestring (truename ".")))
;;; Utilities
(defmacro compose-file-name (&rest parts)
"compose a filename under current *pwd*"
`(concatenate 'string *pwd*
,#(mapcar (lambda (x) `(format nil "/~a" ,x))
parts)))
(defun run-command (command &optional args)
"run a shell comamnd and reflect the stdout on screen."
(let* ((process (sb-ext:run-program command args
:output :stream
:wait nil))
(output (sb-ext:process-output process)))
(loop for line = (read-line output nil)
while line do (format t "~a~%" line))))
(setf *testing* '("1" "2" "3" "4"))
(setf *training* '("5" "6" "7" "8"))
(defun gen-conf (path-id target labeled)
"Prepare the configuration file"
(format t "[~a]: ~a~%" path-id target)
(let ((current-dir (compose-file-name path-id)))
(run-command "/bin/cp" (list "-f" (compose-file-name *shared-folder* *template*)
(format nil "~a/Prediction.conf" current-dir)))
(with-open-file (*standard-output* (format nil "~a/Prediction.conf" current-dir)
:direction :output
:if-exists :append)
(format t "--estimate ~a~%" path-id))))
(defun first-iteration ()
(loop for i below 20
do (gen-conf (thread-name *current-thread*) (format nil "~a" i) (list "123" "456"))))
;;; main
(defun main ()
(let ((child-threads (loop for i below *path-num*
collect (make-thread
(lambda () (first-iteration))
:name (format nil "~a" i)))))
(loop for th in child-threads
do (join-thread th))))
(main)
where in (main) 4 threads are created, and each of them will run (first-iteration), and in (first-iteration) it calls (gen-conf) several times which involves both (sb-ext:run-program) and file I/O.
I thought maybe the dead lock is due to incorrectly using of sb-thread, but just by looking at the SBCL manual I cannot find out the correct way. Any suggestion will be helpful.
btw, to run the program, get http://pages.cs.wisc.edu/~breakds/thread.tar.gz which have all the required directories/files created.
Thank you!
Related
I am trying to build a common lisp implementation of the channel construct of Golang for a personal project (also to learn lisp). So far I've implemented the channels as objects of a class, containing a queue, a lock and a condition variable to signal listening functions that a new message has been added to the queue. I'm using bordeaux threads to create threads, locks, condition variables and join the executions (from the lisp cookbook).
This is the channel class and the recive function:
(defclass channel ()
((messages :initform '()
:accessor messages
:documentation "Messages in the channel")
(lock :initform (bt:make-lock)
:accessor lock
:documentation
"Lock to push/pop messages in the channel")
(cv :initarg :cv
:initform (bt:make-condition-variable)
:accessor cv
:documentation
"Condtional variable to notify the channel of a new message")))
(defmethod recive-loop ((self channel))
(with-slots (lock cv messages) self
(let ((to-ret nil))
(loop
(bt:with-lock-held (lock)
(if (not (null messages))
(setf to-ret (car (pop messages)))
(bt:condition-wait cv lock))
(if to-ret (return to-ret)))))))
(defmethod recive ((self channel))
(with-slots (name thread) self
(let ((thread
(bt:make-thread #'(lambda() (recive-loop self))
:name name)))
(bt:join-thread thread))))
(defmacro gorun (f &rest args)
(flet ((fn () (apply f args)))
(bt:make-thread #'fn
:initial-bindings (list args)
:name "gorun worker")))
gorun should be the equivalent of go routine() for go (without the light threading). To test the setup I've built a printer function over a channel
(defvar printch (channel))
(defun printover (ch)
(let ((x (recive ch)))
(format t "Recived variable x: ~d~%" x)))
but when I run
(gorun printover printch)
The interpreter (using sbcl, but with clisp the same happens) gives back an error:
There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION COMMON-LISP-USER::RECIVE (1)>
when called with arguments
(PRINTCH).
[Condition of type SB-PCL::NO-APPLICABLE-METHOD-ERROR]
See also:
Common Lisp Hyperspec, 7.6.6 [:section]
Restarts:
0: [RETRY] Retry calling the generic function.
1: [ABORT] abort thread (#<THREAD "gorun worker" RUNNING {100293E9F3}>)
Backtrace:
0: ((:METHOD NO-APPLICABLE-METHOD (T)) #<STANDARD-GENERIC-FUNCTION COMMON-LISP-USER::RECIVE (1)> PRINTCH) [fast-method]
Locals:
SB-PCL::ARGS = (PRINTCH)
GENERIC-FUNCTION = #<STANDARD-GENERIC-FUNCTION COMMON-LISP-USER::RECIVE (1)>
1: (SB-PCL::CALL-NO-APPLICABLE-METHOD #<STANDARD-GENERIC-FUNCTION COMMON-LISP-USER::RECIVE (1)> (PRINTCH))
Locals:
ARGS = (PRINTCH)
GF = #<STANDARD-GENERIC-FUNCTION COMMON-LISP-USER::RECIVE (1)>
2: (PRINTOVER PRINTCH)
Locals:
CH = PRINTCH
3: ((LAMBDA NIL :IN BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS))
[No Locals]
I'm confused, since the method to run over the channel printch should be the one I've defined.
Trying to call a class method inside of a new thread, but got no applicable method
A macros is supposed to return code to run in place of the original call. Your macro is creating the thread at expansion time.
If you're not using backtick in a macro definition, there's usually something wrong with it. You should figure out what the code would look like without the macro, then define a macro that returns code with that same structure in a backticked list, replacing the places that need to vary with the parameters, using comma to expand them.
(defmacro gorun (f &rest args)
`(bt:make-thread (function ,f)
:initial-bindings (list ,#args)
:name "gorun worker"))
In the above, you need to substitute the function name into a (function ...) expression, and the args list as the :initial-bindings argument.
In multi-threaded environments it is often the case that special variables are thread-local. The global binding is visible from all threads, but if you bind one locally its value will not automatically be transferred to a thread created in that context. It has to be done explicitly, and I wrote a pair of macros recently just for that.
The first one captures bindings into lexically-scoped variables; the other bind the original variables back to the values captured in a different context.
I am using an intermediate data structure in the code to store bindings:
(defstruct bindings data)
The first macro is with-captured-bindings:
(defmacro with-captured-bindings ((&rest symbols) as name &body body)
(assert (eq as :as))
(loop for s in (alexandria:flatten
(sublis
'((:stdio *standard-output* *error-output* *standard-input*)
(:path *default-pathname-defaults*))
symbols))
for g = (gensym)
collect (list g s) into capture
collect (list s g) into rebind
finally
(return
`(let ,capture
,#(subst (make-bindings :data rebind)
name
body)))))
The capture variable holds a list of bindings to initialize the lexically-scoped variables. The rebind variables is a list of bindings to set back special variables to their values in another thread.
I inject with subst an instance of the bindings struct in the code. It helps to have a dedicated data structure, but the crude search-and-replace approach means the symbols name will not be usable as a function, local macro, etc. in body. I don't think it is too much of a problem.
Also, I define aliases like :stdio and :path for commonly used variables.
The second macro is with-bindings:
(defmacro with-bindings (bindings &body body)
(check-type bindings bindings)
`(let ,(bindings-data bindings)
,#body))
This replaces the intermediate struct with the proper code. The final code does not have this struct anymore and can be processed as usual.
For example:
(defvar *my-var* "hello")
(with-captured-bindings (:stdio :path *my-var*) :as <bindings>
(sb-thread:make-thread
(lambda ()
(with-bindings <bindings>
(print *var*)))))
A first application of macroexpand gives:
(LET ((#:G3882 *STANDARD-OUTPUT*)
(#:G3883 *ERROR-OUTPUT*)
(#:G3884 *STANDARD-INPUT*)
(#:G3885 *DEFAULT-PATHNAME-DEFAULTS*)
(#:G3886 *MY-VAR*))
(SB-THREAD:MAKE-THREAD
(LAMBDA ()
(WITH-BINDINGS #S(BINDINGS
:DATA ((*STANDARD-OUTPUT* #:G3882)
(*ERROR-OUTPUT* #:G3883)
(*STANDARD-INPUT* #:G3884)
(*DEFAULT-PATHNAME-DEFAULTS* #:G3885)
(*MY-VAR* #:G3886)))
(PRINT *MY-VAR*)))))
Notice that there is #S(BINDINGS ...) object in the tree.
The full expansion is:
(LET ((#:G3887 *STANDARD-OUTPUT*)
(#:G3888 *ERROR-OUTPUT*)
(#:G3889 *STANDARD-INPUT*)
(#:G3890 *DEFAULT-PATHNAME-DEFAULTS*)
(#:G3891 *MY-VAR*))
(SB-THREAD:MAKE-THREAD
(LAMBDA ()
(LET ((*STANDARD-OUTPUT* #:G3887)
(*ERROR-OUTPUT* #:G3888)
(*STANDARD-INPUT* #:G3889)
(*DEFAULT-PATHNAME-DEFAULTS* #:G3890)
(*MY-VAR* #:G3891))
(PRINT *MY-VAR*)))))
I want to do something that means the following:
(with-output-to-string (*standard-output*)
(bt:join-thread
(bt:make-thread
(lambda ()
(format *standard-output* "Hello World")))))
;=> "" (actual output)
;=> "Hello World" (expected output)
In my understanding, this does not work because the *standard-output* that gets dynamically rebound by with-output-to-string outside the thread does not take effect inside the thread. What are the possible and recommedable ways?
In essence, I want to capture the output that was written to *standard-output* by another thread.
One can rebind the special variable to be thread local:
(with-output-to-string (*standard-output*)
(bt:join-thread
(bt:make-thread
(lambda ()
(format *standard-output* "Hello World"))
:initial-bindings `((*standard-output* . ,*standard-output*)))))
*initial-bindings* is an alist with (variable . value) elements.
A previous idea was to mutate the original binding of *standard-output* itself. As #coredump suggested, this has the downside that the binding will be mutated in all the threads - other threads that are sending their output to *standard-output* would also send their output to the string-output-stream.
Another idea is to let the thread itself decide whether to send the output to *standard-output* or to some other stream:
(let ((in-with-output-to-string nil)
(output-stream-string nil))
(unwind-protect
(progn
(setq output-stream-string (make-string-output-stream))
(setq in-with-output-to-string t)
(bt:join-thread
(bt:make-thread
(lambda ()
(format (if in-with-output-to-string
output-stream-string
*standard-output*)
"Hello World"))))
(get-output-stream-string output-stream-string))
(setq in-with-output-to-string nil)))
;=> "Hello World"
A more involved example is illustrated in the following. The general situation I was interested in involved a thread reading some stream and sending the contents of that stream to *standard-output*. However, in certain cases, I was interested in capturing the output of that thread into a string.
Even before that, drawing inspiration from [1], we define a helper macro which captures the variable bindings that were present before executing the body and then restores them once the body has completed execution.
(deftype list-of (&rest types)
(if types
`(cons ,(first types) (list-of ,#(rest types)))
'null))
(defmacro thread-global-let (bindings &body body)
(let* ((bindings (mapcar (lambda (binding)
;; Normalize the bindings
(etypecase binding
(symbol
(list binding nil))
((list-of symbol)
(list (first binding) nil))
((list-of symbol t)
binding)))
bindings))
(variables (mapcar #'first bindings))
(gensyms (alexandria:make-gensym-list (length variables))))
`(let (,#(mapcar (lambda (var gensym)
`(,gensym ,var))
variables gensyms))
(unwind-protect
(progn
,#(mapcar (lambda (binding)
`(setq ,#binding))
bindings)
,#body)
,#(mapcar (lambda (var gensym)
`(setq ,var ,gensym))
variables gensyms)))))
The main example then is the following:
(defvar *input-wait-condition* (bt:make-condition-variable))
(defvar *input-wait-lock* (bt:make-lock))
(defvar *stream-input-string* nil)
(defvar *thread*)
(let ((in-with-thread-output nil)
(stream-output-string nil))
(when (and (boundp '*thread*)
(bt:threadp *thread*))
(bt:destroy-thread *thread*))
(setq *thread*
(bt:make-thread
(lambda ()
(bt:with-lock-held (*input-wait-lock*)
(loop :do (bt:condition-wait *input-wait-condition* *input-wait-lock*)
(loop :while (listen *stream-input-string*)
:do (write-char (read-char *stream-input-string*)
(if in-with-thread-output
stream-output-string
*standard-output*))))))))
(defun thread-output-thunk (thunk)
(thread-global-let ((stream-output-string (make-string-output-stream))
(in-with-thread-output t))
(funcall thunk)
(get-output-stream-string stream-output-string))))
(defmacro with-thread-output (&body body)
`(thread-output-thunk (lambda () ,#body)))
What it essentially achieves is the following:
CL-USER> (setq *stream-input-string* (make-string-input-stream "Hello World"))
#<SB-IMPL::STRING-INPUT-STREAM {100D0D47A3}>
CL-USER> (bt:condition-notify *input-wait-condition*)
NIL
Hello World
CL-USER> (with-thread-output
(thread-global-let
((*stream-input-string*
(make-string-input-stream "Output from a thread")))
(bt:condition-notify *input-wait-condition*)
(loop :while (listen *stream-input-string*))))
"Output from a thread"
CL-USER> (with-thread-output
(thread-global-let
((*stream-input-string*
(make-string-input-stream "Output from a thread")))
(print (with-thread-output
(thread-global-let
((*stream-input-string*
(make-string-input-stream "Output from a thread 2")))
(bt:with-lock-held (*input-wait-lock*)
(bt:condition-notify *input-wait-condition*))
(loop :while (listen *stream-input-string*)))))
(bt:with-lock-held (*input-wait-lock*)
(bt:condition-notify *input-wait-condition*))
(loop :while (listen *stream-input-string*))))
"Output from a thread 2"
"Output from a thread"
The following code illustrates the previous idea of mutating the original binding of *standard-output*. This has the downside of the mutation affecting all the threads.
(let ((original-stdout *standard-output*))
(with-output-to-string (stdout)
(unwind-protect
(progn
(setq *standard-output* stdout)
(bt:join-thread
(bt:make-thread
(lambda ()
(format *standard-output* "Hello World")))))
(setq *standard-output* original-stdout))))
This all seem a bit complex, and it looks like you are calling bt:join-thread to wait for the thread to finish. Unfortunately, this means that your main thread is blocked until the worker thread is finished, something that typically is a code smell in multi-threaded applications (if you block the main thread, you might as well call the function directly in the same thread).
In fact, when threads are involved, lexically scoped macros like with-X are usually either better done inside the thread, or not at all. I am going to use the lparallel library because it provides queues datastructures.
(defpackage :so (:use :cl))
(in-package :so)
(ql:quickload :lparallel)
Let's define a sample test function that uses standard input and output streams:
(defun test-function ()
"A test function that acts on standard input/output streams"
(format t "input is: ~s" (read-line)))
The following make-thread/redirect-io function takes a function to execute as well as its input as a string. It returns another function that will block until the thread terminates and return the accumulated output as a string. In practice you would also need to handle exceptions:
(defun make-thread/redirect-io (fn input-as-string)
(let ((queue (lparallel.queue:make-queue)))
(values (lambda () (lparallel.queue:pop-queue queue))
(bt:make-thread
(lambda ()
(lparallel.queue:push-queue
(with-output-to-string (*standard-output*)
(with-input-from-string (*standard-input* input-as-string)
(funcall fn)))
queue))))))
This allows you to really run things in parallel, for example you can spawn two threads with different inputs:
(let ((join-a (make-thread/redirect-io #'test-function "Hello"))
(join-b (make-thread/redirect-io #'test-function "World")))
;; do something else in parallel, do not join the thread otherwise
;; it would just be blocking as-if you called the function in the
;; same thread
;; then, get the results
(list (funcall join-a)
(funcall join-b)))
This returns the following list:
("input is: \"Hello\"" "input is: \"World\"")
In fact, I'd suggest using having a look at lparallel.org to see if you can use it directly, it can greatly simplify working with threads.
How do I spawn off a background (named) sub-process/thread in ABCL? That is, I want to spawn the sub-process (or thread) to run in the background and leave the top-level evaluation free for other processing.
Using (apropos 'process/thread) I have found undocumented functions like those listed below, but I can't figure out the syntax. I am looking for the running example code to follow/modify. I seem to have created a process with the following make-process function, but I get an error when I try to kill it, and it runs in the foreground. There is no entry in the ABCL manual for make-process. MAKE-THREAD is listed, but as not-documented.
Where is the documentation / examples for all the functions listed in the ABCL manual with this "not-documented" designation? (Also those found with apropos?)
As a separate but related issue, is there a repository of ABCL-specific running code examples online that cover edge-case questions like these?
In other common-lisps I would use functions like:
(activate-process *initial-process*)
or
#+(:and MULTITASKING :lucid)
(defun mpd (&optional (reinit nil))
(user::make-process :name "Pdraw-proc" :function #'pd::pdraw :args (list reinit)))
In ABCL I have muddled around getting not far:
CL-USER> (setf uu (make-thread (my-reader))) <-- runs at the top level / hogs read loop
CL-USER> (setf jj (system::%make-process (foo)))
#S(SYSTEM:PROCESS :JPROCESS 3 :INPUT NIL :OUTPUT NIL :ERROR NIL)
CL-USER> jj
#S(SYSTEM:PROCESS :JPROCESS 3 :INPUT NIL :OUTPUT NIL :ERROR NIL)
SYSTEM::MAKE-PROCESS (fbound)
SYSTEM::%PROCESS-KILL (fbound)
SYSTEM::%MAKE-PROCESS (fbound)
and
THREADS:MAKE-THREAD (fbound)
THREADS:DESTROY-THREAD (fbound)
and
(make-two-way-stream ...)
[Syntax / examples for creating necessary streams for the threads maybe?]
Thanks in advance for pointers or code.
I use ABCL with roswell so it is easy to use in conjuntion with quicklisp, but there is also a project for that, but I think that you could easily use quicklisp or load libraries in ABCL. There are a lot of libraries that you can load on ABCL that are from quicklisp, unfortunately not all (Quicklisp is tested over linux & SBCL), but for concurrency you can load two great libraries that I normally use bordeaux-threads (the common threats library in common lisp) and Chanl a library that ports go channnels to common lisp. There are others that you could try but I'm not sure if they work lparallel, cl-actors ...
Let's do an example with this libraries:
CL-USER> (lisp-implementation-type)
"Armed Bear Common Lisp"
CL-USER> (lisp-implementation-version)
"1.5.0"
"Java_HotSpot(TM)_64-Bit_Server_VM-Oracle_Corporation-1.8.0_162-b12"
"x86_64-Mac_OS_X-10.12.6"
CL-USER> (ql:quickload 'bt-semaphore)
To load "bt-semaphore":
Load 1 ASDF system:
bt-semaphore
; Loading "bt-semaphore"
[package bt-semaphore]
(BT-SEMAPHORE)
CL-USER> bt:*supports-threads-p*
T
CL-USER> (defparameter *counter* 0)
*COUNTER*
CL-USER> (defun test-update-global-variable ()
(bt:make-thread
(lambda ()
(sleep 10)
(incf *counter*)))
*counter*)
TEST-UPDATE-GLOBAL-VARIABLE
CL-USER> *counter*
0 (0 bits, #x0, #o0, #b0)
CL-USER> (test-update-global-variable)
0 (0 bits, #x0, #o0, #b0)
CL-USER> *counter*
0 (0 bits, #x0, #o0, #b0)
CL-USER> (+ 2 3)
5 (3 bits, #x5, #o5, #b101)
CL-USER> (format t "I'm wainting for counter")
I'm wainting for counter
NIL
CL-USER> (format t "let'see the counter value ~a~%" *counter*)
let'see the counter value 1
NIL
CL-USER> (ql:quickload :chanl)
To load "chanl":
Load 1 ASDF system:
chanl
; Loading "chanl"
(:CHANL)
CL-USER> (chanl:pcall (lambda () (sleep 10) (incf *counter*)))
#<CHANL:TASK Anonymous task [ALIVE] {2360938E}>
CL-USER> *counter*
1 (1 bit, #x1, #o1, #b1)
CL-USER> ;; waiting
; No values
CL-USER> *counter*
2 (2 bits, #x2, #o2, #b10)
Note that this are only example purpouses a global variable is not a good use for threats, also take a look on the libraries for further documentation,that should work, Also you in ABCL it is easy tou use java libraries, so maybe you can use akka actors, or other java concurrency libraries
Also as you poiinted ABCL has a package for threats, it is easy to use, like this:
CL-USER> (threads:make-thread (lambda () (sleep 10) (incf *counter*)) :name 'patata)
#<THREAD "PATATA" {49998577}>
CL-USER> *counter*
2 (2 bits, #x2, #o2, #b10)
CL-USER> ; wait
; No values
CL-USER> *counter*
3 (2 bits, #x3, #o3, #b11)
Also it has implemented mailbox threats to pass message to the threads
With the prompting of the kind Vibhu I have found what appears to be the same native solution suggested by Anquegi. Thanks for the :name arg!
CL-USER> (lisp-implementation-type)
"Armed Bear Common Lisp"
CL-USER> (lisp-implementation-version)
"1.3.3"
"Java_HotSpot(TM)_64-Bit_Server_VM-Oracle_Corporation-1.8.0_161-b12"
"amd64-Windows_7-6.1"
CL-USER>
(setf my-val 1)
;;; Output to *standard-output* for Inferior Lisp, so careful with SLIME:
(defun make-my-thread ()
(setf q
(threads:make-thread
#'(lambda ()
(format t "I am alive!~%")
(sleep 15)
(format t "Goodbye Cruel World~%")
(setf my-val (1+ my-val))))))
;;; Works, but takes a while:
(defun kill-it () (threads:destroy-thread q))
(defun alivep () (THREADS:THREAD-ALIVE-P q))
(make-my-thread) runs in the background without hogging standard-input
my-val can be queried and is not set until after the sleep.
(alivep) returns T until the thread completes
or until several seconds after (kill-it) is called, then NIL.
So this minimal functionality now allows me a great deal of flexibility to run threads in the background.
Preamble
Using VTK library with C++, quite often I have to write something like this:
vtkInteractorStyleRubberBandZoom *isrbz = vtkInteractorStyleRubberBandZoom::New();
Furthermore, every time I need to use a new VTK class in my program, I have to go somewhere up the source file and add #include "vtkInteractorStyleRubberBandZoom.h"
How do I automate it, so I have to type each of the excruciatingly long class names one time instead of three?
I tried writing an Emacs minor mode for it. There are probably existing solutions out there already (YaSnippet?), but I thought that writing it myself would be a good excercise, too.
Code
;vtk-mode.el
;add to .emacs:
;(load "vtk-mode")
;(global-set-key [(control =)] 'expand-vtk)
(defun expand-vtk ()
(interactive)
(setq now (point))
(setq vtkstart (search-backward "vtk"))
(setq vtkend (- (search-forward " ") 1))
(setq vtkname (buffer-substring vtkstart vtkend))
;check for #include "vtkBlah.h"
(setq includename (format "#include \"%s.h\"\n" vtkname))
(search-backward includename nil (append-include-vtk includename))
(goto-char (+ now (length includename)))
(insert (format "= %s::New();" vtkname)))
(defun append-include-vtk (incname)
(goto-char 0)
(insert incname))
Problem
Basically, it works, except that searching for an include name always fails, e. g.:
vtkSomething *smth /*press C-= here, it looks backward for
#include "vtkSomething.h", can't find it and
calls append-include-vtk, adding it to the beginning
of the file, then comes back here and expands this line into: */
vtkSomething *smth = vtkSomething::New();
//and let's add another instance of vtkSomething...
vtkSomething *smth2 /*press C-= again, it looks backward for
#include "vtkSomething", and fails, despite the fact
that it was added by the previous command. So it adds it again."*/
What am I doing wrong here with search-backward?
(there's another (at least one) bug in the code, I shouldn't add the (length includename) if the search-backward for it was successful, but for now I am more interested in how to make it successful, in the first place)
OK, I got it. Somehow I got an idea that the third argument of search-backward (noerror) is a callback, which it isn't. Therefore it is evaluated every time, not just when the search fails. It should be something like this instead:
(defun expand-vtk ()
(interactive)
(setq now (point))
(setq vtkstart (search-backward "vtk"))
(setq vtkend (- (search-forward " ") 1))
(setq vtkname (buffer-substring vtkstart vtkend))
;check for #include "vtkBlah.h"
(setq includename (format "#include \"%s.h\"\n" vtkname))
(if (search-backward includename nil t)
(goto-char now)
(progn (append-include-vtk includename)
(goto-char (+ now (length includename)))))
(insert (format "= %s::New();" vtkname)))
(defun append-include-vtk (incname)
(goto-char 0)
(insert incname))
A command that's built into Emacs and will help you avoid typing excruciatingly long class names is dabbrev-expand (bound to M-/):
(dabbrev-expand ARG)
Expand previous word "dynamically".
Expands to the most recent, preceding word for which this is a prefix.
If no suitable preceding word is found, words following point are
considered. If still no suitable word is found, then look in the
buffers accepted by the function pointed out by variable
`dabbrev-friend-buffer-function'.
Having typed vtkInteractorStyleRubberBandZoom once, the next time you need it you just type vtkI M-/.
I have the following function that deletes the LaTeX command surrounding the current cursor position:
(defun remove-tex-cmd ()
(interactive)
(save-excursion
(let (cur-point beg-point end-point)
(setq cur-point (point))
(catch 'notexcmd
(if (not (re-search-backward "\\.*?{" nil t)) ; now the point is at the {
(throw 'notexcmd nil))
(search-backward "\\" nil t)
(setq beg-point (point))
(re-search-forward "}")
(setq end-point (point))
(if (> end-point cur-point)
(kill-region beg-point end-point))
(throw 'notexcmd nil)))
(if 'notexcmd
(message "no tex command at point"))))
It works well except for the following situation, because it simply matches the next closing }:
\test{a<cursor here>sdf ${bla}+1$}
results in
+1$}
I could, of course, count the opening and closing brackets. However, as this problem should occur frequently, I wonder whether there exists some more intelligent search function, or am I missing a totally different point?
Use list- or sexp- based operations:
(defun remove-tex-cmd ()
(interactive)
(backward-up-list 1)
(backward-sexp 1)
(kill-sexp 2))
To handle scan error when outside parentheses:
(defun remove-tex-cmd ()
(interactive)
(condition-case nil
(progn
(backward-up-list 1)
(backward-sexp 1)
(kill-sexp 2))
(scan-error (message "Outside parentheses."))))