Skip to content

Commit

Permalink
Merge pull request geany#1350 from scresto09/vimode-fold-support-fix
Browse files Browse the repository at this point in the history
Vimode: implement fold in vimode plugin
  • Loading branch information
techee committed May 25, 2024
2 parents 7da7553 + 5c74ce1 commit 3e38966
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 2 deletions.
11 changes: 10 additions & 1 deletion vimode/README
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ This is an incomplete list of known limitations of the plugin:
* named registers and related commands are not implemented
* Ctrl+X mode is not implemented
* marks are not implemented
* fold commands are not implemented
* many fold commands are not implemented
* most commands starting with "'", "z", and "g" are not implemented
* most ex mode commands are not implemented (excluding basic stuff like search,
replace, saving, etc.)
Expand Down Expand Up @@ -501,7 +501,16 @@ a new command, please do not forget to update the table below.::
cursor on first non-blank
z. z. redraw, cursor line to center of window,
cursor on first non-blank
zA zA open a closed fold or close an open fold
recursively
zC zC close folds recursively
zM zM set 'foldlevel' to zero
zO zO open folds recursively
zR zR set 'foldlevel' to the deepest fold
za za open a closed fold, close an open fold
zb zb redraw, cursor line at bottom of window
zc zc close a fold
zo zo open fold
zt zt redraw, cursor line at top of window
zz zz redraw, cursor line at center of window

Expand Down
4 changes: 3 additions & 1 deletion vimode/src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ vi_srcs = \
cmds/excmds.h \
cmds/excmds.c \
cmds/undo.h \
cmds/undo.c
cmds/undo.c \
cmds/fold.h \
cmds/fold.c

vimode_la_SOURCES = \
backends/backend-geany.c \
Expand Down
10 changes: 10 additions & 0 deletions vimode/src/cmd-runner.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "cmds/changemode.h"
#include "cmds/edit.h"
#include "cmds/special.h"
#include "cmds/fold.h"

#include <gdk/gdkkeysyms.h>

