How can I read a single character from STDIN in Clojure? - terminal

I'm writing a loop that only works on single-character inputs. Depending on what the user pressed (without pressing ENTER), I want to display what key the user typed in, and then repeat. If the user presses "q", then the loop must exit.
Constraints:
I don't care about Unicode (only supporting US ASCII character set is desirable).
I only care about Unixy systems (only Linux is fine).
I am using Leiningen.
Can this be done? Some searching led me to jline2 which had ConsoleReader class but it seems to have disappeared in jline3.

I saw https://gist.github.com/mikeananev/f5138eeee12144a3ca82136184e7a742 and using the linked duplicate answer, came up with this:
; Need `(:import [org.jline.terminal TerminalBuilder Terminal])`
(defn new-terminal
"creates new JLine3 Terminal.
returns terminal object"
^Terminal [term-name]
(let [terminal (-> (TerminalBuilder/builder)
(.jna true)
(.system true)
(.name term-name)
(.build))]
terminal))
(defn interactive-loop []
(let [t (new-terminal "xxx")]
(.enterRawMode t)
(let [reader (.reader t)]
(loop [char-int (.read reader)]
(case (char char-int)
\q (do
(println "Bye!")
(.close reader)
(.close t))
(do (println (char char-int))
(recur (.read reader))))))))
I'm on NixOS and apparently the jline3 library depends on the infocmp binary being installed, which is part of the popular ncurses package. Unfortunately the Nixpkgs version I use currently does not package this binary so I put in a PR here: https://github.com/NixOS/nixpkgs/pull/72135

Related

How do I use with-type to use Typed Racket fragments within untyped modules?

