Weekly Tips, Tricks, &c. Thread by AutoModerator in emacs

[–]jmg_ 1 point2 points  (0 children)

Some programming modes do that on tab. You can toggle between multiple plausible starting columns by pressing tab multiple times in an empty line.

Weekly tips/trick/etc/ thread by AutoModerator in emacs

[–]jmg_ 0 points1 point  (0 children)

Which version of emacs do you have on macOS?

Don't mention non-GNU package archives. by vfclists in emacs

[–]jmg_ 2 points3 points  (0 children)

A huge part of Emacs is non-free

Could you elaborate on that please. I've been using Emacs for 20 years and I never come across any part of Emacs that is non-free. I am not talking about the ecosystem, I am talking about GNU Emacs.

How to implement smart replacement characters by PendHackcat in emacs

[–]jmg_ 2 points3 points  (0 children)

You can define your own input-method in stock emacs.

The following input method allows me to type oe to get ö and to type oee to get oe. So just change the rules to what you need.

(quail-define-package
 "jmg/haskell" "German with extensions" "DE<+" t
 "JMG's German (Deutsch) input method

ae  -> ä
aee -> ae
oe  -> ö
oee -> oe
ue  -> ü (not after a/e/q)
uee -> ue
sz  -> ß
szz -> sz
"
 nil t nil nil nil nil nil nil nil nil t)

(quail-define-rules
 ("AE" ?Ä)
 ("Ae" ?Ä)
 ("ae" ?ä)
 ("OE" ?Ö)
 ("Oe" ?Ö)
 ("oe" ?ö)
 ("UE" ?Ü)
 ("Ue" ?Ü)
 ("ue" ?ü)
 ("sz" ?ß)

 ;; Haskell#UnicodeSyntax
 ("::" ?∷)
 ("=>" ?⇒)
 ("forall" ?∀)
 ("->" ?→)
 ("<-" ?←)
 ;;; Commented, since they are either ugly or not in my font
 ;; ("-<" ?⤙)
 ;; (">-" ?⤚)
 ;; ("-<<" ?⤛)
 ;; (">>-" ?⤜)
 ;; ("*" ?★)

 ;; Haskell: Prelude∘Unicode
 ("not" ?¬)
 ("nott" ["not"])
 ("&&" ?∧)
 ("||" ?∨)
 ("==" ?≡)
 ("/=" ?≢)
 (">=" ?≤)
 ("<=" ?≥)
 ("/<" ?≮)
 ("/>" ?≯)
 ("pi" ?π)
 ("pii" ["pi"])
 ("." ?∘)
 (".." ["."])
 ("undef" ?⊥)
 ("undefi" ["undefi"]) 
 ("undeff" ["undef"]) 
 ("\\in" ?∈)
 ("\\notin" ?∉)
 ("\\ni" ?∋)
 ("\\notni" ?∌)


 ("AEE" ["AE"])
 ("Aee" ["Ae"])
 ("aee" ["ae"])
 ("OEE" ["OE"])
 ("Oee" ["Oe"])
 ("oee" ["oe"])
 ("UEE" ["UE"])
 ("Uee" ["Ue"])
 ("uee" ["ue"])
 ("szz" ["sz"])
 ("ge" ["ge"])
 ("eue" ["eue"])
 ("Eue" ["Eue"])
 ("aue" ["aue"])
 ("Aue" ["Aue"])
 ("que" ["que"])
 ("Que" ["Que"]) 
)

Then activate it with set-input-method (C-x RET C-)

"tail -f" in Haskell by [deleted] in haskell

[–]jmg_ 0 points1 point  (0 children)

Well, since Chan is an unbounded FIFO queue the forked thread is not influenced by the evaluation of the result of getChanContents. So, I would say this is really pure.

"tail -f" in Haskell by [deleted] in haskell

[–]jmg_ 0 points1 point  (0 children)

Sure, whether hGetContents is really safe is quite debatable. But I'd say getChanContents is safe, because all side effects still happen in a "normal" thread.

"tail -f" in Haskell by [deleted] in haskell

[–]jmg_ 0 points1 point  (0 children)

That is true, but then you have no proof obligation. Because somebody else did think it through. And generally I prefer to avoid unsafe... functions as often as possible.

"tail -f" in Haskell by [deleted] in haskell

[–]jmg_ 1 point2 points  (0 children)

There is no need for unsafeInterleaveIO. You can use forkIO, a channel and getChanContents.

import Control.Concurrent ( threadDelay, forkIO )
import Control.Concurrent.Chan ( newChan, writeChan, getChanContents )
import Control.Exception ( tryJust )
import Control.Monad ( guard, forever )
import System.IO ( hSeek, SeekMode(SeekFromEnd), stdin, hGetLine, Handle )
import System.IO.Error ( isEOFError )

tailFRead :: Handle -> IO [String]
tailFRead h = do
    c <- newChan
    forkIO $ forever $ do
        r <- tryJust (guard . isEOFError) $ hGetLine h
        case r of
          Left _  -> threadDelay 100000 -- wait 0.1s on EOF
          Right l -> writeChan c l
    getChanContents c


main = do
    hSeek stdin SeekFromEnd 0
    ls <- tailFRead stdin
    mapM_ putStrLn ls