aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuchen Pei <id@ypei.org>2025-01-05 17:34:34 +1100
committerYuchen Pei <id@ypei.org>2025-01-05 17:34:34 +1100
commitbb57c3e606d844000ceb725a4f15f7d92a1d5b67 (patch)
treeb6ce6cf0aa8e619dd3b1de03ff35e34d38961c0a
parent72139ef3250f7cad9dad3ccbdc7a829befcb5c5f (diff)
[emacs][gdb] Infobox with gitlab
* emacs/.emacs.d/init/ycp-org.el: Forgot to require 'my-org-remark * emacs/.emacs.d/lisp/my/infobox.el: A utility to display alist in a help buffer * emacs/.emacs.d/lisp/my/my-buffer.el: Add a function that fontify a string with a given mode * emacs/.emacs.d/lisp/my/my-gitlab.el: Example of using infobox, by displaying gitlab project info in a help buffer * emacs/.emacs.d/lisp/my/my-net.el: add a function that fetch a url raw * emacs/.emacs.d/lisp/my/my-prog.el: reduce timeout in gdb completion from 1 to .1 sec, but the code is commented out anyway because it does not work (see preceding comments) * misc/.gdbinit: enable debuginfod and reduce max-completions to 20 to reduce hanging caused by exhaustive search of completions
-rw-r--r--emacs/.emacs.d/init/ycp-org.el1
-rw-r--r--emacs/.emacs.d/lisp/my/infobox.el65
-rw-r--r--emacs/.emacs.d/lisp/my/my-buffer.el10
-rw-r--r--emacs/.emacs.d/lisp/my/my-gitlab.el75
-rw-r--r--emacs/.emacs.d/lisp/my/my-net.el10
-rw-r--r--emacs/.emacs.d/lisp/my/my-prog.el2
-rw-r--r--misc/.gdbinit2
7 files changed, 153 insertions, 12 deletions
diff --git a/emacs/.emacs.d/init/ycp-org.el b/emacs/.emacs.d/init/ycp-org.el
index c69c762..ea95d2a 100644
--- a/emacs/.emacs.d/init/ycp-org.el
+++ b/emacs/.emacs.d/init/ycp-org.el
@@ -525,6 +525,7 @@
(my-package org-remark
(:install t)
(:delay 60)
+ (require 'my-org-remark)
(setq org-remark-notes-display-buffer-action
'(display-buffer-reuse-mode-window))
(require 'nov)
diff --git a/emacs/.emacs.d/lisp/my/infobox.el b/emacs/.emacs.d/lisp/my/infobox.el
new file mode 100644
index 0000000..81a66ce
--- /dev/null
+++ b/emacs/.emacs.d/lisp/my/infobox.el
@@ -0,0 +1,65 @@
+;;; infobox.el -- Infobox in a help buffer -*- lexical-binding: t -*-
+
+;; Copyright (C) 2025 Free Software Foundation, Inc.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "29.4"))
+
+;; This file is part of dotted.
+
+;; dotted is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotted is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotted. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Infobox in a help buffer.
+
+;;; Code:
+
+
+(defun infobox-translate (info specs)
+ "Translate INFO according to SPECS.
+
+TODO: allow multiple levels in specs keys using let-alist, i.e.
+something like
+
+(.channel.name . \"Channel name\")"
+ (seq-map
+ (lambda (pair)
+ (when-let ((val (alist-get (car pair) info)))
+ (if (or (stringp (cdr pair)) (symbolp (cdr pair)))
+ (cons (cdr pair) val)
+ (cons (cadr pair) (funcall (cddr pair) val)))))
+ specs))
+
+(defun infobox-render (info item &optional interactive-p)
+ "Render and display a help buffer of INFO."
+ (help-setup-xref item interactive-p)
+ (with-help-window (help-buffer)
+ (with-current-buffer standard-output
+ (let ((n-rows 0))
+ (seq-do
+ (lambda (pair)
+ (when pair
+ (when (stringp (car pair))
+ (insert (car pair) ": ")
+ (setq n-rows (1+ n-rows)))
+ (insert (cdr pair) "\n")))
+ info)
+ (align-regexp
+ (point-min)
+ (progn (goto-line (1+ n-rows)) (point))
+ "\\(\\s-*\\):"))
+ (visual-line-mode))))
+
+(provide 'infobox)
diff --git a/emacs/.emacs.d/lisp/my/my-buffer.el b/emacs/.emacs.d/lisp/my/my-buffer.el
index c17e765..f2da7f5 100644
--- a/emacs/.emacs.d/lisp/my/my-buffer.el
+++ b/emacs/.emacs.d/lisp/my/my-buffer.el
@@ -518,5 +518,15 @@ With double prefix arguments, create a new indirect buffer."
(revert-buffer t t))
(switch-to-buffer buffer)))
+(defun my-fontify-with-mode (text mode)
+ "Fontify TEXT with MODE."
+ (with-temp-buffer
+ (funcall mode)
+ (insert text)
+ (if (fboundp 'font-lock-ensure)
+ (font-lock-ensure)
+ (with-no-warnings (font-lock-fontify-buffer)))
+ (buffer-string)))
+
(provide 'my-buffer)
;;; my-buffer.el ends here
diff --git a/emacs/.emacs.d/lisp/my/my-gitlab.el b/emacs/.emacs.d/lisp/my/my-gitlab.el
index 6dd484c..04d2ba0 100644
--- a/emacs/.emacs.d/lisp/my/my-gitlab.el
+++ b/emacs/.emacs.d/lisp/my/my-gitlab.el
@@ -26,8 +26,9 @@
;;; Code:
+(require 'infobox)
-(defun my-get-gitlab-project-id (url)
+(defun my-gitlab-get-project-id (url)
(with-current-buffer (url-retrieve-synchronously
(replace-regexp-in-string "\\.git$" "" url))
(let ((dom (libxml-parse-html-region (point-min) (point-max))))
@@ -35,16 +36,70 @@
(dom-search dom (lambda (n) (dom-attr n 'data-project-id))))
'data-project-id))))
-(defun my-grok-gitlab (url)
+(defun my-gitlab-api-projects (url)
(when-let* ((urlobj (url-generic-parse-url url))
- (project-id (my-get-gitlab-project-id url)))
- (with-current-buffer
- (url-retrieve-synchronously
- (concat (url-type urlobj) "://" (url-host urlobj)
- "/api/v4/projects/" project-id))
- (set-buffer-multibyte t)
- (my-delete-http-header)
- (my-grok-gitlab-make-info (json-read)))))
+ (project-id (my-gitlab-get-project-id url)))
+ (my-url-fetch-json
+ (format "%s://%s/api/v4/projects/%s"
+ (url-type urlobj)
+ (url-host urlobj)
+ project-id))))
+
+(defvar my-gitlab-readme-get-raw nil "Whether to get raw or html readme")
+
+(defun my-gitlab-project-info (url)
+ "Given a url, returns project info."
+ (let ((info (my-gitlab-api-projects url)))
+ (let-alist info
+ (when .readme_url
+ (setf (alist-get 'readme info)
+ (if my-gitlab-readme-get-raw
+ (format
+ "\n%s"
+ (my-url-fetch-raw
+ (replace-regexp-in-string "/-/blob/" "/-/raw/" .readme_url)))
+ (alist-get
+ 'html
+ (my-url-fetch-json
+ (format "%s?format=json&viewer=rich" .readme_url)))))))
+ info))
+
+(defun my-gitlab-format-time-string (t)
+ (format-time-string "%Y-%m-%d %M:%M:%S" (encode-time (parse-time-string t))))
+
+(require 'my-buffer)
+
+(defvar my-gitlab-project-info-specs
+ `((http_url_to_repo . "Clone")
+ (name_with_namespace . "Name")
+ (description . "Description")
+ (created_at . ("Created at" . my-gitlab-format-time-string))
+ (last_activity_at . ("Updated at" . my-gitlab-format-time-string))
+ (topics . ("Topics" . ,(lambda (xs)
+ (mapconcat #'identity xs "; "))))
+ (star_count . ("Stars" . number-to-string))
+ (forks_count . ("Forks" . number-to-string))
+ (readme . (body . ,(lambda (text)
+ (with-temp-buffer
+ (insert text)
+ (shr-render-region (point-min) (point-max))
+ (buffer-string)))))))
+
+(defun my-gitlab-project-infobox (url)
+ "Display a gitlab project info at URL in a help buffer.
+
+A good example would be
+<https://gitlab.com/woob/woob>
+"
+ (interactive "sGitlab project URL: ")
+ (infobox-render
+ (infobox-translate
+ (my-gitlab-project-info url) my-gitlab-project-info-specs)
+ `(my-gitlab-project-infobox ,url)
+ (called-interactively-p 'interactive)))
+
+(defun my-grok-gitlab (url)
+ (my-grok-gitlab-make-info (my-gitlab-api-projects url)))
(defun my-grok-gitlab-make-info (raw)
(list (cons "Title" (alist-get 'name raw))
diff --git a/emacs/.emacs.d/lisp/my/my-net.el b/emacs/.emacs.d/lisp/my/my-net.el
index 1f1cbc6..2574789 100644
--- a/emacs/.emacs.d/lisp/my/my-net.el
+++ b/emacs/.emacs.d/lisp/my/my-net.el
@@ -119,6 +119,14 @@ It checks the STATUS, and if it is ok, saves the payload to FILE-NAME."
decompression
with-header))
+
+(defun my-url-fetch-raw (url &optional decompression with-header)
+ (my-url-fetch-internal
+ url
+ (lambda () (decode-coding-string (buffer-string) 'utf-8))
+ decompression
+ with-header))
+
(defun my-url-fetch-internal (url buffer-processor decompression with-header)
(with-current-buffer (get-buffer-create my-client-buffer-name)
(goto-char (point-max))
@@ -141,7 +149,7 @@ It checks the STATUS, and if it is ok, saves the payload to FILE-NAME."
(list
(cons 'header fields)
(cons 'json (funcall buffer-processor)))
- (funcall buffer-processor)))
+ (when buffer-processor (funcall buffer-processor))))
(error "HTTP error: %s" (buffer-substring (point) (point-max)))))))
(provide 'my-net)
diff --git a/emacs/.emacs.d/lisp/my/my-prog.el b/emacs/.emacs.d/lisp/my/my-prog.el
index 396d919..a81d36d 100644
--- a/emacs/.emacs.d/lisp/my/my-prog.el
+++ b/emacs/.emacs.d/lisp/my/my-prog.el
@@ -419,7 +419,7 @@ overlay arrow in source buffer."
;; (gdb-input (concat "complete " context command)
;; (lambda () (setq gud-gdb-fetch-lines-in-progress nil)))
;; (while gud-gdb-fetch-lines-in-progress
-;; (accept-process-output (get-buffer-process gud-comint-buffer) 1)))
+;; (accept-process-output (get-buffer-process gud-comint-buffer) .1)))
;; (gud-gdb-completions-1 gud-gdb-fetched-lines)))
;;; which-func
diff --git a/misc/.gdbinit b/misc/.gdbinit
index b84dbef..b06bc7f 100644
--- a/misc/.gdbinit
+++ b/misc/.gdbinit
@@ -1,3 +1,5 @@
+set debuginfod enabled on
+set max-completions 20
set print static-members off
set print frame-arguments all
# unlimited print string length