Skip to main content leehalls.net

Emacs Lisp & Yasnippet

On my home machines as detailed in this post i keep a journal and used some fu to determine which machine the journal entry was written on. I also keep a daily log for work normally this consists of start time, mileage to be claimed so the snippet template resembles

text code snippet start

# -*- mode: snippet -*-
# name: daily
# key: daily
# --
** `(format-time-string "%Y-%m-%d-%H:%m" (current-time))`
:PROPERTIES:
:LOCATION:
:MILEAGE:
:START: `(format-time-string "%H:%M" (current-time))`
:FINISH:
:END:

text code snippet end

At the start of everyday when i open up the laptop emacs is always there waiting and in the log for this year i type daily hit tab and voila my entry for the day commences

text code snippet start

** 2020-06-05-14:06
   :PROPERTIES:
   :LOCATION:
   :MILEAGE:
   :START: 14:06
   :FINISH:
   :END:

text code snippet end

Location, mileage and end time are manually entered and normally i keep location as a set of abbreviations that match the mileage to claim this means using dynamic column view i can get a nice table of times/locations such as;

ITEM LOCATIONS START FINISH MILEAGE EXPENSE TAGS
July 2018 745 207.03
20180705 05:56 15:10 0.00 :clock_anamoly:
20180706 07:40 14:00 0.00
20180709 MEA-WAR 10:25 17:00 90 0.00 :clock_anamoly:travel:
20180710 WAR 07:40 17:00 0.00 :travel:
20180711 WAR 07:40 17:00 3.30 :travel:
20180712 WAR-MEA 07:40 13:30 90 48.45 :travel:clock_anamoly:
20180713 MEA-TAM-MEA 07:45 14:00 25 0.00
20180716 MEA-BHX-PARIS 05:00 20:00 25 29.00 :travel:clock_anamoly:
20180717 PARIS 08:30 18:30 0.00 :travel:clock_anamoly:
20180718 PARIS-BHX-MEA 08:30 00:00 25 0.00 :travel:clock_anamoly:

This then at the top of the file gets rendered into a smaller dynamic table so i can see cumulative mileage by month

ITEM LOCATIONS START FINISH MILEAGE TAGS
April 2018 400
May 2018 689
June 2018 682
July 2018 745
August 2018 155

now i’m working from home due to COVID i got tired of typing “home” everytime but i know there will be site & supplier visits coming up so i didnt want to alter the template and just add the text “home” so back to the point of this post which was to use a bit of emacs-lisp fu to get the snippet template to auto update location but how?

After a little thinking i came to the conclusion the easiest way would be to identify the network address the laptop is currently on, now admittedly this falls down if by some miracle everywhere i go has the same 192.168.1 start for IP address but i’ll test that when on the road. I started by reading up on network commands via

https://www.gnu.org/software/emacs/manual/html_node/elisp/Misc-Network.html

i then searched and found https://emacs.stackexchange.com/questions/7653/elisp-code-to-check-for-internet-connection and this was discussing auto updating packages if the connection was alive.

A bit of playing around i could see network-interface-list contained the info i wanted

elisp code snippet start

(print (network-interface-list))

#+RESULTS:
: ((lo0 . [127 0 0 1 0]) (lo0 . [0 0 0 0 0 0 0 1 0]) (eth1 . [169 254 195 98 0]) (eth1 . [65152 0 0 0 2226 39545 32787 50018 0]) (wlan2 . [169 254 127 144 0]) (wlan2 . [65152 0 0 0 20906 64385 58821 32656 0]) (wlan1 . [169 254 218 84 0]) (wlan1 . [65152 0 0 0 12504 37352 2860 55892 0]) (wlan0 . [169 254 231 54 0]) (wlan0 . [65152 0 0 0 41016 7035 59478 59190 0]) (eth0 . [192 168 1 14 0]) (eth0 . [65152 0 0 0 4387 56520 32424 30320 0]))

elisp code snippet end

but then reading the first site also gave me network-interface-info so specifying the wireless network or in this case ethernet (i’m writing this on my main m\c) gives

elisp code snippet start

(print (network-interface-info "eth0"))

#+RESULTS:
: ([192 168 1 14 0] [192 168 1 255 0] [255 255 255 0 0] (1 . [244 77 48 24 93 135]) (dynamic running multicast broadcast up))

elisp code snippet end

ok so i have the data what next? a little trial and error follows;

emacs-lisp code snippet start

(print (network-interface-info "wlan0"))
(setq x (nth 0 (network-interface-info "wlan0")))
(print x)
(format "%s" x)
(if (string-match-p "192 168 1" (format "%s" x))
"home"
"work")

emacs-lisp code snippet end

there’s a lot wrong with the above and i’ve learned a bit more however given i start with zero emacs-lisp fu i think i can be spared a little leeway however it does ultimately work and can be pared down to the following;

emacs-lisp code snippet start

(if (string-match-p "192 168 1" (format "%s" (network-interface-info "wlan0")))
"home"
"work")

emacs-lisp code snippet end

All that needs to happen now is for the code to be incorporated into the snippet;

text code snippet start

# -*- mode: snippet -*-
# name: daily
# key: daily
# --
** `(format-time-string "%Y-%m-%d-%H:%m" (current-time))`

:PROPERTIES:
`(if (string-match-p "192 168 1" (format "%s" (network-interface-info "wlan0")))
":LOCATION: HOME"
":LOCATION: ")`
:MILEAGE:
:START: `(format-time-string "%H:%M" (current-time))`
:FINISH:
:END:

text code snippet end

Basically an hour of research and testing to save me what? 20s per day? thats going to be a long ROI before it pays off but i like learning and how knows what else may now be automated now that i have a little more fu.