Override default settings in NvChad Nvim - neovim

I wish to change the layout_strategy for the telescope plugin from the NvChad default value of horizontal to vertical. This should be possible by setting layout_strategy = "vertical" somewhere...
According to the NvChad docs I can override the default settings specified in plugins/configs/telescope.lua in my own custom/init.lua, but I also found that it could/should be done in the custom/chadrc.lua.
Question
What line(s) do I have to add to what file to change the default layout_strategy for the telescope plugin, and only that (keeping other defaults intact)?
I have tried adding to
custom/chadrc.lua
M.telescope = {
layout_strategy = "vertical"
}
Also tried
M.telescope = {
defaults = {
layout_strategy = "vertical",
},
}
}
and
local o = vim.telescope.defaults
o.layout_strategy = "vertical"
But that does not seem to work.

In your chadrc.lua you would override options like so:
M.plugins = {
-- ...
["nvim-telescope/telescope.nvim"] = {
override_options = function()
return {
defaults = {
layout_strategy = "vertical",
layout_config = {
height = 0.95,
prompt_position = "top",
vertical = {
mirror = true,
preview_cutoff = 0,
},
},
},
}
end,
},
-- ...
}
I included my additional layout_config in case you want to have the preview part in the bottom half. Also preview_cutoff was necessary for me or the preview would never show up.
Essentially, the returned table of override_options will forcefully extend the default configs provided by NvChad and the result table would be passed into the setup function of the plugin.
Defining override_options is the way to go for pre-installed plugins of NvChad. If you deal with a new custom plugin, you'd rather need to call the setup function of the plugin on your own in the config function of the plugin declaration like so:
M.plugins = {
-- ...
["any-vendor/any-custom-plugin.nvim"] = {
config = function()
require('custom-plugin').setup({
-- ...
})
end,
},
-- ...
}
This is not relevant for telescope.nvim, since it is pre-installed, but I wanted to address this for completeness anyways.

Related

How to dynamically change gutter icons in VSCode with TextEditor.setDecorations()

