Skip to content

Commit cda498f

Browse files
Added support for customizing keyboard shortcuts in the Query Tool's Edit menu. #2659
1 parent 67c18cb commit cda498f

File tree

6 files changed

+227
-181
lines changed

6 files changed

+227
-181
lines changed

web/pgadmin/static/js/components/ReactCodeMirror/index.jsx

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import { styled } from '@mui/material/styles';
1212
import FileCopyRoundedIcon from '@mui/icons-material/FileCopyRounded';
1313
import CheckRoundedIcon from '@mui/icons-material/CheckRounded';
1414
import PropTypes from 'prop-types';
15+
import { startCompletion } from '@codemirror/autocomplete';
16+
import { format } from 'sql-formatter';
1517

1618
import gettext from 'sources/gettext';
1719
import { PgIconButton } from '../Buttons';
@@ -22,6 +24,8 @@ import Editor from './components/Editor';
2224
import CustomPropTypes from '../../custom_prop_types';
2325
import FindDialog from './components/FindDialog';
2426
import GotoDialog from './components/GotoDialog';
27+
import usePreferences from '../../../../preferences/static/js/store';
28+
import { toCodeMirrorKey } from '../../utils';
2529

2630
const Root = styled('div')(() => ({
2731
position: 'relative',
@@ -64,25 +68,71 @@ export default function CodeMirror({className, currEditor, showCopyBtn=false, cu
6468
const [[showFind, isReplace, findKey], setShowFind] = useState([false, false, false]);
6569
const [showGoto, setShowGoto] = useState(false);
6670
const [showCopy, setShowCopy] = useState(false);
71+
const preferences = usePreferences().getPreferencesForModule('sqleditor');
72+
73+
const formatSQL = (view)=>{
74+
let selection = true, sql = view.getSelection();
75+
/* New library does not support capitalize casing
76+
so if a user has set capitalize casing we will
77+
use preserve casing which is default for the library.
78+
*/
79+
let formatPrefs = {
80+
language: 'postgresql',
81+
keywordCase: preferences.keyword_case === 'capitalize' ? 'preserve' : preferences.keyword_case,
82+
identifierCase: preferences.identifier_case === 'capitalize' ? 'preserve' : preferences.identifier_case,
83+
dataTypeCase: preferences.data_type_case,
84+
functionCase: preferences.function_case,
85+
logicalOperatorNewline: preferences.logical_operator_new_line,
86+
expressionWidth: preferences.expression_width,
87+
linesBetweenQueries: preferences.lines_between_queries,
88+
tabWidth: preferences.tab_size,
89+
useTabs: !preferences.use_spaces,
90+
denseOperators: !preferences.spaces_around_operators,
91+
newlineBeforeSemicolon: preferences.new_line_before_semicolon
92+
};
93+
if(sql == '') {
94+
sql = view.getValue();
95+
selection = false;
96+
}
97+
let formattedSql = format(sql,formatPrefs);
98+
if(selection) {
99+
view.replaceSelection(formattedSql);
100+
} else {
101+
view.setValue(formattedSql);
102+
}
103+
};
67104

68105
const finalCustomKeyMap = useMemo(()=>[{
69-
key: 'Mod-f', run: () => {
106+
key: toCodeMirrorKey(preferences.find), run: () => {
70107
setShowFind(prevVal => [true, false, !prevVal[2]]);
71108
},
72109
preventDefault: true,
73110
stopPropagation: true,
74111
}, {
75-
key: 'Mod-Alt-f', run: () => {
112+
key: toCodeMirrorKey(preferences.replace), run: () => {
76113
setShowFind(prevVal => [true, true, !prevVal[2]]);
77114
},
78115
preventDefault: true,
79116
stopPropagation: true,
80117
}, {
81-
key: 'Mod-l', run: () => {
118+
key: toCodeMirrorKey(preferences.goto_line_col), run: () => {
82119
setShowGoto(true);
83120
},
84121
preventDefault: true,
85122
stopPropagation: true,
123+
}, {
124+
key: toCodeMirrorKey(preferences.comment), run: () => {
125+
editor.current?.execCommand('toggleComment');
126+
},
127+
preventDefault: true,
128+
stopPropagation: true,
129+
},{
130+
key: toCodeMirrorKey(preferences.format_sql), run: formatSQL,
131+
preventDefault: true,
132+
stopPropagation: true,
133+
},{
134+
key: toCodeMirrorKey(preferences.autocomplete), run: startCompletion,
135+
preventDefault: true,
86136
},
87137
...customKeyMap], [customKeyMap]);
88138

@@ -148,5 +198,5 @@ CodeMirror.propTypes = {
148198
className: CustomPropTypes.className,
149199
showCopyBtn: PropTypes.bool,
150200
customKeyMap: PropTypes.array,
151-
onTextSelect:PropTypes.func
201+
onTextSelect:PropTypes.func,
152202
};

web/pgadmin/tools/sqleditor/static/js/components/QueryToolComponent.jsx

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -92,36 +92,6 @@ function setPanelTitle(docker, panelId, title, qtState, dirty=false) {
9292
}
9393

9494
const FIXED_PREF = {
95-
find: {
96-
'control': true,
97-
ctrl_is_meta: true,
98-
'shift': false,
99-
'alt': false,
100-
'key': {
101-
'key_code': 70,
102-
'char': 'F',
103-
},
104-
},
105-
replace: {
106-
'control': true,
107-
ctrl_is_meta: true,
108-
'shift': false,
109-
'alt': true,
110-
'key': {
111-
'key_code': 70,
112-
'char': 'F',
113-
},
114-
},
115-
gotolinecol: {
116-
'control': true,
117-
ctrl_is_meta: true,
118-
'shift': false,
119-
'alt': false,
120-
'key': {
121-
'key_code': 76,
122-
'char': 'L',
123-
},
124-
},
12595
indent: {
12696
'control': false,
12797
'shift': false,
@@ -140,26 +110,6 @@ const FIXED_PREF = {
140110
'char': 'Tab',
141111
},
142112
},
143-
comment: {
144-
'control': true,
145-
ctrl_is_meta: true,
146-
'shift': false,
147-
'alt': false,
148-
'key': {
149-
'key_code': 191,
150-
'char': '/',
151-
},
152-
},
153-
format_sql: {
154-
'control': true,
155-
ctrl_is_meta: true,
156-
'shift': false,
157-
'alt': false,
158-
'key': {
159-
'key_code': 75,
160-
'char': 'k',
161-
},
162-
},
163113
};
164114

165115
export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedNodeInfo, qtPanelDocker, qtPanelId, eventBusObj}) {

web/pgadmin/tools/sqleditor/static/js/components/QueryToolConstants.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ export const QUERY_TOOL_EVENTS = {
2626
TRIGGER_INCLUDE_EXCLUDE_FILTER: 'TRIGGER_INCLUDE_EXCLUDE_FILTER',
2727
TRIGGER_REMOVE_FILTER: 'TRIGGER_REMOVE_FILTER',
2828
TRIGGER_SET_LIMIT: 'TRIGGER_SET_LIMIT',
29-
TRIGGER_FORMAT_SQL: 'TRIGGER_FORMAT_SQL',
3029
TRIGGER_GRAPH_VISUALISER: 'TRIGGER_GRAPH_VISUALISER',
3130
TRIGGER_SELECT_ALL: 'TRIGGER_SELECT_ALL',
3231
TRIGGER_SAVE_QUERY_TOOL_DATA: 'TRIGGER_SAVE_QUERY_TOOL_DATA',

web/pgadmin/tools/sqleditor/static/js/components/sections/MainToolBar.jsx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -291,9 +291,6 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
291291
setLimit(e.target.value);
292292
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_SET_LIMIT,e.target.value);
293293
};
294-
const formatSQL=()=>{
295-
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_FORMAT_SQL);
296-
};
297294
const toggleCase=()=>{
298295
eventBus.fireEvent(QUERY_TOOL_EVENTS.EDITOR_TOGGLE_CASE);
299296
};
@@ -444,12 +441,6 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
444441
callback: ()=>{clearQuery();}
445442
}
446443
},
447-
{
448-
shortcut: queryToolPref.format_sql,
449-
options: {
450-
callback: ()=>{formatSQL();}
451-
}
452-
},
453444
], containerRef);
454445

455446
/* Macro shortcuts */
@@ -598,7 +589,7 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
598589
onClick={()=>{eventBus.fireEvent(QUERY_TOOL_EVENTS.EDITOR_FIND_REPLACE, false);}}>{gettext('Find')}</PgMenuItem>
599590
<PgMenuItem shortcut={queryToolPref.replace}
600591
onClick={()=>{eventBus.fireEvent(QUERY_TOOL_EVENTS.EDITOR_FIND_REPLACE, true);}}>{gettext('Replace')}</PgMenuItem>
601-
<PgMenuItem shortcut={queryToolPref.gotolinecol}
592+
<PgMenuItem shortcut={queryToolPref.goto_line_col}
602593
onClick={()=>{executeCmd('gotoLineCol');}}>{gettext('Go to Line/Column')}</PgMenuItem>
603594
<PgMenuDivider />
604595
<PgMenuItem shortcut={queryToolPref.indent}
@@ -612,7 +603,7 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
612603
<PgMenuItem shortcut={queryToolPref.clear_query}
613604
onClick={clearQuery}>{gettext('Clear Query')}</PgMenuItem>
614605
<PgMenuDivider />
615-
<PgMenuItem shortcut={queryToolPref.format_sql} onClick={formatSQL}>{gettext('Format SQL')}</PgMenuItem>
606+
<PgMenuItem shortcut={queryToolPref.format_sql} onClick={()=>{executeCmd('formatSql');}}>{gettext('Format SQL')}</PgMenuItem>
616607
</PgMenu>
617608
<PgMenu
618609
anchorRef={filterMenuRef}

0 commit comments

Comments
 (0)