Expand Down Expand Up @@ -262,6 +263,15 @@ CmdDef text_object_cmds[] = {
{cmd_copy_line, GDK_KEY_Y, 0, 0, 0, FALSE, FALSE}, \
{cmd_paste_after, GDK_KEY_p, 0, 0, 0, FALSE, FALSE}, \
{cmd_paste_before, GDK_KEY_P, 0, 0, 0, FALSE, FALSE}, \
/* fold */ \
{cmd_toggle_fold, GDK_KEY_z, GDK_KEY_a, 0, 0, FALSE, FALSE}, \
{cmd_open_fold, GDK_KEY_z, GDK_KEY_o, 0, 0, FALSE, FALSE}, \
{cmd_close_fold, GDK_KEY_z, GDK_KEY_c, 0, 0, FALSE, FALSE}, \
{cmd_toggle_fold_child, GDK_KEY_z, GDK_KEY_A, 0, 0, FALSE, FALSE}, \
{cmd_open_fold_child, GDK_KEY_z, GDK_KEY_O, 0, 0, FALSE, FALSE}, \
{cmd_close_fold_child, GDK_KEY_z, GDK_KEY_C, 0, 0, FALSE, FALSE}, \
{cmd_open_fold_all, GDK_KEY_z, GDK_KEY_R, 0, 0, FALSE, FALSE}, \
{cmd_close_fold_all, GDK_KEY_z, GDK_KEY_M, 0, 0, FALSE, FALSE}, \
/* changing text */ \
{cmd_enter_insert_cut_line, GDK_KEY_c, GDK_KEY_c, 0, 0, FALSE, FALSE}, \
{cmd_enter_insert_cut_line, GDK_KEY_S, 0, 0, 0, FALSE, FALSE}, \
Expand Down
127 changes: 127 additions & 0 deletions vimode/src/cmds/fold.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
* Copyright 2024 Sylvain Cresto <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#include "cmds/fold.h"
#include "utils.h"

#define GOTO_NEAREST_PARENT 0
#define GOTO_TOPMOST_PARENT 1
#define GOTO_CONTRACTED_PARENT 2

static gint goto_above_fold(CmdParams *p, gint type)
{
/* foldparent of the next line */
gint line = SSM(p->sci, SCI_GETFOLDPARENT, p->line + 1, 0);

if (p->line == line)
; /* we are already on the fold point line */
else
{
/* foldparent of the current line */
line = SSM(p->sci, SCI_GETFOLDPARENT, p->line, 0);
}

/* retreive first parent when type != GOTO_NEAREST_PARENT
when type == GOTO_CONTRACTED_PARENT we stop on first contracted parent if exist
*/
if (type == GOTO_CONTRACTED_PARENT && line != -1 && ! SSM(p->sci, SCI_GETFOLDEXPANDED, line, 0))
; /* this fold point is contracted and type == GOTO_CONTRACTED_PARENT */
else if (type != GOTO_NEAREST_PARENT)
{
gint prev_line = line;
while (prev_line != -1)
{
prev_line = SSM(p->sci, SCI_GETFOLDPARENT, prev_line, 0);
if (prev_line != -1)
{
line = prev_line;
if (type == GOTO_CONTRACTED_PARENT && ! SSM(p->sci, SCI_GETFOLDEXPANDED, line, 0))
break;
}
}
}

if (line != -1)
{
/* move the cursor on the visible line before the fold */
gint pos = SSM(p->sci, SCI_POSITIONFROMLINE, line, 0);
SET_POS_NOX(p->sci, pos, TRUE);
}

return line;
}


void cmd_toggle_fold(CmdContext *c, CmdParams *p)
{
gint line = goto_above_fold(p, GOTO_NEAREST_PARENT);
if (line != -1)
SSM(p->sci, SCI_FOLDLINE, (uptr_t) line, SC_FOLDACTION_TOGGLE);
}


void cmd_open_fold(CmdContext *c, CmdParams *p)
{
gint line = goto_above_fold(p, GOTO_NEAREST_PARENT);
if (line != -1)
SSM(p->sci, SCI_FOLDLINE, (uptr_t) line, SC_FOLDACTION_EXPAND);
}


void cmd_close_fold(CmdContext *c, CmdParams *p)
{
gint line = goto_above_fold(p, GOTO_NEAREST_PARENT);
if (line != -1)
SSM(p->sci, SCI_FOLDLINE, (uptr_t) line, SC_FOLDACTION_CONTRACT);
}


void cmd_toggle_fold_child(CmdContext *c, CmdParams *p)
{
gint line = goto_above_fold(p, GOTO_CONTRACTED_PARENT);
if (line != -1)
SSM(p->sci, SCI_FOLDCHILDREN, (uptr_t) line, SC_FOLDACTION_TOGGLE);
}


void cmd_open_fold_child(CmdContext *c, CmdParams *p)
{
gint line = goto_above_fold(p, GOTO_NEAREST_PARENT);
SSM(p->sci, SCI_FOLDCHILDREN, (uptr_t) line, SC_FOLDACTION_EXPAND);
}


void cmd_close_fold_child(CmdContext *c, CmdParams *p)
{
gint line = goto_above_fold(p, GOTO_TOPMOST_PARENT);
if (line != -1)
SSM(p->sci, SCI_FOLDCHILDREN, (uptr_t) line, SC_FOLDACTION_CONTRACT);
}


void cmd_open_fold_all(CmdContext *c, CmdParams *p)
{
SSM(p->sci, SCI_FOLDALL, SC_FOLDACTION_EXPAND | SC_FOLDACTION_CONTRACT_EVERY_LEVEL, 0);
}


void cmd_close_fold_all(CmdContext *c, CmdParams *p)
{
goto_above_fold(p, GOTO_TOPMOST_PARENT);
SSM(p->sci, SCI_FOLDALL, SC_FOLDACTION_CONTRACT | SC_FOLDACTION_CONTRACT_EVERY_LEVEL, 0);
}
37 changes: 37 additions & 0 deletions vimode/src/cmds/fold.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2024 Sylvain Cresto <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#ifndef __VIMODE_CMDS_FOLD_H__
#define __VIMODE_CMDS_FOLD_H__

#include "context.h"
#include "cmd-params.h"

void cmd_toggle_fold(CmdContext *c, CmdParams *p);
void cmd_open_fold(CmdContext *c, CmdParams *p);
void cmd_close_fold(CmdContext *c, CmdParams *p);

void cmd_toggle_fold_child(CmdContext *c, CmdParams *p);
void cmd_open_fold_child(CmdContext *c, CmdParams *p);
void cmd_close_fold_child(CmdContext *c, CmdParams *p);

void cmd_toggle_fold_all(CmdContext *c, CmdParams *p);
void cmd_open_fold_all(CmdContext *c, CmdParams *p);
void cmd_close_fold_all(CmdContext *c, CmdParams *p);

#endif

0 comments on commit 3e38966

Please sign in to comment.