Skip to content

Conversation

@tanrax
Copy link

@tanrax tanrax commented Oct 13, 2025

Would that be interesting?

@basil-conto basil-conto added the enhancement Feature request label Oct 13, 2025
Copy link
Collaborator

@basil-conto basil-conto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for the contribution! There is definitely interest in improving the UI.

I won't have time to review this carefully for a little while, so here are some thoughts after a quick scan of the changes.

  • The topic of improving the UI has been brought up before. Have you looked over #44, #45, and #55? Since those discussions, I have also learned of another attractive UI/MVC framework that is built into Emacs, namely ewoc: (info "(elisp) Abstract Display")

  • Ideally the choice of UI should be configurable via a user option. Similarly, we should try to avoid changing default key bindings (and their effects) if possible.

hackernews.el Outdated
Comment on lines 354 to 361
(when size
(push `(:height ,size) props))
(when font-color
(push `(:foreground ,font-color) props))
(when background-color
(push `(:background ,background-color) props))
(when props
(put-text-property start end 'face (apply #'append props))))))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be more configurable and play better with Font Lock if we used named faces defined via defface rather than ad-hoc anonymous faces. Ideally the default colours would adapt well to the user's background mode etc.

hackernews.el Outdated
:notify (lambda (&rest _)
(hackernews-top-stories))
:help-echo "View top stories"
" 🔥 Top ")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can assume that emoji will always be displayable in the user's system/font, so this should degrade gracefully or at least be configurable. IIRC more recent Emacs versions introduced a mechanism for this, namely define-icon or similar: (info "(elisp) Icons")

hackernews.el Outdated
Comment on lines 467 to 469
(let ((separator-regex (concat "^" (regexp-quote (hackernews--string-separator)) "$")))
(if (search-forward-regexp separator-regex nil t)
(forward-line 2)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My first reaction is that this is too tightly coupled with the display format. I would prefer to avoid search-based motion, instead relying on either some feature of the UI, or some marker (e.g. text property) that we place in the buffer that is independent of how the buffer is displayed.

hackernews.el Outdated
(inhibit-read-only t))
(feed (hackernews--get :feed))
(feed-name (hackernews--feed-name feed))
(is-first-load (= (point-max) 1)))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general there's no need to compare against concrete position values in Elisp. If you want to check whether the narrowed portion of the buffer is empty, you can compare point-min to point-max; and for checking whether the buffer is empty irrespective of narrowing, there is buffer-size.

hackernews.el Outdated
(is-first-load (= (point-max) 1)))

;; Temporarily disable read-only mode
(read-only-mode -1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not bind inhibit-read-only?

Comment on lines +722 to +724
;; Disable line numbers
(when (fboundp 'display-line-numbers-mode)
(display-line-numbers-mode 0))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed? Ideally we shouldn't have to override user preferences.

hackernews.el Outdated
Comment on lines 782 to 786
(when (and hackernews-enable-visual-fill-column
(require 'visual-fill-column nil t))
(setq-local visual-fill-column-center-text t)
(setq-local visual-fill-column-width hackernews-display-width)
(visual-fill-column-mode 1))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does hackernews need to be aware of visual-fill-column-mode, and load and enable it explicitly? Can't the user enable the minor mode as desired via hackernews-mode-hook? If the setup is nontrivial we can always document it in our README/wiki.

hackernews.el Outdated
Comment on lines 787 to 788
;; Activate the keymap
(use-local-map hackernews-mode-map))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed? Usually this is done automatically by define-derived-mode.

hackernews.el Outdated
Comment on lines 863 to 864
;; Kill local variables BEFORE disabling read-only (like Lobsters)
(kill-all-local-variables)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

hackernews.el Outdated
Comment on lines 866 to 870
;; Temporarily disable read-only mode
(read-only-mode -1)

;; Clear buffer
(let ((inhibit-read-only t))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed given the subsequent inhibit-read-only?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically it is not necessary

hackernews.el Outdated
;; Keywords: comm hypermedia news
;; Version: 0.7.1
;; Version: 0.8.0
;; Package-Requires: ((emacs "24.3"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either:

Personally I am happy to raise the minimum required Emacs version as needed, given that the hackernews package talks to remote third-party machines over the network.

@tanrax
Copy link
Author

tanrax commented Oct 13, 2025

Thank you very much for the detailed review and feedback!

Previous discussions and ewoc: I'll review those now. The ewoc framework sounds interesting; I wasn't familiar with it.
Configurable UI: The default could remain the current minimal UI, and users could opt into the enhanced
version. Does this sound like the right approach?

Regarding specific code issues:

  • Anonymous faces vs defface: You're completely right. I'll refactor this.
  • Emoji support: Good point. It should be configurable.
  • Search-based navigation: I see the issue with coupling navigation to the visual format. Would you recommend using text properties or markers to identify item boundaries?
  • Position comparisons: I'll change (= (point-max) 1) to (= (buffer-size) 0) or (= (point-min) (point-max)).
  • The inhibit-read-only, switch-to-buffer, mode timing, and other issues: These were carryovers from my attempts to get the code working. I will make changes.

Well...would you prefer that I:

  1. Make all these fixes in the current PR, or
  2. Close this PR and open a new one after studying ewoc and the previous discussions more carefully?

@basil-conto
Copy link
Collaborator

Configurable UI: The default could remain the current minimal UI, and users could opt into the enhanced version. Does this sound like the right approach?

That would be amazing for backward compatibility, which though a general goal of the Emacs project, may or may not be our highest priority for the hackernews project. However, a secondary benefit of designing the new UI to be optional is that the resulting solution will hopefully be general enough to afford any number of future UIs :).

If it proves too much of a hassle we can always reconsider.

* Search-based navigation: I see the issue with coupling navigation to the visual format. Would you recommend using text properties or markers to identify item boundaries?

Markers can degrade Emacs redisplay performance (at least this was the case historically in Emacs, though more recent changes to Emacs internals may have mitigated this). The penalty may be negligible in the case of hackernews, but if all else is the same, then my vote is for plain text properties.

However, if the Widget/EWOC/etc. library provides functions for locating UI elements, then I think we should prefer that over a custom solution.

Well...would you prefer that I:

1. Make all these fixes in the current PR, or

2. Close this PR and open a new one after studying ewoc and the previous discussions more carefully?

It's completely up to you, AFAIC there's no harm in leaving this PR open and in progress.

Thanks again, and happy hacking! :)

@tanrax
Copy link
Author

tanrax commented Dec 16, 2025

This commit implements a dual UI system, allowing users to choose between the classic minimalist interface (default) and the new interface. I believe it doesn't break any compatibility issues.

It is configured with the hackernews-ui-style variable with values ​​'classic (default)' and 'modern'. For example:

(use-package hackernews
    :ensure t
    :config
        (setq hackernews-ui-style 'modern)
       (setq hackernews-enable-emojis t))

(global-set-key (kbd "C-c x h") 'hackernews)

@tanrax
Copy link
Author

tanrax commented Dec 16, 2025

I want to mention that I'm not particularly happy with maintaining both the current and new appearances. The code has become more complex. It's been very difficult to keep all the functionalities of both the current and new code. Perhaps the problem is architectural; the logic isn't properly separated from the UI

Andros Fenollosa added 5 commits December 16, 2025 12:39
Move hackernews-mode activation before setting local variables.
Remove redundant kill-all-local-variables and read-only-mode calls.
Remove deleted/dead stories that return null from API.
Use composed keymap for modern UI to preserve all keybindings.
Filter deleted and dead items in addition to null.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Feature request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants