What is Hackers' Pub?

Hackers' Pub is a place for software engineers to share their knowledge and experience with each other. It's also an ActivityPub-enabled social network, so you can follow your favorite hackers in the fediverse and get their latest posts in your feed.

0
9
0

Do you like ?
Do you like songs?
Do you like supporting independent artists?

If you answered yes to any of these questions, I have some great news for you!!

Itโ€™s !!

Now is your chance to get your grubby little mitts on some !!

AS SEEN ON MASTODON!!

Have you ever wanted to know:
โ€ข What day it is on the Moon?
โ€ข The capacity of a Dizzy 8-0 Ray?
โ€ข What she said?
โ€ข Who is making it up?
โ€ข Where do all Zombies go?

makes learning fun, and rock music depressing, so add some Dgar tracks to your library today, on !

Hurry, while stocks last!!

CLICK NOW!!!

dgar.bandcamp.com

{([BOOST THIS TOOT])}

0
1
0
1
1
0
0
0
0

ใ‚ซใƒƒใƒ—ใƒŒใƒผใƒ‰ใƒซใฎใƒŒใƒผใƒ‰ใฎ้ƒจๅˆ†ใฏใ‚ซใƒƒใƒ—ใƒซใซๆŒŸใพใ‚Œใฆใ„ใ‚‹ใจใ„ใ†ๆฐ—ไป˜ใใ‚’ๆœใ‹ใ‚‰ๅพ—ใฆใ—ใพใฃใŸใ€‚

1
0
0
2
0
0
0
1
0
1

[๋‹จ๋…] โ€˜์ฟ ํŒก ๊ฐ€๋งŒ ์•ˆ ๋‘ฌโ€™ ์Šค์ฝ”ํ‹€๋žœ๋“œ 3์œ„ ์—ฐ๊ธฐ๊ธˆ, ์ด๋Œ€ ๋ฉ”๊ณ  ์†Œ์†ก ์ „๋ฉด์ „ 2026. 3. 5. 17:31 700๋งŒ๋‹ฌ๋Ÿฌ ์†์‹ค ๋ณธ ์Šค์ฝ”ํ‹€๋žœ๋“œ ์—ฐ๊ธฐ๊ธˆ ๊ฐœ๋ฏธํˆฌ์ž์ž ์†Œ์†ก์— ๋Œ€ํ‘œ์›๊ณ  ์ง€์ • ์š”๊ตฌ ์••๋ฐ• ํ‚ค์šฐ๋ฉฐ ์†Œ์†ก ํŒ๋„ ๋ฐ”๊ฟ€ ๋ณ€์ˆ˜๋กœ ๋ถ€์ƒ v.daum.net/v/2026030517...

[๋‹จ๋…] โ€˜์ฟ ํŒก ๊ฐ€๋งŒ ์•ˆ ๋‘ฌโ€™ ์Šค์ฝ”ํ‹€๋žœ๋“œ 3์œ„ ์—ฐ๊ธฐ๊ธˆ,...

0
1
1
0
1
0

Friday night is the best time to learn more about emacsredux.com/blog/2026/03/06

Mastering Compilation Mode