I am getting some odd behavior when updating gutter icons in VSCode using TextEditor.setDecorations() https://code.visualstudio.com/api/references/vscode-api#TextEditor.
On activate of my VSCode extension the class below is instantiated and it's constructor called which "one-time" creates 3 TextEditorDecorationType's https://code.visualstudio.com/api/references/vscode-api#TextEditorDecorationType, one for each state that a test result can be in represented by a NONE, PASS, FAIL icon and finally triggerUpdateDecorations() is called to collect the current globalResults within 3 arrays and set the gutter icons with vscode.window.activeTextEditor.setDecorations()
So far everything works as expected. No tests have been run and every test shown in the editor is updated with a NONE gutter icon.
Now as each test is run in the editor, on completion, triggerUpdateDecorations() is called once again to collect results and update the gutter icons.
If there are for example 10 tests in the editor, each with a NONE gutter icon, if I run a single test that test correctly updates with either a PASS or FAIL gutter icon. This behavior repeats itself for all subsequent tests run, except for the last one. The last test run remains set with its NONE gutter icon. It's not tied to a specific test as I can jump around and the behavior follows the last test run.
I've tried adding a dummy NONE icon to a random place in the gutter not tied to a test and that allows all gutter icons tied to a test to be updated with PASS or FAIL gutter icons.
I've been experimenting a lot to try and solve this and can't seem to find the root cause. Greatly appreciate any insights on how to solve this.
Note some of this code stems from the VSCode Samples shown here
https://github.com/microsoft/vscode-extension-samples/blob/main/decorator-sample/src/extension.ts#L58
import * as path from 'path';
import * as vscode from 'vscode';
class ProviderDecorations
{
private timeout: NodeJS.Timeout;
private context: vscode.ExtensionContext;
private activeEditor: vscode.TextEditor;
private readonly decorationNone: vscode.TextEditorDecorationType;
private readonly decorationPass: vscode.TextEditorDecorationType;
private readonly decorationFail: vscode.TextEditorDecorationType;
constructor(context: vscode.ExtensionContext)
{
this.context = context;
this.activeEditor = vscode.window.activeTextEditor;
this.decorationNone = this.getDecorationType(ENTRY_STATE.NONE);
this.decorationPass = this.getDecorationType(ENTRY_STATE.PASS);
this.decorationFail = this.getDecorationType(ENTRY_STATE.FAIL);
vscode.window.onDidChangeActiveTextEditor(editor =>
{
this.activeEditor = editor;
if (editor)
{
this.triggerUpdateDecorations();
}
}, null, this.context.subscriptions);
vscode.workspace.onDidChangeTextDocument(event =>
{
if (this.activeEditor && event.document === this.activeEditor.document)
{
this.triggerUpdateDecorations();
}
}, null, this.context.subscriptions);
this.triggerUpdateDecorations();
}
public updateDecorations()
{
if (!this.activeEditor)
{
return;
}
let rangeNone = [];
let rangePass = [];
let rangeFail = [];
globalResults.forEach((result) =>
{
let range = new vscode.Range(result.line, 0, result.line, 0);
switch (result.state)
{
case ENTRY_STATE.NONE:
rangeNone.push({ range });
break;
case ENTRY_STATE.PASS:
rangePass.push({ range });
break;
case ENTRY_STATE.FAIL:
rangeFail.push({ range });
break;
}
});
if (rangePass.length > 0)
{
this.activeEditor.setDecorations(this.decorationPass, rangePass);
}
if (rangeFail.length > 0)
{
this.activeEditor.setDecorations(this.decorationFail, rangeFail);
}
if (rangeNone.length > 0)
{
this.activeEditor.setDecorations(this.decorationNone, rangeNone);
}
}
private getDecorationType(state: ENTRY_STATE): vscode.TextEditorDecorationType
{
let icon = 'none.svg';
if (state === ENTRY_STATE.PASS)
{
icon = 'pass.svg';
}
else if (state === ENTRY_STATE.FAIL)
{
icon = 'fail.svg';
}
const decorationType = vscode.window.createTextEditorDecorationType(
{
light:
{
gutterIconPath: path.join(__dirname, '..', 'resources', 'light', icon),
gutterIconSize: '85%',
},
dark:
{
gutterIconPath: path.join(__dirname, '..', 'resources', 'dark', icon),
gutterIconSize: '85%'
}
});
return decorationType;
}
public triggerUpdateDecorations()
{
if (this.timeout)
{
clearTimeout(this.timeout);
this.timeout = undefined;
}
this.timeout = setTimeout(() =>
{
this.updateDecorations();
}, 250);
}
}
export default ProviderDecorations;
You never clear a Decorator type, remove the if (rangePass.length > 0) parts
this.activeEditor.setDecorations(this.decorationPass, rangePass);
this.activeEditor.setDecorations(this.decorationFail, rangeFail);
this.activeEditor.setDecorations(this.decorationNone, rangeNone);

Display values outside of pie chart in chartjs

