Background:
I'm writing a fuzzy-finding vim plugin which runs a graphical program as a separate process. It opens a window, you type into it, press return, and then the vim plugin processes its output and navigates to the file / buffer you selected.
The time between triggering the find function and the new process grabbing keyboard input is a fraction of a second, so it's possible to accidentally type too soon, which causes that input to be delivered to vim.
Given that vim is single-threaded, I know (and have verified) that the errant keyboard input is not actually processed until the program finishes - the input is buffered while the program runs, and afterwards the random keys I typed are interpreted as vim actions.
Question:
How can I discard input that's sitting in vim's input buffer but has not yet been processed?
inputsave() takes pending keyboard input and saves it onto a stack. This would be what I want, except that it causes a memory leak if I don't match it with a call to inputrestore(). Is it possible to discard the stored input without executing it?
If that's not directly possible, can anyone think of a good way to discharge those events into a safe place? i.e call inputrestore() in such a state that the stored input will have no visible effect.
I need to do this in both a normal-mode mapping, and a command-mode mapping. So I'd prefer a solution which doesn't abandon the current command-mode input.
Related
first, I cannot attach my vi files, sorry. I'm not allowed, but I can attach snippets.
I've got a vi that opens and executes functions from a script file, and I'd like to be able to continuously click a button to reload the script file without having to restart the program. Currently the script file commands sit outside my main while loop and and uses a case statement to put the system in idle mode (manual control) when the button is not depressed before launching the program, or if it is, it will instantly open a dialog box looking for a script file upon program launch. I'd like to be able to open a script file numerous times during the execution of my program, but don't fully understand how, and this may be my own misunderstanding of what's going on with the code if I move it inside the main while loop. how is this best accomplished?
If you put your code outside of the loop, it is only executed once (very important: "dataflow"). You need to put the code into a loop to execute it multiple times.
You can insert the vi-snippet into your vi by drag&drop.
My vi contains two different options. You can change the vi as you need it, my vi is incomplete. I inserted a simple 2D-Array because I'm not sure if the vi you use after building the path is selfmade or given by LabVIEW.
For both options you should let the code run in some kind of state machine and use an Event Structure (I think you already implemented your program this way since you wrote about a main loop).
Version 1:
Everytime you click the button, the event is triggered and the code inside the event structure is executed.
Version 2:
Here you set a boolean if the button is pressed and handle the event with that value.
Since you wrote that you already have a main while loop, this option might be better four you. The first loop would be your main-loop, second one would be the loop in Version 2. You just need to add another case for the script to be loaded in.
VI:
I hope this is helpful for your problem.
Feel free to ask if you need more help or if you have any questions :)
I am building a NetLogo model that needs to integrate with another model (not NetLogo). So if the NetLogo model is set up to run continuously, at each tick I want it to wait for a file created by the linked model to appear within the parent folder. Once this file appears, NetLogo reads it in and continues with all the steps specified in Go. So essentially, i would like NetLogo to pause while it waits for the file and then once the file appears, resume. I tried using the 'while' function, but it did not do the job.
For example, when I set it up this way
to go
while [file-exists? "biosim.asc"][
grow-grass
grow-herd
delete-biosim
tick]
Here, NetLogo reads in the biosim file and after the procedures grow-grass, grow-herd are completed, the program deletes the ascii file biosim. Ideally I would like it to then wait for a new file by the name biosim to appear in the working folder and then repeat the steps. The above code does not get me what I want. Any help would be appreciated.
Thanks,
Rekha
What happens if you instead use the while loop to hold the run when the file is not there, and then put the actions outside the loop. For example:
to go
while [not file-exists? "biosim.asc"] [wait 1]
grow-grass
grow-herd
delete-biosim
tick
end
You could probably simply have [] instead of the wait but I suspect that would be fairly inefficient as it would constantly check. This instead checks every 1 second (you can make the check shorter or longer of course depending on how often the file is created) and once the file is there, it moves on to the other code.
Another option depends on what language the other model is built in. If it's something like R of java, you can control the NetLogo model from that code and couple the models directly.
I have created two vi's in LabVIEW: one to acquire serial data and another to plot the acquired data on an XY graph.
The second VI gets called when a Value Change event occurs on a button in the first VI. But the problem is that when the second VI is called the first VI suspends its operation, hence the values don't get updated.
Is there any solution for this?
First VI block diagram:
First VI front panel:
Second VI (ALL DATA) block diagram:
Well, you are doing some nasty stuff with global variables. This works but is not considered as good practice. (Have a look at queues and notifiers). Further, I don't see how your data gets written to those variables...
In any case, put your 2nd VI in a separate while-loop and schedule it to about 100ms (that is usually enough to update front panels or to interact with users. I'm not sure if your button-event is the right way to go. That is exactly because, the second VI waits for the callback. Just use a simple button and a true-false case to let the second VI keep running (this should even be the solution if you don't want to move the case to a second VI). Just make sure that you change the mechanics of the button to be a switch because you're checking its value not at infinite speed and you want to ensure that it gets caught every time, you click it;)
You will need to use the VI Server functionality. The exact method has changed over the years, but I believe the current recommended implementation is to use 'Start Asynchronous Call'
There is an example that you can view using the example finder. To open the example finder navigate to Help>Find Examples. Then select the 'Search' tab and search for 'asynchronous'. Finally select the VI called 'Asynchronous Call and Forget.vi'
There are other variations for asynchronous implementations, but this is probably a good place to start.
I have a Windows Application in VB.NET. I want to know if a value is entered by a user via the keyboard, or if it is coming from a barcode reader. I want to store values that come from
the keyboard in a different database than the ones the come from the barcode reader.
Option 1:
Get a barcode-scanner that is connected to a serial-port (raw serial device read by a COM port). As most barcode-scanners emulate keyboard strokes there is no way to directly distinguish a barcode scanner input from a keyboard input (see next option) without going low-level (see last update).
One connected to a serial port (or emulated one via USB as serial-ports are not so common anymore) gives you full control on where the input comes from.
Option 2:
Count number of chars typed by time. Barcode-scanners inject a sequence (line) pretty fast compared to typing. Measuring the time used in the textbox by counting key-presses (use CR+LF as a measure point as these are sent by the scanner as well) can give you one method to distinguish if a human is typing (unless there is one typing fast as f) or the content was injected. If timed-out just reject/clear the input.
In addition the checksum of the barcode (if you use one that contains that) can be used to do an extra validation in addition to time measurement.
(you can detect pasting by overriding the ctrl + v as in the next option).
Option 3:
Combine option 2 but instead of measure in the textbox tap into the ProcessCmdKey() function (by overriding it) and measure there if textbox has focus. This way you can first buffer input, measure time and if within a set time-out value, inject the line into the textbox.
Option 4:
This might be a good option as well:
http://nicholas.piasecki.name/blog/2009/02/distinguishing-barcode-scanners-from-the-keyboard-in-winforms/
Option 5: a non-technical approach -
Usability improvements: make it visually very clear that bar-codes must be entered with a scanner and not typed. I am including as an option as it is simple and if made correct also effective (there's no right answer of what is correct unfortunately).
Approached could include f.ex. a watermark in the textbox ("Don't type, scan!" or something in that order). Give it a different color, border, size etc. to distinguish it from normal textboxes, and have a help text associated and available at all time that improves clarity.
Sometimes when I am using less within a screen tab, the arrow keys display ^[OA, ^[OB, ^[OC, and ^[OD instead of doing what I want them to do. Is there something I can do to fix this and gain control of less again?
enter !reset at the less prompt
I have found that reset from within screen does not solve the problem sometimes, as it's the outer client/shell whose state is actually confused and screen captures the control characters from reset and prevents them from reaching the outer client. In this situation, I have to detach my session (Ctrl+a, d), run reset, then attach to the session again (screen -r).
If it happens from time to time, it seems, that some application (e.g. cat or less a binary file) shatters your console by sending it control characters. You need to run reset command from command line to recover.
Otherwise you have to trick your terminal application. I suggest you to use CryptoTerm which allows you to define custom key mappings.
Another thing to check is your TERM variable. In my case I ssh into a Linux box and run less inside screen - the TERM variable was set to 'screen' - which breaks arrow keys. It works perfectly if I run less this way:
TERM=xterm less <file>