Emacs APAC: Announcing Emacs Asia-Pacific (APAC) virtual meetup, Saturday, October 26, 2024
-1:-- Announcing Emacs Asia-Pacific (APAC) virtual meetup, Saturday, October 26, 2024 (Post)--L0--C0--October 12, 2024 12:02 AM
-1:-- Announcing Emacs Asia-Pacific (APAC) virtual meetup, Saturday, October 26, 2024 (Post)--L0--C0--October 12, 2024 12:02 AM
-1:-- Using Whitespace Mode in Emacs - EP4 (Post Discovering Emacs)--L0--C0--October 11, 2024 05:03 PM
2024-09-14. I’m somewhere in the Italian-speaking parts of Switzerland with my wife. There is a lot of running, hiking, hugging, kissing, eating and drinking involved. 🥰
2024-09-15. Still on the trip but late at night I spent more than an hour trying to figure out why my server had a load of nearly 40. 💻
All I discovered is that load went down when I shut down Emacs Wiki. See also 2024-09-16 on Emacs Wiki.
Well, I needed to sleep and I’ve got plans for the next few days so I shut it down while I slept hoping that the misconfigured spider is fixed or the inept programmer discovers their mistake. Just another day in the Butlerian Jihad. Some misguided soul probably wanted to download it all and wrote a broken web crawler and when that got blocked they bought some nice scaling infrastructure from Amazon, Hetzner, OHV or Alibaba Cloud or whatever they are called, allowing them to use a gazillion different IP numbers that will eventually lead me to implement some sort of cloud service provider block.
2024-09-16. Switched Emacs Wiki back on after a few hours of sleep and it did fine. But then it restarted again… at 18:00, 19:00, 21:00, 22:00… and so I switched Emacs Wiki off again. Time to ban some networks!
Anybody interested in my banning of IP ranges and possibly interested in me reverting any of these, take a look at ban-cidr … from a network that isn’t banned, I guess. 😏
2024-09-17. This continues to keep me busy and angry every evening. Too bad I don’t have a real fast network-lookup to firewall ban pipeline. I’m using this script instead of carefully checking IP numbers and networks. I’m also sick and tired of the same networks popping up again and again.
I added over a hundred Chinese networks to the firewall rules and I’m seriously considering blocking the whole country for a week. It seems that most of the offenders are networks run by China Telecoms and China Mobile.
2024-09-18. So far, so good. Load stays below two.
Here’s example usage for network-lookup
, filtering for Emacs Wiki and a URL parameter used when requesting recent changes or a RSS feed for a single page only. That would count as suspicious misbehaving crawler behaviour in my book.
Made 16 DNS requests.
4 cache hits.
Range | Hits | Org |
---|---|---|
34.32.128.0/17 | 3 | Google LLC / GOOGL-2 |
113.0.0.0/13 | 3 | UNICOM-HL / CNC Group CHINA169 Heilongjiang Province Network |
14.208.0.0/12 | 1 | CHINANET-GD / China Telecom |
39.64.0.0/11 | 1 | China Unicom Shandong Province Network / UNICOM-SD |
111.36.192.0/20 | 1 | China Mobile communications corporation / China Mobile / CMNET / ORG-CM1-AP |
223.167.0.0/16 | 1 | UNICOM-SH / China Unicom Shanghai Province Network |
39.184.0.0/18 | 1 | Internet Service Provider in China / CMNET / ORG-CM1-AP / China Mobile |
111.18.128.0/20 | 1 | China Mobile / ORG-CM1-AP / CMNET / China Mobile communications corporation |
27.38.200.0/24 | 1 | UNICOM-GDSZ / China Unicom |
112.47.128.0/18 | 1 | China Mobile communications corporation / China Mobile Communications Corporation / ORG-CMCC1-AP / CMNET |
218.71.0.0/16 | 1 | CHINANET-ZJ-WZ / Zhejiang Telecom |
39.130.48.0/20 | 1 | CMNET / ORG-CM1-AP / China Mobile / Internet Service Provider in China |
222.90.0.0/16 | 1 | CHINANET-SN / Beijing 100088 |
223.81.240.0/20 | 1 | ORG-CM1-AP / CMNET / China Mobile / China Mobile communications corporation |
218.107.192.0/19 | 1 | CNCGROUP-FJ-XIAMEN-MAN / CNCGroup CHINA169 FuJian province network |
219.128.0.0/13 | 1 | CHINANET-GD / China Telecom |
34.32.128.0/17 Google LLC / GOOGL-2
34.32.172.122 34.32.172.122 34.32.172.122
34.32.128.0/17 | 34.32.172.122 | 18/Sep/2024:18:02:12 +0200 | GET /cgi-bin/emacs?action=rss;rcidonly=RssExclude;days=1;all=1;showedit=1;full=1 HTTP/1.1 | Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
34.32.128.0/17 | 34.32.172.122 | 18/Sep/2024:18:02:12 +0200 | GET /cgi-bin/emacs?action=rss;rcidonly=RssExclude;days=1;all=1;showedit=1;full=1 HTTP/1.1 | Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
34.32.128.0/17 | 34.32.172.122 | 18/Sep/2024:18:02:12 +0200 | GET /emacs?action=rss;rcidonly=RssExclude;days=1;all=1;showedit=1;full=1 HTTP/1.1 | Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
ipset add banlist 34.32.128.0/17
113.0.0.0/13 UNICOM-HL / CNC Group CHINA169 Heilongjiang Province Network
113.2.156.201 113.2.184.52 113.1.92.78
113.0.0.0/13 | 113.2.156.201 | 18/Sep/2024:18:02:11 +0200 | GET /emacs?action=rc&all=1&days=14&rcidonly=tzhelp.el&showedit=0 HTTP/1.1 | Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 ADG/11.0.2566 AOLBUILD/11.0.2566 Safari/537.36
113.0.0.0/13 | 113.2.184.52 | 18/Sep/2024:18:02:16 +0200 | GET /emacs?action=rc&all=1&days=7&rcidonly=WriteRoom&showedit=1 HTTP/1.1 | Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Brave Chrome/88.0.4324.152 Safari/537.36
113.0.0.0/13 | 113.1.92.78 | 18/Sep/2024:18:02:21 +0200 | GET /emacs?action=rc&all=1&from=1&rcidonly=screen-term.el&showedit=1 HTTP/1.1 | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.63 Safari/537.36
ipset add banlist 113.0.0.0/13
14.208.0.0/12 CHINANET-GD / China Telecom
14.216.128.162
14.208.0.0/12 | 14.216.128.162 | 18/Sep/2024:18:02:27 +0200 | GET /emacs?action=rc&all=1&from=1&rcidonly=SyncBBDB&showedit=1 HTTP/1.1 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36
ipset add banlist 14.208.0.0/12
39.64.0.0/11 China Unicom Shandong Province Network / UNICOM-SD
39.76.103.29
39.64.0.0/11 | 39.76.103.29 | 18/Sep/2024:18:02:17 +0200 | GET /emacs?action=rc&all=1&days=1&rcidonly=FinderMode&showedit=1 HTTP/1.1 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36
ipset add banlist 39.64.0.0/11
111.36.192.0/20 China Mobile communications corporation / China Mobile / CMNET / ORG-CM1-AP
111.36.200.78
111.36.192.0/20 | 111.36.200.78 | 18/Sep/2024:18:01:50 +0200 | GET /emacs?action=rc&all=1&days=28&rcidonly=DiredPlusMarkMenu&showedit=1 HTTP/1.1 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
ipset add banlist 111.36.192.0/20
223.167.0.0/16 UNICOM-SH / China Unicom Shanghai Province Network
223.167.74.168
223.167.0.0/16 | 223.167.74.168 | 18/Sep/2024:18:01:39 +0200 | GET /emacs?action=rc&all=1&from=1726266329&rcidonly=etagsselect&showedit=1 HTTP/1.1 | Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
ipset add banlist 223.167.0.0/16
39.184.0.0/18 Internet Service Provider in China / CMNET / ORG-CM1-AP / China Mobile
39.184.45.222
39.184.0.0/18 | 39.184.45.222 | 18/Sep/2024:18:02:28 +0200 | GET /emacs?action=rss&all=1&days=14&rcidonly=BufferMenuPlus&showedit=1 HTTP/1.1 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Brave Chrome/81.0.4044.122 Safari/537.36
ipset add banlist 39.184.0.0/18
111.18.128.0/20 China Mobile / ORG-CM1-AP / CMNET / China Mobile communications corporation
111.18.142.15
111.18.128.0/20 | 111.18.142.15 | 18/Sep/2024:18:02:00 +0200 | GET /emacs?action=rc&all=1&from=1&rcidonly=orgfold-separate-file.el&showedit=1 HTTP/1.1 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36
ipset add banlist 111.18.128.0/20
27.38.200.0/24 UNICOM-GDSZ / China Unicom
27.38.200.210
27.38.200.0/24 | 27.38.200.210 | 18/Sep/2024:18:01:57 +0200 | GET /emacs?action=rc&all=1&from=1723764629&rcidonly=AnselmHelbig&showedit=1&upto=1724974229 HTTP/1.1 | Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36
ipset add banlist 27.38.200.0/24
112.47.128.0/18 China Mobile communications corporation / China Mobile Communications Corporation / ORG-CMCC1-AP / CMNET
112.47.136.104
112.47.128.0/18 | 112.47.136.104 | 18/Sep/2024:18:01:28 +0200 | GET /emacs?action=rc&all=0&days=14&rcidonly=RubyEvalRegion&showedit=1 HTTP/1.1 | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36
ipset add banlist 112.47.128.0/18
218.71.0.0/16 CHINANET-ZJ-WZ / Zhejiang Telecom
218.71.59.116
218.71.0.0/16 | 218.71.59.116 | 18/Sep/2024:18:01:55 +0200 | GET /emacs?action=rc&all=1&from=1726412272&rcidonly=AnilTappetla&showedit=1 HTTP/1.1 | Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36
ipset add banlist 218.71.0.0/16
39.130.48.0/20 CMNET / ORG-CM1-AP / China Mobile / Internet Service Provider in China
39.130.50.65
39.130.48.0/20 | 39.130.50.65 | 18/Sep/2024:18:02:28 +0200 | GET /emacs?action=rc&all=1&days=7&rcidonly=CarlMikkelsen&showedit=1 HTTP/1.1 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
ipset add banlist 39.130.48.0/20
222.90.0.0/16 CHINANET-SN / Beijing 100088
222.90.194.237
222.90.0.0/16 | 222.90.194.237 | 18/Sep/2024:18:01:57 +0200 | GET /emacs?action=rc&all=1&from=1&rcidonly=AnIntroductionToTheEmacsEditor&showedit=1 HTTP/1.1 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36
ipset add banlist 222.90.0.0/16
223.81.240.0/20 ORG-CM1-AP / CMNET / China Mobile / China Mobile communications corporation
223.81.249.112
223.81.240.0/20 | 223.81.249.112 | 18/Sep/2024:18:01:43 +0200 | GET /emacs?action=rc&all=1&from=1726333566&rcidonly=iclects_-_search_search_commands,_overview&showedit=1 HTTP/1.1 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.9999.0 Safari/537.36
ipset add banlist 223.81.240.0/20
218.107.192.0/19 CNCGROUP-FJ-XIAMEN-MAN / CNCGroup CHINA169 FuJian province network
218.107.204.27
218.107.192.0/19 | 218.107.204.27 | 18/Sep/2024:18:01:57 +0200 | GET /emacs?action=rc&all=1&from=1&rcidonly=DiredPlusPopupRegionRemoveRectMenu&showedit=1 HTTP/1.1 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Brave Chrome/88.0.4324.152 Safari/537.36
ipset add banlist 218.107.192.0/19
219.128.0.0/13 CHINANET-GD / China Telecom
219.133.249.75
219.128.0.0/13 | 219.133.249.75 | 18/Sep/2024:18:02:11 +0200 | GET /emacs?action=rc&all=1&days=1&rcidonly=Categor%C3%ADaHerramientasOnline&showedit=1 HTTP/1.1 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36
ipset add banlist 219.128.0.0/13
As far as I am concerned, all deserve to be banned. Over-banning? Maybe. What do you think?
For demonstration purposes, this is what I ran:
ssh sibirocobombus.root grep '"^www.emacswiki.org.*rcidonly"' /var/log
/apache2/access.log \
| tail -n 20 \
| ssh sibirocobombus.root bin/admin/network-lookup \
| wl-copy
So now I’m ready to ban them all:
wl-paste | grep ipset
#Emacs #Butlerian Jihad #Administration
2024-10-01. Today I came back to the server with load at 40. Again! Here’s me filtering the log for requests that got a server error status code (500–509).
root@sibirocobombus ~# tail -n 20000 /var/log/apache2/access.log \
| grep -v ^social \
| grep " 50[0-9] " \
| tail -n 50 \
| bin/admin/network-lookup
Made 44 DNS requests.
6 cache hits.
I think the only one I didn’t ban was the unknown one, Gwene and Bing (Microsoft).
Range | Hits | Org |
---|---|---|
1.56.0.0/13 | 3 | UNICOM-HL / China Unicom Heilongjiang Province Network |
221.208.0.0/14 | 3 | UNICOM-HL / CNC Group CHINA169 Heilongjiang Province Network |
112.224.0.0/11 | 2 | China Unicom CHINA169 Shandong Province Network / UNICOM-SD |
39.184.104.0/21 | 2 | China Mobile / CMNET / Internet Service Provider in China / ORG-CM1-AP |
unknown | 2 | ? |
36.132.172.0/22 | 1 | China Mobile Communications Corporation / China Mobile Communications Corporation / CMNET / ORG-CMCC1-AP |
113.248.0.0/14 | 1 | China Telecom / CHINANET-CQ |
221.5.0.0/17 | 1 | CNC Group CHINA169 Guangdong Province Network / UNICOM-GD |
111.36.240.0/20 | 1 | China Mobile / China Mobile communications corporation / CMNET / ORG-CM1-AP |
223.88.64.0/19 | 1 | CMNET / China Mobile communications corporation / ORG-CM1-AP / China Mobile |
111.16.32.0/20 | 1 | China Mobile communications corporation / CMNET / ORG-CM1-AP / China Mobile |
111.34.144.0/20 | 1 | China Mobile / ORG-CM1-AP / CMNET / China Mobile communications corporation |
182.32.0.0/12 | 1 | CHINANET-SD / Beijing 100032 |
183.92.0.0/14 | 1 | UNICOM-HB / China Unicom Hubei Province Network |
60.218.0.0/15 | 1 | CNC Group CHINA169 Heilongjiang Province Network / UNICOM-HL |
114.216.20.0/23 | 1 | CHINANET-JS / Beijing 100032 |
139.227.0.0/16 | 1 | China Unicom / UNICOM-SH |
119.176.0.0/12 | 1 | UNICOM-SD / CNC Group CHINA169 Shandong Province Network |
119.96.0.0/13 | 1 | China Telecom / CHINANET-HB |
115.48.0.0/12 | 1 | UNICOM-HA / CNC Group CHINA169 Henan Province Network |
42.100.0.0/15 | 1 | CHINANET-HL / NO.178 Zhongshan Road,Haerbin,Heilongjiang 150040 |
60.255.0.0/16 | 1 | SCN / China Unicom China169 Network |
157.55.0.0/16 | 1 | Microsoft Corporation / MSFT-GFS |
116.202.0.0/16 | 1 | Transferred to the RIPE region on 2018-08-28T00:42:30Z. / STUB-116-202SLASH15 |
111.37.176.0/20 | 1 | CMNET / China Mobile communications corporation / ORG-CM1-AP / China Mobile |
117.179.28.0/22 | 1 | China Mobile / China Mobile communications corporation / CMNET / ORG-CM1-AP |
58.21.0.0/16 | 1 | CNC Group CHINA169 Jilin Province Network / UNICOM-JL |
27.8.0.0/13 | 1 | UNICOM-CQ / China Unicom Chongqing Province Network |
65.19.128.0/18 | 1 | Hurricane Electric LLC / HURRICANE-4 |
223.94.208.0/20 | 1 | China Mobile / China Mobile communications corporation / CMNET / ORG-CM1-AP |
111.37.224.0/19 | 1 | ORG-CM1-AP / China Mobile communications corporation / CMNET / China Mobile |
183.64.0.0/13 | 1 | CHINANET-CQ / China Telecom |
1.188.0.0/14 | 1 | UNICOM-HL / China Unicom Heilongjiang Province Network |
112.36.80.0/20 | 1 | China Mobile Communications Corporation / CMNET / China Mobile communications corporation / ORG-CMCC1-AP |
163.125.191.0/24 | 1 | UNICOM-GD / China Unicom Guangdong Province Network |
36.143.23.0/24 | 1 | China Mobile Communications Corporation / ORG-CMCC1-AP / China Mobile Communications Corporation / CMNET |
61.162.0.0/16 | 1 | CNC Group CHINA169 Shandong Province Network / UNICOM-SD |
27.152.0.0/13 | 1 | Fujian Province / QZCABID-QZ-FJ |
222.136.0.0/13 | 1 | UNICOM-HA / CNC Group CHINA169 Henan Province Network |
36.132.191.0/24 | 1 | China Mobile Communications Corporation / CMNET / ORG-CMCC1-AP / China Mobile Communications Corporation |
58.19.0.0/16 | 1 | UNICOM-HB / CNCGroup HuBei province network |
139.226.0.0/16 | 1 | China Unicom / UNICOM-SH |
118.86.0.0/16 | 1 | JCOM-NET / Jupiter Telecommunications Co., Ltd. |
Load is now at around 31.
2024-10-01. Getting lazier… Pick a suspicious pattern and check for China…
root@sibirocobombus ~# tail -n 500 /var/log/apache2/access.log \
| grep -v ^social \
| grep "action=browse&id=" \
| tail -n 50 \
| bin/admin/network-lookup > result.log
root@sibirocobombus ~# grep ipset result.log
ipset add banlist 27.16.0.0/12 # CHINANET-HB / China Telecom
ipset add banlist 219.145.0.0/16 # CHINANET-SN / Beijing 100032
ipset add banlist 116.179.0.0/16 # UNICOM / China Unicom CHINA169 Network
ipset add banlist 221.219.0.0/18 # China Unicom Beijing Province Network / UNICOM-BJ
ipset add banlist 119.128.0.0/12 # China Telecom / CHINANET-GD
ipset add banlist 124.234.0.0/15 # CHINANET-JL / China Telecom
ipset add banlist 101.80.0.0/13 # Beijing 100032 / CHINANET-SH
ipset add banlist 111.41.128.0/17 # China Mobile communications corporation / CMNET / China Mobile / ORG-CM1-AP
ipset add banlist 111.14.0.0/20 # ORG-CM1-AP / China Mobile / CMNET / China Mobile communications corporation
ipset add banlist 110.176.0.0/13 # shanxi telecom linfen branch ip node links to customer ip address / sxlfbas
ipset add banlist 221.232.0.0/14 # Beijing 100088 / CHINANET-HB
ipset add banlist 116.4.0.0/14 # Beijing 100032 / CHINANET-GD
ipset add banlist 111.41.16.0/22 # ORG-CM1-AP / China Mobile / China Mobile communications corporation / CMNET
ipset add banlist 36.44.0.0/15 # CHINANET-SN / Beijing 100032
ipset add banlist 112.10.192.0/18 # China Mobile communications corporation / CMNET / ORG-CMCC1-AP / China Mobile Communications Corporation
ipset add banlist 117.154.240.0/20 # China Mobile / ORG-CM1-AP / CMNET / China Mobile communications corporation
ipset add banlist 111.43.58.0/23 # China Mobile communications corporation / CMNET / ORG-CM1-AP / China Mobile
ipset add banlist 111.19.0.0/17 # China Mobile communications corporation / CMNET / ORG-CM1-AP / China Mobile
ipset add banlist 183.229.0.0/16 # ORG-CMCC1-AP / China Mobile Communications Corporation / CMNET / China Mobile communications corporation
ipset add banlist 223.89.128.0/18 # CMNET / China Mobile communications corporation / ORG-CM1-AP / China Mobile
ipset add banlist 42.184.0.0/16 # NO.178 Zhongshan Road,Haerbin,Heilongjiang 150040 / CHINANET-HL
ipset add banlist 60.162.0.0/15 # CHINANET-ZJ-TZ / Zhejiang Telecom
ipset add banlist 112.8.32.0/19 # China Mobile communications corporation / CMNET / ORG-CMCC1-AP / China Mobile Communications Corporation
ipset add banlist 39.129.248.0/21 # Internet Service Provider in China / CMNET / ORG-CM1-AP / China Mobile
ipset add banlist 36.46.0.0/16 # CHINANET-SN / Beijing 100032
ipset add banlist 125.76.128.0/17 # From Shanxi(CHINANET-SN) Network of ChinaTelecom / CHINANET-SN
ipset add banlist 123.121.128.0/18 # China Unicom Beijing Province Network / UNICOM-BJ
ipset add banlist 140.75.0.0/16 # CHINANET-SD / Beijing 100032
ipset add banlist 112.88.0.0/13 # UNICOM-GD / China Unicom CHINA169 Guangdong Province Network
ipset add banlist 112.49.192.0/18 # ORG-CMCC1-AP / China Mobile Communications Corporation / CMNET / China Mobile communications corporation
ipset add banlist 113.204.0.0/14 # UNICOM-CQ / CNC Group CHINA169 Chongqing Province Network
ipset add banlist 123.149.0.0/16 # CHINANET-HA / Beijing 100032
ipset add banlist 60.14.0.0/15 # CNC Group CHINA169 Heilongjiang Province Network / UNICOM-HL
ipset add banlist 114.92.0.0/17 # Beijing 100032 / CHINANET-SH
ipset add banlist 1.56.0.0/13 # China Unicom Heilongjiang Province Network / UNICOM-HL
ipset add banlist 111.14.64.0/21 # ORG-CM1-AP / China Mobile / CMNET / China Mobile communications corporation
ipset add banlist 123.128.0.0/13 # CNC Group CHINA169 Shandong Province Network / UNICOM-SD
ipset add banlist 119.120.0.0/13 # China Telecom / CHINANET-GD
ipset add banlist 222.68.0.0/16 # CHINANET-SH / Beijing 100032
ipset add banlist 36.248.0.0/14 # UNICOM-FJ-QUANZHOU-MAN / China Unicom Fujian Province Network
ipset add banlist 221.0.0.0/15 # UNICOM-SD / CNC Group CHINA169 Shandong Province Network
ipset add banlist 113.56.0.0/15 # CNC Group CHINA169 Hubei Province Network / UNICOM-HB
ipset add banlist 223.78.192.0/18 # China Mobile / China Mobile communications corporation / CMNET / ORG-CM1-AP
ipset add banlist 112.2.128.0/19 # ORG-CMCC1-AP / CMNET / China Mobile communications corporation / China Mobile Communications Corporation
ipset add banlist 183.227.0.0/16 # CMNET / ORG-CMCC1-AP / China Mobile Communications Corporation / China Mobile communications corporation
ipset add banlist 106.46.0.0/16 # CHINANET henan province network / CHINANET-HA
ipset add banlist 123.8.0.0/13 # CNC Group CHINA169 Henan Province Network / UNICOM-HA
ipset add banlist 219.136.0.0/15 # CHINANET-GD / China Telecom
ipset add banlist 111.172.0.0/14 # CHINANET-HB / Beijing 100032
ipset add banlist 118.112.0.0/13 # Beijing 100088 / CHINANET-SC
ipset add banlist 27.148.0.0/14 # Beijing 100032 / CHINANET-FJ
ipset add banlist 153.101.0.0/16 # UNICOM-JS / China Unicom Jiangsu Province Network
ipset add banlist 221.237.0.0/16 # CHINANET-SC / Beijing 100088
ipset add banlist 121.28.0.0/15 # UNICOM-HE / CNC Group CHINA169 Hebei Province Network
ipset add banlist 61.241.192.0/19 # UNICOM / Beijing 100140 ,P.R.China
ipset add banlist 114.86.128.0/17 # CHINANET-SH / Beijing 100032
ipset add banlist 223.67.32.0/19 # CMNET / ORG-CM1-AP / China Mobile / China Mobile communications corporation
ipset add banlist 122.136.0.0/13 # UNICOM-JL / CNC Group CHINA169 Jilin Province Network
ipset add banlist 27.36.0.0/14 # China Unicom Guangdong Province Network / UNICOM-GDDG
ipset add banlist 117.147.0.0/17 # China Mobile / China Mobile communications corporation / ORG-CM1-AP / CMNET
ipset add banlist 153.3.0.0/16 # UNICOM-JS / China Unicom Jiangsu Province Network
ipset add banlist 14.112.0.0/12 # China Telecom / CHINANET-GD
ipset add banlist 183.253.0.0/19 # China Mobile Communications Corporation / China Mobile Communications Corporation / ORG-CMCC1-AP / CMNET
ipset add banlist 183.228.0.0/16 # China Mobile communications corporation / China Mobile Communications Corporation / ORG-CMCC1-AP / CMNET
ipset add banlist 221.196.0.0/15 # UNICOM-TJ / CNC Group CHINA169 Tianjin Province Network
ipset add banlist 111.196.192.0/18 # UNICOM-BJ / China Unicom Beijing Province Network
ipset add banlist 14.107.172.0/22 # CHINANET-CQ / China Telecom
ipset add banlist 114.216.66.0/23 # Beijing 100032 / CHINANET-JS
ipset add banlist 112.1.32.0/19 # China Mobile communications corporation / China Mobile Communications Corporation / CMNET / ORG-CMCC1-AP
ipset add banlist 221.182.0.0/18 # China Mobile communications corporation / China Mobile / CMNET / ORG-CM1-AP
ipset add banlist 118.72.0.0/13 # CNC Group CHINA169 Shanxi Province Network / sxyc-yongji-BAS
ipset add banlist 58.59.0.0/17 # No.999,Shunhua road,Jinan,Shandong / CHINANET-SD
ipset add banlist 111.1.96.0/20 # China Mobile / China Mobile communications corporation / ORG-CM1-AP / CMNET
ipset add banlist 36.104.0.0/16 # China Telecom / CHINANET-ZJ
ipset add banlist 117.151.16.0/20 # China Mobile / China Mobile communications corporation / CMNET / ORG-CM1-AP
ipset add banlist 119.34.128.0/17 # GZPRBNET / GuangDong, China 510010
ipset add banlist 112.0.192.0/19 # China Mobile Communications Corporation / China Mobile communications corporation / ORG-CMCC1-AP / CMNET
ipset add banlist 111.1.192.0/19 # CMNET / ORG-CM1-AP / China Mobile / China Mobile communications corporation
ipset add banlist 183.225.0.0/19 # CMNET / ORG-CMCC1-AP / China Mobile communications corporation / China Mobile Communications Corporation
ipset add banlist 58.60.0.0/14 # Beijing 100032 / CHINANET-GD
ipset add banlist 117.24.0.0/13 # CHINANET-FJ / 7,East Street ,Fuzhou ,Fujian ,PRC
ipset add banlist 112.24.224.0/19 # CMNET / ORG-CMCC1-AP / China Mobile Communications Corporation / China Mobile communications corporation
ipset add banlist 39.130.64.0/19 # Internet Service Provider in China / China Mobile / CMNET / ORG-CM1-AP
ipset add banlist 119.164.0.0/14 # UNICOM-SD / CNC Group CHINA169 Shandong Province Network
ipset add banlist 39.190.96.0/21 # China Mobile / Internet Service Provider in China / CMNET / ORG-CM1-AP
ipset add banlist 111.224.0.0/14 # Beijing 100032 / CHINANET-HE
ipset add banlist 112.0.128.0/19 # China Mobile Communications Corporation / China Mobile communications corporation / CMNET / ORG-CMCC1-AP
ipset add banlist 211.103.72.0/21 # China Mobile / CMNET / ORG-CM1-AP / China Mobile
ipset add banlist 1.202.0.0/17 # CHINANET-BJ / CHINANET Beijing Province Network
ipset add banlist 39.149.80.0/20 # CMNET / Internet Service Provider in China / ORG-CM1-AP / China Mobile
ipset add banlist 218.10.0.0/16 # UNICOM-HL / CNC Group CHINA169 Heilongjiang Province Network
ipset add banlist 36.143.46.0/23 # CMNET / China Mobile Communications Corporation / ORG-CMCC1-AP / China Mobile Communications Corporation
ipset add banlist 223.97.160.0/19 # ORG-CM1-AP / CMNET / China Mobile communications corporation / China Mobile
ipset add banlist 111.14.96.0/19 # China Mobile / ORG-CM1-AP / CMNET / China Mobile communications corporation
ipset add banlist 122.240.0.0/13 # CHINANET-ZJ-WZ / Zhejiang Telecom
ipset add banlist 120.80.0.0/13 # UNICOM-GD / CNC Group CHINA169 Guangdong Province Network
ipset add banlist 120.85.182.0/23 # China Unicom / GuangZhou-unicom
ipset add banlist 171.43.0.0/16 # China Telecom / CHINANET-HB
ipset add banlist 117.144.0.0/16 # CMNET-shanghai / China Mobile communications corporation
ipset add banlist 117.179.107.0/24 # China Mobile communications corporation / CMNET / ORG-CM1-AP / China Mobile
ipset add banlist 117.179.122.0/23 # CMNET / China Mobile communications corporation / ORG-CM1-AP / China Mobile
ipset add banlist 112.20.224.0/19 # CMNET / China Mobile communications corporation / ORG-CMCC1-AP / China Mobile Communications Corporation
ipset add banlist 111.35.224.0/20 # China Mobile communications corporation / CMNET / ORG-CM1-AP / China Mobile
ipset add banlist 223.106.128.0/18 # CMNET / China Mobile communications corporation / ORG-CM1-AP / China Mobile
ipset add banlist 61.156.0.0/16 # UNICOM-CN / CNC Group CHINA169 Shandong Province Network
ipset add banlist 111.48.77.0/24 # China Mobile / CMNET / China Mobile communications corporation / ORG-CM1-AP
ipset add banlist 36.40.0.0/14 # CHINANET-SN / Beijing 100032
2024-10-02. The situation is under control again, but since I’m vindictive, I’ll block some more.
tail -n 500 /var/log/apache2/access.log \
| grep -v ^social \
| grep "rcidonly=" \
| tail -n 50 \
| bin/admin/network-lookup > result.log
grep ipset result.log
ipset add banlist 101.16.0.0/12 # CNCGROUP-HE / China Unicom Hebei Province Network
ipset add banlist 111.18.32.0/20 # China Mobile / CMNET / China Mobile communications corporation / ORG-CM1-AP
ipset add banlist 36.16.0.0/12 # CHINANET-ZJ-TZ / Zhejiang Telecom
ipset add banlist 112.20.96.0/19 # CMNET / China Mobile communications corporation / ORG-CMCC1-AP / China Mobile Communications Corporation
ipset add banlist 223.67.224.0/19 # China Mobile communications corporation / CMNET / ORG-CM1-AP / China Mobile
ipset add banlist 36.132.168.0/22 # China Mobile Communications Corporation / CMNET / China Mobile Communications Corporation / ORG-CMCC1-AP
ipset add banlist 123.120.0.0/18 # China Unicom Beijing Province Network / UNICOM-BJ
ipset add banlist 111.43.144.0/24 # ORG-CM1-AP / CMNET / China Mobile communications corporation / China Mobile
ipset add banlist 116.231.0.0/16 # Beijing 100032 / CHINANET-SH
ipset add banlist 39.149.0.0/20 # ORG-CM1-AP / CMNET / Internet Service Provider in China / China Mobile
ipset add banlist 223.73.84.0/22 # ORG-CM1-AP / CMNET / China Mobile communications corporation / China Mobile
ipset add banlist 218.8.0.0/15 # UNICOM-HL / CNC Group CHINA169 Heilongjiang Province Network
ipset add banlist 36.132.166.0/23 # China Mobile Communications Corporation / ORG-CMCC1-AP / China Mobile Communications Corporation / CMNET
ipset add banlist 58.22.0.0/15 # CNCGROUP-FJ-XIAMEN-MAN / CNCGroup FuJian province network
ipset add banlist 117.143.52.0/22 # China Mobile communications corporation / CMNET-shanghai
ipset add banlist 111.41.34.0/24 # ORG-CM1-AP / China Mobile communications corporation / CMNET / China Mobile
ipset add banlist 125.40.0.0/13 # UNICOM-HA / CNC Group CHINA169 Henan Province Network
ipset add banlist 171.40.0.0/15 # China Telecom / CHINANET-HB
ipset add banlist 112.64.0.0/17 # Addresses from APNIC / UNICOM-SH
ipset add banlist 117.179.181.0/24 # ORG-CM1-AP / CMNET / China Mobile communications corporation / China Mobile
ipset add banlist 223.66.192.0/19 # China Mobile / ORG-CM1-AP / CMNET / China Mobile communications corporation
ipset add banlist 111.33.0.0/17 # China Mobile / CMNET / China Mobile communications corporation / ORG-CM1-AP
ipset add banlist 101.44.160.0/20 # Huawei-Cloud-SG / HUAWEI INTERNATIONAL PTE. LTD.
ipset add banlist 36.106.148.0/23 # CHINANET TIANJIN PROVINCE NETWORK / CHINANET-TJ
ipset add banlist 117.179.33.0/24 # ORG-CM1-AP / CMNET / China Mobile communications corporation / China Mobile
ipset add banlist 124.114.0.0/16 # Beijing 100088 / CHINANET-SN
ipset add banlist 223.89.192.0/18 # ORG-CM1-AP / China Mobile communications corporation / CMNET / China Mobile
ipset add banlist 118.248.0.0/13 # Beijing 100032 / CHINANET-HN
ipset add banlist 223.81.128.0/19 # China Mobile / ORG-CM1-AP / CMNET / China Mobile communications corporation
ipset add banlist 223.74.216.0/22 # China Mobile communications corporation / CMNET / ORG-CM1-AP / China Mobile
ipset add banlist 111.41.14.0/23 # ORG-CM1-AP / CMNET / China Mobile communications corporation / China Mobile
ipset add banlist 223.74.103.0/24 # China Mobile / ORG-CM1-AP / CMNET / China Mobile communications corporation
ipset add banlist 223.74.72.0/21 # CMNET / China Mobile communications corporation / ORG-CM1-AP / China Mobile
ipset add banlist 39.130.96.0/19 # China Mobile / CMNET / Internet Service Provider in China / ORG-CM1-AP
ipset add banlist 221.228.192.0/20 # CHINANET-JS / Beijing 100088
ipset add banlist 180.175.0.0/16 # CHINANET-SH / Beijing 100032
ipset add banlist 112.100.0.0/14 # NO.178 Zhongshan Road,Haerbin,Heilongjiang 150040 / CHINANET-HL
ipset add banlist 223.95.192.0/19 # China Mobile / China Mobile communications corporation / CMNET / ORG-CM1-AP
ipset add banlist 111.34.192.0/20 # China Mobile communications corporation / CMNET / ORG-CM1-AP / China Mobile
ipset add banlist 111.36.160.0/20 # ORG-CM1-AP / CMNET / China Mobile communications corporation / China Mobile
ipset add banlist 111.17.64.0/19 # ORG-CM1-AP / China Mobile communications corporation / CMNET / China Mobile
ipset add banlist 101.69.0.0/16 # UNICOM-ZJ / China Unicom Zhejiang Province Network
ipset add banlist 112.116.0.0/15 # CHINANET-YN / Beijing 100032
ipset add banlist 111.14.144.0/20 # China Mobile / ORG-CM1-AP / China Mobile communications corporation / CMNET
ipset add banlist 111.18.0.0/16 # China Mobile / ORG-CM1-AP / CMNET / China Mobile communications corporation
ipset add banlist 220.192.0.0/18 # China Unicom Network / UNICOM
ipset add banlist 123.118.0.0/18 # China Unicom Beijing Province Network / UNICOM-BJ
2024-10-10. Load is at 30 again. Another round!
ipset add banlist 14.208.0.0/12 # CHINANET-GD / China Telecom
ipset add banlist 113.0.0.0/13 # CNC Group CHINA169 Heilongjiang Province Network / UNICOM-HL
ipset add banlist 223.81.240.0/20 # China Mobile communications corporation / ORG-CM1-AP / China Mobile / CMNET
ipset add banlist 112.38.0.0/16 # ORG-CMCC1-AP / China Mobile communications corporation / CMNET / China Mobile Communications Corporation
ipset add banlist 222.129.0.0/18 # UNICOM-BJ / China Unicom Beijing Province Network
ipset add banlist 117.176.208.0/21 # CMNET / China Mobile / China Mobile communications corporation / ORG-CM1-AP
ipset add banlist 153.34.0.0/15 # UNICOM-JS / China Unicom Jiangsu Province Network
ipset add banlist 116.149.128.0/17 # China Unicom CHINA169 Network / UNICOM
ipset add banlist 182.112.0.0/12 # China Unicom Henan Province Network / UNICOM-HA
ipset add banlist 112.51.16.0/20 # China Mobile communications corporation / ORG-CMCC1-AP / China Mobile Communications Corporation / CMNET
ipset add banlist 39.190.112.0/21 # China Mobile / CMNET / Internet Service Provider in China / ORG-CM1-AP
ipset add banlist 112.65.0.0/17 # UNICOM-SH / Addresses from APNIC
ipset add banlist 223.88.192.0/18 # China Mobile / CMNET / China Mobile communications corporation / ORG-CM1-AP
ipset add banlist 111.33.192.0/18 # CMNET / China Mobile / ORG-CM1-AP / China Mobile communications corporation
ipset add banlist 114.88.0.0/17 # CHINANET-SH / Beijing 100032
ipset add banlist 36.32.0.0/14 # UNICOM-AH / China Unicom Anhui Province Network
ipset add banlist 61.174.0.0/15 # YINXIAN-MINGHUI-LTD / Ningbo Minghui International Trade Co.,Ltd
ipset add banlist 112.98.0.0/15 # NO.178 Zhongshan Road,Haerbin,Heilongjiang 150040 / CHINANET-HL
ipset add banlist 39.163.64.0/20 # China Mobile / CMNET / ORG-CM1-AP / Internet Service Provider in China
ipset add banlist 117.179.8.0/21 # ORG-CM1-AP / China Mobile communications corporation / China Mobile / CMNET
ipset add banlist 117.179.249.0/24 # ORG-CM1-AP / China Mobile communications corporation / China Mobile / CMNET
ipset add banlist 42.185.0.0/16 # CHINANET-HL / NO.178 Zhongshan Road,Haerbin,Heilongjiang 150040
ipset add banlist 218.58.0.0/15 # CNC Group CHINA169 Shandong Province Network / UNICOM-SD
ipset add banlist 211.143.180.0/22 # CMNET-fujian / China Mobile communications corporation
ipset add banlist 223.167.0.0/16 # China Unicom Shanghai Province Network / UNICOM-SH
ipset add banlist 112.49.128.0/17 # China Mobile communications corporation / ORG-CMCC1-AP / China Mobile Communications Corporation / CMNET
ipset add banlist 223.96.128.0/20 # China Mobile / CMNET / ORG-CM1-AP / China Mobile communications corporation
ipset add banlist 117.152.240.0/20 # China Mobile communications corporation / ORG-CM1-AP / CMNET / China Mobile
ipset add banlist 117.179.38.0/23 # China Mobile / CMNET / ORG-CM1-AP / China Mobile communications corporation
ipset add banlist 39.148.48.0/20 # China Mobile / CMNET / ORG-CM1-AP / Internet Service Provider in China
ipset add banlist 223.80.192.0/18 # ORG-CM1-AP / China Mobile communications corporation / CMNET / China Mobile
ipset add banlist 112.20.64.0/19 # CMNET / China Mobile Communications Corporation / China Mobile communications corporation / ORG-CMCC1-AP
ipset add banlist 144.52.0.0/16 # Beijing 100032 / CHINANET-SD
ipset add banlist 36.100.96.0/22 # China Telecom / CHINANET-ZJ
ipset add banlist 60.168.0.0/13 # CHINANET-AH / Beijing 100088
ipset add banlist 61.159.192.0/18 # CHINANET Yunnan province network / CHINANET-YN
ipset add banlist 125.36.0.0/14 # CNC Group CHINA169 Tianjin Province Network / UNICOM-TJ
ipset add banlist 124.236.0.0/14 # CHINANET-HE / Beijing 100032
ipset add banlist 183.226.0.0/16 # China Mobile communications corporation / ORG-CMCC1-AP / CMNET / China Mobile Communications Corporation
ipset add banlist 223.166.0.0/16 # UNICOM-SH / China Unicom Shanghai Province Network
ipset add banlist 218.93.0.0/16 # CHANGZHOU-Xinhua-bookshop-CORP / Jiangsu Province
ipset add banlist 39.183.128.0/19 # China Mobile / CMNET / Internet Service Provider in China / ORG-CM1-AP
ipset add banlist 180.160.0.0/13 # CHINANET-SH / Beijing 100032
ipset add banlist 223.73.56.0/21 # China Mobile communications corporation / ORG-CM1-AP / CMNET / China Mobile
-1:-- 2024-09-18 Emacs Wiki and China (Post)--L0--C0--October 11, 2024 09:56 AM
In my previous post about creating simple functions to create a new directory and file in dired
, I received an interesting comment suggesting another way to bypass the potential messiness of completion and pass through the literal text input.
My last post :
Simple Directory and File Creation in Dired
It is a subtlety of most if not all completion systems, and that is to exit with any input, hence exiting without having to necessarily match and complete.
Given this, and given that I’m using the completion framework of vertico
, I thought I would revisit the vertico github manual : https://github.com/minad/vertico
and I find :
M-RET -> vertico-exit-input
vertico-exit-input exits with the minibuffer input instead. Exiting with the current input is needed when you want to create a new buffer or a new file with find-file or switch-to-buffer. As an alternative to pressing M-RET, move the selection up to the input prompt by pressing the up arrow key and then press RET.
Well this is exactly the issue I was having and why I wrote my two little simple functions. Now if I build in M-RET into my muscle memory (which already seems pretty natural), I can refine my Emacs init, while adhering more to vanilla Emacs concepts. Also as I now am being more idiomatic, I suspect the M-RET keybinding may just come in handy at some point in the future.
So, now rebinding dired-mode-map
as follows:
("_" . dired-create-empty-file)
This is all that is required; note that dired-create-directory
is already bound to my preferred keybinding.
So continues the evolution of my Emacs understanding!
As a side-ish note, I have found that writing this blog provides not only an opportunity to explore a topic further and thoroughly understand it, thereby enabling me to articulate the subject fully, but also to receive comments and discover subtle nuances that I hadn’t realized existed or hadn’t thought to explore!
-1:-- Simple Directory and File Creation Using Vertico Completion Exit With Input (Post James Dyer)--L0--C0--October 09, 2024 07:30 PM
Four years ago I wrote about James Gill’s list of Emacs resources for writers. It was a curated list of resources that addressed writing prose of various sorts with Emacs. In April, I revisited the list. Judging from what I wrote, I had forgotten about my first post.
Now, I’m writing about it again because of Gill’s latest post about the list. In it, he says that surprisingly to him, that repository is the most popular of all his Github repositories. It’s not surprising to me because it’s a really great resource.
What was surprising to me, as I read down the his list, is how any are things that I have written about on Irreal. You may or may not think of that as an indication of quality but one thing for sure, it’s indicative of how interesting they are to me.
Regardless, if you use Emacs to write prose—for a blog, for reports, for articles, or even for books—you should take a look at this list. There’s sure to be something useful to you in it.
-1:-- Writing With Emacs Redux (Post jcs)--L0--C0--October 09, 2024 03:21 PM
In a typical spreadsheet app, a common user interface practice is to avoid forcing the user to keep track of cell references as much as possible. This is usually seen in selecting a range of cells to construct a formula, where the user only needs to control the range of selection; the app keeps track of which cell references to pass into the formula.
Sadly, this feature is not available by default in Org tables. But no need to fret; Emacs and Org give you the mechanisms to build a reasonable emulation of spreadsheet-style cell range selection. This post shows you how.
Before going into details, here’s a demo of selecting a row of values and using that selection to compute its sum.
| a | b | c | Total |
|---+---+---+-------|
| 1 | 5 | 2 | |
| 3 | 4 | 1 | 8 |
| 8 | 1 | 2 | |
#+TBLFM: $4=vsum(@3$1..@3$3)
In the example above the following steps are taken:
vsum()
.vsum
here stands for vector sum.C-M-mouse-1
lets you mouse select a rectangle? I didn't until recently 🤯.@3$1..@3$3
).kill-ring
.vsum()
.TAB
or RET
to compute the formula.Some observations:
#+TBLFM:
left-hand-side (lhs) is populated with only the column after step 6.@3$4
to specify that the formula should only apply to that cell.org-table-edit-formulas
has been made. Details at end of this post.cc/copy-org-table-reference-dwim
to convert a text region into an Org table reference.Intrigued? Okay, let’s do this.
First off, let’s understand how Org tables address cells. A table cell is addressed using the following representation:
@ROW$COLUMN
A row is prefixed with @
whereas a column is prefixed with $
. The row specification is placed before the column specification which is opposite of what's seen in conventional spreadsheets and Cartesian coordinates that specify the column first, then the row. Anyways, water under the bridge. With Org tables, it is always row first, column second.
A reference to an individual cell is called a field reference.
A reference to a set of cells is called a range reference. A range reference is constructed from two field references, where a and c are row values, b and d are column values.
@a$b..@c$d
Range references are translated into a vector of values that can be fed into Calc vector functions. Typically the two field references in a range reference are either in the same row or column. If not, then the vector of values is constructed using the two field references as a bounding box.
Most importantly, a range reference specifies values in a single vector. The orientation (row or column) of a range reference matters. To clarify, this is best illustrated by example.
#+NAME: vector-example
| a | b | c |
|---+---+---|
| 1 | 2 | 3 |
| 4 | 5 | 6 |
| 7 | 8 | 9 |
| Range | Vector | Notes |
|------------+--------------+--------------------------------------------------------|
| @2$1..@2$3 | [1, 2, 3] | Cell values taken left to right. |
| @2$2..@4$2 | [2, 5, 8] | Cell values "sliced" wrt column specification. |
| @3$2..@4$3 | [5, 6, 8, 9] | Cell values taken using the extents as a bounding box. |
#+TBLFM: @2$2=remote(vector-example, @2$1..@2$3)
#+TBLFM: @3$2=remote(vector-example, @2$2..@4$2)
#+TBLFM: @4$2=remote(vector-example, @3$2..@4$3)
With the background out of the way, let’s put down some requirements.
Given an active region within an Org table, translate it to a range reference with the following specifics:
Support both a mouse menu and mini-buffer command interface for obtaining an Org table region reference from a selected text region.
As a table is a convenient representation of a matrix, the above requirements makes the design decision to reflect that in mapping a text region having multiple rows and columns to a vector of vectors instead of a single vector.
Here’s code that meets the requirements described above. Commands of note:
cc/copy-org-table-reference-dwim
cc/mouse-copy-org-table-reference-dwim
Given a point or region (text or rectangle) in an Org table, either of the two commands will create an Org table reference and push it in the kill-ring
. The first command is intended to be called from the keyboard, the second from a mouse menu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
|
AMENDED 2024-10-10: cc/copy-org-table-reference-dwim
and cc/mouse-copy-org-table-reference-dwim
modified to insert content into table formula buffer when org-table-edit-formulas
is called.
The following abridged code illustrates how one could configure their context menu to show the current Org table reference and copy it into the kill-ring
if selected. See Customizing the Emacs Context Menu for more on Emacs context menus.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
All code running on Emacs 29.4.
The following table illustrates the result of selecting the text region between the cell with value 2
(@2$2
) and the cell with value 12
(@4$4
) and inserting its translated Org table reference into different formulas.
The first formula in @2$5
is just the matrix representation between 2
and 12
.
The second formula takes the transpose (trn
) of the first formula.
The third formula uses some matrix arithmetic to get the sum of each row of the matrix in @2$5
.
#+NAME: matrix-example
| a | b | c | d | result |
|---+----+----+----+--------------------------------------|
| 1 | 2 | 3 | 4 | [[2, 3, 4], [6, 7, 8], [10, 11, 12]] |
| 5 | 6 | 7 | 8 | [[2, 6, 10], [3, 7, 11], [4, 8, 12]] |
| 9 | 10 | 11 | 12 | [9, 21, 33] |
#+TBLFM: @2$5=vec(@2$2..@2$4, @3$2..@3$4, @4$2..@4$4)
#+TBLFM: @3$5=trn(vec(@2$2..@2$4, @3$2..@3$4, @4$2..@4$4))
#+TBLFM: @4$5=@2$5 * [1 1 1]
Manually dealing with Org table references is both tedious and error-prone. Automating their generation using text range selection seems like a good way to make this more bearable. If you're comfortable with Elisp, I recommend you give this code a try.
I’m considering publishing this code as a package on MELPA but I think the utility of it is high enough to merit being in Org itself. For next steps, I look forward to finding out if that is true.
In sharing this post at the 2024-10-09 Org Meetup, I was made aware by Ihor Radchenko that the point position in the special buffer (named *Edit Formulas*
) created by the org-table-edit-formulas
command (binding C-c '
) will highlight any field or range reference. This special buffer provides context from which we can enhance the commands cc/copy-org-table-reference-dwim
and cc/mouse-copy-org-table-reference-dwim
to insert their results directly into it, removing the step to yank. cc/mouse-copy-org-table-reference-dwim
is further enhanced to check if the point in *Edit Formulas*
is also at the beginning of a line. If so, then the inserted field reference will be treated as the lhs argument of a formula. This approach can be viewed as a workaround the direct entry of a formula in a cell with the "=" character, which will only insert in the lhs a column reference.
-1:-- Referencing Org Table Cells with Text Regions (Post Charles Choi)--L0--C0--October 08, 2024 06:00 PM
I'm tweaking my video workflow. I use Orgzly Revived on my Android phone to write the text, and I use Easy Voice Recorder to record it. Syncthing automatically copies both to my laptop. I use WhisperX to transcribe my recording, and I use a little bit of Emacs Lisp to figure out timestamps for each word. I edit this to fix errors. I can even rearrange things and get rid of umms or ahs or anything I don't want.Then I use subed-convert to turn it into a VTT file. I can tweak the start and end times by looking at the waveforms. Then I add comments with the visuals I want. I can add images, animated GIFs, or videos, and they're automatically squeezed or stretched to fit. I can also have them play at original speed. Then I set up open captions and use subed-record-compile-video. Tada!
Links:
You can watch this on YouTube, download the video, or download the audio.
-1:-- Yay Emacs 5: Tweaking my video workflow with WhisperX and subed-record (Post Sacha Chua)--L0--C0--October 07, 2024 06:16 PM
A frequent complaint we hear from n00bs is that Emacs out of the box is unusable, that it’s really hard to configure, and so you need something like Doom to get going. Generations of Emacs users have put the lie to that. Lots of us have been starting with vanilla Emacs and configuring it to our needs for 40 years.
Over at the Emacs subreddit, permetz suggests that it’s fine to have a simple configuration that builds on default Emacs. Permetz has been using Emacs since 1983 and considers himself a power user but he has a simple config file that mostly consists of setting a few variables to adjust things to his liking.
That’s how I started. Back then I was still writing in C so I spent a bit of time getting Emacs to indent C the way I liked. As I went along I added some packages and wrote some custom Elisp for bespoke operations that no one else would need. Even so, after 16 or 17 years my init.el
is still pretty small and I could easily trim it down by getting rid of stuff I no longer need or use.
Permetz’s message is don’t be afraid of starting small from vanilla Emacs and having a simple configuration. You’ll be surprisingly productive and your init.el
can grow organically as your needs change.
-1:-- Emacs Configuration Can Be Easy (Post jcs)--L0--C0--October 07, 2024 04:56 PM
Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Mastodon #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, communick.news, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!
-1:-- 2024-10-07 Emacs news (Post Sacha Chua)--L0--C0--October 07, 2024 12:22 PM
Wait. What? Is Lisp syntax boring? My immediate response is, “Of course it is.” That’s its strength. Lisp doesn’t have much syntax so unlike other languages you can immediately start using the language without having to worry about learning a bunch of syntax rules. Everybody who’s learned a non-Lisp language knows that a significant part of learning the language is imbibing the syntax. An advantage of Lisp is that you can mostly avoid that step.
You’d think that would be obvious to anyone with a passing familiarity with Lisp but apparently not. Aggravating_Date_315 over at the Emacs subreddit asks if anyone else finds Lisp syntax boring. Not in the sense that I do but that there’s not enough structure and sugar. He wants superfluous keywords and structure because the simplicity of Emacs is boring. He loves how easy it is to edit Elisp in Emacs but finds Lisp joyless and sterile.
The commenters were not particularly supportive although a few did offer some suggestions for dealing with the matter. My favorite was from intergalactic_llama who says, “People looking to create problems for them selves always fascinate me.”
I don’t understand how anyone could think that making something more complicated would make it more natural and fun. To me, the joy of programming is writing code to solve a problem and I have no interest in making that code more convoluted than it needs to be.
-1:-- 🥩 Red Meat Friday: Is Lisp Syntax Boring (Post jcs)--L0--C0--October 04, 2024 02:24 PM
Since I started using Emacs, I’ve written hundreds of functions that I only used once and then were left to rot in the depths of my init.el
.
Today I would like to share some simple commands that I wrote when I was just starting off with Emacs that I had forgotten that I had written and assumed that this was the default behaviour as it now seems to natural to me.
A very small amount of the code here will be specific to evil-mode
, but it shouldn’t be too difficult to adapt it to work without.
I like to have a clean, distraction free reading experiences in major-modes such as elfeed
, eww
, and nov
.
I achieve this by:
I use olivetti
for centring text and have no complaints.
It works seamlessly for my needs.
In fact, I also enable this in Org-Mode and Markdown-Mode.
(defun my/centre-visual-fill-on ()
;; Centre the text in one column
(visual-line-mode 1)
(setq olivetti-body-width 100)
(olivetti-mode 1))
(defun my/centre-visual-fill-off ()
(visual-line-mode 0)
(kill-local-variable 'olivetti-body-width)
(olivetti-mode 0))
I’ve seen lots of people do this one and it is useful when wanting to focus. Unlike the previous commands, this is something that I sometimes toggle so I made an interactive function too.
(defun my/kill-modeline ()
(setq-local mode-line-format nil))
(defun my/restore-modeline ()
(kill-local-variable 'mode-line-format))
(defun my/toggle-modeline ()
(interactive)
(if (null mode-line-format)
(my/restore-modeline)
(my/kill-modeline)))
This is one that I don’t remember seeing anybody else do, but it’s a game changer. When I’m reading, I’m following with my eyes and I don’t care where the cursor is unless I decide that I want to highlight some text. Again, I want to be able to toggle this quickly so I wrote an interactive function too.
(defun my/hide-cursor-evil ()
(setq-local evil-default-cursor '(ignore))
(setq-local cursor-type nil))
(defun my/show-cursor-evil ()
(kill-local-variable 'evil-default-cursor)
(kill-local-variable 'cursor-type))
(defun my/toggle-cursor ()
(interactive)
(if (null cursor-type)
(my/show-cursor-evil)
(my/hide-cursor-evil)))
I combine these three ideas into a simple hook that gets ran whenever I open a new buffer in one of my reading modes.
(defun my/reading-mode-hook ()
(my/centre-visual-fill-on)
(my/hide-cursor-evil)
(my/kill-modeline))
I’ve seen takes on the previous ideas many times while reading other Emacs users' blogs, but I haven’t seen many users describe how they move around buffers that are primarily meant to be read.
Initially I tried using a form of paging, but I found it tedious to have to scan for where I left off before I scrolled down.
Ultimately, I settled on the following logic, which was very simple to implement:
(defun my-view-down ()
(interactive)
(if (null cursor-type)
(scroll-up-line)
(next-line)))
(defun my-view-up ()
(interactive)
(if (null cursor-type)
(scroll-down-line)
(previous-line)))
I could have come up with a minor mode for enabling this in each major mode, but I like how this reminds me of a time when I didn’t spend so long dicking about with functions that I only use once.
Here is a simple example configuration of how I have elfeed
set up.
(use-package elfeed
:hook
(elfeed-show-mode . my/reading-mode-hook))
(evil-define-key 'normal elfeed-show-mode-map (kbd "j") 'my-view-down)
(evil-define-key 'normal elfeed-show-mode-map (kbd "k") 'my-view-up)
-1:-- Useful Emacs commands for reading (Post)--L0--C0--October 04, 2024 12:00 AM
As those of you who have been around for awhile know, Irreal has a fascination with fonts for Emacs. I most recently wrote about them here. But, all those posts have been about coding fonts. Today, I want to talk about proportional fonts.
You can, of course use proportional fonts for coding but it’s mostly Rob Pike and his disciples that champion that. Still, most of use proportional fonts for everything else. Recently, Charles Choi even convinced me to write my posts in a proportional font.
This post was inspired by an article on the Atkinson Hyperlegible Font. It’s a font developed by the Braille Institute for low vision readers. Those of us without vision problems should also take notice because the font really is easy to read and, most importantly, it’s easy to distinguish among those hard to discern characters that I use to decide if a font is acceptable for programming use.
It’s usually not as important to distinguish them in a prose environment but most programmers are anal about things like that and would prefer having clarity in all the text that they read. Take a look at the Atkinson Hyperlegible Font article to see it in action and to see how well it distinguishes among all those problematic characters.
For me, one of the worst problems with proportional fonts is telling the difference between capital I (eye) and lowercase l (ell). As I write this in Emacs using my proportional font, those two letters look virtually the same. That’s a problem I wouldn’t have if I were using Inconsolata, my coding font. Atkinson Hyperlegible makes the difference clear. That alone is worth adopting the font.
You can download the font for free but the Braille Institute would appreciate a contribution. This seems like a great font and is worth a contribution to help the Institute in their work.
-1:-- The Atkinson Hyperlegible Font (Post jcs)--L0--C0--October 03, 2024 03:43 PM
-1:-- Essential Movement and Editing Shortcuts in Emacs - EP5 (Post Discovering Emacs)--L0--C0--October 02, 2024 08:05 PM
No! Not ewwwwwwwww! But EWW (or eww). It's the text browser which comes in Emacs, and it's fantastic for quickly reading articles and doing even more than that.
Recently, I started using it every day. Here's a quick summary of how I work:
Here's the code to open a link in Emacs with either your preferred browser or eww:
;; Open link in eww or browser
(defun open-link-at-point-or-minibuffer-with-choice ()
"Use `consult` to select a link at point, in the buffer, from `consult-omni` results, or prompt for a URL.
Then choose to open it in macOS default browser or eww.
If 'eww' is chosen, the link is opened in a window that occupies 80% of the frame height below the current one."
(interactive)
(let* ((url (or (thing-at-point 'url) ;; Check if there's a URL at point
(consult--read (thing-at-point--list 'url)) ;; Use consult to select a URL from the buffer
(consult-omni) ;; Use consult-omni results to select a link
(read-string "Enter URL: ")))) ;; Fall back to manual URL entry
(if url
(let ((choice (completing-read "Open link in: " '("macOS Browser" "eww"))))
(cond
((string-equal choice "macOS Browser")
(shell-command (concat "open " (shell-quote-argument url))))
((string-equal choice "eww")
;; Calculate the height for the top window (20% of the frame height)
(let ((window (selected-window))
(top-window-height (floor (* 0.2 (window-total-height)))))
;; Split window with 20% height on top and 80% height for eww on the bottom
(select-window (split-window window top-window-height))
(eww url)))))
(message "No URL provided."))))
And here's a handy little bit of extra code. I've tied this to C-q w c (for window close), so I don't get a ton of eww buffers hanging around if I just want to close the article after I'm done, but it's handy for any window closing as well:
;; close buffer and window
(defun close-buffer-and-window ()
"Close the current buffer and the window it's in."
(interactive)
(let ((window (selected-window)))
(kill-buffer) ;; Kill the current buffer
(when (window-live-p window) ;; Check if the window is still live
(delete-window)))) ;; Delete the window if it exists
Now, like I said, I tie these to my universal key binding which is C-q for me as it's super fast and easy to type if you use Caps Lock as your Control key (which I do). But I'll leave that up to you on how you want to do that.
Here's where I got the "capture URL to inbox" setup. It's for Mac but I'm sure Linux users can mod it to suit their needs.
Mac Owner's Club: Org capture from everywhere in macOS
And here's the post where I got the "send Safari url to eww". He uses Chrome but the Mac Owners Club guy posts the Safari snippet at the bottom of the page. Also, keep in mind that you want to take -c
out of the Applescript if you want it to appear in the existing frame, or it'll create a new frame when it opens up eww with the link.
Github: agzam/send-browser-urls-to-emacs-eww
I want to thank those guys because it's made Emacs and MacOS even better than ever before. 🙃
And since I just posted it on Mastodon, I'll include this really nice link of text-based sites for different kinds of sources (NPR, CNN, NYT, and other places including tech ones):
Greycoder: A List Of Text-Only & Minimalist News Sites
Remember: with any page in eww, you can just use Emacs Bookmarks to get to it immediately again. So if you want to check NYT articles daily or even a few times a day, just head to that portal, bookmark it with like nyt
and then use that as your instant news source for them. Get into the habit of using bookmarks, people! (Thank you for reminding me of this use, Fade@libera).
That's all for today!
👋
-1:-- Open with EWW (Post)--L0--C0--October 01, 2024 11:00 PM
One of the activities that Irreal encourages is the sanding down of friction points. Despite that, I’m almost always surprised when I do automate some routine task and wonder why I waited so long to do it. If you’ve been around Irreal for a while, you’ve seen me write about that several times.
Over at dyerdwelling there’s a handy post on how to sand down one set of friction points. His particular friction point is creating directories and files from within Dired. That’s possible, of course, but the various completion engines can trip you up but substituting your choice for an existing file or directory with a name that matches in the fuzzy sense.
His solution is to define two new functions that ask for the directory or file name without invoking completion. The code is simple, short, and easy to understand. If you use Dired to creat files and directories, take a look at this post
-1:-- File And Directory Creation In Dired (Post jcs)--L0--C0--October 01, 2024 04:11 PM
Previously I wrote about the incompatibility of some Emacs themes with the tab-bar and my temporary fix:
The tab bar was introduced in Emacs 27.1, during which I created a function to apply some simple logic to make the tabs look moderately decent and fit in with the new theme. The only thing I couldn’t figure out was how to activate the function after a theme load, as there didn’t seem to be a hook.
Well, actually there does seem to be such a hook and it seems to have gone into Emacs 29. As with a lot of these little tweaks I found this on reddit in the emacs subreddit:
https://www.reddit.com/r/emacs/comments/1ft3wwm/did_the_much_needed_theme_change_hook_arrive_with/
From my previous post I wrote :
Now that the
defun
is available, how to activate it? My first thought was to add a hook for when a theme is loaded, but there doesn’t seem to be such a feature!? I also tried advising around `load-theme`, but that didn’t go well either, it worked for themes that were not loaded, but for those that were, a change in state was not detected, and the tab theme tweak was not applied.
The solution is to simply add the following to your init file. Now that I know about this, I might even find some other use for it.
(defun my/after-theme-loaded(theme)
(my/sync-tab-bar-to-theme))
(add-hook 'enable-theme-functions 'my/after-theme-loaded)
with the original my/sync-tab-bar-to-theme
as follows:
(defun my/sync-tab-bar-to-theme ()
"Synchronize tab-bar faces with the current theme."
(interactive)
(let ((default-bg (face-background 'default))
(default-fg (face-foreground 'default))
(inactive-fg (face-foreground 'mode-line-inactive))) ;; Fallback to mode-line-inactive
(custom-set-faces
`(tab-bar ((t (:inherit default :background ,default-bg :foreground ,default-fg))))
`(tab-bar-tab ((t (:inherit default :background ,default-fg :foreground ,default-bg))))
`(tab-bar-tab-inactive ((t (:inherit default :background ,default-bg :foreground ,inactive-fg)))))))
My tab theme fix is now activated on every theme load, and I no longer have to rely on muscle memory to make Emacs look colour-coherent when changing themes, which I do a lot!! 😀
-1:-- Syncing Tab Theme After Theme Load (Post James Dyer)--L0--C0--October 01, 2024 08:50 AM
It just works. — Steve Jobs
If you follow this blog, you’ll know that I’m doing a series called “Emacs
Config From Scratch”1.
Emacs is an editor operating system, where you can configure and customize
literally everything.
I like that you can truly make it yours, but it’s a lot of work to get there.
Recently, I’ve become fond of (command line) tools that just work, out of the box2. This blogpost is an ode to them.
Julia Evans recently posted Reasons I still love the fish shell, and the first point she makes is “no configuration”.
Things that require plugins and lots of code in shells like ZSH, like autosuggestions, are included and configured by default in fish. At the time of writing this, my fish config has less than 31 loc, most of which are abbreviations.
I have two fish plugins configured: z for jumping to a directory, and hydro as my shell prompt. Neither need configuration.
My Neovim config had 21 external plugins. Making LSP, tree-sitter and formatting work took a while (LSP alone needs 3 plugins) and in the end there were still things that didn’t work.
I’ve switched to Helix, which can do so much out of the box, here’s a non-exhaustive list:
The config for the code editor I use all day is 5 loc. Here it is:
= "kanagawa"
[]
= "relative"
= true
= [80]
I will say that it takes some getting used to as it folows the selection -> action
model, i.e. you need to run wd
instead of dw
to delete the next
word.
After raving about Magit in London, my team showed me Lazygit and I’ve been using it ever since—it’s really good and it does exactly what you want it to do, without configuration3.
You can toggle different screen modes, panes adjust in size when active and pretty much everything you want to do is only a few keystrokes away.
A batteries-included Tmux alternative, Zellij doesn’t need any configuration to work well. You can set up Layouts without additional plugins (although there is a plugin system) and I’m generally not missing anything from my Tmux configuration.
My favorite feature is the floating panes. Press Ctrl + p, w
to toggle a
pane floating on top of everything else—I often use this for Lazygit.
Here are some tools you have sent me that are zero/minimal config:
Do you have a tool that requires no (or minimal) configuration? Send me an email and I’ll add it to the list!
And if you’re building something, please strive to make the default experience work really well for most people.
-1:-- We need more zero config tools (Post Arne Bahlo)--L0--C0--October 01, 2024 12:00 AM
Paul E. Johnson is a member of the Political Science Department at the University of Kansas. As such, he’s not a canonical Emacs user but he has a provacative set of slides that suggests that, in fact, Emacs doesn’t have a steep learning curve. Or, at least, it needn’t have one.
His thesis is that one can use Emacs with more or less “standard” keybindings by using the arrow and other special purpose keys and by turning on CUA mode to make Emacs input more like “modern” apps.
That’s all true, of course, but it strikes me as riding a bicycle with training wheels. Yes, you can ride around and do bicycle-like things but you can’t really call yourself a bicycle rider. Even Johnson recognizes this and notes that you’re going to want to learn at least some of those native Emacs commands.
When I learned to ride a bike, I didn’t use training wheels and I don’t recommend them for new Emacs users either. Sometimes you just need to grasp the nettle and push through the pain. The benefit is that at the other end you can ride a bike or use Emacs well.
Still, Johnson has a point. It’s possible to start using Emacs without having to learn all those bespoke keybindings. The question is whether that’s the best path forward. I think not but obviously others disagree and I’m willing to stipulate that they may be right, at least for some people.
-1:-- Emacs Has No Learning Curve (Post jcs)--L0--C0--September 30, 2024 02:58 PM
Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Mastodon #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, communick.news, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!
-1:-- 2024-09-30 Emacs news (Post Sacha Chua)--L0--C0--September 30, 2024 02:02 PM
A couple of weeks ago, I wrote about Protesilaos Stavrou’s excellent post on triggering an Emacs popup from anywhere in your system. It’s perfect for Org capture and other things you might want to do when you’re in some other app. I have something similar specialized to Org capture and Phil in the comments said he also has a few bespoke popups. The advantage of Prot’s framework is that it’s easy to invoke any Emacs command from outside of Emacs.
Grant Rosson liked the idea but found that Prot’s Linux based code didn’t port directly to macOS and he presented the code for the minimal changes required to get things working on a Mac. Despite what some folks seem to think, Mac users are a significant portion of the Emacs community so his changes are welcome for those of us using macOS.
Rosson gives some examples of commands other than Org capture that may give you some ideas. What I really like about Prot’s and Rosson’s frameworks is that they help you move as many chores as possible into Emacs. A lot of that simply boils down to being able to enter text in a reasonable—by which I mean Emacs—environment.
If you’re a Mac user and interested in being able to popup a temporary Emacs frame to do whatever you need to do, take a look at Prot’s video and Rosson’s post. You’ll be glad you did.
-1:-- Emacs Popups In macOS (Post jcs)--L0--C0--September 29, 2024 03:14 PM
I've been experimenting with the Supernote's Browse and Access feature because I want to be able to upload files quickly instead of waiting for Dropbox to synchronize. First, I want to store the IP address in a variable:
(defvar my-supernote-ip-address "192.168.1.221")
Here's how to upload:
(defun my-supernote-upload (filename &optional supernote-path) (interactive "FFile: ") (setq supernote-path (or supernote-path "/INBOX")) (let* ((boundary (mml-compute-boundary '())) (url-request-method "POST") (url-request-extra-headers `(("Content-Type" . ,(format "multipart/form-data; boundary=%s" boundary)))) (url-request-data (mm-url-encode-multipart-form-data `(("file" . (("name" . "file") ("filename" . ,(file-name-nondirectory filename)) ("content-type" . "application/octet-stream") ("filedata" . ,(with-temp-buffer (insert-file-contents-literally filename) (buffer-substring-no-properties (point-min) (point-max))))))) boundary))) (with-current-buffer (url-retrieve-synchronously (format "http://%s:8089%s" my-supernote-ip-address supernote-path)) (re-search-backward "^$") (prog1 (json-read) (kill-buffer)))))
HTML isn't supported. Text works, but it doesn't support annotation. PDF or EPUB could work. It would make sense to register this as an export backend so that I can call it as part of the usual export process.
(defun my-supernote-org-upload-as-text (&optional async subtree visible-only body-only ext-plist) "Export Org format, but save it with a .txt extension." (interactive (list nil current-prefix-arg)) (let ((filename (org-export-output-file-name ".txt" subtree)) (text (org-export-as 'org subtree visible-only body-only ext-plist))) ;; consider copying instead of exporting so that #+begin_export html etc. is preserved (with-temp-file filename (insert text)) (my-supernote-upload filename))) (defun my-supernote-org-upload-as-pdf (&optional async subtree visible-only body-only ext-plist) (interactive (list nil current-prefix-arg)) (my-supernote-upload (org-latex-export-to-pdf async subtree visible-only body-only ext-plist))) (defun my-supernote-org-upload-as-epub (&optional async subtree visible-only body-only ext-plist) (interactive (list nil current-prefix-arg)) (my-supernote-upload (org-epub-export-to-epub async subtree visible-only ext-plist))) (org-export-define-backend 'supernote nil :menu-entry '(?s "Supernote" ((?s "as PDF" my-supernote-org-upload-as-pdf) (?e "as EPUB" my-supernote-org-upload-as-epub) (?o "as Org" my-supernote-org-upload-as-text))))
Adding this line to my Org file allows me to use \spacing{1.5}
for 1.5 line spacing, so I can write in more annotations..
#+LATEX_HEADER+: \usepackage{setspace}
Sometimes I use custom blocks for HTML classes. When LaTeX complains about undefined environments, I can define them like this:
#+LATEX_HEADER+: \newenvironment{whatever_my_custom_environment_is_called}
Now I can export a subtree or file to my Supernote for easy review.
I wonder if multimodal AI models can handle annotated images with editing marks…
-1:-- Using Emacs Lisp to export TXT/EPUB/PDF from Org Mode to the Supernote via Browse and Access (Post Sacha Chua)--L0--C0--September 29, 2024 12:27 PM
-1:-- Emacs display code on TTY (Post)--L0--C0--September 28, 2024 09:15 PM
As every Irreal surely knows, I’m a die hard Emacs user but I was, for a long time, a Vim user and still consider it one of the two best editors. It’s long been my view that Emacs and Vim serve two different constituencies and aren’t really the same type of application. The TL;DR is that Vim is for people who want a small, fast, editor that excels at editing and doesn’t bother with anything else. Emacs, on the other hand, is for people who want a unified operating environment that—sort of—recapitulates the Lisp Machines.
Nicholas Bernstein is a committed Vi/Vim user who more or less agrees with me. Like me, he thinks that Vi/Vim and Emacs are distinct types of applications that serve different needs. He has a nice nice video that discusses this and makes the case that Emacs is all about providing a consistent interface for text based applications.
I think that that’s true but doesn’t tell the entire truth about Emacs. Yes, it does provide a consistent interface for text but it offers much more. It is, as I’ve often said, a light weight Lisp Machine that provides an integrating environment for all your computing needs. If you’re happy with a text-centric browser, Emacs can be the center of all your needs. Even if, like me, you use a standard browser for the dealing with the Web, Emacs can still provide almost everything else.
As I’ve said before, I spend almost all my time in either Emacs or Safari. I have to say, it’s a pretty nice environment. Bernstein makes the same case from the point of view of a Vi/Vim user.
-1:-- Why Emacs: The View From Vim (Post jcs)--L0--C0--September 28, 2024 03:11 PM
This post shows how to set up Emacs popup frames in macOS, allowing quick access to Emacs functions from anywhere on your system.
——————————————————————————————
As much as I would like to live in Emacs full time, I’m not quite there. But a recent post by Protesilaos Stavrou (aka Prot) is helping me bridge the gap.
Prot has written a short but powerful bit of code that allows you to access any piece of Emacs goodness — like org-capture
— from outside Emacs with just one keystroke. The only requirement is that you are running in server-mode
or using the Emacs daemon.
Whether you’re in a web browser, a PDF reader, or just staring at an empty desktop, your favorite Emacs command can be right at your fingertips. See Prot’s video for a thorough demonstration.
Now, I can quickly open a PDF using citar or copy a password from my pass-store. See below for some other useful popups — org-agenda view, mu4e inbox, and a quick translation interface.
Since Prot wrote the code for use in Linux, it didn’t immediately work in MacOS. It turns out, the only necessary change was to add a window-system
frame parameter to the popup frame. (See code below).
But while I was at it, I made a few additions: 1) a title
frame parameter, which allows me to configure the popup frame size and placement through my tiling window manager, yabai; and 2) an optional argument that runs delete-frame
after the main command runs. This makes it possible to call commands that are minibuffer-centric — in my case, that’s citar-open-file
and password-store-copy
.
Here’s the main code:
(defun popup-frame-delete (&rest _)
"Kill selected frame if it has parameter `popup-frame'."
(when (frame-parameter nil 'popup-frame))
(delete-frame))
(defmacro popup-frame-define (command title &optional delete-frame)
"Define interactive function to call COMMAND in frame with TITLE."
`(defun ,(intern (format "popup-frame-%s" command)) ()
(interactive)
(let* ((display-buffer-alist '(("")
(display-buffer-full-frame))))
(frame (make-frame
'((title . ,title)
(window-system . ns)
(popup-frame . t)))))
(select-frame frame)
(switch-to-buffer " popup-frame-hidden-buffer")
(condition-case nil
(progn
(call-interactively ',command)
(delete-other-windows))
(error (delete-frame frame)))
(when ,delete-frame
(sit-for 0.2)
(delete-frame frame))))
(use-package server
:defer 1
:config
(unless (server-running-p)
(server-start)))
And here are the macro calls that define commands:
(popup-frame-define org-capture "capture-popup")
(add-hook 'org-capture-after-finalize-hook #'popup-frame-delete)
(popup-frame-define password-store-copy "minimal-popup" 'delete-frame)
(popup-frame-define citar-open-files "minimal-popup" 'delete-frame)
To quickly bring up these popup frames with keyboard shortcuts, I use skhd, a hotkey daemon for macOS. The following configuration goes in the skhd config file:
cmd + ctrl - c : emacsclient -e '(popup-frame-org-capture)' || yabai -m window --focus recent
cmd + ctrl - o : emacsclient -e '(popup-frame-citar-open-files)' || yabai -m window --focus recent
cmd + ctrl - p : emacsclient -e '(popup-frame-password-store-copy)' || yabai -m window --focus recent
Finally, I have configured my tiling window manager, yabai, to give the popup frames the desired size and placement.
First, the following goes in the yabai config file:
yabai -m signal --add event=window_created app="Emacs" action="~/.yabai-emacs-window-handler.sh"
This will run a bash script (located at ~/.yabai-emacs-window-handler.sh) every time a new Emacs frame is created. The script tells yabai how to move and resize the new frame, depending on the frame’s title. Here is that script:
#!/bin/bash
data=$(yabai -m query --windows --window $YABAI_WINDOW_ID)
title=$(echo $data | jq .title)
display=$(echo $data | jq .display)
if [[ $title =~ "capture-popup" && $display == 1 ]]; then
yabai -m window $YABAI_WINDOW_ID --toggle float --move abs:430:230
yabai -m window $YABAI_WINDOW_ID --resize abs:655:300
yabai -m window $YABAI_WINDOW_ID --focus
elif
[[ $title =~ "minimal-popup" && $display == 1 ]]; then
yabai -m window $YABAI_WINDOW_ID --toggle float --move abs:430:230
yabai -m window $YABAI_WINDOW_ID --resize abs:655:200
yabai -m window $YABAI_WINDOW_ID --focus
else
false
fi
In some cases, an Emacs command will work nicely in a popup frame right out of the box. A good case in point is org-capture
. In other cases, I have needed to write my own custom commands. Here a few:
(defun my/translate ()
(interactive)
(let ((choice
(completing-read "Select: " '("EN->LT" "LT->EN"))))
(cond ((string= choice "EN->LT")
(google-translate-query-translate-reverse))
((string= choice "LT->EN")
(google-translate-query-translate)))))
(popup-frame-define my/translate "minimal-popup")
(defun my/mu4e-unread ()
(interactive)
(mu4e 'background)
(mu4e-search-bookmark
(mu4e-get-bookmark-query ?u)))
(popup-frame-define my/org-agenda "large-popup")
For this, I add another “elif” to the bash script, to ensure I can see the whole inbox in the popup:
elif
[[ $title =~ "large-popup" && $display == 1 ]]; then
yabai -m window $YABAI_WINDOW_ID --toggle float --move abs:350:130
yabai -m window $YABAI_WINDOW_ID --resize abs:730:600
yabai -m window $YABAI_WINDOW_ID --focus
(defun my/org-agenda (&optional p)
(interactive "P")
(org-agenda p "d")
(org-agenda-redo-all))
(popup-frame-define my/org-agenda "large-popup")
Just don’t forget to add a system-wide keyboard shortcut for each new command!
-1:-- Emacs Popup Frames Anywere — MacOS Edition (Post)--L0--C0--September 28, 2024 08:15 AM
An Elisp implementation of HTML table rendering using SVG.
Note: The entry point is shr-render.
Sample Table
-1:-- HTML Renderer (Post Anand Tamariya (noreply@blogger.com))--L0--C0--September 27, 2024 03:46 AM
#+ATTR_HTML :data-link t
to make it link instead of include.
In my Org Mode HTML and Markdown exports, I
usually want to include SVGs inline so that I can
use links. Sometimes I also want to use Javascript
and CSS to modify elements within the images. I
used to use a my-include: link to do this, but I
realized that I can also modify this behaviour by
making my own functions that call org-html-link
or org-md-link
and then put those functions in
org-export-backend-transcoders
.
Here is an example of an SVG:
The following code overrides HTML and Markdown exports to include SVGs.
(defun my-ox-link-path (link _ info) (let* ((raw-path (org-element-property :path link))) (setq raw-path (org-export-file-uri (org-publish-file-relative-name raw-path info))) ;; Possibly append `:html-link-home' to relative file ;; name. (let ((home (and (plist-get info :html-link-home) (org-trim (plist-get info :html-link-home))))) (when (and home (plist-get info :html-link-use-abs-url) (not (file-name-absolute-p raw-path))) (setq raw-path (concat (file-name-as-directory home) raw-path)))) raw-path)) (defun my-org-html-link (link desc info) (if (and (string= (org-element-property :type link) "file") (not (plist-get (org-export-read-attribute :attr_html (org-element-parent-element link)) :data-link)) (org-export-inline-image-p link (plist-get info :html-inline-image-rules))) (let ((path (my-ox-link-path link desc info))) (if (string= (file-name-extension path) "svg") (with-temp-buffer (insert-file-contents-literally path) (buffer-string)) (org-html-link link desc info))) (org-html-link link desc info))) (defun my-org-md-link (link desc info) (if (and (string= (org-element-property :type link) "file") (not (plist-get (org-export-read-attribute :attr_html (org-element-parent-element link)) :data-link))) (let ((path (my-ox-link-path link desc info))) (if (string= (file-name-extension path) "svg") (with-temp-buffer (insert-file-contents-literally path) (buffer-string)) (org-md-link link desc info))) (org-md-link link desc info))) (defun my-org-11ty-link (link desc info) (if (and (string= (org-element-property :type link) "file") (not (plist-get (org-export-read-attribute :attr_html (org-element-parent-element link)) :data-link))) (let ((path (my-ox-link-path link desc info))) (if (string= (file-name-extension path) "svg") (with-temp-buffer (insert-file-contents-literally path) (buffer-string)) (org-11ty-link link desc info))) (org-11ty-link link desc info))) (with-eval-after-load 'ox-html (setf (alist-get 'link (org-export-backend-transcoders (org-export-get-backend 'html))) 'my-org-html-link)) (with-eval-after-load 'ox-md (setf (alist-get 'link (org-export-backend-transcoders (org-export-get-backend 'md))) 'my-org-md-link)) (with-eval-after-load 'ox-11ty (setf (alist-get 'link (org-export-backend-transcoders (org-export-get-backend '11ty))) 'my-org-11ty-link))
-1:-- Include inline SVGs in Org Mode HTML and Markdown exports (Post Sacha Chua)--L0--C0--September 26, 2024 04:54 PM
: Use sketch links when possible. Recolor before cropping so that the grid is removed.
Supernote A5X
Bonus: Autocropping encourages me to just get stuff out there even if I haven't filled a page
ideas: remove template automatically? I wonder if I can use another color…
2024-09-26-01
I want to quickly get drawings from my Supernote A5X into Emacs so that I can include them in blog posts. Dropbox/Google Drive sync is slow because it synchronizes all the files. The Supernote can mirror its screen as an .mjpeg stream. I couldn't figure out how to grab a frame from that, but I did find out how to use Puppeteer to take an screenshot of the Supernote's screen mirror. Still, the resulting image is a little pixelated. If I turn on Browse and Access, the Supernote can serve directories and files as webpages. This lets me grab the latest file and process it. I don't often have time to fill a full A5 page with thoughts, so autocropping the image encourages me to get stuff out there instead of holding on to things.
(defvar my-supernote-ip-address "192.168.1.221") (defun my-supernote-get-exported-files () (let ((data (plz 'get (format "http://%s:8089/EXPORT" my-supernote-ip-address))) (list)) (when (string-match "const json = '\\(.*\\)'" data) (sort (alist-get 'fileList (json-parse-string (match-string 1 data) :object-type 'alist :array-type 'list)) :key (lambda (o) (alist-get 'date o)) :lessp 'string< :reverse t)))) (defun my-supernote-org-attach-latest-exported-file () (interactive) ;; save the file to the screenshot directory (let ((info (car (my-supernote-get-exported-files))) new-file renamed) ;; delete matching files (setq new-file (expand-file-name (replace-regexp-in-string " " "%20" (alist-get 'name info) (org-attach-dir)))) (when (file-exists-p new-file) (delete-file new-file)) (org-attach-attach (format "http://%s:8089%s" my-supernote-ip-address (alist-get 'uri info)) nil 'url) (setq new-file (my-latest-file (org-attach-dir))) ;; recolor (my-sketch-recolor-png new-file) ;; autocrop that image (my-image-autocrop new-file) ;; possibly rename (setq renamed (my-image-recognize-get-new-filename new-file)) (when renamed (setq renamed (expand-file-name renamed (org-attach-dir))) (rename-file new-file renamed t) (my-image-store renamed) ; file it in my archive (setq new-file renamed)) ;; use a sketch link if it has an ID (if (string-match "^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9] " (file-name-base renamed)) (org-insert-link nil (concat "sketchFull:" (file-name-base renamed))) ;; insert the link (org-insert-link nil (concat "attachment:" (replace-regexp-in-string "#" "%23" (file-name-nondirectory new-file))))) (org-redisplay-inline-images)))
-1:-- org-attaching the latest image from my Supernote via Browse and Access (Post Sacha Chua)--L0--C0--September 26, 2024 12:25 PM
As most of you know, Irreal doesn’t think much of editor-connected bling. We much prefer simple efficiency to flashy accouterments that, in the end, simply get in the way of a decent editing experience. That’s true even though they can, arguably, make it easier to get started with a new editor.
It feels a little odd, then, to be writing favorably about these reformatted Emacs documents that, while they have the same content as the official documents, have been reformatted to look a bit nicer and, more importantly, be easier to navigate. It’s probably not accurate to describes the results as “bling” especially since the point of the change is better navigation.
The two major changes are a sidebar that essentially recapitulates the table of contents so that it’s easy to get an overall view of the document and an improved search function that makes parsing the search results easier.
Irreal does think that these documents are a worthwhile addition to the Emacs document stack and wouldn’t object if, arguendo, they were adopted by GNU. Still, the Irreal bunker is probably going to continue to use the “official” documents but doesn’t object if others make a different choice.
The documents that are available are:
Take a look at one or more of them and see what you think.
-1:-- Emacs Doc Bling (Post jcs)--L0--C0--September 25, 2024 05:45 PM
Today I’ll simply delve into two custom functions that I’ve had in my init file for quite some time, my/dired-create-directory
and my/dired-create-empty-file
I use them frequently enough that I thought they were worth mentioning and they augment my dired
workflow when mapped to dired-mode-map
keybindings.
For many years I would create a new file or folder in one of two ways, through the command line, or a GUI file explorer (with either a click in or bound F2 to edit the name), Emacs comes with it’s own directory manager so why not augment it with these features?
What about find-file
I hear you say?, just press C-x C-f. This will prompt for a filename using the current directory of the current buffer and if you type a unique name it will create the file for you. Unfortunately though this will not always work in a simple predictable manner when the minibuffer completion mechanism kicks in.
my/dired-create-directory
This custom function simplifies creating a new directory by prompting for a name in the minibuffer, bypassing the default completion mechanism to avoid unwanted name suggestions.
(defun my/dired-create-directory ()
"Wrapper to dired-create-directory to avoid minibuffer completion."
(interactive)
(let ((search-term
(read-from-minibuffer "Dir : ")))
(dired-create-directory search-term)))
dired-create-directory
function, designed to avoid the potential confusion of minibuffer completion and directly ask for the directory name.dired-create-directory
function.my/dired-create-empty-file
Similarly, this custom function facilitates the creation of an empty file by asking for the filename in the minibuffer without the default completion.
(defun my/dired-create-empty-file ()
"Wrapper to dired-create-empty-file to avoid minibuffer completion."
(interactive)
(let ((search-term
(read-from-minibuffer "File : ")))
(dired-create-empty-file search-term)))
dired-create-empty-file
, providing a straightforward prompt for creating a new file.These functions are bound to dired-mode-map
as follows:
_
: Create an empty file using my/dired-create-empty-file
+
: Create a new directory using my/dired-create-directory
This gives me a good ergonomic LShift+<Right hand of number row> combination and is therefore not too taxing on the hands and each key command are just next to each-other to emphasize their similar nature.
In addition the dired mode map keybinding for creating a new directory is bound to + so there is consistency there too.
I suspect there are probably many other ways to achieve this functionality in Emacs, in this case I am specifically relying on dired
function calls here but there is also the make-directory
function and the shell-command
for example if you want to drop in to using the operating systems tool set.
-1:-- Simple Directory and File Creation in Dired (Post James Dyer)--L0--C0--September 24, 2024 07:00 PM
#Emacs #TIL : I learned about save-interprogram-paste-before-kill
- which saves the existing system clipboard text into the kill ring before replacing it. This ensures that Emacs kill operations do not irrevocably overwrite existing clipboard text.
A common workflow for me is to copy some text from a different application and paste it inside Emacs. But, if I want to first delete a word or region to replace, the deleted word or region goes to the system clipboard and replaces my copied text. This config saves the previous entry in the system clipboard so I can do a C-p
after paste to choose the previous paste.
Syndicated to:
-1:-- 2024-09-24-001 (Post Srijan Choudhary)--L0--C0--September 24, 2024 05:20 PM
Charles Choi has another Casual app on offer. This time it’s a comprehensive set of menus, Casual EditKit, that capture the various editing commands. On the one hand, these are commands that you really need to know to become proficient with Emacs. On the other hand, as Choi says, the menus serve as a means of discovering those commands.
The problem is that Emacs has such a rich set of commands for editing text that it can be hard to learn them or even know that they exist. For example, I am always seeing comments from people expressing surprise about the transpose-chars
and transpose-words
commands. I use them everyday and wouldn’t want to live without them, yet there are lots of folks who don’t even know they exist. There are a bunch of other transpose commands that I don’t have bound but that I know exist so I can invoke them—with the help of fuzzy command completion—as named commands when I need them.
This all works because I know these commands exist and it’s not hard for me to invoke them even if I don’t remember their bindings or they have none. The advantage of Choi’s Casual EditKit is that helps you discover these commands and once you know they exist, they’re easy to invoke even if you can’t remember all the details.
Choi just announced Casual EditKit so I obviously don’t have any experience with it but my snap judgment is that its main benefit is teaching a new user what editing commands are available. But, in the long run, every user is going to have to learn those commands. Still, I suppose the menus could be useful for little used commands such as, say, the rectangle commands.
In any event, Casual EditKit is a welcome addition to Choi’s wonderful collection of Emacs menus.
-1:-- Casual EditKit (Post jcs)--L0--C0--September 24, 2024 03:41 PM
-1:-- Efficiency With The Mark Ring in Emacs - EP2 (Post Discovering Emacs)--L0--C0--September 23, 2024 08:17 PM
An old joke of Emacs is that it’s a great operating system in need of a good text editor. In truth, Emacs is unmatched in its commands for editing, offering many different commands for editing words, sentences, paragraphs, balanced expressions (sexps) and functions (defuns). The problem is knowing beforehand that such a command that you could use exists.
Casual EditKit is an Emacs package designed to surface these editing commands in a usable way by organizing them into keyboard-driven menus. Casual EditKit is now available on MELPA.
Among the editing and editing-related menus Casual EditKit provides are those for:
Shown below is a reference menu (casual-editkit-main-tmenu
) designed to demonstrate all of the above menus. Use it to get an immediate feel for what Casual EditKit offers.
As editing is such a personal experience, Casual EditKit can be considered a library of menus from which a bespoke solution can be crafted. Motivated readers comfortable with Elisp are encouraged to review the Casual EditKit README file and study its source code to make their own customized menus.
In many ways, Casual EditKit can be seen as a continuation of my earlier work to move text elegantly. In that post, I posited that instrumenting mouse menus (both main and context) to access text movement commands was ideal for recognition. However, as mouse menus in Emacs cannot be "pinned" to stay persistent, this discourages repeated behavior. Transient menus however can be "pinned". This allows for behavior like moving text (word, sentence, paragraph, etc.) forwards or backwards in an interactive fashion.
Knowing how to use the editing commands in Emacs is a superpower. That knowledge used to be hard won. Casual EditKit now makes this less so.
As Casual EditKit is new, feedback is welcome. Please share your thoughts on it at the discussion group.
Finally, if you have benefited from using Casual EditKit or any of the Casual packages (now counting at 12!), please consider buying me a coffee to help in their development and maintenance. It would be greatly appreciated.
-1:-- Announcing Casual EditKit (Post Charles Choi)--L0--C0--September 23, 2024 07:00 PM
Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Mastodon #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, communick.news, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!
-1:-- 2024-09-23 Emacs news (Post Sacha Chua)--L0--C0--September 23, 2024 06:23 PM
Paul Graham has a very interesting post that considers why it’s so hard for most corporations to produce good software. Actually, his post isn’t quite about that. Rather, it discusses why it’s so hard and so important for a programmer to hold a program in his head. Graham gives a list of 8 prerequisites for enabling programmers to do that. He says that:
I agree very strongly with everything he says. I program the way he describes and I hate having anyone else touch the particular piece of code I’m working on. I also believe in small teams with a minimum of interference from above. Every manager’s nightmare.
Plenty of people will, of course, disagree but Graham’s article got me thinking about a discussion I had with Perry Metzger in an Irreal comment about pair programming. Metzger had observed that Emacs wasn’t very useful for pair programming and I made a snarky remark about pair programming. Metzger responded that he really enjoyed it and that he’s never been so productive.
That seems to directly contravene what Graham said and it certainly runs against my inclinations. The thing is, Metzger is a serious and accomplished computer scientist as well as a long time Emacs user so nothing he says should be dismissed out of hand. I suppose that this is another case of different strokes for different folks so we can only agree to disagree. In any event, take a look at Graham’s post and Metzger’s comment to see what you think.
-1:-- Holding The Program In Your Head (Post jcs)--L0--C0--September 23, 2024 03:38 PM
-1:-- Hy 1.0 Released (Post)--L0--C0--September 23, 2024 12:00 AM
My significant other needed to share proof of address by providing a number of bank statements for a period of time. That's easy enough to download as pdfs from the bank, but statements typically provide more personal information than the recipient requires. For a proof of address, the first page is more than enough.
macOS's Preview app can easily delete pages from a pdf by selecting undesired pages and hitting the delete key. This is fine for one pdf but for a handful of them, I figured there's a command line incantation I could use out there, and indeed there is:
qpdf my.pdf --pages . 1 -- my-one-page.pdf
With command in mind, I resorted to my now my typical approach of:
I could be done at this point, but since I now have the command fresh in mind…
So let's get on with it.
qpdf '' --pages . 1 -- '_1.'
Other than show it in action, it may be worth mentioning dwim-shell-command recognizes files in region (in addition to dired's mark of course), so you can just select and apply.
Saving these commands for future usage typically consists of merely wrapping in an Emacs command so we can invoke via M-x (and your favorite narrowing framework for that fuzzy quick magic).
(defun dwim-shell-commands-keep-pdf-page () "Keep a page from pdf." (interactive) (let ((page-num (read-number "Keep page number: " 1))) (dwim-shell-command-on-marked-files "Keep pdf page" (format "qpdf ' ' --pages . %d -- ' _%d. '" page-num page-num) :utils "qpdf")))
For this instance, there's a tiny bit of additional logic to ask the user which page they'd like to keep.
While there's no way I'll remember qpdf my.pdf --pages . 1 -- my-one-page.pdf
, I can easily find it in the future by searching with something like M-x keep page
.
I've saved a bunch of these commands and use many of them regularly. You can find in the optional component of dwim-shell-command.
Help make the work sustainable. Consider sponsoring. I'm also building lmno.lol. A platform to drag and drop your blog to the web.
-1:-- How I batch apply and save one-liners (Post)--L0--C0--September 21, 2024 06:00 PM
Protesilaos Stavrou (Prot) has posted a really nice and useful video on something that I’ve been struggling with off and on for many years. The problem is I often want—usually several times a day—to pop up an Emacs buffer and run some command like org-capture
. There’s no problem with that, of course, if I’m in Emacs but what if—as is often the case—I’m in some other app?
The basic strategy is to call emacsclient
with a -e
parameter specifying whatever Emacs command you want to run. The devil, as they say, is in the details. First of all, you have to arrange for an Emacs frame to hold the popup menu and then you have to arrange for it to be deleted when you’re done.
Prot provides a complete, easy to understand framework for all of this. He defines a macro that lets you specify an Emacs command for a popup. You need only specify an OS level key binding to call the function and identify a hook function that will call the function to delete the popup frame when the command is done—most other situations are handled by the code generated by the macro.
I’ve tried to solve this problem with everything from some Applescript to Alphapapas yequake. I’m currently using yequake and it works well for me but if I were starting out I’d definitely take a look at Prot’s code. It’s self contained, easily understandable and hackable, and can be adjusted to your particular use case. All you need is a way of binding an OS level key sequence to the appropriate command. If you need to execute Emacs commands from outside of Emacs, take a look at Prot’s code.
-1:-- Emacs Popup Frames (Post jcs)--L0--C0--September 21, 2024 03:28 PM
-1:-- Emacs and redisplay on the terminal (TTY). ``Because the true color of computing is phosphorescent green on black.'' (Post)--L0--C0--September 20, 2024 11:02 PM
You can think of today’s post as a coda to last week’s Red Meat Friday. Unlike that post, this week’s offering isn’t really about the editor holy war. It’s about Emacs versus every other editor out there, which is a different thing.
As you know, I don’t really take sides in the Emacs/Vim debate. I think they offer different things to people with different needs. The rest of those editors though… Well, you all know my feelings about editors and their users who prioritize bling over efficiency: If your editor uses menus exclusively and you have to click to do anything then, sorry, your editor isn’t efficient.
Of course, none of that will matter because those editors are “modern” and Emacs is old and used only by boomers. Or something. Doubtless, some of those people will have the scales fall from their eyes and discover true editor efficiency. Sadly many others will never make that discovery and will end their days clicking on menus and using the arrow keys.
But this is, after all, Red Meat Friday so enjoy the red meat now because tomorrow we get back to serious stuff.
-1:-- 🥩 Red Meat Friday: More Red Meat For Emacsers (Post jcs)--L0--C0--September 20, 2024 04:05 PM
Please note that planet.emacslife.com aggregates blogs, and blog authors might mention or link to nonfree things. To add a feed to this page, please e-mail the RSS or ATOM feed URL to sacha@sachachua.com . Thank you!