Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

formatting issue (in terminal) #10

Open
carlcotner opened this issue Jan 2, 2017 · 8 comments
Open

formatting issue (in terminal) #10

carlcotner opened this issue Jan 2, 2017 · 8 comments

Comments

@carlcotner
Copy link

I use Emacs in a terminal, and I just tried ivy-rich. Each line wraps with the last trailing space extending to the next line, so that all the lines are essentially double-spaced. I'm not sure what the design considerations are, but one fix in this case would be just not to add any trailing spaces to the lines. (Another, of course, would be to add one or two fewer trailing spaces.)

I have no idea why the problem would be appearing in my case but not for everyone else. Do line lengths or line wrapping work differently for Emacs in the terminal?

@Yevgnen
Copy link
Owner

Yevgnen commented Jan 3, 2017

Hi, thanks for reporting this. The trailing spaces are used to make each line have the same length for better display. But the in terminal, the last space seems wrap into next line. Subtracting 1 of the path width seems fix the issue here. Please check after the elpa version updated.

@carlcotner
Copy link
Author

Thanks, this completely solves the problem I described! Now I notice a few more things that I'll mention -- not all directly about ivy-rich, and maybe not all problems.

First, I show trailing whitespace, so the minibuffer has the trailing whitespace indicator on most of the lines. (I'll figure out how to turn this off just for the minibuffer.)

Second, for the Recentf files (added for Issue #4), files with long path names wrap, even though the paths are abbreviated with an ellipsis, when either the first or last directory name is itself long. I'm not sure what a good solution is in this case. Perhaps abbreviating long first and last directory components with ellipses?

Finally, in the example I'm looking at, there is a lot of unused whitespace between the first file-name column and the file-size column. Maybe the file-size column position could be determined dynamically so that if the ivy-rich-switch-buffer-name-max-length is larger than necessary, the file-size column is moved to the left and the extra whitespace reclaimed?

@carlcotner
Copy link
Author

carlcotner commented Jan 3, 2017

Turning off show-trailing-whitespace for the minibuffer is simple. I'll record it here for reference:
(add-hook 'minibuffer-setup-hook (lambda () (setq show-trailing-whitespace nil)))

@Yevgnen
Copy link
Owner

Yevgnen commented Jan 3, 2017

Hi, thanks for addressing the issues of the package in terminal emacs.

For second, I will try to find a better solution of it.

For third, since the transformer process the candidate one by one, and the path column has ready dynamically determined based on the window width and other length of columns, so I think it would a bit difficult to dynamically determine the width of buffer name too(the file size column position is indeed the width of file name column). A possible bad solution is to read the buffer list and recentf list to find the suitable length each time processing a candidate. But I doubt whether this is necessary and I guess a 30~40 file name width shall be enough in most situations?

@carlcotner
Copy link
Author

Yes, you're right. I reduced ivy-rich-switch-buffer-name-max-length from 48 to 35, and that was enough to clear up all the specific formatting problems I saw. Thanks.

I don't know much about Emacs overlays and other advanced display stuff, but I will mention one other thing that may be of interest to you if you're not aware of it. I just discovered that Emacs hl-line-mode highlights the full width of the current line whether the line in the buffer spans the whole width of the window or not. This doesn't quite work:

(add-hook 'minibuffer-setup-hook (lambda () (setq hl-line-mode t)))

but whatever hl-line-mode is doing to achieve whole-line highlighting should allow ivy-rich to be able to highlight all the way to the very right side of the window, and independent of actual line length, if you'd like.

@Yevgnen
Copy link
Owner

Yevgnen commented Jan 4, 2017

I don't know much about Emacs overlays too and I'm quite new to programming in elisp😅. I use hl-line-mode in my normal buffers but I don't use it in minibuffer since the ivy candidate has its own faces ivy-current-match and ivy-minibuffer-match-*. I guessed using both will cause thing mess up before but I tried just now and found that even disabling ivy-rich, hl-line-mode did not play well with ivy. Maybe they use different techniques to handle the faces or maybe some conflicts there. I'll try to figure out it when I have time.

For the issue

Second, for the Recentf files (added for Issue #4), files with long path names wrap, even though the paths are abbreviated with an ellipsis, when either the first or last directory name is itself long. I'm not sure what a good solution is in this case. Perhaps abbreviating long first and last directory components with ellipses?

I've tried to modified the shorten function. Previous a path /a/b/c/d/e/f.el will be always shortened to /a/…/e/f.el when it's too long but now the function will try /a/…/c/d/e/f.el then /a/…/d/e/f.el then /a/…/e/f.el then /a/…/f.el till its length <= max-allow-length. The first directory name /a can still be abbreviated but I think we need to find a suitable representation of the abbreviated path since .../f.el is bit confusing and ../../../../../f.el maybe a bit inelegant😅.

@madand
Copy link

madand commented Apr 13, 2017

To make long buffer names/paths not wrap (in terminal) or visually skew otherwise nice looking columns, I use modified version of ivy-rich-switch-buffer-pad that truncates inputs that are too long:

(defun madand-base/ivy-rich-switch-buffer-pad (str len &optional left)
  "Improved version of `ivy-rich-switch-buffer-pad' that truncates long inputs."
  (let ((real-len (length str)))
    (cond
     ((< real-len len) (if left
                           (concat (make-string (- len real-len) ? ) str)
                         (concat str (make-string (- len real-len) ? ))))
     ((= len real-len) str)
     (t (concat (substring str 0 (- len 1)) "")))))

;; Override the original function using advice
(advice-add 'ivy-rich-switch-buffer-pad :override #'madand-base/ivy-rich-switch-buffer-pad)

@amosbird
Copy link

amosbird commented Dec 1, 2017

@madand Hi, this doesn't work if emacs window's width is small. I get

Debugger entered--Lisp error: (args-out-of-range "" 0 -5)
  substring("" 0 -5)
  (concat (substring str 0 (- len 1)) "…")
  (cond ((< real-len len) (if left (concat (make-string (- len real-len) 32) str) (concat str (make-string (- len real-len) 32)))) ((= len real-len) str) (t (concat (substring str 0 (- len 1)) "…")))
  (let ((real-len (length str))) (cond ((< real-len len) (if left (concat (make-string (- len real-len) 32) str) (concat str (make-string (- len real-len) 32)))) ((= len real-len) str) (t (concat (substring str 0 (- len 1)) "…"))))
  +amos*ivy-rich-switch-buffer-pad("" -4)
  apply(+amos*ivy-rich-switch-buffer-pad ("" -4))
  ivy-rich-switch-buffer-pad("" -4)
  ivy-rich-switch-buffer-path(#("               " 0 15 (face success)))
  ivy-rich-switch-buffer-transformer("*scratch*")
  mapcar(ivy-rich-switch-buffer-transformer ("evil-jumps.el" "buffer.c" "cl-macs.el.gz" "ring.el.gz" "gv.el.gz" "evil-commands.el" "*scratch*" "amos-dired.el" "centos.txt" "*magit: htop-vim" "Action.c"))
  ivy--format(("evil-jumps.el" "buffer.c" "cl-macs.el.gz" "ring.el.gz" "gv.el.gz" "evil-commands.el" "*scratch*" "amos-dired.el" "centos.txt" "*magit: htop-vim" "Action.c" "Process.c" "htop.1.in" "LinuxProcess.c" #("clickhouse.org" 0 14 (face org-level-4)) "Makefile" "*Messages*" "*Compile-Log*" "*Ediff Registry*" "*vc*" "MainPanel.c" "Panel.c" "Panel.h" "ScreenManager.c" "README" "*magit-process: htop-vim" "*magit-revision: htop-vim" "*magit-log: htop-vim" "*magit-diff: htop-vim" #("*tramp/sudo root@t450s*" 0 23 (face ivy-remote)) "*Dired log*" "*helm-dash-errors*" "*Semantic SymRef*" "company-stats-cache.el" "*Help*" "*magit-log: evil" "*magit-diff: evil" "*magit-process: evil" "*magit: evil" #("/home/amos/git/evil/evil-jumps.el" 0 33 (face ivy-virtual)) #("/home/amos/.emacs.d/modules/private/amos/init.el" 0 48 (face ivy-virtual)) #("/home/amos/.emacs.d/modules/private/amos/cc/config.el" 0 53 (face ivy-virtual)) #("/sudo:root@t450s:/etc/profile.d/clojure.sh" 0 42 (face ivy-virtual)) #("/home/amos/.emacs.d/.local/@t450s/etc/bookmarks" 0 47 (face ivy-virtual)) #("/home/amos/git/htop-vim/Makefile.am" 0 35 (face ivy-virtual)) #("/home/amos/git/htop-vim/Makefile.in" 0 35 (face ivy-virtual)) #("/home/amos/notes/gcc.txt" 0 24 (face ivy-virtual)) #("/home/amos/.tmux/.tmux.conf.amos" 0 32 (face ivy-virtual)) #("/home/amos/dotfiles/scripts/g201.sh" 0 35 (face ivy-virtual)) #("/home/amos/dotfiles/scripts/lab142" 0 34 (face ivy-virtual)) ...))
  ivy--exhibit()
  ivy--minibuffer-setup()
  #[0 "\302\303\301\242\"\210\300 \207" [ivy--minibuffer-setup (#0) remove-hook minibuffer-setup-hook] 3]()
  read-from-minibuffer("Switch to buffer: " nil (keymap (keymap) keymap (21 . ivy-kill-line) (M-backspace . ivy-backward-kill-word) (23 . ivy-yank-word) (12 . ivy-alt-done) (11 . ivy-previous-line) (escape . keyboard-escape-quit) (3 keymap (19 . ivy-rotate-sort) (1 . ivy-toggle-ignore) (15 . ivy-occur)) (67108903 . ivy-avy) (33554464 . ivy-restrict-to-matches) (15 . +ivy@coo/body) (22 . ivy-scroll-up-command) (prior . ivy-scroll-down-command) (next . ivy-scroll-up-command) (7 . minibuffer-keyboard-quit) (32 . self-insert-command) (18 . evil-paste-from-register) (19 . ivy-next-line-or-history) (remap keymap (describe-mode . ivy-help) (kill-ring-save . ivy-kill-ring-save) (kill-line . ivy-kill-line) (scroll-down-command . ivy-scroll-down-command) (scroll-up-command . ivy-scroll-up-command) (end-of-buffer . ivy-end-of-buffer) (beginning-of-buffer . ivy-beginning-of-buffer) (kill-word . ivy-kill-word) (forward-char . ivy-forward-char) (delete-char . ivy-delete-char) (backward-kill-word . ivy-backward-kill-word) (backward-delete-char-untabify . ivy-backward-delete-char) (delete-backward-char . ivy-backward-delete-char) (previous-line . ivy-previous-line) (next-line . ivy-next-line)) (9 . ivy-call-and-recenter) (10 . ivy-next-line) (27 keymap (102 . forward-word) (98 . backward-word) (122 . undo) (1 . ivy-read-action) (15 . ivy-dispatching-call) (111 . ivy-dispatching-done-hydra) (105 . ivy-insert-current) (106 . ivy-immediate-done) (114 . ivy-toggle-regexp-quote) (16 . ivy-previous-line-and-call) (14 . ivy-next-line-and-call) (118 . ivy-scroll-down-command) (112 . ivy-previous-history-element) (110 . ivy-next-history-element) (10 . ivy-immediate-done) (13 . ivy-call)) (13 . ivy-done)) nil ivy-history)
  ivy-read("Switch to buffer: " internal-complete-buffer :matcher ivy--switch-buffer-matcher :preselect "evil" :action ivy--switch-buffer-action :keymap (keymap) :caller ivy-switch-buffer)
  ivy-switch-buffer()
  funcall-interactively(ivy-switch-buffer)
  call-interactively(ivy-switch-buffer nil nil)
  command-execute(ivy-switch-buffer)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants