(or emacs: Testing your .emacs sanity

Here's a little snippet that came up as a Stack Overflow answer once:

(defun ora-test-emacs ()
  (interactive)
  (require 'async)
  (async-start
   (lambda () (shell-command-to-string
          "emacs --batch --eval \"
(condition-case e
    (progn
      (load \\\"~/.emacs\\\")
      (message \\\"-OK-\\\"))
  (error
   (message \\\"ERROR!\\\")
   (signal (car e) (cdr e))))\""))
   `(lambda (output)
      (if (string-match "-OK-" output)
          (when ,(called-interactively-p 'any)
            (message "All is well"))
        (switch-to-buffer-other-window "*startup error*")
        (delete-region (point-min) (point-max))
        (insert output)
        (search-backward "ERROR!")))))

This function will quietly run a batch Emacs with your current config to see if it errors out or not.

  • in case that there were no start up errors, it will echo "All is well"
  • when there's an error, it will pop to a *startup error* buffer with the error description

The nice thing about this is that in case of an error you have a functional Emacs to fix that error, since fixing errors with emacs -Q is quite painful.

Another approach could be to just start a new Emacs instance, and close the window in case there isn't an error. So all that the code above does is automate closing the window (sort of, since the window never opens). Still, I think it's pretty cool. And you could attach it to the after-save-hook of your .emacs, or a timer.

You could even configure Emacs to send you an email in case it notices that there will be an error on the next start up. Or add the test to before-save-hook and abort the save in case it results in an error. That's some HAL 9000 level stuff right there:

I'm sorry Dave, I'm afraid I can't do that.

-1:-- Testing your .emacs sanity (Post)--L0--C0--March 04, 2015 11:00 PM

Irreal: The Emacs Way

Howard Abrams over at howardism.org has a nice post on the The Tao of Emacs. His idea is to compare the Emacs workflow with that of other editors such as Vim. While Vim users have a shell-centric workflow where actions such as editing, compiling and testing are orchestrated from the shell, Emacs users prefer to stay in their editor and run the compilation and testing from there. Emacs, of course, has the tools to do this easily and “never leave Emacs” is a sacred precept for many Emacs users. Certainly almost all proficient Emacs users will perform the entire development cycle completely from with the editor.

Abrams then moves on to considering editing remote files. With Tramp, it's easy to retrieve a file on a remote server that's behind a firewall or even a set of firewalls. For frequently used files, this can be configured so that it happens automatically, but even a one-off edit is pretty easy because you can specify the series of hosts to go through in the file path. If you're using ssh keys, as you should, this will be almost transparent because you won't be prompted for passwords.

Abrams gives a nice example of something I hadn't thought about: you can make a call to sudo the last hop in the sequence of hosts in the file path. This allows you to edit file owned by root (or others) on the remote host. See Abrams post for the details. One final thing I didn't know is that you can bookmark a remote file and access it again very easily by simply invoking the bookmark. Again, see Abrams post for the details.

This is a nice post that makes explicit how the Emacs workflow differs from that of other editors. The bits about using Tramp may teach you things you didn't know. It's well worth a read.

UPDATE: Be sure to see Phil's comment about using sudo at the end of a chain of intermediate hosts.

-1:-- The Emacs Way (Post jcs)--L0--C0--March 04, 2015 01:18 PM

sachachua: Getting Helm and org-refile to clock in or create tasks

I’ve been thinking about how to improve the way that I navigate to, clock in, and create tasks in Org Mode. If the task is one of the ones I’ve planned for today, I use my Org agenda. If I know that the task exists, I use C-u C-c C-w (org-refile) to jump to it, and then ! (one of my org-speed-commands-user options) to clock in and track it on Quantified Awesome. If I want to resume an interrupted task, I use C-u C-c j (my shortcut for org-clock-goto). For new tasks, I go to the appropriate project entry and create it, although I really should be using org-capture instead.

2015-01-30 Org Mode jumping to tasks -- index card #emacs #org

2015-01-30 Org Mode jumping to tasks – index card #emacs #org

I thought about how I can reduce some of these distinctions. For example, what if it didn’t matter whether or not a task already exists? I can modify the org-refile interface to make it easier for me to create tasks if my description doesn’t match anything. To make things simpler, I’ll just reuse one of my org-capture-templates, and I’ll pre-fill it with the candidate from Helm.

(ert-deftest sacha/org-capture-prefill-template ()
  (should
   ;; It should fill things in one field at a time
   (string=
    (sacha/org-capture-prefill-template
     "* TODO %^{Task}\nSCHEDULED: %^t\n:PROPERTIES:\n:Effort: %^{effort|1:00|0:05|0:15|0:30|2:00|4:00}\n:END:\n%?\n"
     "Hello World")
    "* TODO Hello World\nSCHEDULED: %^t\n:PROPERTIES:\n:Effort: %^{effort|1:00|0:05|0:15|0:30|2:00|4:00}\n:END:\n%?\n"
    ))
  (should
   (string=
    (sacha/org-capture-prefill-template
     "* TODO %^{Task}\nSCHEDULED: %^t\n:PROPERTIES:\n:Effort: %^{effort|1:00|0:05|0:15|0:30|2:00|4:00}\n:END:\n%?\n"
     "Hello World" "<2015-01-01>")
    "* TODO Hello World\nSCHEDULED: <2015-01-01>\n:PROPERTIES:\n:Effort: %^{effort|1:00|0:05|0:15|0:30|2:00|4:00}\n:END:\n%?\n"))
  (should
   (string=
    (sacha/org-capture-prefill-template
     "* TODO %^{Task}\nSCHEDULED: %^t\n:PROPERTIES:\n:Effort: %^{effort|1:00|0:05|0:15|0:30|2:00|4:00}\n:END:\n%?\n"
     "Hello World" "<2015-01-01>" "0:05")
    "* TODO Hello World\nSCHEDULED: <2015-01-01>\n:PROPERTIES:\n:Effort: 0:05\n:END:\n%?\n")))

(defun sacha/org-capture-prefill-template (template &rest values)
  "Pre-fill TEMPLATE with VALUES."
  (setq template (or template (org-capture-get :template)))
  (with-temp-buffer
    (insert template)
    (goto-char (point-min))
    (while (re-search-forward
            (concat "%\\("
                    "\\[\\(.+\\)\\]\\|"
                    "<\\([^>\n]+\\)>\\|"
                    "\\([tTuUaliAcxkKInfF]\\)\\|"
                    "\\(:[-a-zA-Z]+\\)\\|"
                    "\\^\\({\\([^}]*\\)}\\)"
                    "?\\([gGtTuUCLp]\\)?\\|"
                    "%\\\\\\([1-9][0-9]*\\)"
                    "\\)") nil t)
      (if (car values)
          (replace-match (car values) nil t))
      (setq values (cdr values)))
    (buffer-string)))

(defun sacha/helm-org-create-task (candidate)
  (let ((entry (org-capture-select-template "T")))
    (org-capture-set-plist entry)
    (org-capture-get-template)
    (org-capture-set-target-location)
    (condition-case error
        (progn
          (org-capture-put
           :template
           (org-capture-fill-template
            (sacha/org-capture-prefill-template (org-capture-get :template)
                                                candidate)))
          (org-capture-place-template
           (equal (car (org-capture-get :target)) 'function)))
      ((error quit)
       (if (get-buffer "*Capture*") (kill-buffer "*Capture*"))
       (error "Capture abort: %s" error)))) t)

Next, I want to add this to the way that Helm prompts me to refile. That means that my creation task should return something ready for org-refile. Actually, maybe I don’t have to do that if I know I’m always going to call it when I want to jump to something. I might as well add that bit of code that sets up clocking in, too.

(defvar sacha/helm-org-refile-locations nil)

(defun sacha/helm-org-clock-in-and-track-from-refile (candidate)
  (let ((location (org-refile--get-location candidate sacha/helm-org-refile-locations)))
    (save-window-excursion
      (org-refile 4 nil location)
      (sacha/org-clock-in-and-track)
      t)))

(defun sacha/helm-org-refile-read-location (tbl)
  (setq sacha/helm-org-refile-locations tbl)
  (helm
   (list
    (helm-build-sync-source "Refile targets"
      :candidates (mapcar 'car tbl)
      :action '(("Select" . identity)
                ("Clock in and track" . sacha/helm-org-clock-in-and-track-from-refile))
      :history 'org-refile-history)
    (helm-build-dummy-source "Create task"
      :action (helm-make-actions
               "Create task"
               'sacha/helm-org-create-task)))))

(defun sacha/org-refile-get-location (&optional prompt default-buffer new-nodes no-exclude)
  "Prompt the user for a refile location, using PROMPT.
PROMPT should not be suffixed with a colon and a space, because
this function appends the default value from
`org-refile-history' automatically, if that is not empty.
When NO-EXCLUDE is set, do not exclude headlines in the current subtree,
this is used for the GOTO interface."
  (let ((org-refile-targets org-refile-targets)
        (org-refile-use-outline-path org-refile-use-outline-path)
        excluded-entries)
    (when (and (derived-mode-p 'org-mode)
               (not org-refile-use-cache)
               (not no-exclude))
      (org-map-tree
       (lambda()
         (setq excluded-entries
               (append excluded-entries (list (org-get-heading t t)))))))
    (setq org-refile-target-table
          (org-refile-get-targets default-buffer excluded-entries)))
  (unless org-refile-target-table
    (user-error "No refile targets"))
  (let* ((cbuf (current-buffer))
         (partial-completion-mode nil)
         (cfn (buffer-file-name (buffer-base-buffer cbuf)))
         (cfunc (if (and org-refile-use-outline-path
                         org-outline-path-complete-in-steps)
                    'org-olpath-completing-read
                  'org-icompleting-read))
         (extra (if org-refile-use-outline-path "/" ""))
         (cbnex (concat (buffer-name) extra))
         (filename (and cfn (expand-file-name cfn)))
         (tbl (mapcar
               (lambda (x)
                 (if (and (not (member org-refile-use-outline-path
                                       '(file full-file-path)))
                          (not (equal filename (nth 1 x))))
                     (cons (concat (car x) extra " ("
                                   (file-name-nondirectory (nth 1 x)) ")")
                           (cdr x))
                   (cons (concat (car x) extra) (cdr x))))
               org-refile-target-table))
         (completion-ignore-case t)
         cdef
         (prompt (concat prompt
                         (or (and (car org-refile-history)
                                  (concat " (default " (car org-refile-history) ")"))
                             (and (assoc cbnex tbl) (setq cdef cbnex)
                                  (concat " (default " cbnex ")"))) ": "))
         pa answ parent-target child parent old-hist)
    (setq old-hist org-refile-history)
    ;; Use Helm's sources instead
    (setq answ (sacha/helm-org-refile-read-location tbl))
    (if (and (stringp answ)
             (setq pa (org-refile--get-location answ tbl)))
        (progn
          (org-refile-check-position pa)
          (when (or (not org-refile-history)
                    (not (eq old-hist org-refile-history))
                    (not (equal (car pa) (car org-refile-history))))
            (setq org-refile-history
                  (cons (car pa) (if (assoc (car org-refile-history) tbl)
                                     org-refile-history
                                   (cdr org-refile-history))))
            (if (equal (car org-refile-history) (nth 1 org-refile-history))
                (pop org-refile-history)))
          pa)
      (if (and (stringp answ) (string-match "\\`\\(.*\\)/\\([^/]+\\)\\'" answ))
          (progn
            (setq parent (match-string 1 answ)
                  child (match-string 2 answ))
            (setq parent-target (org-refile--get-location parent tbl))
            (when (and parent-target
                       (or (eq new-nodes t)
                           (and (eq new-nodes 'confirm)
                                (y-or-n-p (format "Create new node \"%s\"? "
                                                  child)))))
              (org-refile-new-child parent-target child)))
        (if (not (equal answ t)) (user-error "Invalid target location"))))))

(fset 'org-refile-get-location 'sacha/org-refile-get-location)

Hooray! Now C-u C-c C-w (org-refile) also lets me use TAB or F2 to select the alternative action of quickly clocking in on a task. Mwahaha.

You can check out this code in my config to see if anything has been updated. Want to learn more about modifying Helm? Check out these posts by John Kitchin and Rubikitch.

I think I’m getting the hang of tweaking Helm.  Yay!

The post Getting Helm and org-refile to clock in or create tasks appeared first on sacha chua :: living an awesome life.

-1:-- Getting Helm and org-refile to clock in or create tasks (Post Sacha Chua)--L0--C0--March 04, 2015 01:00 PM

Timo Geusch: Setting up Emacs spell checking on OS X

Setting up flyspell with hunspell on a Mac OS X Emacs install

The post Setting up Emacs spell checking on OS X appeared first on The Lone C++ Coder's Blog.

-1:-- Setting up Emacs spell checking on OS X (Post Timo Geusch)--L0--C0--March 04, 2015 05:16 AM

(or emacs: Eclipse theme

I started using Emacs around 2010-2011 when I needed an environment for C++ and LaTeX. The default color theme was horrendous (it still is), and I don't fancy myself a designer, so I just copied a color theme of the thing that I was using previously: Eclipse.

This theme modifies almost nothing except the font lock faces, and looks reasonable while called with -nw, although I don't see why anyone wouldn't want to take advantage of what graphical Emacs has to offer.

Here's a sampler:

eclipse-theme.png

It's shown together with my fork of powerline. I'll try to merge it as a theme eventually, I'm delaying it because powerline isn't very easy to understand/modify.

Eclipse theme should be on MELPA soon, I hope you'll enjoy it. I've tried probably 30 themes on MELPA, but I just can't part with eclipse-theme. I'm guessing that it's a feeling that most theme creators share.

-1:-- Eclipse theme (Post)--L0--C0--March 03, 2015 11:00 PM

Irreal: Yet Another Convert

It appears that org2blog is on track for world domination. At least the world of Emacs and WordPress.

-1:-- Yet Another Convert (Post jcs)--L0--C0--March 03, 2015 06:09 PM

Tassilo Horn: Swapping Emacs windows using drag’n’drop

When using Emacs on a larger screen where Emacs’ frame is split into multiple windows, you sometimes wish there was some simple way to rearrange which buffer is shown in which window.  Of course, you can do that by moving through your windows and using switch-to-buffer and friends but that’s not really convenient.

So here’s a command which lets you use drag one buffer from one window to the other. The effect is that the buffers of the start and target window are swapped.

(defun th/swap-window-buffers-by-dnd (drag-event)
  "Swaps the buffers displayed in the DRAG-EVENT's start and end
window."
  (interactive "e")
  (let ((start-win (cl-caadr drag-event))
        (end-win   (cl-caaddr drag-event)))
    (when (and (windowp start-win)
               (windowp end-win)
               (not (eq start-win end-win))
               (not (memq (minibuffer-window)
                          (list start-win end-win))))
      (let ((bs (window-buffer start-win))
            (be (window-buffer end-win)))
        (unless (eq bs be)
          (set-window-buffer start-win be)
          (set-window-buffer end-win bs))))))

Bind it to some mouse drag event and have fun. For example, I use (global-set-key (kbd "<C-S-drag-mouse-1>") #'th/swap-window-buffers-by-dnd) so that drag’n’drop with the left mouse button and control and shift pressed is bound to the command above.


-1:-- Swapping Emacs windows using drag’n’drop (Post tsdh)--L0--C0--March 03, 2015 01:55 PM

Timo Geusch: Improving my blogging workflow using Emacs (of course)

I try not to post too many metablogging posts. Other people do it better and I’m trying to focus on journalling what I learn as a software engineer and manager, not what tools I use for blogging. However after losing another post to WordPress’s built-in editor I decided Something Must Be Done. I think this… Read More »

The post Improving my blogging workflow using Emacs (of course) appeared first on The Lone C++ Coder's Blog.

-1:-- Improving my blogging workflow using Emacs (of course) (Post Timo Geusch)--L0--C0--March 03, 2015 05:02 AM

Endless Parentheses: Prettify your Apostrophes

Now that you’ve started your journey on the Typography Express by using round double quotes, take a seat and extend that to your apostrophes as well. This snippet binds a round apostrophe to the ' key, but also inserts a pair of single round quotes with a prefix.

Finally, like the previous one, it also falls back on self-insert-command inside a code block.

(define-key org-mode-map "'" #'endless/apostrophe)
;; (eval-after-load 'markdown-mode
;;   '(define-key markdown-mode-map "'"
;;      #'endless/apostrophe))

(defun endless/apostrophe (opening)
  "Insert ’ in prose or `self-insert-command' in code.
With prefix argument OPENING, insert ‘’ instead and
leave point in the middle.
Inside a code-block, just call `self-insert-command'."
  (interactive "P")
  (if (and (derived-mode-p 'org-mode)
           (org-in-block-p '("src" "latex" "html")))
      (call-interactively #'self-insert-command)
    (if (looking-at "['’][=_/\\*]?")
        (goto-char (match-end 0))
      (if (null opening)
          (insert "’")
        (insert "‘’")
        (forward-char -1)))))

Comment on this.

-1:-- Prettify your Apostrophes (Post)--L0--C0--March 02, 2015 12:00 AM

Grant Rettke: How to Type the OSX “Pretzel” Key in Unicode

Emacs tells you everything that you need to know about it using describe-char:

             position: 927 of 1056 (88%), column: 33
character: ⌘ (displayed as ⌘) (codepoint 8984, #o21430, #x2318)
preferred charset: unicode (Unicode (ISO10646))
code point in charset: 0x2318
script: symbol
syntax: . which means: punctuation
category: .:Base, j:Japanese
to input: type "C-x 8 RET HEX-CODEPOINT" or "C-x 8 RET NAME"
buffer code: #xE2 #x8C #x98
file code: #xE2 #x8C #x98 (encoded by coding system utf-8-unix)
display: by this font (glyph code)
mac-ct:-*-Lucida Grande-normal-normal-normal-*-17-*-*-*-p-0-iso10646-1 (#x3B4)

Character code properties: customize what to show
name: PLACE OF INTEREST SIGN
old-name: COMMAND KEY
general-category: So (Symbol, Other)
decomposition: (8984) ('⌘')

There are text properties here:
fontified t

-1:-- How to Type the OSX “Pretzel” Key in Unicode (Post Grant)--L0--C0--March 01, 2015 01:45 AM

Grant Rettke: EWS support for Emacs

I use Exchange at work for calendaring. I also use terminal-mode emacsclient when I’m logged in from another machine. In that scenario I can’t easily open a web browser to use Outlook Web Access. It annoyed me that I couldn’t check my schedule from within a terminal Emacs session. Thus, I did the only sensible thing and implemented full Exchange Web Services API support for Emacs.

Of course you did.

-1:-- EWS support for Emacs (Post Grant)--L0--C0--March 01, 2015 12:42 AM

sachachua: Using Emacs to prepare files for external applications like Autodesk Sketchbook Pro

To make it easier to draw using Autodesk Sketchbook Pro on my laptop (a Lenovo X220 tablet PC), I’ve created several templates with consistent dot grids and sizes. Since I want to minimize typing when I’m drawing, I wrote a couple of functions to make it easier to copy these templates and set up appropriately-named files. That way, I can save them without the grid layer, flip between files using Sketchbook Pro’s next/previous file commands, and then process them all when I’m ready.

Index cards

I’ve been experimenting with a habit of drawing at least five index cards every day. Here’s a function that creates five index cards (or a specified number of them) and then opens the last one for me to edit.

(defvar sacha/autodesk-sketchbook-executable "C:/Program Files/Autodesk/SketchBook Pro 7/SketchBookPro.exe")
(defun sacha/prepare-index-cards (n)
  (interactive (list (or current-prefix-arg 5)))
  (let ((counter 1)
        (directory "~/Dropbox/Inbox")
        (template "c:/data/drawing-templates/custom/0 - index.tif")
        (date (org-read-date nil nil "."))
        temp-file)
    (while (> n 0)
      (setq temp-file
            (expand-file-name (format "%s-%d.tif" date counter)
                              directory))
      (unless (file-exists-p temp-file)
        (copy-file template temp-file)
        (setq n (1- n))
        (if (= n 0)
            (shell-command
             (concat (shell-quote-argument sacha/autodesk-sketchbook-executable)
                     " "
                     (shell-quote-argument temp-file) " &"))))
      (setq counter (1+ counter)))))

Afterwards, I call sacha/rename-scanned-cards function to convert the TIFFs to PNGs, display the files and ask me to rename them properly.

Rename scanned index cards

(defun sacha/rename-scanned-cards ()
  "Display and rename the scanned files."
  (interactive)
  (when (directory-files "~/Dropbox/Inbox" t "^[0-9]+-[0-9]+-[0-9]+-.*.tif")
    ;; Convert the TIFFs first
    (apply 'call-process "mogrify" nil nil nil "-format" "png" "-quality" "1"
           (directory-files "~/Dropbox/Inbox" t "^[0-9]+-[0-9]+-[0-9]+-.*.tif"))
    (mapc (lambda (x)
            (rename-file x "~/Dropbox/Inbox/backup"))
          (directory-files "~/Dropbox/Inbox" t "^[0-9]+-[0-9]+-[0-9]+-.*.tif")))
  (mapc (lambda (filename)
          (find-file filename)
          (delete-other-windows)
          (when (string-match "/\\([0-9]+-[0-9]+-[0-9]+\\)" filename)
            (let ((kill-buffer-query-functions nil)
                  (new-name (read-string "New name: "
                                         (concat (match-string 1 filename) " "))))
              (when (> (length new-name) 0)
                (revert-buffer t t)
                (rename-file filename (concat new-name ".png"))
                (kill-buffer)))))
        (directory-files "~/Dropbox/Inbox" t "^[0-9]+-[0-9]+-[0-9]+-.*.png")))

I might tweak the files a little more after I rename them, so I don’t automatically upload them. When I’m happy with the files, I use a Node script to upload the files to Flickr, move them to my To blog directory, and copy Org-formatted text that I can paste into my learning outline.

Automatically resize images

The image+ package is handy for displaying the images so that they’re scaled to the window size.

(use-package image+
 :load-path "~/elisp/Emacs-imagex"
 :init (progn (imagex-global-sticky-mode) (imagex-auto-adjust-mode)))

Get information for sketched books

For sketchnotes of books, I set up the filename based on properties in my Org Mode tree for that book.

(defun sacha/prepare-sketchnote-file ()
  (interactive)
  (let* ((base-name (org-entry-get-with-inheritance  "BASENAME"))
         (filename (expand-file-name (concat base-name ".tif") "~/dropbox/inbox/")))
    (unless base-name (error "Missing basename property"))
    (if (file-exists-p filename)
        (error "File already exists")
        (copy-file "g:/drawing-templates/custom/0 - base.tif" filename))
      (shell-command (concat (shell-quote-argument sacha/autodesk-sketchbook-executable)
                             (shell-quote-argument filename) " &"))))

By using Emacs Lisp functions to set up files that I’m going to use in an external application, I minimize fussing about with the keyboard while still being able to take advantage of structured information.

Do you work with external applications? Where does it make sense to use Emacs Lisp to make setup or processing easier?

The post Using Emacs to prepare files for external applications like Autodesk Sketchbook Pro appeared first on sacha chua :: living an awesome life.

-1:-- Using Emacs to prepare files for external applications like Autodesk Sketchbook Pro (Post Sacha Chua)--L0--C0--February 25, 2015 01:00 PM

Bryan Murdock: Why Open Source Has Not Taken Over EDA


We all know that in the world of general software Open Source has all but won. Linux is everywhere. Nearly all programming languages are Open Source (meaning their compilers/interpreters). IDE's, build tools, revision control, syntax highlighters, refactoring tools, you name it, if it's a development tool it's Open Source. Major infrastructure is Open Source too. I mentioned the Linux operating system, but all the major applications are Open Source too: web servers, databases, queueing systems, messaging systems, load balancing, caching systems, GUI frameworks, encryption, authentication, email servers, instant messaging servers, blog engines, you name it.

In the world of Electronic Design Automation (EDA), Open Source has not won. We do now develop on Linux and we use a lot of ancillary tools from the software world that are Open Source such as scripting languages, text editors, databases, web frameworks, build systems, and so forth, but our core tools are still very much closed source and commercial, namely simulation and synthesis tools.

Why haven't those tools followed the same trend that the general software world has seen? Why don't we have a solid Open Source simulator that every one in the industry rallies around, similar to the way gcc is the defacto standard C compiler? Every time I have posed this question there are a few answers that always come up. One is that our industry is small. There are far more software developers, the argument goes, and so the likelihood of a Linus Torvalds or Richard Stallman like leader emerging is small. Another answer is that we aren't software developers. Our primary skill is designing circuits, not software, therefore we just don't have the skills or drive to write our own tools like software developers have done.

While the logic in those answers seems sound, I don't believe they are the primary reason we still lack quality Open Source tools. There have been hobbyists like Linus and RMS that have started Open Source EDA tool projects that are probably at least as functional and easy to use as early versions of Linux or gcc were, but people just haven't flocked to them. Yes, the number of EDA people that are capable of writing a synthesis tool is small, but how many software developers really have the chops to write operating systems or compilers? Also not very many. There are far more consumers than producers of general Open Source software. I don't believe that's the reason there isn't any successful Open Source EDA tools.

I believe the real reason we don't have Open Source tools is because we haven't had an oppressive monopoly in EDA like Microsoft was in its day. Microsoft was so good at locking people in to their proprietary tools and crushing competition that the only answer was to not play their game. You had two choices, go the Microsoft route or go Open Source. We in the EDA world, on the other hand, actually have a (somewhat) functioning capitalist software economy. There are three (three! not just two like Coke and Pepsi) big EDA companies that sell competing software (these companies are lovingly referred to as, "the big three"). Unlike the days of Microsoft, these companies actually have to listen to their customers[1] and compete on the merits and price of their products[2]. Since we have been able to play the big three against each other and generally get at least the bare minimum of what we need, there hasn't been a strong need for a linux or gcc like project to set us free.

Hooray for capitalism! Yet somehow I'm not satisfied. I am very pro capitalism in general, don't get me wrong. I think my dissatisfaction comes from the fact that I am even more pro freedom, and EDA tools are not Free. They are not Open Source. I'm not free to dig into the code if I desire to. I'm not even free to use the tools as I chose. They are offered under onerous license agreements that don't even allow us to publish performance numbers or talk about their costs publicly[3]. When they don't perform or I encounter bugs, my only recourse is beg for mercy from the vendor or embark on the onerous task of switching vendors (just because it's possible doesn't mean it's easy). If it were open source there would be mailing lists and forums where not just the vendors customer support people participated, but other tool users and the tool developers themselves would be available to collaborate with on solutions.

This would sound like an outrageous and silly utopian dream if it wasn't already working in the software world. It's not just young single dudes living in their parents basement or slumming it in graduate cubicles at MIT anymore either. Red Hat Software is a publicly traded company making 11% profit margin on about $1.8 billion in revenue, which puts it right in among the Big Three. There are plenty of other businesses that make real profits doing various combinations of producing, supporting, and providing services based on Open Source software. It can be done. In fact I'm pretty sure if one of the Big Three even released just their simulator as Open Source they would quickly grab all of the market share for simulators and a whole lot of new customers for their other tools. They would also make the world a much better place for all of EDA.

Footnotes

1. Well, at least their biggest customers.

2. Well, not publicly, because their license agreements don't allow us to publish their tools' merits or prices.

3. See footnote above.
-1:-- Why Open Source Has Not Taken Over EDA (Post Bryan (noreply@blogger.com))--L0--C0--February 23, 2015 03:24 PM

Ben Simon: Nifty emacs trick: impatient-mode for instant buffer sharing

It may only only be 10:20am, but I'm willing to bet this is going to be the coolest thing I see all day. Perhaps all week. Lifted from this post: Emacs: Peer-to-peer coaching is easier when you use impatient-mode to share your buffer I typed the following into emacs:

 M-x package-install impatient-mode
 M-x httpd-start
 C-x b foo
 M-x impatient-mode

I then opened up: http://localhost:8080/imp/ and clicked on foo. As I typed in emacs, my browser automagically updated:

(Yeah, that static screenshot doesn't do the functionality justice.)

I have no idea how I'm going to put this capability to work. But the fact that it just magically works leaves me in awe.

Emacs just never ceases to amaze.

-1:-- Nifty emacs trick: impatient-mode for instant buffer sharing (Post Ben Simon)--L0--C0--February 23, 2015 10:29 AM

Endless Parentheses: Visit Directory inside a Set of Directories

Almost every directory I work with, is either directly under “~/Dropbox/” or under “~/Dropbox/Work/”. However, I never actually visit these two directories, only the directories inside them. The number of possible targets for find-file is approaching the outer borders of two-digit land, so there's no hope for my brain to remember registers for all of these.

The best solution I've found is to compile a list of all possible targets (directories inside those directories) and offer them using ido. This is somewhat similar to using a bookmark for each possible destination, except it it's always up to date with the directory contents and doesn't clog up my actual bookmarks.

(require 'ido)
(require 'cl-lib)

(defcustom endless/favorite-directories 
  '("~/Dropbox/Trabalho/" "~/Dropbox/")
  "List of favorite directories.
Used in `endless/visit-favorite-dir'. The order here 
affects the order that completions will be offered."
  :type '(repeat directory)
  :group 'endless)

(defun endless/visit-favorite-dir (files-too)
  "Offer all directories inside a set of directories.
Compile a list of all directories inside each element of
`endless/favorite-directories', and visit one of them with
`ido-completing-read'.
With prefix argument FILES-TOO also offer to find files."
  (interactive "P")
  (let ((completions
         (mapcar #'abbreviate-file-name
           (cl-remove-if-not
            (if files-too #'file-readable-p
              #'file-directory-p)
            (apply #'append
              (mapcar (lambda (x)
                        (directory-files
                         (expand-file-name x)
                         t "^[^\.].*" t))
                endless/favorite-directories))))))
    (dired
     (ido-completing-read "Open directory: "
                          completions 'ignored nil ""))))

;; Note that C-x d is usually bound to dired. I find
;; this redundant with C-x C-f, so I don't mind
;; overriding it, but you should know before you do.
(define-key ctl-x-map "d" #'endless/visit-favorite-dir)

Some random notes:

  • Having a quick key for this is fantastic. Whenever I want to get work done, I just hit C-x d and I'll my options are presented before me.
  • With a prefix argument it also shows files instead of just directories.
  • If ido is not your completion engine of choice, that's trivial to change.
  • This works best when combined with ido-vertical.

Comment on this.

-1:-- Visit Directory inside a Set of Directories (Post)--L0--C0--February 23, 2015 12:00 AM

Flickr tag 'emacs': 2015 Laptop Desktop - Custom Tiling Window Manager

math0ne posted a photo:

2015 Laptop Desktop - Custom Tiling Window Manager

Been a while since I added a shot, even though I'm now on windows 8 not too much has changed. Couple notes about the setup:

* This is a Samsung ATIV with an 11.6" screen and a 1920x1080 resolution hence the somewhat larger fonts that you might be used to.
* I'm using a custom tiling window manager, I spent a long time tweaking it because some programs I love on windows don’t like to be sized exactly. I used AutoHotKey to make a tiling manager that worked around those issues specifically.
* I have a array of dark user styles for websites I use frequently.
* It's all powered by Cygwin / Futty (the best putty clone).

Here are the credits:

Wall is a re-balanced version of NEVA by Digitalshiva
Visual Style is aeroblack by lukesp
Firefox is FT DeepDark
TBarIconStripper (to remove the icons)
The IRC is irssi with my theme from an earlier release
Foobar is a modified version of ncmpcpp_mod by twnsnd
ZSH Prompt is based on Phil!'s ZSH Prompt
Colors based on Thayer's colors from the archlinux forums
Clock is TClock
Emacs is Customized zenburn to look like Thayer's colors
7conifer with token light for the bar icons
Nexusfile with a custom theme based on pixel by hora hora
Font is Terminus
Startisgone to hide the start menu

I'm actually loving windows 8 and often use it in touch or pen modes, I'm planning on adding a couple shots in one image showing how I transition between the working styles at some point in the future.

-1:-- 2015 Laptop Desktop - Custom Tiling Window Manager (Post math0ne (nobody@flickr.com))--L0--C0--February 20, 2015 10:21 PM

Bryan Murdock: No More Ads, Send Tips with Bitcoin

Summary: ads are gone, send me bitcoin to say thanks instead.

I have always kept notes for myself to remind myself how to do various things. I have also kept a journal since a very young age where I often include opinions and thoughts on various matters. At some point, years ago, I got the idea that I should post some of the notes and thoughts in case they would help someone else. That requires a lot more work than just typing stuff quickly into a text file, though, so I needed a little more motivation. I mean, sharing and helping others is great motivation, but when I read about Adsense from Google, and how Google could show people links to products and services related to my posts, and I could make a few bucks if people thought those links were useful and clicked on them, and how it could help out the people providing those products and services as well, it felt like this great intertwined synergy of helping people out and possibly even gaining some monetary reward as well. And it sort of worked. I put some effort into this blog and my Adsense account started slowly accumulating some credits.

The one downside was, well, advertising. It's often more annoying than helpful. Google's adds were the least annoying I've seen, but still not always that great. To be honest, this blog isn't updated enough and isn't high traffic enough that I'm really sending a lot of business anyone's way, and I'm not making any kind of real money at all with the adds. I've thought about this on and off over the years, but haven't changed anything, until now. What happened is, I finally read up on this crazy thing I'd seen mentioned on Slashdot and Hacker News called bitcoin.

The notion of a digital currency seemed ludicrous when I first read headlines and article summaries about it, and so I ignored it for a while. Now, the more I read about it, the more it makes sense, and the more excited I get about it. You really should go to We Use Coins and learn more, they can explain it better than me. The relevant part of bitcoin to this post is that it is super easy to send money from one person to another with bitcoin. No banks, escrow services, or credit cards are required. If you want to donate money to me to say thank you it's as simple as firing up your bitcoin wallet software and sending coins to this address: 15RNcXeuhjQRKnfLGyVZxpeER8MUmrYLMq (UPDATE, I closed this wallet, but the concept is still valid!). It's a lot like cash that way, only you don't have be standing next to the person you want to pay in order to make the transaction. Way cool. Liberating, in fact. That's what really appeals to me. The lack of central control, and the ease and freedom it provides. Nothing crazy about that.

Now, I didn't just put that bitcoin address in the sidebar of my blog, I used a Coinbase payment button. Coinbase is an online wallet, which is a little more convenient (but less decentralized and free) than running the bitcoin software on your own machine (of course, you can do both). The cool thing the button of theirs provides is a unique bitcoin address for every transaction. That just makes the payments more anonymous. I could have written software to generate those addresses and the button myself, but I'm OK with letting them handle that for me. At least for now as I'm testing the bitcoin waters.
-1:-- No More Ads, Send Tips with Bitcoin (Post Bryan (noreply@blogger.com))--L0--C0--February 20, 2015 01:33 PM

Eric James Michael Ritz: A New Co-Maintainer for PHP Mode

A couple of friends asked me if I had made any progress in finding a new maintainer for PHP Mode. I am happy to announce that I have. Syohei Yoshida (aka. ’syohex’), author of great packages like git-gutter.el and quickrun.el (which I’ve blogged about before), has graciously taken on a co-maintainer role and in quite proactive fashion. I say “co-maintainer” only because I am still not walking away from PHP Mode. I will continue to review patches and offer my input when I can. But Yoshida has been doing work addressing issue, cleaning up older big reports, and managing pull requests. I trust his judgement to the extent that he can merge pull requests into PHP Mode at his own discretion. So if you submit a patch and find it’s been merged by someone who’s not me—well, that’s why.

So I simply wanted to post this announcement in the event that anyone wonders why ‘syohex’ handling pull requests and responding to bug reports. It’s because he’s the new co-maintainer of PHP Mode. And I’m very, very greatful that he’s taken on this role.

Besides, I couldn’t reject help from a guy who shares my enthusiasm for some classic mid-90’s Japanese rock, heh.


-1:-- A New Co-Maintainer for PHP Mode (Post ericjmritz)--L0--C0--February 19, 2015 12:41 AM

emacspeak: Enhanced Audio On The Emacspeak Desktop

Enhanced Audio On The Emacspeak Desktop

1 Enhanced Audio On The Emacspeak Desktop

I recently added a set of modules to Emacspeak to leverage some of the high-end audio functionality available on Linux machines on modern hardware. As an example, applying effects such as 3D spatialization, high-end reverb effects etc. once consumed CPU cycles to the extent where it was not possible to play with these in realtime. All these now take less than 1–5% of the CPU, and that when my laptop is running in power-save mode!

1.1 An Audio Workbench Using SoX

Sound Exchange (SoX), described as the Swiss army knife of sound processing, has been around since the time I was a graduate student. Today it provides a versatile set of tools for editing and manipulating both wave and mp3 files. Module sox.el implements a simple Audio Workbench for the Emacspeak desktop.

1.1.1 Pre-Requisites

SoX with all available auxillary packages for adding support for various filetypes such as mp3. The various Ladspa related packages for installing additional audio effect filters.

1.1.2 Usage Instructions For SoX.el

  • Launch the Audio Workbench via by executing M-x sox.
  • Use f to open a wave or mp3 file you wish to manipulate.
  • Add any of the supported effects using e.
  • Use upper-case E to add more than one effect.
  • Hit p to play the result, s to save the result to a new file.

At present sox.el supports a few effects such as trim for clipping files, reverb for adding a reverb etc., with more to come as I use it.

1.2 Adding High-End Reverb When Playing Media Streams

I use mplayer to play both local and network media streams. MPlayer can apply a wide range of filters to the audio stream; more interestingly it can also apply effects implemented as Ladspa plugins. Package tap-plugins implements a large number of high-quality Ladspa filters, including a versatile Reverb filter.

Once you have package tap-plugins and its dependencies installed, and a relatively new version of MPlayer (with support for Ladspa plugins), you can now apply various Reverb Presets to your media streams via Emacspeak MPlayer command emacspeak-m-player-apply-reverb-preset bound to P in Emacspeak MPlayer. Package tap-plugins defines a total of 42 Reverb Presets, experiment with these when wearing headsets. Once you have applied a Reverb Preset, you can edit its current settings via command emacspeak-m-player-edit-reverb bound to R in Emacspeak MPlayer. Alternatively, you can pick a default effect to use via Emacs' custom interface; see option emacspeak-m-player-reverb-filter.

1.3 Defining Convenient MPLayer Shortcuts

Finally, You can now bind shortcut keys for launching Emacspeak MPlayer from specific locations where you store media, e.g., you can have separate shortcuts for Music vs Audio Books – see command emacspeak-m-player-accelerator. This is best used by customizing Emacspeak option emacspeak-media-location-bindings — just use the Customize interface to specify pairs of shortcut keys and media locations.

Date: <2015-02-17 Tue>

Author: raman

Created: 2015-02-17 Tue 17:37

Emacs 25.0.50.1 (Org mode 8.2.10)

Validate

-1:-- Enhanced Audio On The Emacspeak Desktop (Post T. V. Raman (noreply@blogger.com))--L0--C0--February 18, 2015 01:40 AM

emacspeak: Internet Radio: Tune-In For Emacspeak

Internet Radio: Tune-In For Emacspeak

1 Internet Radio: Tune-In For Emacspeak

I just checked in the ability to browse, search and play radio-stations from TuneIn on the Emacspeak Audio Desktop.

1.1 Pre-Requisites

  1. xsltproc for xsl stylesheet processing.
  2. Linux mplayer for playing streams, preferably the latest version

2 Simple Usage Summary

  • M-x emacspeak-wizards-tune-in-radio-browse brings up the browse interface.
  • M-x emacspeak-wizards-tune-in-radio-search prompts for a query and brings up search results.
  • Both browse and search get the results back as an OPML feed, which gets displayed as a simple Web page within the Emacs Web Browser (EWW if using 24.4).
  • Items identified as (link) are themselves OPML feeds and can be opened via command emacspeak-feeds-opml-display.
  • The initial browse buffer is set up to use opml-display when you click on link items.
  • You can play (audio) links by invoking command emacspeak-webutils-play-media-at-point — this command is bound to _; in EWW.
  • You need to provide an interactive prefix argument to the above command to indicate that it is a playlist — so you actually press C-u ; on audio links.
  • Many of the audio links do not return a playlist – they instead return a link that is a pointer to a playlist. Newer versions of mplayer will throw a security error — you can tell mplayer to follow them by invoking the earlier command with two prefix args so C-u C-u ;.
  • All this works about 90% of the time. In some cases – depending on whether the server failed to generate the right

mimetype for the play URL etc, you may need to run

curl --silent <url> 

where <url> is the URL of the audio link, then pass that resulting URL to command emacspeak-m-player-url.

Share And Enjoy!

Date: <2015-02-17 Tue>

Author: T.V Raman

Created: 2015-02-17 Tue 16:41

Emacs 25.0.50.1 (Org mode 8.2.10)

Validate

-1:-- Internet Radio: Tune-In For Emacspeak (Post T. V. Raman (noreply@blogger.com))--L0--C0--February 18, 2015 12:49 AM

Got Emacs?: Emacs 24.5 Pretest released

The first pretest for what will be the 24.5 release of Emacs is available.
-1:-- Emacs 24.5 Pretest released (Post sivaram (noreply@blogger.com))--L0--C0--February 17, 2015 06:47 PM

Julien Danjou: Hacking Python AST: checking methods declaration

A few months ago, I wrote the definitive guide about Python method declaration, which had quite a good success. I still fight every day in OpenStack to have the developers declare their methods correctly in the patches they submit.

Automation plan

The thing is, I really dislike doing the same things over and over again. Furthermore, I'm not perfect either, and I miss a lot of these kind of problems in the reviews I made. So I decided to replace me by a program – a more scalable and less error-prone version of my brain.

In OpenStack, we rely on flake8 to do static analysis of our Python code in order to spot common programming mistakes.

But we are really pedantic, so we wrote some extra hacking rules that we enforce on our code. To that end, we wrote a flake8 extension called hacking. I really like these rules, I even recommend to apply them in your own project. Though I might be biased or victim of Stockholm syndrome. Your call.

Anyway, it's pretty clear that I need to add a check for method declaration in hacking. Let's write a flake8 extension!

Typical error

The typical error I spot is the following:

class Foo(object):
# self is not used, the method does not need
# to be bound, it should be declared static
def bar(self, a, b, c):
return a + b - c


That would be the correct version:

class Foo(object):
@staticmethod
def bar(a, b, c):
return a + b - c


This kind of mistake is not a show-stopper. It's just not optimized. Why you have to manually declare static or class methods might be a language issue, but I don't want to debate about Python misfeatures or design flaws.

Strategy

We could probably use some big magical regular expression to catch this problem. flake8 is based on the pep8 tool, which can do a line by line analysis of the code. But this method would make it very hard and error prone to detect this pattern.

Though it's also possible to do an AST based analysis on on a per-file basis with pep8. So that's the method I pick as it's the most solid.

AST analysis

I won't dive deeply into Python AST and how it works. You can find plenty of sources on the Internet, and I even talk about it a bit in my book The Hacker's Guide to Python.

To check correctly if all the methods in a Python file are correctly declared, we need to do the following:

  • Iterate over all the statement node of the AST
  • Check that the statement is a class definition (ast.ClassDef)
  • Iterate over all the function definitions (ast.FunctionDef) of that class statement to check if it is already declared with @staticmethod or not
  • If the method is not declared static, we need to check if the first argument (self) is used somewhere in the method

Flake8 plugin

In order to register a new plugin in flake8 via hacking, we just need to add an entry in setup.cfg:

[entry_points]
flake8.extension =
[…]
H904 = hacking.checks.other:StaticmethodChecker
H905 = hacking.checks.other:StaticmethodChecker


We register 2 hacking codes here. As you will notice later, we are actually going to add an extra check in our code for the same price. Stay tuned.

The next step is to write the actual plugin. Since we are using an AST based check, the plugin needs to be a class following a certain signature:

@core.flake8ext
class StaticmethodChecker(object):
def __init__(self, tree, filename):
self.tree = tree
 
def run(self):
pass


So far, so good and pretty easy. We store the tree locally, then we just need to use it in run() and yield the problem we discover following pep8 expected signature, which is a tuple of (lineno, col_offset, error_string, code).

This AST is made for walking ♪ ♬ ♩

The ast module provides the walk function, that allow to iterate easily on a tree. We'll use that to run through the AST. First, let's write a loop that ignores the statement that are not class definition.

@core.flake8ext
class StaticmethodChecker(object):
def __init__(self, tree, filename):
self.tree = tree
 
def run(self):
for stmt in ast.walk(self.tree):
# Ignore non-class
if not isinstance(stmt, ast.ClassDef):
continue


We still don't check for anything, but we know how to ignore statement that are not class definitions. The next step need to be to ignore what is not function definition. We just iterate over the attributes of the class definition.

for stmt in ast.walk(self.tree):
# Ignore non-class
if not isinstance(stmt, ast.ClassDef):
continue
# If it's a class, iterate over its body member to find methods
for body_item in stmt.body:
# Not a method, skip
if not isinstance(body_item, ast.FunctionDef):
continue


We're all set for checking the method, which is body_item. First, we need to check if it's already declared as static. If so, we don't have to do any further check and we can bail out.

for stmt in ast.walk(self.tree):
# Ignore non-class
if not isinstance(stmt, ast.ClassDef):
continue
# If it's a class, iterate over its body member to find methods
for body_item in stmt.body:
# Not a method, skip
if not isinstance(body_item, ast.FunctionDef):
continue
# Check that it has a decorator
for decorator in body_item.decorator_list:
if (isinstance(decorator, ast.Name)
and decorator.id == 'staticmethod'):
# It's a static function, it's OK
break
else:
# Function is not static, we do nothing for now
pass


Note that we use the special for/else form of Python, where the else is evaluated unless we used break to exit the for loop.

for stmt in ast.walk(self.tree):
# Ignore non-class
if not isinstance(stmt, ast.ClassDef):
continue
# If it's a class, iterate over its body member to find methods
for body_item in stmt.body:
# Not a method, skip
if not isinstance(body_item, ast.FunctionDef):
continue
# Check that it has a decorator
for decorator in body_item.decorator_list:
if (isinstance(decorator, ast.Name)
and decorator.id == 'staticmethod'):
# It's a static function, it's OK
break
else:
try:
first_arg = body_item.args.args[0]
except IndexError:
yield (
body_item.lineno,
body_item.col_offset,
"H905: method misses first argument",
"H905",
)
# Check next method
continue


We finally added some check! We grab the first argument from the method signature. Unless it fails, and in that case, we know there's a problem: you can't have a bound method without the self argument, therefore we raise the H905 code to signal a method that misses its first argument.

Now you know why we registered this second pep8 code along with H904 in setup.cfg. We have here a good opportunity to kill two birds with one stone.

The next step is to check if that first argument is used in the code of the method.

for stmt in ast.walk(self.tree):
# Ignore non-class
if not isinstance(stmt, ast.ClassDef):
continue
# If it's a class, iterate over its body member to find methods
for body_item in stmt.body:
# Not a method, skip
if not isinstance(body_item, ast.FunctionDef):
continue
# Check that it has a decorator
for decorator in body_item.decorator_list:
if (isinstance(decorator, ast.Name)
and decorator.id == 'staticmethod'):
# It's a static function, it's OK
break
else:
try:
first_arg = body_item.args.args[0]
except IndexError:
yield (
body_item.lineno,
body_item.col_offset,
"H905: method misses first argument",
"H905",
)
# Check next method
continue
for func_stmt in ast.walk(body_item):
if six.PY3:
if (isinstance(func_stmt, ast.Name)
and first_arg.arg == func_stmt.id):
# The first argument is used, it's OK
break
else:
if (func_stmt != first_arg
and isinstance(func_stmt, ast.Name)
and func_stmt.id == first_arg.id):
# The first argument is used, it's OK
break
else:
yield (
body_item.lineno,
body_item.col_offset,
"H904: method should be declared static",
"H904",
)


To that end, we iterate using ast.walk again and we look for the use of the same variable named (usually self, but if could be anything, like cls for @classmethod) in the body of the function. If not found, we finally yield the H904 error code. Otherwise, we're good.

Conclusion

I've submitted this patch to hacking, and, finger crossed, it might be merged one day. If it's not I'll create a new Python package with that check for flake8. The actual submitted code is a bit more complex to take into account the use of abc module and include some tests.

As you may have notice, the code walks over the module AST definition several times. There might be a couple of optimization to browse the AST in only one pass, but I'm not sure it's worth it considering the actual usage of the tool. I'll let that as an exercise for the reader interested in contributing to OpenStack. 😉

Happy hacking!

A book I wrote talking about designing Python applications, state of the art, advice to apply when building your application, various Python tips, etc. Interested? Check it out.

-1:-- Hacking Python AST: checking methods declaration (Post Julien Danjou)--L0--C0--February 16, 2015 11:39 AM

Emacs Life: A Package in a league of its own: Helm

A Package in a league of its own: <code>Helm</code>:

-1:-- A Package in a league of its own: Helm (Post Steven Ness (noreply@blogger.com))--L0--C0--February 15, 2015 04:12 AM

Flickr tag 'emacs': 2015-02-13b What are the benefits of watching someone code an idea in Emacs Lisp -- index card #coaching #emacs #teaching #emacs-lisp

sachac posted a photo:

2015-02-13b What are the benefits of watching someone code an idea in Emacs Lisp -- index card #coaching #emacs #teaching #emacs-lisp

-1:-- 2015-02-13b What are the benefits of watching someone code an idea in Emacs Lisp -- index card #coaching #emacs #teaching #emacs-lisp (Post sachac (nobody@flickr.com))--L0--C0--February 14, 2015 11:37 PM

Emacs Life: emacs-helm/helm · GitHub

emacs-helm/helm · GitHub: "Helm is now available on Melpa at http://melpa.org/ You will find there instructions to install. See also https://github.com/milkypostman/melpa#usage to startup correctly with the emacs packaging system. Then you should need only in your init file:

(require 'helm-config)
-1:-- emacs-helm/helm · GitHub (Post Steven Ness (noreply@blogger.com))--L0--C0--February 14, 2015 02:44 PM

Phillip Lord: Documenting Lentic

With a previous release of lentic [1], I got a couple of suggestions. One of which was a complaint that it was hard to get going, because lentic lacks documentation. This is a bit unfortunate. Lentic actually did have documentation but it is hidden away as comments in source code; although, it’s not specific to it, I wanted lentic to enable literate programming and it uses itself to document itself.

Now, this makes perfect sense, but there is a problem. The end-user form of the documentation needs generating from the source code. This is true in general in Emacs land, although the standard form is texinfo. The usual solution to this problem is to generate the documentation up during the packaging process.

This should work, but it doesn’t. Or, rather, it does not work in all cases. For an archive such as Marmalade, it is entirely possible. But for MELPA it fails. The problem is that MELPA works directly from a git checkout. My documentation, of course, is not source but generated. Now MELPA has support for the generation of info from texinfo. But my source is Emacs Lisp and I need to use Lentic to generate a readable form.

One solution would, of course, be not to use MELPA. Nic Ferrier recently argued on the emacs-devel mailing list that the idea was fundamentally broken — a package is something that the developers should generate and publish as with Java or Clojure . He makes a good point, and one that is correct. Moving to Marmalade would solve this problems; after Nic’s work it is largely stable, so this was definately an option.

However, I like MELPA (although I have only used it since stable came out). It is nice that it uses what I am doing anyway (tagging, pushing, so forth). And I like the download stats. So I talked with the MELPA folks but, entirely reasonably, they did not want to add specific support to MELPA for this. Nor support for, for example, downloading the source from somewhere else.

Other possibilities did raise themselves; I could just check in my documentation. But my documentation depends on my source, so pretty much every commit would require also require a documentation commit. Not nice. I thought about adding the documentation as an independent package. Then my documentation commits would be in a repo with nothing else; but this hassles the user, even if it auto-installs. And I’d need different packages for MELPA and Marmalade. So, I was left with no good solution.

At the same time, as all of this, I was working on the documentation, generating Org files from my lisp documentation, then converting that to info. This sort of worked, but not nicely. A significant problem was that something in the toolchain did not like having multiple sections with the same names and I have a lot of these (“Commentary, Header, Code”). I have not tracked down yet whether this is a problem with Org’s texinfo export, texinfo itself or info, nor am I sure it would be worth the effort.

Instead, I decided to try HTML output. This worked quite nicely; I use a single Org driver file (called lenticular.org) and imported all the generated org files from here. I also found org-info which I had not seen before — this is Javascript which gives an Info like experience — next, previous, occur, search and so on. It’s imperfect, but pretty usable, and gives a quite nice documentation experience. It’s also possible to view in EWW although there is no Info like paging here.

Dropping info has one other big advantage — my tool chain for generating the documentation is now entirely in Emacs. So, my source code is now enough, because lentic can generate it’s own documentation on-demand after installation. The first time the user requests the documentation either in EWW or a browser, lentic generates org files from it’s own source and then the HTML [2]. The only limitation is that this forces the requirement for a recent Emacs version, since the org mode exporter framework has just been updated; unfortunate but acceptable for a 0.x release.

Not all problems disappear. Because my documentation fits into the Emacs-Lisp commenting standards, it is not structured-ideally for info. For instance, the headers of all the lentic Emacs-Lisp files are included. I also would like to extend org-info so I can switch the “Code” sections on and off (embedded literate sources are useful, but not for everyone). It will need some work on Lentic, and probably also the org-mode HTML exporter.

But, then, neither is it that far off. It is good enough and a bit advance on the previous situation. Perhaps, too, it demonstrates a future for Emacs documentation in general as well, with Info replaced with HTML.

The new release [3] of Lentic is now available on Marmalade and MELPA, complete with documentation avaialble from the menu. Please feel free to try both lentic and its documentation system out now.

References

  1. P. Lord, "Lenticular Text: Looking at code from different angles", An Exercise in Irrelevance, 2015. http://www.russet.org.uk/blog/3035
  2. P. Lord, "Lenticular Text For Emacs"http://homepages.cs.ncl.ac.uk/phillip.lord/lentic/lenticular.html
  3. P. Lord, "Lentic 0.7", An Exercise in Irrelevance, 2015. http://www.russet.org.uk/blog/3047
-1:-- Documenting Lentic (Post Phillip Lord)--L0--C0--February 08, 2015 10:00 PM

Thomas Fitzsimmons: Excorporate: EWS support for Emacs

I use Exchange at work for calendaring. I also use terminal-mode emacsclient when I’m logged in from another machine. In that scenario I can’t easily open a web browser to use Outlook Web Access. It annoyed me that I couldn’t check my schedule from within a terminal Emacs session. Thus, I did the only sensible thing and implemented full Exchange Web Services API support for Emacs.

Excorporate terminal screenshot

The result is a library called Excorporate that has proof-of-concept Calendar integration to show today’s meetings. It’s all written in Elisp, making it cross-platform. It’s also cross-Emacs; I tested it on Emacs 24.1 through Emacs 24.4, on GNU/Linux and MS-Windows. It works on all Emacs versions that support packages.

The tricky parts were:

  • extending soap-client to support all the XML Schema (XSD) datatypes required by the EWS WSDL file,
  • asynchronous URL retrieval without blocking the Emacs main loop,
  • autodiscovery of Exchange server settings from an email address, and,
  • implementing NTLMv2 authentication in Elisp.

I’m trying to get it into GNU ELPA so that other modes can always count on its core APIs being available from a default Emacs installation. I haven’t put it on GitHub yet, to keep it hidden from the ruthless efficiency of MELPA. I was impressed and appreciative when MELPA bundled slime-volleyball shortly after I released it. But I’d prefer to keep Excorporate in GNU ELPA only for now.

Anyway, I’m publishing this mode in the hope that it’s useful to other Emacs-and-Exchange users.

-1:-- Excorporate: EWS support for Emacs (Post Thomas Fitzsimmons)--L0--C0--February 08, 2015 06:13 PM

Jorgen Schäfer: Elpy 1.7.0 released

I just released version 1.7.0 of Elpy, the Emacs Python Development Environment. This is a feature release.

Elpy is an Emacs package to bring powerful Python editing to Emacs. It combines a number of other packages, both written in Emacs Lisp as well as Python.

Quick Installation

Evaluate this:

(require 'package)
(add-to-list 'package-archives
'("elpy" .
"http://jorgenschaefer.github.io/packages/"))

Then run M-x package-install RET elpy RET.

Finally, run the following (and add them to your .emacs):

(package-initialize)
(elpy-enable)

Changes in 1.7.0

  • Elpy now can add missing import directives automatically, by using Alec Thomas' excellent importmagic library. Use C-c C-m to add a single import statement, or C-c C-S-m to include all missing import statements. Many thanks to Georg Brandl for doing a lot of work to bring this feature to Elpy!
  • The Jedi backend now also supports C-c C-d to display a docstring. Thanks again to Georg Brandl for the patch.
  • It is now possible to disable the display of the current function in the echo area by setting elpy-eldoc-show-current-function to nil.
  • idomenu was removed as a dependency. Elpy did not have any particular provision for this aside from loading it. Users who want to keep using it can just install the package manually.
  • Twisted's Trial test runner is now supported. Thanks to Elric Milon for the patch!
  • All test runners now use a variable to decide which command to run, which for example allows using manage.py for the Django test runner, or your own test script which sets up the environment correctly.
  • Emacs 24.4 is now officially supported.
  • Various bugfixes.
More thanks go out to Georg Brandl, fleimgruber, Eric Hanchrow, Elric Milon and eduardo naufel schettino for their contributions.
-1:-- Elpy 1.7.0 released (Post Jorgen Schäfer (noreply@blogger.com))--L0--C0--February 06, 2015 06:16 PM

Phillip Lord: Lentic 0.7

Lentic is an Emacs mode which supports multiple views over the same text. This can be used for a form of literate programming. It has specific support for Clojure which it can combine with either LaTeX, Asciidoc or Org-Mode.

Two lentic buffers, by default, the two share content but are otherwise independent. Therefore, you can have two buffers open, each showing the content in different modes; to switch modes, you simply switch buffers. The content, location of point, and view are shared.

However, lentic also allows a bi-directional transformation between lentic buffers — the buffers can have different but related text. This allows, for example, one buffer to contain an Emacs lisp file, while the other contains the same text but with “;;” comment characters removed leaving the content in org-mode, enabling a form of literate Emacs-Lisp programming with no change to either org-mode or Emacs-Lisp. Ready made transformations are also available for Clojure, latex and asciidoc.

Lentic is both configurable and extensible, using the EIEIO object system.

Lentic was previously known as Linked-Buffers.

The 0.7 release adds an integrated documentation system, support for Haskell, LaTeX literate programming and best of all, a ROT-13 transformation.

Available on MELPA-stable, MELPA and Marmalade https://github.com/phillord/lentic

-1:-- Lentic 0.7 (Post Phillip Lord)--L0--C0--February 05, 2015 10:41 AM

Ben Simon: The Agony and Ecstasy of Linux on the Desktop

It all started with an anonymous comment: why run Windows if all the software you're running is Linux flavored? I didn't have a particularly good answer.

Thing is, there used to be a time when I only ran Linux. Shira reminds me that back in the day I wouldn't even *allow* a Windows box under my roof (really? She says so). So how did I drift so far away from my roots?

Who cares. Let's fix this.

In theory, you can experiment with Linux before you install it as your primary OS. By default, Fedora comes with a (amazingly cool) Live version that lets you run Linux without messing with Windows. And then there's always the option to install Linux on old laptop or desktop, and play with it there. I've talked about doing those things for years.

However, the only way I know how to truly use Linux is to frigging Use Linux. That is, jump in the deep end of the pool and hope you can learn to swim in time. And so that's exactly what I did: I installed the latest version of Fedora on my brand new Dell laptop. Rolling back to Windows is possible, but it ain't easy.

My adventure started at 6:56am on January 26, 2015. I know this, because for the last 10 days I've been keeping a log of my trials and tribulations.

I'll spare you the details of reading the log (though, please, be my guest) and give you the Cliff Notes version. First, I was amazed at how easily Linux installed. It was effortless. And then I was amazed at the slick desktop that booted up. And then reality started setting in. First, stuff just didn't work. For example, I couldn't move windows around by clicking and dragging the mouse. I was left baffled: was something not configured properly, or was I just clueless as to how a modern version of Linux works?

And then I got more frustrated: what I was looking at was a slick user interface, which as far as I can tell, was trying to be a better version of Windows. But if I wanted Windows, I would have just continued to use the version of Windows I already had!

So, I turned off Gnome, that fancy Desktop Manager and turned on plain o'l X-Windows. Hello 1999! I was no closer to a functioning system, but at least I had that warm fuzzy feeling that comes from recreating the Good Old Days.

Next up, I installed ratpoison. This infamous Window Manager let's you manage your desktop by barely touching the mouse. It's crude and cryptic. Now this is a Linux box!

But still, the list of things that didn't work far outnumbered the list of things that did. Firefox menus didn't work. Selecting text didn't work. Copying between an X-term and Firefox didn't work. WiFi didn't work. Good Lord, what did work?

At this point, I wanted off this ride. My Windows + Cygwin + Emacs approach may have been klugy at times, but at least the friggin mouse worked!

Then I finally had a small bright spot. While working on a network hardware post, I realized that I could measure the strength of my wireless router by kicking off nmcli like so:

  while sleep 1; do nmcli dev wifi >> wifi.stats ; done

I could then walk around the house and collect data. When I was done, I used awk to pull out the WiFi signal strength and generated this graph. Could I have done this in Windows? Sure, but not with zero effort.

As I thought about this victory, I remembered that Windows has always been the OS where things Just Work, whereas Linux let's you be productive in ways you never even imagined. Sure, that's changed over the years: X used to require massive amounts to effort to configure (and you risked ruining your monitor!), now it Just Works. But as I was learning first hand, when it comes to a flawless system out of the box Windows still has Linux beat. But, as my little network script showed, Linux can run circles around a typical Windows configuration when it comes to actually getting things done.

So I pushed forward. And so far, I'm glad I did.

Over the last few days, I've figured out many an issue. My trackpad, for example, needed to be marked as a 'clickpad' to truly function (ahhh, now it works!). I got copy and paste working correctly, my phone to be detected, multiple monitors to work well with ratpoison and a slew of other victories.

Things are far from fully setup (I'm looking at you, 'SD Card'), but they're getting there.

More importantly, I've gotten a number of scripts in place to streamline tasks that used to be all manual. I can now type:

 s5 mount ; s5 grab ; s5 unmount

to grab all the images from my cell phone and have them archived in directory named with the date. Here's the script:

#!/bin/bash

##
## A script for working with our galaxy s5
##
S5_ROOT=$HOME/devices/s5
S5_PICTURES=$HOME/Pictures/s5
action=$1 ; shift

case $action in
  mount)
    simple-mtpfs $S5_ROOT ;;
  umount)
    fusermount -u $S5_ROOT ;;
  slurp)
    for img in $S5_ROOT/Card/DCIM/Camera/*.jpg ; do
      date=`imgcreated $img`
      echo "$img -> $date"
      mkdir -p $S5_PICTURES/$date
      mv -i $img $S5_PICTURES/$date
    done
    ;;
  *)
    echo "Usage: `basename $0` {mount|umount|slurp}"
    exit
    ;;
esac

It's this sort of automation that makes me feel like this Linux experiment is more than just a walk down memory lane.

Expect to see more scripts and tales from the command line as I continue to refine my desktop Linux experience.

-1:-- The Agony and Ecstasy of Linux on the Desktop (Post Ben Simon)--L0--C0--February 04, 2015 08:29 PM