When I hover on pie chart, the values are displayed in tooltip. However, I want to display values outside of pie chart. I want to make chart like this image:
How to do this?
I was able to get something similar working using chart.js v2.3.0 using both the plugin API and extending chart types API. You should be able to take this as a starting point and tweak it to your needs.
Here is how it looks after being rendered.
Note, this requires digging deep into chart.js internals and could break if they change the way tooltips are positioned or rendered in the future. I also added a new configuration option called showAllTooltips to enable selectively using the plugin on certain charts. This should work for all chart types, but I am currently only using it for pie, doughnut, bar, and line charts so far.
With that said, here is a working solution for the image above.
Chart.plugins.register({
beforeRender: function (chart) {
if (chart.config.options.showAllTooltips) {
// create a namespace to persist plugin state (which unfortunately we have to do)
if (!chart.showAllTooltipsPlugin) {
chart.showAllTooltipsPlugin = {};
}
// turn off normal tooltips in case it was also enabled (which is the global default)
chart.options.tooltips.enabled = false;
// we can't use the chart tooltip because there is only one tooltip per chart which gets
// re-positioned via animation steps.....so let's create a place to hold our tooltips
chart.showAllTooltipsPlugin.tooltipsCollection = [];
// create a tooltip for each plot on the chart
chart.config.data.datasets.forEach(function (dataset, i) {
chart.getDatasetMeta(i).data.forEach(function (sector, j) {
// but only create one for pie and doughnut charts if the plot is large enough to even see
if (!_.contains(['doughnut', 'pie'], sector._chart.config.type) || sector._model.circumference > 0.1) {
var tooltip;
// create a new tooltip based upon configuration
if (chart.config.options.showAllTooltips.extendOut) {
// this tooltip reverses the location of the carets from the default
tooltip = new Chart.TooltipReversed({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options.tooltips,
_active: [sector]
}, chart);
} else {
tooltip = new Chart.Tooltip({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options.tooltips,
_active: [sector]
}, chart);
}
// might as well initialize this now...it would be a waste to do it once we are looping over our tooltips
tooltip.initialize();
// save the tooltips so they can be rendered later
chart.showAllTooltipsPlugin.tooltipsCollection.push(tooltip);
}
});
});
}
},
afterDraw: function (chart, easing) {
if (chart.config.options.showAllTooltips) {
// we want to wait until everything on the chart has been rendered before showing the
// tooltips for the first time...otherwise it looks weird
if (!chart.showAllTooltipsPlugin.initialRenderComplete) {
// still animating until easing === 1
if (easing !== 1) {
return;
}
// animation is complete, let's remember that fact
chart.showAllTooltipsPlugin.initialRenderComplete = true;
}
// at this point the chart has been fully rendered for the first time so start rendering tooltips
Chart.helpers.each(chart.showAllTooltipsPlugin.tooltipsCollection, function (tooltip) {
// create a namespace to persist plugin state within this tooltip (which unfortunately we have to do)
if (!tooltip.showAllTooltipsPlugin) {
tooltip.showAllTooltipsPlugin = {};
}
// re-enable this tooltip otherise it won't be drawn (remember we disabled all tooltips in beforeRender)
tooltip._options.enabled = true;
// perform standard tooltip setup (which determines it's alignment and x, y coordinates)
tooltip.update(); // determines alignment/position and stores in _view
tooltip.pivot(); // we don't actually need this since we are not animating tooltips, but let's be consistent
tooltip.transition(easing).draw(); // render and animate the tooltip
// disable this tooltip in case something else tries to do something with it later
tooltip._options.enabled = false;
});
}
},
});
// A 'reversed' tooltip places the caret on the opposite side from the current default.
// In order to do this we just need to change the 'alignment' logic
Chart.TooltipReversed = Chart.Tooltip.extend({
// Note: tooltipSize is the size of the box (not including the caret)
determineAlignment: function(tooltipSize) {
var me = this;
var model = me._model;
var chart = me._chart;
var chartArea = me._chartInstance.chartArea;
// set caret position to top or bottom if tooltip y position will extend outsite the chart top/bottom
if (model.y < tooltipSize.height) {
model.yAlign = 'top';
} else if (model.y > (chart.height - tooltipSize.height)) {
model.yAlign = 'bottom';
}
var leftAlign, rightAlign; // functions to determine left, right alignment
var overflowLeft, overflowRight; // functions to determine if left/right alignment causes tooltip to go outside chart
var yAlign; // function to get the y alignment if the tooltip goes outside of the left or right edges
var midX = (chartArea.left + chartArea.right) / 2;
var midY = (chartArea.top + chartArea.bottom) / 2;
if (model.yAlign === 'center') {
leftAlign = function(x) {
return x >= midX;
};
rightAlign = function(x) {
return x < midX;
};
} else {
leftAlign = function(x) {
return x <= (tooltipSize.width / 2);
};
rightAlign = function(x) {
return x >= (chart.width - (tooltipSize.width / 2));
};
}
overflowLeft = function(x) {
return x - tooltipSize.width < 0;
};
overflowRight = function(x) {
return x + tooltipSize.width > chart.width;
};
yAlign = function(y) {
return y <= midY ? 'bottom' : 'top';
};
if (leftAlign(model.x)) {
model.xAlign = 'left';
// Is tooltip too wide and goes over the right side of the chart.?
if (overflowLeft(model.x)) {
model.xAlign = 'center';
model.yAlign = yAlign(model.y);
}
} else if (rightAlign(model.x)) {
model.xAlign = 'right';
// Is tooltip too wide and goes outside left edge of canvas?
if (overflowRight(model.x)) {
model.xAlign = 'center';
model.yAlign = yAlign(model.y);
}
}
}
});

