The eldoc-box-frame-hook might be broken and how to draw a border around the child frame
Thank you for this nice little package. Curious if the following is a bug, and, if not, what one should do instead. I'd like to draw a white border in the child frame. I'm emacs 29.3 on an intel mac, in case the mac drawing code is at fault. I do not have another platform on which to test.
In the function
(defun eldoc-box--get-frame (buffer)
...
(with-selected-frame frame
(run-hook-with-args 'eldoc-box-frame-hook main-frame))
(make-frame-visible frame))))
it seems to me that the hook should be called with the child frame and not the main frame?
Shouldn't this work?
(defun my/eldoc-box-post-frame-hook (frame)
(modify-frame-parameters
eldoc-box--frame ; frame here is the main-frame so force internal reference
`((internal-border-width . ,1))
)
)
(add-hook 'eldoc-box-frame-hook #'my/eldoc-box-post-frame-hook)
By the way, the hacked version doesn't seem to work, either. So maybe it is the mac drawing code at fault?
I looked at my config and I just have
(set-face-attribute 'eldoc-box-border nil :background "darkgray")
Give that a try and see it if works for you.
Hi, and thank you for taking a look. No box border appears at all. The effect I'm trying to achieve is a white box around the pop-up. I've attached a screenshot of what it looks like. I set the height to 0.85 so it's clearly a tooltip (I've done the same for corfu-default). The theme is modus-vivendi from the 29.3 distribution (not prot's latest) if that has any bearing.
Something like this (but only one pixel, ofc (I'd also like a box around the corfu popup, too):
I still wonder if the hook is being called with a reference to the correct child frame or not.
I still wonder if the hook is being called with a reference to the correct child frame or not.
It's working as expected; the docstring says "Each function runs inside the new frame and receives the main frame as argument". So if you want to reference the childframe, you should use current-frame.
If my config doesn't work, then it's probably Emacs 29 on Mac not drawing the border properly. (I remember it not working in the past but I don't remember since when it starts to work :-) Maybe try Emacs master?
I'll keep at it.
This works for me BUT I still don't get why the hook is being passed the frame of the buffer window vs. the child frame.
(defun my/eldoc-box-post-frame-hook (frame)
(modify-frame-parameters
;; the hook sends the parent frame this is not what we want we force the child frame
eldoc-box--frame
`(
(background-color . "white")
(internal-border-width . ,1)
)
)
)
(add-hook 'eldoc-box-frame-hook #'my/eldoc-box-post-frame-hook)
FYI, this cosmetic hack now also eliminates fringes because they create weird visual artifacts in the child frame.
(defun my/eldoc-box-post-frame-hook (_frame)
(modify-frame-parameters
;; the hook sends the parent frame this is not what we want we force the child frame
eldoc-box--frame
`(
(left-fringe . ,0)
(right-fringe . ,0)
(background-color . "white")
(internal-border-width . ,1)
)))
(add-hook 'eldoc-box-frame-hook #'my/eldoc-box-post-frame-hook)
What kind of visual artifacts? Maybe I can fix it without disabling fringes. I kept the left and right fringe so there's a little gap between the text and the border, otherwise the text is right against the border and it doesn't look good.
Internal border would've been the best way to create padding around the text, but we use it for displaying border because childframe doesn't support external border IIRC.
This works for me BUT I still don't get why the hook is being passed the frame of the buffer window vs. the child frame.
Regarding that, it's mainly to have access to both the original buffer and the childframe. Since the hook is called in the child frame (so we already have access to it), we pass the original frame as a parameter.
Here's a screenshot with fringes left enabled.
And one with fringes disabled.
It's also not very nice that the text in the box doesn't wrap properly so some words before eol are put on the next line despite there being plenty of space. Not sure where to look for the culprit.
Hmm, so it's the line-wrap marker. But as you observed, the line shouldn't wrap in the first place. eldoc-box should resize the frame to fit all content, and in this case there're clearly enough room. Could you send me this text? Just click inside the childframe, and C-x h copy all the text in the buffer. I want to see if there's anything funny in the text.
Verbatim:
DataFrame(data=None, index: 'Axes | None'=None, columns: 'Axes | None'=None, dtype: 'Dtype | None'=None, copy: 'bool | None'=None)
Two-dimensional, size-mutable, potentially heterogeneous tabular data.
Data structure also contains labeled axes (rows and columns).
Arithmetic operations align on both row and column labels. Can be
thought of as a dict-like container for Series objects. The primary
pandas data structure.
#### Parameters
- data: ndarray (structured or homogeneous), Iterable, dict, or DataFrame
Dict can contain Series, arrays, constants, dataclass or list-like objects. If
data is a dict, column order follows insertion-order. If a dict contains Series
which have an index defined, it is aligned by its index. This alignment also
occurs if data is a Series or a DataFrame itself. Alignment is done on
Series/DataFrame inputs.
If data is a list of dicts, column order follows insertion-order.
- index: Index or array-like
Index to use for resulting frame. Will default to RangeIndex if
no indexing information part of input data and no index provided.
- columns: Index or array-like
Column labels to use for resulting frame when data does not have them,
defaulting to RangeIndex(0, 1, 2, ..., n). If data contains column labels,
will perform column selection instead.
- dtype: dtype, default None
Data type to force. Only a single dtype is allowed. If None, infer.
- copy: bool or None, default None
Copy data from inputs.
For dict data, the default of None behaves like copy=True. For DataFrame
or 2d ndarray input, the default of None behaves like copy=False.
If data is a dict containing one or more Series (possibly of different dtypes),
copy=False will ensure that these inputs are not copied.
Changed in 1.3.0
#### See Also
- DataFrame.from_records: Constructor from tuples, also record arrays.
- DataFrame.from_dict: From dicts of Series, arrays, or dicts.
- read_csv: Read a comma-separated values (csv) file into DataFrame.
- read_table: Read general delimited file into DataFrame.
- read_clipboard: Read text from clipboard into DataFrame.
#### Notes
Please reference the User Guide: basics.dataframe for more information.
#### Examples
Constructing DataFrame from a dictionary.
d = {'col1': [1, 2], 'col2': [3, 4]}
df = pd.DataFrame(data=d)
df
col1 col2
0 1 3
1 2 4
Notice that the inferred dtype is int64.
df.dtypes
col1 int64
col2 int64
dtype: object
To enforce a single dtype:
df = pd.DataFrame(data=d, dtype=np.int8)
df.dtypes
col1 int8
col2 int8
dtype: object
Constructing DataFrame from a dictionary including Series:
d = {'col1': [0, 1, 2, 3], 'col2': pd.Series([2, 3], index=[2, 3])}
pd.DataFrame(data=d, index=[0, 1, 2, 3])
col1 col2
0 0 NaN
1 1 NaN
2 2 2.0
3 3 3.0
Constructing DataFrame from numpy ndarray:
df2 = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]),
columns=['a', 'b', 'c'])
df2
a b c
0 1 2 3
1 4 5 6
2 7 8 9
Constructing DataFrame from a numpy ndarray that has labeled columns:
data = np.array([(1, 2, 3), (4, 5, 6), (7, 8, 9)],
dtype=[("a", "i4"), ("b", "i4"), ("c", "i4")])
df3 = pd.DataFrame(data, columns=['c', 'a'])
df3
c a
0 3 1
1 6 4
2 9 7
Constructing DataFrame from dataclass:
from dataclasses import make_dataclass
Point = make_dataclass("Point", [("x", int), ("y", int)])
pd.DataFrame([Point(0, 0), Point(0, 3), Point(2, 3)])
x y
0 0 0
1 0 3
2 2 3
Constructing DataFrame from Series/DataFrame:
ser = pd.Series([1, 2, 3], index=["a", "b", "c"])
df = pd.DataFrame(data=ser, index=["a", "c"])
df
0
a 1
c 3
df1 = pd.DataFrame([1, 2, 3], index=["a", "b", "c"], columns=["x"])
df2 = pd.DataFrame(data=df1, index=["a", "c"])
df2
x
a 1
c 3
This could be a hint. I have global-hl-line-mode enabled and you can see it with the subtle dark gray bar over the word "data". It looks like the window width and the frame width are divergent.
Could disable truncate long lines in the doc buffer?