Iโ€™ve been using Emacs for over 20 years. Iโ€™ve always used M-x compile and next-error without thinking much about them โ€“ you run a build, you jump to errors, life is good. But recently, while working on neocaml (a Tree-sitter-based OCaml major mode), I had to write a custom compilation error regexp and learned that compile.el is far more sophisticated and extensible than I ever appreciated. This post is a deep dive into compilation mode โ€“ how it works, how to customize it, and how to build on top of it. The Basics If youโ€™re not already using M-x compile, start today. It runs a shell command, captures the output in a *compilation* buffer, and parses error messages so you can jump directly to the offending source locations. The essential keybindings in a compilation buffer: Keybinding Command What it does g recompile Re-run the last compilation command M-n compilation-next-error Move to the next error message M-p compilation-previous-error Move to the previous error message RET compile-goto-error Jump to the source location of the error at point C-c C-f next-error-follow-minor-mode Auto-display source as you move through errors But the real power move is using next-error and previous-error (M-g n and M-g p) from any buffer. You donโ€™t need to be in the compilation buffer โ€“ Emacs tracks the last buffer that produced errors and jumps you there. This works across compile, grep, occur, and any other mode that produces error-like output. Pro tip: M-g M-n and M-g M-p do the same thing as M-g n / M-g p but are easier to type since you can hold Meta throughout. How Error Parsing Actually Works Hereโ€™s the part that surprised me. Compilation mode doesnโ€™t have a single regexp that it tries to match against output. Instead, it has a list of regexp entries, and it tries all of them against every line. The list lives in two variables: compilation-error-regexp-alist โ€“ a list of symbols naming active entries compilation-error-regexp-alist-alist โ€“ an alist mapping those symbols to their actual regexp definitions Emacs ships with dozens of entries out of the box โ€“ for GCC, Java, Ruby, Python, Perl, Gradle, Maven, and many more. You can see all of them with: (mapcar #'car compilation-error-regexp-alist-alist) Each entry in the alist has this shape: (SYMBOL REGEXP FILE LINE COLUMN TYPE HYPERLINK HIGHLIGHT...) Where: REGEXP โ€“ the regular expression to match FILE โ€“ group number (or function) for the filename LINE โ€“ group number (or cons of start/end groups) for the line COLUMN โ€“ group number (or cons of start/end groups) for the column TYPE โ€“ severity: 2 = error, 1 = warning, 0 = info (can also be a cons for conditional severity) HYPERLINK โ€“ group number for the clickable portion HIGHLIGHT โ€“ additional faces to apply The TYPE field is particularly interesting. It can be a cons cell (WARNING-GROUP . INFO-GROUP), meaning โ€œif group N matched, itโ€™s a warning; if group M matched, itโ€™s info; otherwise itโ€™s an error.โ€ This is how a single regexp can handle errors, warnings, and informational messages. A Real-World Example: OCaml Errors Let me show you what I built for neocaml. OCaml compiler output looks like this: File "foo.ml", line 10, characters 5-12: 10 | let x = bad_value ^^^^^^^ Error: Unbound value bad_value Warnings: File "foo.ml", line 3, characters 6-7: 3 | let _ x = () ^ Warning 27 [unused-var-strict]: unused variable x. And ancillary locations (indented 7 spaces): File "foo.ml", line 5, characters 0-20: 5 | let f (x : int) = x ^^^^^^^^^^^^^^^^^^^^ File "foo.ml", line 10, characters 6-7: 10 | f "hello" ^ Error: This expression has type string but ... One regexp needs to handle all of this. Hereโ€™s the (slightly simplified) entry: (push `(ocaml ,neocaml--compilation-error-regexp 3 ; FILE = group 3 (4 . 5) ; LINE = groups 4-5 (6 . neocaml--compilation-end-column) ; COLUMN = group 6, end via function (8 . 9) ; TYPE = warning if group 8, info if group 9 1 ; HYPERLINK = group 1 (8 font-lock-function-name-face)) ; HIGHLIGHT group 8 compilation-error-regexp-alist-alist) A few things worth noting: The COLUMN end position uses a function instead of a group number. OCamlโ€™s end column is exclusive, but Emacs expects inclusive, so neocaml--compilation-end-column subtracts 1. The TYPE cons (8 . 9) means: if group 8 matched (Warning/Alert text), itโ€™s a warning; if group 9 matched (7-space indent), itโ€™s info; otherwise itโ€™s an error. Three severity levels from one regexp. The entry is registered globally in compilation-error-regexp-alist-alist because *compilation* buffers arenโ€™t in any language-specific mode. Every active entry is tried against every line. Adding Your Own Error Regexp You donโ€™t need to be writing a major mode to add your own entry. Say youโ€™re working with a custom linter that outputs: [ERROR] src/app.js:42:10 - Unused import 'foo' [WARN] src/app.js:15:3 - Missing return type You can teach compilation mode about it: (with-eval-after-load 'compile (push '(my-linter "^\\[\\(ERROR\\|WARN\\)\\] \\([^:]+\\):\\([0-9]+\\):\\([0-9]+\\)" 2 3 4 (1 . nil)) compilation-error-regexp-alist-alist) (push 'my-linter compilation-error-regexp-alist)) The TYPE field (1 . nil) means: โ€œif group 1 matches, itโ€™s a warningโ€ โ€“ but wait, group 1 always matches. The trick is that compilation mode checks the content of the match. Actually, let me correct myself. The TYPE field should be a number or expression. A cleaner approach: (with-eval-after-load 'compile (push '(my-linter "^\\[\\(?:ERROR\\|\\(WARN\\)\\)\\] \\([^:]+\\):\\([0-9]+\\):\\([0-9]+\\)" 2 3 4 (1)) compilation-error-regexp-alist-alist) (push 'my-linter compilation-error-regexp-alist)) Here group 1 only matches for WARN lines (itโ€™s inside a non-capturing group with an alternative). TYPE is (1) meaning โ€œif group 1 matched, itโ€™s a warning; otherwise itโ€™s an error.โ€ Now M-x compile with your linter command will highlight errors and warnings differently, and next-error will jump right to them. Useful Variables You Might Not Know A few compilation variables that are worth knowing: ;; OCaml (and some other languages) use 0-indexed columns (setq-local compilation-first-column 0) ;; Scroll the compilation buffer to follow output (setq compilation-scroll-output t) ;; ... or scroll until the first error appears (setq compilation-scroll-output 'first-error) ;; Skip warnings and info when navigating with next-error (setq compilation-skip-threshold 2) ;; Auto-close the compilation window on success (setq compilation-finish-functions (list (lambda (buf status) (when (string-match-p "finished" status) (run-at-time 1 nil #'delete-windows-on buf))))) The compilation-skip-threshold is particularly useful. Set it to 2 and next-error will only stop at actual errors, skipping warnings and info messages. Set it to 1 to also stop at warnings but skip info. Set it to 0 to stop at everything. The Compilation Mode Family Compilation mode isnโ€™t just for compilers. Several built-in modes derive from it: grep-mode โ€“ M-x grep, M-x rgrep, M-x lgrep all produce output in a compilation-derived buffer. Same next-error navigation, same keybindings. occur-mode โ€“ M-x occur isnโ€™t technically derived from compilation mode, but it participates in the same next-error infrastructure. flymake/flycheck โ€“ uses compilation-style error navigation under the hood. The grep family deserves special mention. M-x rgrep is recursive grep with file-type filtering, and itโ€™s surprisingly powerful for a built-in tool. The results buffer supports all the same navigation, plus M-x wgrep (from the wgrep package) lets you edit grep results and write the changes back to the original files. Thatโ€™s a workflow that rivals any modern IDE. Building a Derived Mode The real fun begins when you create your own compilation-derived mode. Letโ€™s build one for running RuboCop (a Ruby linter and formatter). RuboCopโ€™s emacs output format looks like this: app/models/user.rb:10:5: C: Style/StringLiterals: Prefer single-quoted strings app/models/user.rb:25:3: W: Lint/UselessAssignment: Useless assignment to variable - x app/models/user.rb:42:1: E: Naming/MethodName: Use snake_case for method names The format is FILE:LINE:COLUMN: SEVERITY: CopName: Message where severity is C (convention), W (warning), E (error), or F (fatal). Hereโ€™s a complete derived mode: (require 'compile) (defvar rubocop-error-regexp-alist `((rubocop-offense ;; file:line:col: S: Cop/Name: message "^\\([^:]+\\):\\([0-9]+\\):\\([0-9]+\\): \\(\\([EWFC]\\)\\): " 1 2 3 (5 . nil) nil (4 compilation-warning-face))) "Error regexp alist for RuboCop output. Group 5 captures the severity letter: E/F = error, W/C = warning.") (define-compilation-mode rubocop-mode "RuboCop" "Major mode for RuboCop output." (setq-local compilation-error-regexp-alist (mapcar #'car rubocop-error-regexp-alist)) (setq-local compilation-error-regexp-alist-alist rubocop-error-regexp-alist)) (defun rubocop-run (&optional directory) "Run RuboCop on DIRECTORY (defaults to project root)." (interactive) (let ((default-directory (or directory (project-root (project-current t))))) (compilation-start "rubocop --format emacs" #'rubocop-mode))) A few things to note: define-compilation-mode creates a major mode derived from compilation-mode. It inherits all the navigation, font-locking, and next-error integration for free. We set compilation-error-regexp-alist and compilation-error-regexp-alist-alist as buffer-local. This means our mode only uses its own regexps, not the global ones. No interference with other tools. compilation-start is the workhorse โ€“ it runs the command and displays output in a buffer using our mode. The TYPE field (5 . nil) means: if group 5 matched, check its content โ€“ but actually, here all lines match group 5. The subtlety is that compilation mode treats a non-nil TYPE group as a warning. To distinguish E/F from W/C, youโ€™d need a predicate or two separate regexp entries. For simplicity, this version treats everything as an error, which is usually fine for a linter. You could extend this with auto-fix support (rubocop -A), or a sentinel function that sends a notification when the run finishes: (defun rubocop-run (&optional directory) "Run RuboCop on DIRECTORY (defaults to project root)." (interactive) (let ((default-directory (or directory (project-root (project-current t)))) (compilation-finish-functions (cons (lambda (_buf status) (message "RuboCop %s" (string-trim status))) compilation-finish-functions))) (compilation-start "rubocop --format emacs" #'rubocop-mode))) Side note: RuboCop actually ships with a built-in emacs output formatter (thatโ€™s what --format emacs uses above), so its output already matches Emacsโ€™s default compilation regexps out of the box โ€“ no custom mode needed. I used it here purely to illustrate how define-compilation-mode works. In practice youโ€™d just M-x compile RET rubocop --format emacs and everything would Just Work.1 next-error is not really an error There is no spoon. โ€“ The Matrix The most powerful insight about compilation mode is that itโ€™s not really about compilation. Itโ€™s about structured output with source locations. Any tool that produces file/line references can plug into this infrastructure, and once it does, you get next-error navigation for free. The name compilation-mode is a bit of a misnomer โ€“ something like structured-output-mode would be more accurate. But then again, naming is hard, and this one has 30+ years of momentum behind it. This is one of Emacsโ€™s great architectural wins. Whether youโ€™re navigating compiler errors, grep results, test failures, or linter output, the workflow is the same: M-g n to jump to the next problem. Once your fingers learn that pattern, it works everywhere. I used M-x compile for two decades before I really understood the machinery underneath. Sometimes the tools you use every day are the ones most worth revisiting. Thatโ€™s all I have for you today. In Emacs we trust! Full disclosure: I may know a thing or two about RuboCopโ€™s Emacs formatter.ย โ†ฉ

emacsredux.com ยท Emacs Redux

0
0
1
1
0
0
3
0
0
13
1
0
0
0
0
0
0
0
0
0
0
0
0

ใƒ‡ใ‚ธใ‚ฟใƒซใƒใ‚ฌใจใ„ใ†ๆ‰‹ๆณ•ใ€‚
https://note.com/okeke_okeke/n/n4bd171540c69

๏ผ•ใ€€ใƒ‡ใ‚ธใ‚ฟใƒซใƒใ‚ฌใฎๆ€ใ„ๅ‡บ๏ฝœokeke

็š†ใ•ใ‚“ใฎๆŠ•็จฟใ‚’่‰ฒใ€…ๆ‹่ฆ‹ใ•ใ›ใฆใ‚‚ใ‚‰ใ†ใจใ€Œใƒ‡ใ‚ธใ‚ฟใƒซใƒใ‚ฌใ€ใฎ่จ˜ไบ‹ใ‚’็™บ่ฆ‹ใ€‚ใƒ‡ใ‚ธใ‚ฟใƒซใƒใ‚ฌใฃใฆใ€ใ”ๅญ˜็Ÿฅใงใ™ใ‹๏ผŸๅฎŸใฏ็งใ‚‚ใ€ใ ใ„ใถๅ‰ใซใชใ‚Šใพใ™ใŒใ€ใกใ‚‡ใฃใจใ ใ‘ๆŒ‘ๆˆฆใ—ใŸใ“ใจใŒใ‚ใ‚Šใพใ™ใ€‚ 2026.2ใ€€nikon coolpix p330 ๅทจๅคงใชใƒใ‚ฌใƒ•ใ‚ฃใƒซใƒ ใ‚’ไฝœใ‚‹ ใƒ‡ใ‚ธใ‚ฟใƒซใƒใ‚ฌใจใ„ใ†ใฎใฏใ€้€ๆ˜Žใชใƒ•ใ‚ฃใƒซใƒ ใ‚ทใƒผใƒˆ๏ผˆๆ˜”ใ€ๅญฆๆ กใฎๅ…ˆ็”ŸใŒๆŽˆๆฅญใงไฝฟใฃใฆใ„ใŸOHPใ‚ทใƒผใƒˆใ‚’ๆ€ใ„ๆตฎใ‹ในใฆใใ ใ•ใ„๏ผ‰ใซใ€ใƒ‡ใ‚ธใ‚ฟใƒซๆ’ฎๅฝฑใ—ใŸๅ†™็œŸใƒ‡ใƒผใ‚ฟใ‚’ๅ่ปขใ•ใ›ใฆใ‚คใƒณใ‚ฏใ‚ธใ‚งใƒƒใƒˆใƒ—ใƒชใƒณใ‚ฟใƒผใงๅ‡บๅŠ›ใ—ใŸใ‚‚ใฎใ€‚A๏ผ”ใ‚ตใ‚คใ‚บใ‚„A๏ผ“ใ‚ตใ‚คใ‚บใฎใƒ•ใ‚ฃใƒซใƒ ใ‚ทใƒผใƒˆใงใ€Œๅทจๅคงใชใƒใ‚ฌใƒ•ใ‚ฃใƒซใƒ ใ€ใ‚’ไฝœใ‚Šใพใ™ใ€‚็งใ‚‚ๆŒ‘ๆˆฆใ—ใพใ—ใŸใŒใ€ใ€ŒDGSM Printใ€ใจใ„ใ†ๆŠ€ๆณ•ใ‚’ๅˆฉ็”จใ•ใ›ใฆใ‚‚ใ‚‰ใ„ใพ

note.com ยท note๏ผˆใƒŽใƒผใƒˆ๏ผ‰

0
1

if you're depressed about the state of the world right now

or you're too numb to be able to feel anything at all

it means you have a moral compass. hold on to that.

people who are cheerfully going about business as usual right now, terrify us

0
0

@catsaladCat ๐Ÿˆ๐Ÿฅ— (D.Burch) :paw:โ :paw:
Reading about the optical photoelectric triggers makes me want to talk about this with the people

When @mwicharyMarcin Wichary was writing his Shift Happens history of (typing) keyboards) I was writing my book on the

A fun coincidence of buttons and keys and patents all around the same time in the 1830sโ€“1860s

Charles Wheatstoneโ€™s Symphonium. Direct predecessor of the English concertina. Patented 1829 same year as the first instrument called an Accordion. Looks like a small silver box with ivory buttons on the side with an ivory-lined hole you blow into on the front.The Hansen Writing Ball. The first commercially successful typewriter. Looks like a complicated brass hedgehog with letters on top of the spikey ball. Below the spiky ball is the paper which moves in order to type on it. A foot bass, pump organ. Like can accordion you play with your feet. Large flat dark wooden box with a row of round buttons on top that you play like the foot pedals of an organ while you press down with your feet.An old prototype Wheatstone telegraph keyboard developed by the same guy who did the concertina. Looks like a wooden cigar box with a split ergonomic keyboard on top made of wooden circular buttons splayed like two birds wings.
0
0
38
0
0
13
1
0
0