The Typed Racket reference indicates that it's possible to use with-type to created “typed regions” within untyped code.
The with-type form allows for localized Typed Racket regions in otherwise untyped code.
It’s a little unclear how to actually use this, though. Obviously, using such a feature needs to take place within an untyped module using #lang racket or something similar. How should the with-type binding be imported?
A naïve attempt is just to require Typed Racket, but this causes failures with how TR overwrites existing syntactic forms.
(require typed/racket)
(struct point (x y)) ; complains about missing type annotations
Trying to use only-in to simply require with-type and nothing else sort of works, but then none of the required type bindings (such as Number or ->) exist.
It seems like the only way to do this would be to manually use only-in to import only the things that I need, but this feels laborious. I could also use prefix-in, but then of course everything would be scattered with prefixes.
Is there a recommended way of doing this, or is this feature somewhat deprecated?
I don't know the fundamental answer. A guess is that it's the sort of thing that would be useful when writing macros, as opposed to code you'd write directly?
A practical idea: You can use local-require to limit the "contamination" of the TR require. And you can flip to using except-in if that's less work then only-in.
For instance this example from the docs get close, but gives a weird error presumably because it's using TR's quote:
#lang racket/base
(let ([x 'hello])
(local-require typed/racket)
(with-type
#:result String
#:freevars ([x String])
(string-append x ", world")))
; /tmp/so.rkt:7:21: quote: identifier used out of context
; in: quote
Excluding that with except-in gives the desired error:
(let ([x 'hello])
(local-require (except-in typed/racket quote))
(with-type
#:result String
#:freevars ([x String])
(string-append x ", world")))
; x: broke its contract
; promised: String
; produced: 'hello
; in: String
; contract from: /tmp/so.rkt
; blaming: /tmp/so.rkt
; (assuming the contract is correct)
; at: /tmp/so.rkt:14.17
But yeah. This is just fiddling with the edges and not getting to the heart of it.
I would just use except-in (or perhaps rename-in) to avoid the few identifiers that don't work in both typed and untyped programs. Like this modification of Greg's program:
#lang racket/base
(require (except-in typed/racket struct))
(struct point (x y))
(let ([x 'hello])
(with-type
#:result String
#:freevars ([x String])
(string-append x ", world")))

Change program code while running in Chicken Scheme

Is it possible to update the program code while it is being interpreted by csi, the Chicken Scheme Interpreter? If so, how?
So that I can interactively change part of the code and immediately see the effects of that changes.
For example, suppose I have written the following program:
(define (loop)
(print "Ciao")
(rest 1)
(loop))
(loop)
(assume (rest 1) has the effect of pausing the program for a second).
If I run this program, trough csi, it prints the string "Ciao" every second. If I change the string "Ciao" into something else, for example into "else", and I save the program code file, then csi continue interpreting the old program code, so I continuously see the string "Ciao". I'd like, in this case, that when I save the modified code with the string "Ciao" replaced by "else", csi continue its interpretation job by looking into the modified file, instead of the old file.
So that I obtain as output some "Ciao" followed by some "else": the "else" start to appear when I replace "Ciao" by "else" in the source code.
In general, the answer is "don't". The way you're supposed to use the REPL is by evaluating piecemeal changes against it, then evaluating a function or two to make sure everything went as expected. Part of this approach is structuring your program so that it can be easily tested in pieces, which implies not automatically starting any infinite loops. In the specific case you're asking about, you could instead write
(define (do-stuff)
(print "Ciao"))
(define (main-loop)
(do-stuff)
(rest 1)
(main-loop))
(define (start) (main-loop))
You can now incrementally develop do-stuff, periodically evaluating new versions to your interpreter and calling them to make sure they work, then eventually calling start once you're confident that it's doing the right thing.
You may get mileage out of this similar question asked about Common Lisp.
As an aside, if you were using Common Lisp and SLIME, you could now do more or less what you proposed:
(defun do-stuff ()
(format t "Ciao~%"))
(defun main-loop ()
(loop (progn (do-stuff)
(sleep 1))))
(main-loop)
Starting that up would start printing Ciao on separate lines in your SLIME REPL. If you changed do-stuff to
(defun do-stuff ()
(format t "else~%"))
then hit it with C-c C-c (the default binding for slime-compile-defun), you'd see your SLIME REPL start printing else lines in-flight.
CL-USER> (main-loop)
Ciao
Ciao
Ciao
; compiling (DEFUN DO-STUFF ...)else
else
else
else
else
else
; Evaluation aborted on NIL. User break.
CL-USER>
I'm not sure how to accomplish the same thing in Scheme, but I'm reasonably sure it's possible.
All that being said, you sometimes want to run a program part of which is an infinite loop. A real world example would be while testing a TCP server of some sort. If you're in such a situation, and your desired workflow is
Write file
Run csi my-file.scm
Edit file
Kill csi
Run csi my-file.scm
goto 3
and you basically just want to automate steps 4 through 6, you'll need an external tool to do it for you. Take a look at entr or hsandbox (the latter doesn't have Scheme support out of the box, but it doesn't look like it would be too hard to add).
There is no common way to make a running program check its source for changes but you there seems to be enough feratures available in Chicken to roll your own:
(use posix)
(use srfi-18)
(define (watch-reload! file)
(define (tsleep n)
(thread-sleep! (seconds->time (+ n (time->seconds (current-time))))))
(define (get-time)
(file-modification-time file))
(thread-start!
(lambda ()
(let loop ((filetime '()))
(let ((newtime (get-time)))
(when (not (equal? filetime newtime))
(load file))
(tsleep 10)
(loop newtime))))))
Now all you have to do is to use watch-reload! instead of load and it will check and reload every 10 seconds if the file has been modified.
If you save when the file is not valid scheme it stops working until you call watch-reload! on it again.
It may be that chicken programmers might have a better solution.

How to turn off standard osx text editing bindings in emacs on OSX

I want to not have any standard osx text editing bindings available in emacs anymore. I'm using standard gnu emacs. leaving only the "old school" emacs commands. In other words: no more command+c for copy, no command+z for undo, etc. Is there some way to do this without explicitly rebinding each key combination? I tried googling for a way to do this but did not find anything.
These key bindings are defined here, in ns-win.el.
There seems to be no simple way to unbind all of them. You could copy all of those key bindings from ns-win.el into the scratch buffer. They look like this:
(define-key global-map [?\s-,] 'customize)
Then hit C-M-% for query-replace-regexp, type ^(define-key global-map \(.*\) '.*)$ as the search expression and (global-unset-key \1) as the replacement, turning those key bindings into:
(global-unset-key [?\s-,])
Then, select them all and type M-x eval-region.
In Emacs in OS X, the default setup is that the CMD key is bound to the SUPER qualifier, and the a number of keys like S-x, S-c, and S-v are bound to commands to minic the normal OS functions. The OPTION key is bound to META. Unfortunately, the basic setup doesn't allow you to type characters that normally would require the OPTION key, like "|" and "\".
The following will bind CMD to meta and make OPTION available for normal character composition.
(if (boundp 'ns-command-modifier)
(setq ns-command-modifier 'meta))
(if (boundp 'ns-option-modifier)
(setq ns-option-modifier nil))
The keybindings I find objectionable are the bindings to SUPER aka command. To disable these binding, though not all the NS bindings made:
File global-unset-all-super-key.el:
(defun global-unset-all-super-key ()
"Will unset any single key in global keymap that has the super
modifier."
(let ((km (current-global-map)))
(while km
(let ((maybe-event (and (listp (car km))
(caar km))))
(if (and (eventp maybe-event) ; Also filters maybe-event when
; nil because (car km) was not a list.
(memq 'super (event-modifiers maybe-event)))
(global-unset-key (vector maybe-event))))
(setq km (cdr km)))))
(provide 'global-unset-all-super-key)
Place global-unset-all-super-key.el in the Emacs lisp load path and add the following to init.el or .emacs:
;; Remove default super bindings on Mac systems.
;; Do this early, before any mappings are added.
(when (string-equal system-type "darwin")
(require 'global-unset-all-super-key)
(global-unset-all-super-key))

How do I get a list of functions defined in an emacs-lisp file

Is it possible to get a list of functions defined in an emacs-lisp file? I found this sort of related answer: How do I get a list of Emacs lisp non-interactive functions?, but it involves a map over all of the atoms defined, not just what is in a file.
If the file in question has already been loaded, then you can modify the code in the question you link to filter out the symbols defined in other files:
(let ((funclist ()))
(mapatoms
(lambda (x)
(when (and (fboundp x) ; does x name a function?
(let ((f (symbol-file x)))
(and f (string= (file-name-base f) "my-file.el"))))
(push x funclist))))
funclist)
If the file has not been loaded, you would have to scan it with scan-sexps and find defun forms.
You might, however, prefer to use etags or imenu instead of scanning the file yourself.
Maybe a faster way is to look for the file in load-history, which will then give you the list of variables and functions defined therein.
Not sure if your asking for a non interactive approach.
With M-x occur ENT (defun.* ENT you get a buffer with more or less all function-definitions found in (current-buffer).
The quick&dirty way: extract all defuns via regex. It works instantly on a buffer with 5000 lines.
(-map 'cadr (s-match-strings-all "defun \\(.*?\\) " (buffer-string)))
This returns a list of function names that are defined via defun in the current open buffer. buffer-string returns content of a current buffer in a string, -map and s-match-string-all are taken from dash and s third party libraries (their GitHub pages explain how to install them), cadr returns a 2nd element of a list.
-map is analogous to Emacs built-in mapcar, it applies a function to each element of a list and returns a new list, s-match-string-all returns all possible regex matches in a string, parentheses in a regex denote a group (read more how to form Emacs regular expressions from EmacsWiki).
If you run it in eval-expression (Alt+:), it will just throw it into echo area, but that's not what you need. So below are variations that work with custom buffer or file. with-current-buffer allows to temporarily switch a buffer, while some code does actions inside it, f-read is a file reading function form another third-party library f.
(defun list-defined-functions (buffer)
(with-current-buffer buffer
(-map 'cadr (s-match-strings-all "defun \\(.*?\\) "
(buffer-string)))))
(defun list-defined-functions-in-file (file)
(-map 'cadr (s-match-strings-all "defun \\(.*?\\) "
(f-read file))))
Read Emacs Lisp manual and try to come up with whatever is useful for you.

Emacs ruby symbol word completion

Quite often I define a ruby symbol (eg. :some_value), then I want to create a method with the same name def some_value.
Unfortunately, the autocompletion(M + /) for the second occurrence of some_value string does not work, being slightly different (:some_value vs some_value).
How can I setup emacs to handle such events?
Assuming that M-/ is bound to dabbrev-expand, you can configure dabbrev-mode to ignore certain prefixes when expanding strings. To make a single colon a prefix to be ignored, type
M-x customize-group
and then
dabbrev
This will take you to the customization page for dabbrev-mode. Go to the point Dabbrev Abbrev Skip Leading Regexp and click on Value menu. From the menu, pick "Regexp".
Now you see a textfield labeled "Regexp: " next to the value menu in which you enter a single colon.
:
Then click on the button State in the next line and choose the value "Save for Future Sessions".
First, my results! I typed :some_crazy_symbol in my model. On a newline, I typed def so, hit M-/ twice, and ended up with
def some_crazy_symbol
end
(Rinari supplied the end.)
I got this to work quite well by using hippie-expand. If you want to test it out, bind hippie-expand to M-/ like so:
(global-set-key (kbd "M-/") 'hippie-expand)
Heres' the documentation. Hippie expand works by trying out a number of different expansions on the current point. These expansions are stored in the hippie-expand-try-functions-list variable. On my system (and be default), this variable is set to:
(try-complete-file-name-partially try-complete-file-name try-expand-all-abbrevs try-expand-list try-expand-line try-expand-dabbrev try-expand-dabbrev-all-buffers try-expand-dabbrev-from-kill try-complete-lisp-symbol-partially try-complete-lisp-symbol)
The minibuffer readout showed that this particular expansion was accomplished using the try-expand-dabbrev function.
Not a direct answer to your question, but you should get more intelligent Ruby autocompletion by using auto complete mode paired with rsense.
If Dabbrev Abbrev Skip Leading Regexp and hippie-expand doesn't do exactly what you want and you've got some elisp skills, you could create a custom function for hippie-expand.
See the section about "substring expansion" on the hippie-expand page on the emacs-wiki. There's a function you could use there you could tailor to customize..
Substring Expansion
When doing lisp programming standard dabbrev is less useful, because Emacs has no namespaces, so in a package symbols begin with the same prefix, therefore the same prefix has to be typed again and again if one wants to complete symbols from the package. As with IswitchBuffers it is much more effective if a unique substring can be typed to get to the desired symbol.
Dabbrev offers nothing in this regard, so I turned to Hippie Expand which I had never used before.
Here’s a function based on hippie expand dabbrev expansion which performs substring expansion:
(defun try-my-dabbrev-substring (old)
(let ((old-fun (symbol-function 'he-dabbrev-search)))
(fset 'he-dabbrev-search (symbol-function 'my-dabbrev-substring-search))
(unwind-protect
(try-expand-dabbrev old)
(fset 'he-dabbrev-search old-fun))))
(defun my-dabbrev-substring-search (pattern &optional reverse limit)
(let ((result ())
(regpat (cond ((not hippie-expand-dabbrev-as-symbol)
(concat (regexp-quote pattern) "\\sw+"))
((eq (char-syntax (aref pattern 0)) ?_)
(concat (regexp-quote pattern) "\\(\\sw\\|\\s_\\)+"))
(t
(concat (regexp-quote pattern)
"\\(\\sw\\|\\s_\\)+")))))
(while (and (not result)
(if reverse
(re-search-backward regpat limit t)
(re-search-forward regpat limit t)))
(setq result (buffer-substring-no-properties (save-excursion
(goto-char (match-beginning 0))
(skip-syntax-backward "w_")
(point))
(match-end 0)))
(if (he-string-member result he-tried-table t)
(setq result nil))) ; ignore if bad prefix or already in table
result))
I figured I'd share the solution I came up with that works for hippie-expand.
To summarize:
(defun hippie-expand-ruby-symbols (orig-fun &rest args)
(if (eq major-mode 'ruby-mode)
(let ((table (make-syntax-table ruby-mode-syntax-table)))
(modify-syntax-entry ?: "." table)
(with-syntax-table table (apply orig-fun args)))
(apply orig-fun args)))
(advice-add 'hippie-expand :around #'hippie-expand-ruby-symbols)
hippie-expand will expand symbols in ruby-mode when : is considered a punctuation character, so this advice creates a temporary syntax table where : is a punctuation character and calls hippie-expand with it.

Resources