How to disable animation in sap.m.ProgressIndicator on "percentValue" change?

As the title says, how to make the sap.m.ProgressIndicator not animated when changing the percent value of it?
I cannot find a method for it, and extending would probably be the way to go, but maybe somebody has already figured it out and done it?
My Google search was not successful though.
interesting question, below is the sap.m.ProgressIndication.prototype.setPercentValue function, you can see when the percent value changes the bars values is changed via an linear animation
My suggestion, the easiest way to change this behavior is to extend the control to your own control and to redefine the setPercentValue, either remove the animate function on the bar or set time to null so there is no animation
sap.m.ProgressIndicator.prototype.setPercentValue = function(fPercentValue) {
var that = this;
...
if (that.getPercentValue() != fPercentValue) {
// animation without rerendering
this.$().addClass("sapMPIAnimate");
var time = Math.abs(that.getPercentValue() - fPercentValue) * 20;
this.setProperty("percentValue", fPercentValue, true);
var $Bar = this.$("bar");
$Bar.animate({
width : fPercentValue + "%"
}, time, "linear", function() {
that._setText.apply(that);
that.$().removeClass("sapMPIAnimate");
});
}
something like
jQuery.sap.declare("my.ProgressIndicator");
jQuery.sap.require("sap.m.ProgressIndicator");
sap.m.ProgressIndicator.extend("my.ProgressIndicator", {
renderer: {}
});
my.ProgressIndicator.prototype.setPercentValue = function(fPercentValue) {
var that = this;
// validation of fPercentValue
if (typeof (fPercentValue) == "number") {
if (that.getPercentValue() != fPercentValue) {
// animation without rerendering
this.$().addClass("sapMPIAnimate");
//var time = Math.abs(that.getPercentValue() - fPercentValue) * 20;
var time = 0;
this.setProperty("percentValue", fPercentValue, true);
var $Bar = this.$("bar");
$Bar.animate({
width : fPercentValue + "%"
}, time, "linear", function() {
that._setText.apply(that);
that.$().removeClass("sapMPIAnimate");
});
}
return this;
};
There is no convenient method to suppress this behavior.
You can only extend the control and overwrite the method setPercentValue to you desired behavior.
As of UI5 1.73, the animation on percantageValue-change can be turned off by setting the property displayAnimation to false.
Determines whether a percentage change is displayed with animation.
Since: 1.73.
<ProgressIndicator displayAnimation="false" />

how to have minimum AreaRegistrations with putting duplicated elements in single place

i have several AreaRegistration classes which one each registers own routes and each one have some duplicated elements such as bolded text in below:
context.MapRoute("Search", "**{culture}/{style}**/search",
new
{
**culture = cultureValue,
style = styleValue,**
controller = "search",
action = "default"
},
new
{
**culture = new CultureRouteConstraint(),
style = new StyleRouteConstraint()**
});
how i can have minimum AreaRegistrations with putting duplicated elements in single place which handles that? this is possible?
You can add routes to the Global.asax file and use the area route value. For example:
routes.MapRoute("Search", "{culture}/{style}/search", new
{
culture = cultureValue,
style = styleValue,
controller = "search",
action = "default",
area = "areaName"
});

is there an alternative to DOMAttrModified that will work in webkit

I need to leverage this DOM event. IE has onpropertychange, which does what I need it to do also. Webkit doesn't seem to support this event, however. Is there an alternative I could use?
Although Chrome does not dispatch DOMAttrModified events, the more lightweighted mutation observers are supported since 2011 and these work for attribute changes, too.
Here is an example for the document body:
var element = document.body, bubbles = false;
var observer = new WebKitMutationObserver(function (mutations) {
mutations.forEach(attrModified);
});
observer.observe(element, { attributes: true, subtree: bubbles });
function attrModified(mutation) {
var name = mutation.attributeName,
newValue = mutation.target.getAttribute(name),
oldValue = mutation.oldValue;
console.log(name, newValue, oldValue);
}
For a simple attribute change, the console.log statement would print:
<body color="black">
<script type="text/html">
document.body.setAttribute("color", "red");
</script>
</body>
Console:
> color red black
If you are happy with merely detecting calls to setAttribute() (as opposed to monitoring all attribute modifications) then you could over-ride that method on all elements with:
Element.prototype._setAttribute = Element.prototype.setAttribute
Element.prototype.setAttribute = function(name, val) {
var e = document.createEvent("MutationEvents");
var prev = this.getAttribute(name);
this._setAttribute(name, val);
e.initMutationEvent("DOMAttrModified", true, true, null, prev, val, name, 2);
this.dispatchEvent(e);
}
I had the same question and was thinking of modifying setAttribute, so seeing what Sean did, I copied that. Worked great, except that it was firing when an attribute was repeatedly set to the same value, so I added a check to my copy to skip firing the event if the value is not being changed. I also added val = String(val), based on the rationale that setAttribute will coerce numbers to strings, so the comparison should anticipate that.
My modified version is:
var emulateDOMAttrModified = {
isSupportedNatively: function () {
var supported = false;
function handler() {
supported = true;
}
document.addEventListener('DOMAttrModified', handler);
var attr = 'emulateDOMAttrModifiedTEST';
document.body.setAttribute(attr, 'foo'); // aka $('body').attr(attr, 'foo');
document.removeEventListener('DOMAttrModified', handler);
document.body.removeAttribute(attr);
return supported;
},
install: function () {
if (!this.isSupportedNatively() &&
!Element.prototype._setAttribute_before_emulateDOMAttrModified) {
Element.prototype._setAttribute_before_emulateDOMAttrModified = Element.prototype.setAttribute
Element.prototype.setAttribute = function(name, val) {
var prev = this.getAttribute(name);
val = String(val); /* since attributes do type coercion to strings,
do type coercion here too; in particular, D3 animations set x and y to a number. */
if (prev !== val) {
this._setAttribute_before_emulateDOMAttrModified(name, val);
var e = document.createEvent('MutationEvents');
e.initMutationEvent('DOMAttrModified', true, true, null, prev, val, name, 2);
this.dispatchEvent(e);
}
};
}
}
};
// Install this when loaded. No other file needs to reference this; it will just make Chrome and Safari
// support the standard same as Firefox does.
emulateDOMAttrModified.install();
Please refer code:
https://github.com/meetselva/attrchange/blob/master/attrchange.js
'DOMAttrModified' + ('propertychange' for IE) are used there like in your case. If it's not suitable for you, the "ugly" solution that can satisfy this demand should be setInterval(function(){}, delay)
Otherwise see Sean Hogan post above.
The solution provided by #Filip is close (and may have worked at the time) but now you need to request delivery of the old attribute value.
Thus, you'll want to change :
observer.observe(element, { attributes: true, subtree: bubbles });
to this:
observer.observe(element, { attributes: true, attributeOldvalue:true, subtree: bubbles });
Otherwise, you won't see the oldValues (you'll get null instead.) This was tested in Chrome 34.0.1847.131 (Official Build 265687) m.