I’m trying to add --cols
CSS variable to jQuery Terminal, the problem I had before was not able to get the size of the scrollbar but got it in JavaScript.
The problem I have now is that when I set --cols: 80
the size is 79
characters. The question is: why this is happening?
const term = $('#term').terminal();
const wrapper = term.find('.terminal-wrapper');
const padding = term[0].style.getPropertyValue('--padding') || 10;
const wrapper_rect = wrapper[0].getBoundingClientRect();
const container_rect = term[0].getBoundingClientRect();
const content_width = wrapper_rect.width + (padding * 2);
const scrollbar = container_rect.width - content_width;
term[0].style.setProperty('--terminal-scrollbar', scrollbar);
term.echo(() => {
const cols = term.cols();
const rows = term.rows();
return `${cols}x${rows}`;
})
#term {
--cols: 80;
--rows: 10;
width: calc((var(--cols) * 1ch) + (var(--padding, 10) * 2px) + (var(--terminal-scrollbar, 10) * 1px));
}
<script src="https://cdn.jsdelivr.net/npm/jquery"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery.terminal/js/jquery.terminal.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/jquery.terminal/css/jquery.terminal.min.css" rel="stylesheet"/>
<div id="term"></div>
.terminal-wrapper
is an element that is inside scrollbar, so it’s just the content that contain text. I tested the cols()
and it returns correct value.
I can fix my issue by adding:
((var(--cols) + 1) * 1ch)
But I want to know why this off by one error is happening. I’m trying to understand and not add a fix blindly.
I’ve tried to set:
.terminal-wrapper {
width: 80ch;
}
Just to see if I will get 80 characters, but I still get 79 characters.
The way I calculate the number of characters is using this function:
function get_char_size(term) {
var result;
if (terminal_ready(term)) {
var $prompt = term.find('.cmd-prompt').clone().css({
visiblity: 'hidden',
position: 'absolute'
});
$prompt.appendTo(term.find('.cmd'))
.html(' ')
.wrap('<div class="cmd-wrapper"/>');
result = {
width: $prompt.width(),
height: $prompt.height()
};
$prompt.parent().remove();
} else {
var temp = $('<div class="terminal terminal-temp"><div class="terminal-' +
'wrapper"><div class="terminal-output"><div><div class="te' +
'rminal-line" style="float: left"><span> </span></div' +
'></div></div><div class="terminal-pixel"></div></div>')
.appendTo('body');
temp.addClass(term.attr('class')).attr('id', term.attr('id'));
if (term) {
var style = term.attr('style');
if (style) {
style = style.split(/s*;s*/).filter(function(s) {
return !s.match(/displays*:s*none/i);
}).join(';');
temp.attr('style', style);
}
}
var node = temp.find('.terminal-line');
result = {
width: node.width(),
height: node.height()
};
temp.remove();
}
return result;
}
function get_num_chars(terminal, char_size) {
var width = terminal.find('.terminal-fill').width();
var result = Math.floor(width / char_size.width);
// random number to not get NaN in node.js but big enough to
// not wrap exception
return result || 1000;
}
It was proven to work correctly.
I thought that it may be a browser bug related to scrollbar-gutter, but I was not able to reproduce the issue, here is a code that do work: https://codepen.io/jcubic/pen/ExqJwMN. I think that I did exactly the same.
I was checking if the font-size is correctly set on the root element and it have the same font and size as content of the terminal.